Diff for /libaitcfg/src/parse.c between versions 1.7 and 1.12

version 1.7, 2012/04/04 13:11:49 version 1.12, 2013/05/30 09:12:27
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 44  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF TH Line 44  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF TH
 SUCH DAMAGE.  SUCH DAMAGE.
 */  */
 #include "global.h"  #include "global.h"
 #include "aitcfg.h"  
   
   
 static inline int  
 cfg_Write(FILE *f, char *fmt, ...)  
 {  
         int ret = 0;  
         va_list lst;  
   
         va_start(lst, fmt);  
         ret = vfprintf(f, fmt, lst);  
         va_end(lst);  
   
         return ret;  
 }  
   
 static inline void  static inline void
 _invertQueue(cfg_root_t * __restrict cfg)  _invertQueue(cfg_root_t * __restrict cfg)
 {  {
Line 80  _invertQueue(cfg_root_t * __restrict cfg) Line 66  _invertQueue(cfg_root_t * __restrict cfg)
  * @cfg = Config root   * @cfg = Config root
  * return: -1 error or 0 ok   * return: -1 error or 0 ok
  */   */
int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)int
 cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)
 {  {
         char line[BUFSIZ];          char line[BUFSIZ];
         struct tagCfg *av = NULL;          struct tagCfg *av = NULL;
         int flg = 0;          int flg = 0;
         char *psAttr, *psVal, szSection[STRSIZ] = { 0 };          char *psAttr, *psVal, szSection[STRSIZ] = { 0 };
   
           if (!f || !cfg) {
                   cfg_SetErr(EINVAL, "Invalid parameter(s)");
                   return -1;
           }
   
         while (!feof(f)) {          while (!feof(f)) {
                 memset(line, 0, sizeof line);                  memset(line, 0, sizeof line);
                 fgets(line, sizeof line - 1, f);                  fgets(line, sizeof line - 1, f);
Line 100  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg Line 92  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg
                         continue;                          continue;
                 } else {                  } else {
                         *psAttr = 0;                          *psAttr = 0;
                        io_TrimStr(line);                        str_Trim(line);
                 }                  }
   
                 if (flg) {                  if (flg) {
Line 115  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg Line 107  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg
                                 flg = 0;                                  flg = 0;
                         /* concat line to value */                          /* concat line to value */
                         AIT_SET_STRCAT(&av->cfg_val, line);                          AIT_SET_STRCAT(&av->cfg_val, line);
                        if (!flg)                        if (!flg && AIT_ADDR(&av->cfg_val))
                                io_UnquotStr((char*) AIT_GET_STR(&av->cfg_val));                                str_Unquot((char*) AIT_GET_STR(&av->cfg_val));
                         continue;                          continue;
                 }                  }
   
                 /* *NEW PAIR* alloc new pair element */                  /* *NEW PAIR* alloc new pair element */
                av = malloc(sizeof(struct tagCfg));                av = e_malloc(sizeof(struct tagCfg));
                 if (!av) {                  if (!av) {
                        LOGERR;                        cfg_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                         return -1;                          return -1;
                 } else {                  } else {
                         memset(av, 0, sizeof(struct tagCfg));                          memset(av, 0, sizeof(struct tagCfg));
Line 133  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg Line 125  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg
                 }                  }
   
                 /* check for continues line */                  /* check for continues line */
                psAttr = line + strlen(line) - 1;                psAttr = line + (*line ? strlen(line) : 1) - 1;
                 if (*psAttr == '\\') {                  if (*psAttr == '\\') {
                         *psAttr = 0;                          *psAttr = 0;
                         flg = 1;                          flg = 1;
Line 153  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg Line 145  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg
                                 flg = 0;                                  flg = 0;
                                 strlcpy(szSection, line + 1, sizeof szSection);                                  strlcpy(szSection, line + 1, sizeof szSection);
                         } else                          } else
                                ioDEBUG(7, "Ignore section '%s' ... not found ']'", line);                                EDEBUG(7, "Ignore section '%s' ... not found ']'", line);
                         continue;                          continue;
                 }                  }
                 /* parse pair */                  /* parse pair */
                 if (!(psAttr = strchr(line, '='))) {                  if (!(psAttr = strchr(line, '='))) {
                         AIT_SET_STR(&av->cfg_val, line);                          AIT_SET_STR(&av->cfg_val, line);
                        ioDEBUG(7, "Ignore a/v '%s' ... not found '='", line);                        EDEBUG(7, "Ignore a/v '%s' ... not found '='", line);
                         continue;                          continue;
                 } else {                  } else {
                         *psAttr = 0;                          *psAttr = 0;
Line 171  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg Line 163  int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg
                 if (*szSection) {                  if (*szSection) {
                         AIT_SET_STR(&av->cfg_sec, szSection);                          AIT_SET_STR(&av->cfg_sec, szSection);
                         AIT_KEY(&av->cfg_sec) = crcFletcher16(AIT_GET_LIKE(&av->cfg_sec, u_short*),                           AIT_KEY(&av->cfg_sec) = crcFletcher16(AIT_GET_LIKE(&av->cfg_sec, u_short*), 
                                        io_align(AIT_LEN(&av->cfg_sec) - 1, 1) / 2);                                        E_ALIGN(AIT_LEN(&av->cfg_sec) - 1, 2) / 2);
                 }                  }
   
                io_RTrimStr(psAttr);                str_RTrim(psAttr);
                io_LTrimStr(psVal);                str_LTrim(psVal);
                 if (!flg)                  if (!flg)
                        io_UnquotStr(psVal);                        str_Unquot(psVal);
                 AIT_SET_STR(&av->cfg_val, psVal);                  AIT_SET_STR(&av->cfg_val, psVal);
                 AIT_SET_STR(&av->cfg_attr, psAttr);                  AIT_SET_STR(&av->cfg_attr, psAttr);
                 AIT_KEY(&av->cfg_attr) = crcFletcher16(AIT_GET_LIKE(&av->cfg_attr, u_short*),                   AIT_KEY(&av->cfg_attr) = crcFletcher16(AIT_GET_LIKE(&av->cfg_attr, u_short*), 
                                io_align(AIT_LEN(&av->cfg_attr) - 1, 1) / 2);                                E_ALIGN(AIT_LEN(&av->cfg_attr) - 1, 2) / 2);
   
                 CFG_RC_LOCK(cfg);                  CFG_RC_LOCK(cfg);
                 RB_INSERT(tagRC, cfg, av);                  RB_INSERT(tagRC, cfg, av);
Line 206  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i Line 198  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i
         time_t tim;          time_t tim;
         char line[BUFSIZ] = { 0 }, szSection[STRSIZ] = { 0 };          char line[BUFSIZ] = { 0 }, szSection[STRSIZ] = { 0 };
   
           if (!f || !cfg) {
                   cfg_SetErr(EINVAL, "Invalid parameter(s)");
                   return -1;
           }
   
         CFG_RC_LOCK(cfg);          CFG_RC_LOCK(cfg);
         _invertQueue(cfg);          _invertQueue(cfg);
         SLIST_FOREACH(av, cfg, cfg_next) {          SLIST_FOREACH(av, cfg, cfg_next) {
                 /* add +1 line for section [] */                  /* add +1 line for section [] */
                if (!AIT_ISEMPTY(&av->cfg_sec) &&                 if (!AIT_ISEMPTY(&av->cfg_sec) && AIT_ADDR(&av->cfg_sec) && 
                                 strcmp(AIT_GET_STR(&av->cfg_sec), szSection)) {                                  strcmp(AIT_GET_STR(&av->cfg_sec), szSection)) {
                         strlcpy(szSection, AIT_GET_STR(&av->cfg_sec), sizeof szSection);                          strlcpy(szSection, AIT_GET_STR(&av->cfg_sec), sizeof szSection);
                         if (!cfg_Write(f, "\n[%s]\n", AIT_GET_STR(&av->cfg_sec))) {                          if (!cfg_Write(f, "\n[%s]\n", AIT_GET_STR(&av->cfg_sec))) {
Line 231  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i Line 228  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i
                 /* build line */                  /* build line */
                 memset(line, 0, sizeof line);                  memset(line, 0, sizeof line);
                 if (!AIT_ISEMPTY(&av->cfg_attr) && AIT_TYPE(&av->cfg_attr) == string) {                  if (!AIT_ISEMPTY(&av->cfg_attr) && AIT_TYPE(&av->cfg_attr) == string) {
                        strlcpy(line, AIT_GET_STR(&av->cfg_attr), sizeof line);                        strlcpy(line, AIT_GET_STRZ(&av->cfg_attr), sizeof line);
                         if (whitespace)                          if (whitespace)
                                 strlcat(line, " = ", sizeof line);                                  strlcat(line, " = ", sizeof line);
                         else                          else
                                 strlcat(line, "=", sizeof line);                                  strlcat(line, "=", sizeof line);
                 }                  }
                 if (!AIT_ISEMPTY(&av->cfg_val) && AIT_TYPE(&av->cfg_val) == string)                  if (!AIT_ISEMPTY(&av->cfg_val) && AIT_TYPE(&av->cfg_val) == string)
                        strlcat(line, AIT_GET_STR(&av->cfg_val), sizeof line);                        strlcat(line, AIT_GET_STRZ(&av->cfg_val), sizeof line);
   
                 /* write */                  /* write */
                 if (!cfg_Write(f, "%s\n", line)) {                  if (!cfg_Write(f, "%s\n", line)) {
                         LOGERR;                          LOGERR;
                           _invertQueue(cfg);
                         CFG_RC_UNLOCK(cfg);                          CFG_RC_UNLOCK(cfg);
                         return -1;                          return -1;
                 }                  }
Line 287  cfgConcatConfig(cfg_root_t * __restrict cfg, cfg_root_ Line 285  cfgConcatConfig(cfg_root_t * __restrict cfg, cfg_root_
                 RB_INSERT(tagRC, cfg, item);                  RB_INSERT(tagRC, cfg, item);
   
         CFG_RC_UNLOCK(cfg);          CFG_RC_UNLOCK(cfg);
         CFG_RC_UNLOCK(add_cfg);  
   
         add_cfg->slh_first = NULL;          add_cfg->slh_first = NULL;
         add_cfg->rbh_root = NULL;          add_cfg->rbh_root = NULL;
           CFG_RC_UNLOCK(add_cfg);
         pthread_mutex_destroy(&add_cfg->rc_mtx);          pthread_mutex_destroy(&add_cfg->rc_mtx);
         return 0;          return 0;
 }  }
Line 305  cfgConcatConfig(cfg_root_t * __restrict cfg, cfg_root_ Line 303  cfgConcatConfig(cfg_root_t * __restrict cfg, cfg_root_
 int  int
 cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t * __restrict add_cfg)  cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t * __restrict add_cfg)
 {  {
        struct tagCfg *item, *merge, *add_next, *next = NULL;        struct tagCfg *item, *merge, *add_next, *next;
         int flg;          int flg;
   
         if (!cfg || !add_cfg)          if (!cfg || !add_cfg)
Line 313  cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t Line 311  cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t
   
         CFG_RC_LOCK(add_cfg);          CFG_RC_LOCK(add_cfg);
         CFG_RC_LOCK(cfg);          CFG_RC_LOCK(cfg);
   
           /* merge lists */
         SLIST_FOREACH_SAFE(item, add_cfg, cfg_next, add_next) {          SLIST_FOREACH_SAFE(item, add_cfg, cfg_next, add_next) {
                 flg = 0;                  flg = 0;
                 SLIST_FOREACH_SAFE(merge, cfg, cfg_next, next) {                  SLIST_FOREACH_SAFE(merge, cfg, cfg_next, next) {
                         if (AIT_ISEMPTY(&merge->cfg_sec) && AIT_ISEMPTY(&item->cfg_sec)) {                          if (AIT_ISEMPTY(&merge->cfg_sec) && AIT_ISEMPTY(&item->cfg_sec)) {
                                 SLIST_INSERT_AFTER(merge, item, cfg_next);  
                                 RB_INSERT(tagRC, cfg, item);  
                                 flg = 1;                                  flg = 1;
                                 break;                                  break;
                         }                          }
                         if (!AIT_ISEMPTY(&merge->cfg_sec) && !AIT_ISEMPTY(&item->cfg_sec) &&                           if (!AIT_ISEMPTY(&merge->cfg_sec) && !AIT_ISEMPTY(&item->cfg_sec) && 
                                           AIT_ADDR(&merge->cfg_sec) && AIT_ADDR(&item->cfg_sec) &&
                                         !strcmp(AIT_GET_STR(&merge->cfg_sec), AIT_GET_STR(&item->cfg_sec))) {                                          !strcmp(AIT_GET_STR(&merge->cfg_sec), AIT_GET_STR(&item->cfg_sec))) {
                                 SLIST_INSERT_AFTER(merge, item, cfg_next);  
                                 RB_INSERT(tagRC, cfg, item);  
                                 flg = 1;                                  flg = 1;
                                 break;                                  break;
                         }                          }
                 }                  }
   
                if (!flg) {                if (!flg)
                         SLIST_INSERT_HEAD(cfg, item, cfg_next);
                 else
                         SLIST_INSERT_AFTER(merge, item, cfg_next);                          SLIST_INSERT_AFTER(merge, item, cfg_next);
                        RB_INSERT(tagRC, cfg, item);                RB_INSERT(tagRC, cfg, item);
                } 
         }          }
   
         CFG_RC_UNLOCK(cfg);          CFG_RC_UNLOCK(cfg);
         CFG_RC_UNLOCK(add_cfg);  
   
         add_cfg->slh_first = NULL;          add_cfg->slh_first = NULL;
         add_cfg->rbh_root = NULL;          add_cfg->rbh_root = NULL;
           CFG_RC_UNLOCK(add_cfg);
         pthread_mutex_destroy(&add_cfg->rc_mtx);          pthread_mutex_destroy(&add_cfg->rc_mtx);
         return 0;          return 0;
   }
   
   /*
    * cfgReadLines() - Read custom lines and add new item at config root
    *
    * @f = File resource
    * @delim = Custom delimiter, if =NULL default is '='
    * @end = Custom user end of file, if =NULL default is EOF
    * @cfg = Config root
    * return: -1 error or 0 ok
    */
   int
   cfgReadLines(FILE *f, const char *delim, const char *end, cfg_root_t * __restrict cfg)
   {
           char line[BUFSIZ];
           struct tagCfg *d, *av = NULL;
           char *p, *psSec, *psAttr, *psVal;
   
           if (!cfg)
                   return -1;
           if (!delim)
                   delim = ATR_LINES_DELIM;
   
           while (!feof(f)) {
                   psSec = psAttr = psVal = NULL;
                   memset(line, 0, sizeof line);
                   fgets(line, sizeof line - 1, f);
                   /* check for user end-of-file */
                   if (strspn(line, end))
                           break;
   
                   if (!(psAttr = strpbrk(line, "\r\n"))) {
                           /* skip line, too long */
                           continue;
                   } else {
                           *psAttr = 0;
                           str_Trim(line);
                           if (!*line)
                                   continue;
                   }
   
                   if (!av_MakeExt(line, delim, &p, &psVal))
                           continue;
                   else {
                           str_RTrim(p);
                           str_LTrim(psVal);
                   }
                   if (!av_MakeExt(p, SEC_LINES_DELIM, &psSec, &psAttr))
                           psAttr = p;
   
                   /* *NEW PAIR* alloc new pair element */
                   av = e_malloc(sizeof(struct tagCfg));
                   if (!av) {
                           LOGERR;
                           return -1;
                   } else
                           memset(av, 0, sizeof(struct tagCfg));
   
                   if (psSec) {
                           AIT_SET_STR(&av->cfg_sec, psSec);
                           AIT_KEY(&av->cfg_sec) = crcFletcher16(AIT_GET_LIKE(&av->cfg_sec, u_short*), 
                                           E_ALIGN(AIT_LEN(&av->cfg_sec) - 1, 2) / 2);
                   }
                   if (psVal)
                           AIT_SET_STR(&av->cfg_val, psVal);
                   AIT_SET_STR(&av->cfg_attr, psAttr);
                   AIT_KEY(&av->cfg_attr) = crcFletcher16(AIT_GET_LIKE(&av->cfg_attr, u_short*), 
                                   E_ALIGN(AIT_LEN(&av->cfg_attr) - 1, 2) / 2);
   
                   CFG_RC_LOCK(cfg);
                   /* find & delete duplicates */
                   if ((d = RB_FIND(tagRC, cfg, av))) {
                           RB_REMOVE(tagRC, cfg, d);
                           SLIST_REMOVE(cfg, d, tagCfg, cfg_next);
   
                           AIT_FREE_VAL(&d->cfg_val);
                           AIT_FREE_VAL(&d->cfg_attr);
                           AIT_FREE_VAL(&d->cfg_sec);
                           e_free(d);
                   }
   
                   SLIST_INSERT_HEAD(cfg, av, cfg_next);
                   RB_INSERT(tagRC, cfg, av);
                   CFG_RC_UNLOCK(cfg);
           }
   
           return 0;
   }
   
   /*
    * cfgWriteLines() - Write custom lines and export data to variable
    *
    * @f = File resource
    * @delim = Custom delimiter, if =NULL default is '='
    * @eol = End of line string, if =NULL default is "\n"
    * @section = Export only section, if =NULL default is all
    * @cfg = Config root
    * return: =NULL error or !=NULL exported data, must be free after use with ait_freeVar()
    */
   ait_val_t *
   cfgWriteLines(FILE *f, const char *delim, const char *eol, const char *section, cfg_root_t * __restrict cfg)
   {
           ait_val_t *v = NULL;
           struct tagCfg *av;
   
           if (!cfg)
                   return NULL;
           if (!delim)
                   delim = ATR_LINES_DELIM;
           if (!eol)
                   eol = EOL_LINES_DELIM;
           if (!(v = ait_allocVar())) {
                   cfg_SetErr(elwix_GetErrno(), "%s", elwix_GetError());
                   return NULL;
           } else
                   AIT_INIT_VAL2(v, string);
   
           SLIST_FOREACH(av, cfg, cfg_next) {
                   if (AIT_ISEMPTY(&av->cfg_attr))
                           continue;
                   if (section) {
                           if (!AIT_ISEMPTY(&av->cfg_sec) && *section)
                                   continue;
                           if (strcmp(section, AIT_GET_STR(&av->cfg_sec)))
                                   continue;
                   }
   
                   if (!AIT_ISEMPTY(&av->cfg_sec)) {
                           AIT_SET_STRCAT(v, AIT_GET_STR(&av->cfg_sec));
                           AIT_SET_STRCAT(v, SEC_LINES_DELIM);
                   }
                   AIT_SET_STRCAT(v, AIT_GET_STR(&av->cfg_attr));
                   AIT_SET_STRCAT(v, delim);
                   if (!AIT_ISEMPTY(&av->cfg_val))
                           AIT_SET_STRCAT(v, AIT_GET_STR(&av->cfg_val));
                   AIT_SET_STRCAT(v, eol);
           }
   
           if (f)
                   fputs(AIT_GET_STR(v), f);
           return v;
 }  }

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


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>