Diff for /np2/common/profile.c between versions 1.3 and 1.7

version 1.3, 2004/02/19 11:32:11 version 1.7, 2004/04/07 13:33:23
Line 1 Line 1
 #include        "compiler.h"  #include        "compiler.h"
   #include        "strres.h"
 #include        "dosio.h"  #include        "dosio.h"
 #include        "textfile.h"  #include        "textfile.h"
 #include        "profile.h"  #include        "profile.h"
Line 144  const char *profile_getarg(const char *s Line 145  const char *profile_getarg(const char *s
 }  }
   
   
 // ----  
   
 typedef struct {  
         UINT8   num;  
         char    str[7];  
 } KEYNAME;  
   
 #include        "pf_key.tbl"  
   
 static const char *getarg(const char *str, char *buf, UINT leng) {  // ---- まだテスト
   
         UINT8   c;  typedef struct {
           UINT    applen;
         if (leng) {          UINT    keylen;
                 leng--;          UINT    pos;
         }          UINT    size;
         else {          UINT    apphit;
                 buf = NULL;  const char      *data;
         }          UINT    datasize;
         if (str) {  } PFPOS;
                 c = (UINT8)*str;  
                 while(((c - 1) & 0xff) < 0x20) {  static char *delspace(const char *buf, UINT *len) {
                         str++;  
                         c = (UINT8)*str;          UINT    l;
   
           if ((buf != NULL) && (len != NULL)) {
                   l = *len;
                   while((l) && (buf[0] == ' ')) {
                           l--;
                           buf++;
                 }                  }
                 if (c == 0) {                  while((l) && (buf[l - 1] == ' ')) {
                         str = NULL;                          l--;
                 }                  }
                   *len = l;
         }          }
         if (str) {          return((char *)buf);
                 c = (UINT8)*str;  }
                 while(c > 0x20) {  
                         if (leng) {  static BOOL seakey(PFILEH hdl, PFPOS *pfp, const char *app, const char *key) {
                                 *buf++ = c;  
                                 leng--;          PFPOS   ret;
           UINT    pos;
           UINT    size;
           char    *buf;
           UINT    len;
           UINT    cnt;
   
           if ((hdl == NULL) || (app == NULL) || (key == NULL)) {
                   return(FAILURE);
           }
           ZeroMemory(&ret, sizeof(ret));
           ret.applen = strlen(app);
           ret.keylen = strlen(key);
           if ((ret.applen == 0) || (ret.keylen == 0)) {
                   return(FAILURE);
           }
   
           pos = 0;
           size = hdl->size;
           while(size) {
                   buf = hdl->buffer + pos;
                   len = 0;
                   cnt = 0;
                   do {
                           if (buf[len] == '\r') {
                                   if (((len + 1) < size) && (buf[len + 1] == '\n')) {
                                           cnt = 2;
                                   }
                                   else {
                                           cnt = 1;
                                   }
                                   break;
                           }
                           if (buf[len] == '\n') {
                                   cnt = 1;
                                   break;
                           }
                           len++;
                   } while(len < size);
                   cnt += len;
                   buf = delspace(buf, &len);
                   if ((len >= 2) && (buf[0] == '[') && (buf[len - 1] == ']')) {
                           if (ret.apphit) {
                                   break;
                           }
                           buf++;
                           len -= 2;
                           buf = delspace(buf, &len);
                           if ((len == ret.applen) && (!milstr_memcmp(buf, app))) {
                                   ret.apphit = 1;
                         }                          }
                         str++;  
                         c = (UINT8)*str;  
                 }                  }
                   else if ((ret.apphit) && (len > ret.keylen) &&
                                   (!milstr_memcmp(buf, key))) {
                           buf += ret.keylen;
                           len -= ret.keylen;
                           buf = delspace(buf, &len);
                           if ((len) && (buf[0] == '=')) {
                                   buf++;
                                   len--;
                                   buf = delspace(buf, &len);
                                   ret.pos = pos;
                                   ret.size = cnt;
                                   ret.data = buf;
                                   ret.datasize = len;
                                   break;
                           }
                   }
                   if (len) {
                           ret.pos = pos + cnt;
                           ret.size = 0;
                   }
                   pos += cnt;
                   size -= cnt;
         }          }
         if (buf) {          if (pfp) {
                 buf[0] = '\0';                  *pfp = ret;
         }          }
         return(str);          return(SUCCESS);
 }  }
   
 static const KEYNAME *searchkeynum(const char *str) {  static BOOL replace(PFILEH hdl, UINT pos, UINT size1, UINT size2) {
   
 const KEYNAME   *n;          UINT    cnt;
 const KEYNAME   *nterm;          UINT    size;
           char    *p;
           char    *q;
   
         n = keyname;          size1 += pos;
         nterm = keyname + (sizeof(keyname) / sizeof(KEYNAME));          size2 += pos;
         while(n < nterm) {          if (size1 > hdl->size) {
                 if (!milstr_cmp(str, n->str)) {                  return(FAILURE);
                         return(n);          }
           cnt = hdl->size - size1;
           if (size1 < size2) {
                   size = size2 - size1;
                   if ((hdl->size + size) > hdl->buffers) {
                           return(FAILURE);
                   }
                   hdl->size += size;
                   if (cnt) {
                           p = hdl->buffer + size1;
                           q = hdl->buffer + size2;
                           do {
                                   --cnt;
                                   q[cnt] = p[cnt];
                           } while(cnt);
                   }
           }
           else if (size1 > size2) {
                   hdl->size -= (size1 - size2);
                   if (cnt) {
                           p = hdl->buffer + size1;
                           q = hdl->buffer + size2;
                           do {
                                   *q++ = *p++;
                           } while(--cnt);
                 }                  }
                 n++;  
         }          }
           hdl->flag |= PFILEH_MODIFY;
           return(SUCCESS);
   }
   
   PFILEH profile_open(const char *filename, UINT flag) {
   
           FILEH   fh;
           UINT    filesize;
           UINT    size;
           PFILEH  ret;
   
           if (filename == NULL) {
                   goto pfore_err1;
           }
           fh = file_open(filename);
           filesize = 0;
           if (fh != FILEH_INVALID) {
                   filesize = file_getsize(fh);
           }
           else if (flag & PFILEH_READONLY) {
                   goto pfore_err1;
           }
           else {
                   fh = file_create(filename);
                   if (fh == FILEH_INVALID) {
                           goto pfore_err1;
                   }
           }
           size = filesize + 0x2000;
           ret = (PFILEH)_MALLOC(sizeof(_PFILEH) + size, filename);
           if (ret == NULL) {
                   goto pfore_err2;
           }
           if (filesize) {
                   if (file_read(fh, ret + 1, filesize) != filesize) {
                           goto pfore_err3;
                   }
           }
           file_close(fh);
           ret->buffer = (BYTE *)(ret + 1);
           ret->buffers = size;
           ret->size = filesize;
           ret->flag = flag;
           file_cpyname(ret->path, filename, sizeof(ret->path));
           return(ret);
   
   pfore_err3:
           _MFREE(ret);
   
   pfore_err2:
           file_close(fh);
   
   pfore_err1:
         return(NULL);          return(NULL);
 }  }
   
 static const KEYNAME *searchkeystr(UINT8 num) {  void profile_close(PFILEH hdl) {
   
 const KEYNAME   *n;          FILEH   fh;
 const KEYNAME   *nterm;  
   
         n = keyname;          if (hdl) {
         nterm = keyname + (sizeof(keyname) / sizeof(KEYNAME));                  if (hdl->flag & PFILEH_MODIFY) {
         while(n < nterm) {                          fh = file_create(hdl->path);
                 if (n->num == num) {                          if (fh != FILEH_INVALID) {
                         return(n);                                  file_write(fh, hdl->buffer, hdl->size);
                                   file_close(fh);
                           }
                 }                  }
                 n++;                  _MFREE(hdl);
         }          }
         return(NULL);  
 }  }
   
 UINT profile_setkeys(const char *str, UINT8 *key, UINT keymax) {  BOOL profile_read(const char *app, const char *key, const char *def,
                                                                                   char *ret, UINT size, PFILEH hdl) {
   
         UINT            ret;          PFPOS   pfp;
         char            work[7];  
 const KEYNAME   *k;          if ((seakey(hdl, &pfp, app, key) != SUCCESS) || (pfp.data == NULL)) {
                   if (def == NULL) {
         ret = 0;                          def = str_null;
         while(ret < keymax) {  
                 str = getarg(str, work, sizeof(work));  
                 if (str == NULL) {  
                         break;  
                 }                  }
                 k = searchkeynum(work);                  milstr_ncpy(ret, def, size);
                 if (k) {                  return(FAILURE);
                         key[ret] = k->num;          }
                         ret++;          else {
                   size = min(size, pfp.datasize + 1);
                   milstr_ncpy(ret, pfp.data, size);
                   return(SUCCESS);
           }
   }
   
   BOOL profile_write(const char *app, const char *key,
                                                                                           const char *data, PFILEH hdl) {
   
           PFPOS   pfp;
           UINT    newsize;
           UINT    datalen;
           char    *buf;
   
           if ((hdl == NULL) || (hdl->flag & PFILEH_READONLY) ||
                   (data == NULL) || (seakey(hdl, &pfp, app, key) != SUCCESS)) {
                   return(FAILURE);
           }
           if (!pfp.apphit) {
                   newsize = pfp.applen + 2 + 2;
                   if (replace(hdl, pfp.pos, 0, newsize) != SUCCESS) {
                           return(FAILURE);
                   }
                   buf = hdl->buffer + pfp.pos;
                   *buf++ = '[';
                   CopyMemory(buf, app, pfp.applen);
                   buf += pfp.applen;
                   buf[0] = ']';
                   buf[1] = '\r';
                   buf[2] = '\n';
                   pfp.pos += newsize;
           }
           datalen = strlen(data);
           newsize = pfp.keylen + 1 + datalen + 2;
           if (replace(hdl, pfp.pos, pfp.size, newsize) != SUCCESS) {
                   return(FAILURE);
           }
           buf = hdl->buffer + pfp.pos;
           CopyMemory(buf, key, pfp.keylen);
           buf += pfp.keylen;
           *buf++ = '=';
           CopyMemory(buf, data, datalen);
           buf += datalen;
           buf[0] = '\r';
           buf[1] = '\n';
           return(SUCCESS);
   }
   
   
   // ----
   
   void profile_iniread(const char *path, const char *app,
                                                                   const PFTBL *tbl, UINT count, PFREAD cb) {
   
           PFILEH  pfh;
   const PFTBL     *p;
   const PFTBL     *pterm;
           char    work[512];
   
           pfh = profile_open(path, 0);
           if (pfh == NULL) {
                   return;
           }
           p = tbl;
           pterm = tbl + count;
           while(p < pterm) {
                   if (profile_read(app, p->item, NULL, work, sizeof(work), pfh)
                                                                                                                                   == SUCCESS) {
                           switch(p->itemtype & PFITYPE_MASK) {
                                   case PFTYPE_STR:
                                           milstr_ncpy(p->value, work, p->arg);
                                           break;
   
                                   case PFTYPE_BOOL:
                                           *((UINT8 *)p->value) = (!milstr_cmp(work, str_true))?1:0;
                                           break;
   
                                   case PFTYPE_BITMAP:             // Todo
                                   case PFTYPE_BIN:
                                           break;
   
                                   case PFTYPE_SINT8:
                                   case PFTYPE_UINT8:
                                           *(UINT8 *)p->value = (UINT32)milstr_solveINT(work);
                                           break;
   
                                   case PFTYPE_SINT16:
                                   case PFTYPE_UINT16:
                                           *(UINT16 *)p->value = (UINT32)milstr_solveINT(work);
                                           break;
   
                                   case PFTYPE_SINT32:
                                   case PFTYPE_UINT32:
                                           *(UINT32 *)p->value = (UINT32)milstr_solveINT(work);
                                           break;
   
                                   case PFTYPE_HEX8:
                                           *(UINT8 *)p->value = (UINT8)milstr_solveHEX(work);
                                           break;
   
                                   case PFTYPE_HEX16:
                                           *(UINT16 *)p->value = (UINT16)milstr_solveHEX(work);
                                           break;
   
                                   case PFTYPE_HEX32:
                                           *(UINT32 *)p->value = (UINT32)milstr_solveHEX(work);
                                           break;
   
                                   default:
                                           if (cb != NULL) {
                                                   (*cb)(p, work);
                                           }
                                           break;
                           }
                 }                  }
                   p++;
         }          }
         return(ret);          profile_close(pfh);
 }  }
   
 void profile_getkeys(char *str, UINT strmax, const UINT8 *key, UINT keys) {  void profile_iniwrite(const char *path, const char *app,
                                                                   const PFTBL *tbl, UINT count, PFWRITE cb) {
   
         UINT            space;          PFILEH  pfh;
         UINT            i;  const PFTBL     *p;
 const KEYNAME   *k;  const PFTBL     *pterm;
         UINT            len;  const char      *set;
           char    work[512];
   
         if ((str == NULL) || (strmax == 0)) {          pfh = profile_open(path, 0);
           if (pfh == NULL) {
                 return;                  return;
         }          }
         strmax--;          p = tbl;
         space = 0;          pterm = tbl + count;
         for (i=0; i<keys; i++) {          while(p < pterm) {
                 k = searchkeystr(key[i]);                  if (!(p->itemtype & PFFLAG_RO)) {
                 if (k) {                          work[0] = '\0';
                         len = strlen(k->str);                          set = work;
                         if ((len + space) > strmax) {                          switch(p->itemtype & PFITYPE_MASK) {
                                 break;                                  case PFTYPE_STR:
                                           set = (char *)p->value;
                                           break;
   
                                   case PFTYPE_BOOL:
                                           set = (*((UINT8 *)p->value))?str_true:str_false;
                                           break;
   
                                   case PFTYPE_BITMAP:             // Todo
                                   case PFTYPE_BIN:
                                           set = NULL;
                                           break;
   
                                   case PFTYPE_SINT8:
                                           SPRINTF(work, str_d, *((SINT8 *)p->value));
                                           break;
   
                                   case PFTYPE_SINT16:
                                           SPRINTF(work, str_d, *((SINT16 *)p->value));
                                           break;
   
                                   case PFTYPE_SINT32:
                                           SPRINTF(work, str_d, *((SINT32 *)p->value));
                                           break;
   
                                   case PFTYPE_UINT8:
                                           SPRINTF(work, str_u, *((UINT8 *)p->value));
                                           break;
   
                                   case PFTYPE_UINT16:
                                           SPRINTF(work, str_u, *((UINT16 *)p->value));
                                           break;
   
                                   case PFTYPE_UINT32:
                                           SPRINTF(work, str_u, *((UINT32 *)p->value));
                                           break;
   
                                   case PFTYPE_HEX8:
                                           SPRINTF(work, str_x, *((UINT8 *)p->value));
                                           break;
   
                                   case PFTYPE_HEX16:
                                           SPRINTF(work, str_x, *((UINT16 *)p->value));
                                           break;
   
                                   case PFTYPE_HEX32:
                                           SPRINTF(work, str_x, *((UINT32 *)p->value));
                                           break;
   
                                   default:
                                           if (cb != NULL) {
                                                   set = (*cb)(p, work, sizeof(work));
                                           }
                                           else {
                                                   set = NULL;
                                           }
                                           break;
                         }                          }
                         if (space) {                          if (set) {
                                 *str++ = ' ';                                  profile_write(app, p->item, set, pfh);
                         }                          }
                         CopyMemory(str, k->str, len);  
                         str += len;  
                         space = 1;  
                 }                  }
                   p++;
         }          }
         str[0] = '\0';          profile_close(pfh);
 }  }
   

Removed from v.1.3  
changed lines
  Added in v.1.7


RetroPC.NET-CVS <cvs@retropc.net>