Diff for /libaitcfg/src/parse.c between versions 1.9 and 1.19

version 1.9, 2012/08/01 00:39:11 version 1.19, 2021/11/26 01:15:03
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 - 2021
         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  
 _invertQueue(cfg_root_t * __restrict cfg)  
 {  
         struct tagCfg *item, *next, *prev = NULL;  
   
         SLIST_FOREACH_SAFE(item, cfg, cfg_next, next) {  
                 item->cfg_next.sle_next = prev;  
                 prev = item;  
         }  
         cfg->slh_first = prev;  
 }  
   
   
 /*  /*
  * cfgReadConfig() - Read file and add new item at config root   * cfgReadConfig() - Read file and add new item at config root
  *   *
Line 83  _invertQueue(cfg_root_t * __restrict cfg) Line 56  _invertQueue(cfg_root_t * __restrict cfg)
 int  int
 cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)
 {  {
        char line[BUFSIZ];        char line[BUFSIZ], origin[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 };
           FILE *ff;
   
           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 101  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) Line 80  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)
                         continue;                          continue;
                 } else {                  } else {
                         *psAttr = 0;                          *psAttr = 0;
                        io_TrimStr(line);                        strlcpy(origin, line, sizeof origin);
                         str_Trim(line);
                 }                  }
   
                 if (flg) {                  if (flg) {
Line 116  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) Line 96  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));
 
                         /* read include file */
                         if (!flg && AIT_ADDR(&av->cfg_val) && 
                                         *AIT_GET_STR(&av->cfg_attr) == '%' && 
                                         !strcmp(AIT_GET_STR(&av->cfg_attr), "%include")) {
                                 ff = fopen(AIT_GET_STR(&av->cfg_val), "r");
                                 if (ff) {
                                         cfgReadConfig(ff, cfg);
                                         fclose(ff);
                                 } else
                                         EDEBUG(7, "Error:: Can't open %s file", 
                                                         AIT_GET_STR(&av->cfg_val));
                         }
                         continue;                          continue;
                 }                  }
   
                 /* *NEW PAIR* alloc new pair element */                  /* *NEW PAIR* alloc new pair element */
                av = io_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));
                         CFG_RC_LOCK(cfg);                          CFG_RC_LOCK(cfg);
                        SLIST_INSERT_HEAD(cfg, av, cfg_next);                        TAILQ_INSERT_TAIL(cfg, av, cfg_next);
                         CFG_RC_UNLOCK(cfg);                          CFG_RC_UNLOCK(cfg);
                 }                  }
   
                   /* check for comment or empty line */
                   if (!*line || *line == '#' || *line == ';') {
                           AIT_SET_STR(&av->cfg_val, line);
                           continue;
                   }
   
                 /* check for continues line */                  /* check for continues line */
                 psAttr = line + (*line ? strlen(line) : 1) - 1;                  psAttr = line + (*line ? strlen(line) : 1) - 1;
                 if (*psAttr == '\\') {                  if (*psAttr == '\\') {
Line 140  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) Line 139  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)
                         flg = 1;                          flg = 1;
                 }                  }
   
                 /* check for comment or empty line */  
                 if (!*line || *line == '#' || *line == ';') {  
                         AIT_SET_STR(&av->cfg_val, line);  
                         continue;  
                 }  
                 /* section */                  /* section */
                 if (*line == '[') {                  if (*line == '[') {
                         AIT_SET_STR(&av->cfg_val, line);  
                         psAttr = line + strlen(line) - 1;                          psAttr = line + strlen(line) - 1;
                         if (*psAttr == ']') {                          if (*psAttr == ']') {
                                 *psAttr = 0;                                   *psAttr = 0; 
                                 flg = 0;                                  flg = 0;
                                 strlcpy(szSection, line + 1, sizeof szSection);                                  strlcpy(szSection, line + 1, sizeof szSection);
                                   AIT_SET_STR(&av->cfg_sec, line);
                         } 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, origin);
                        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 172  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) Line 166  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);
                 CFG_RC_UNLOCK(cfg);                  CFG_RC_UNLOCK(cfg);
   
                   /* read include file */
                   if (!flg && *AIT_GET_STR(&av->cfg_attr) == '%' && 
                                   !strcmp(AIT_GET_STR(&av->cfg_attr), "%include")) {
                           ff = fopen(AIT_GET_STR(&av->cfg_val), "r");
                           if (ff) {
                                   cfgReadConfig(ff, cfg);
                                   fclose(ff);
                           } else
                                   EDEBUG(7, "Error:: Can't open %s file", 
                                                   AIT_GET_STR(&av->cfg_val));
                   }
         }          }
   
         return 0;          return 0;
Line 204  int Line 210  int
 cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, int whitespace)  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, int whitespace)
 {  {
         struct tagCfg *av;          struct tagCfg *av;
        time_t tim;        char line[BUFSIZ] = { 0 }, szSection[STRSIZ] = { [0 ... STRSIZ - 1] = 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);        RB_FOREACH(av, tagRC, cfg) {
        SLIST_FOREACH(av, cfg, cfg_next) {                /* empty lines or comment */
                /* add +1 line for section [] */                if (AIT_ISEMPTY(&av->cfg_attr)) {
                if (!AIT_ISEMPTY(&av->cfg_sec) &&                         if (AIT_ISEMPTY(&av->cfg_val))
                                strcmp(AIT_GET_STR(&av->cfg_sec), szSection)) {                                continue;
                         strlcpy(line, AIT_GET_STR(&av->cfg_val), sizeof line);
                         goto skip_sec;
                 }
 
                 /* section [] */
                 if (!AIT_ISEMPTY(&av->cfg_sec) && AIT_ADDR(&av->cfg_sec) && 
                                 strcmp(AIT_GET_STRZ(&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))) {
                                 LOGERR;                                  LOGERR;
                                 CFG_RC_UNLOCK(cfg);                                  CFG_RC_UNLOCK(cfg);
                                 return -1;                                  return -1;
                         }                          }
                }                } else if (AIT_ISEMPTY(&av->cfg_sec) && *szSection) {
                if (AIT_ISEMPTY(&av->cfg_sec) && *szSection) { 
                         memset(szSection, 0, sizeof szSection);                          memset(szSection, 0, sizeof szSection);
                         if (!cfg_Write(f, "\n[]\n")) {                          if (!cfg_Write(f, "\n[]\n")) {
                                 LOGERR;                                  LOGERR;
Line 232  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i Line 248  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);
skip_sec:
                 /* write */                  /* write */
                 if (!cfg_Write(f, "%s\n", line)) {                  if (!cfg_Write(f, "%s\n", line)) {
                         LOGERR;                          LOGERR;
Line 248  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i Line 264  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i
                         return -1;                          return -1;
                 }                  }
         }          }
         _invertQueue(cfg);  
         CFG_RC_UNLOCK(cfg);          CFG_RC_UNLOCK(cfg);
   
        if (whitespace) {        return 0;
                time(&tim);}
 
 /*
  * cfgWriteConfigRaw() - Write config from memory by list
  *
  * @f = File handle
  * @cfg = Config root
  * @whitespace = Additional whitespace characters to file
  * return: -1 error or 0 ok
  */
 int
 cfgWriteConfigRaw(FILE *f, cfg_root_t * __restrict cfg, int whitespace)
 {
         struct tagCfg *av, *nxt;
         char line[BUFSIZ] = { 0 }, szSection[STRSIZ] = { [0 ... STRSIZ - 1] = 0 };
 
         if (!f || !cfg) {
                 cfg_SetErr(EINVAL, "Invalid parameter(s)");
                 return -1;
         }
 
         CFG_RC_LOCK(cfg);
         TAILQ_FOREACH_SAFE(av, cfg, cfg_next, nxt) {
                 /* empty lines or comment */
                 if (AIT_ISEMPTY(&av->cfg_attr)) {
                         if (AIT_ISEMPTY(&av->cfg_val))
                                 continue;
                         strlcpy(line, AIT_GET_STR(&av->cfg_val), sizeof line);
                         goto skip_sec;
                 }
 
                 /* section [] */
                 if (!AIT_ISEMPTY(&av->cfg_sec) && AIT_ADDR(&av->cfg_sec) && 
                                 strcmp(AIT_GET_STRZ(&av->cfg_sec), szSection)) {
                         strlcpy(szSection, AIT_GET_STR(&av->cfg_sec), sizeof szSection);
                         if (!cfg_Write(f, "\n[%s]\n", AIT_GET_STR(&av->cfg_sec))) {
                                 LOGERR;
                                 CFG_RC_UNLOCK(cfg);
                                 return -1;
                         }
                 } else if (AIT_ISEMPTY(&av->cfg_sec) && *szSection) {
                         memset(szSection, 0, sizeof szSection);
                         if (!cfg_Write(f, "\n[]\n")) {
                                 LOGERR;
                                 CFG_RC_UNLOCK(cfg);
                                 return -1;
                         }
                 }
 
                 /* build line */
                 memset(line, 0, sizeof line);                  memset(line, 0, sizeof line);
                strftime(line, sizeof line, "(UTC) %Y-%m-%d %H:%M:%S", gmtime(&tim));                if (!AIT_ISEMPTY(&av->cfg_attr) && AIT_TYPE(&av->cfg_attr) == string) {
                cfg_Write(f, "\n## Config was saved at :: %s ##\n", line);                        strlcpy(line, AIT_GET_STRZ(&av->cfg_attr), sizeof line);
                         if (whitespace)
                                 strlcat(line, " = ", sizeof line);
                         else
                                 strlcat(line, "=", sizeof line);
                 }
                 if (!AIT_ISEMPTY(&av->cfg_val) && AIT_TYPE(&av->cfg_val) == string)
                         strlcat(line, AIT_GET_STRZ(&av->cfg_val), sizeof line);
 skip_sec:
                 /* write */
                 if (!cfg_Write(f, "%s\n", line)) {
                         LOGERR;
                         CFG_RC_UNLOCK(cfg);
                         return -1;
                 }
         }          }
           CFG_RC_UNLOCK(cfg);
   
         return 0;          return 0;
 }  }
   
 /*  /*
  * cfgConcatConfig() - Concat two configs into one   * cfgConcatConfig() - Concat two configs into one
  *   *
Line 279  cfgConcatConfig(cfg_root_t * __restrict cfg, cfg_root_ Line 357  cfgConcatConfig(cfg_root_t * __restrict cfg, cfg_root_
         CFG_RC_LOCK(add_cfg);          CFG_RC_LOCK(add_cfg);
         CFG_RC_LOCK(cfg);          CFG_RC_LOCK(cfg);
   
        /* concat lists */        /* concat lists & red-black trees */
        for (item = SLIST_FIRST(cfg); SLIST_NEXT(item, cfg_next); item = SLIST_NEXT(item, cfg_next));        TAILQ_FOREACH(item, add_cfg, cfg_next) {
        SLIST_NEXT(item, cfg_next) = SLIST_FIRST(add_cfg);                TAILQ_INSERT_TAIL(cfg, item, cfg_next);
 
        /* concat red-black trees */ 
        SLIST_FOREACH(item, add_cfg, 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;        TAILQ_INIT(add_cfg);
        add_cfg->rbh_root = NULL;        RB_INIT(add_cfg);
         CFG_RC_UNLOCK(add_cfg);
         pthread_mutex_destroy(&add_cfg->rc_mtx);          pthread_mutex_destroy(&add_cfg->rc_mtx);
         return 0;          return 0;
 }  }
Line 306  cfgConcatConfig(cfg_root_t * __restrict cfg, cfg_root_ Line 382  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 314  cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t Line 390  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);
        SLIST_FOREACH_SAFE(item, add_cfg, cfg_next, add_next) {
         /* merge lists */
         TAILQ_FOREACH_SAFE(item, add_cfg, cfg_next, add_next) {
                 flg = 0;                  flg = 0;
                SLIST_FOREACH_SAFE(merge, cfg, cfg_next, next) {                TAILQ_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_AFTER(merge, item, cfg_next);                        TAILQ_INSERT_TAIL(cfg, item, cfg_next);
                        RB_INSERT(tagRC, cfg, item);                else
                }                        TAILQ_INSERT_AFTER(cfg, merge, item, cfg_next);
                 RB_INSERT(tagRC, cfg, item);
         }          }
   
         CFG_RC_UNLOCK(cfg);          CFG_RC_UNLOCK(cfg);
         CFG_RC_UNLOCK(add_cfg);  
   
        add_cfg->slh_first = NULL;        TAILQ_INIT(add_cfg);
        add_cfg->rbh_root = NULL;        RB_INIT(add_cfg);
         CFG_RC_UNLOCK(add_cfg);
         pthread_mutex_destroy(&add_cfg->rc_mtx);          pthread_mutex_destroy(&add_cfg->rc_mtx);
         return 0;          return 0;
 }  }
Line 360  cfgReadLines(FILE *f, const char *delim, const char *e Line 437  cfgReadLines(FILE *f, const char *delim, const char *e
 {  {
         char line[BUFSIZ];          char line[BUFSIZ];
         struct tagCfg *d, *av = NULL;          struct tagCfg *d, *av = NULL;
        char *psAttr, *psVal = NULL;        char *p, *psSec, *psAttr, *psVal;
   
           if (!cfg)
                   return -1;
           if (!delim)
                   delim = ATR_LINES_DELIM;
   
         while (!feof(f)) {          while (!feof(f)) {
                   psSec = psAttr = psVal = NULL;
                 memset(line, 0, sizeof line);                  memset(line, 0, sizeof line);
                 fgets(line, sizeof line - 1, f);                  fgets(line, sizeof line - 1, f);
                 /* check for user end-of-file */                  /* check for user end-of-file */
Line 374  cfgReadLines(FILE *f, const char *delim, const char *e Line 457  cfgReadLines(FILE *f, const char *delim, const char *e
                         continue;                          continue;
                 } else {                  } else {
                         *psAttr = 0;                          *psAttr = 0;
                        io_TrimStr(line);                        str_Trim(line);
                         if (!*line)                          if (!*line)
                                 continue;                                  continue;
                 }                  }
   
                if (!io_MakeAV2(line, delim, &psAttr, &psVal))                if (!av_MakeExt(line, delim, &p, &psVal))
                         continue;                          continue;
                 else {                  else {
                        io_LTrimStr(psVal);                        str_RTrim(p);
                        io_RTrimStr(psAttr);                        str_LTrim(psVal);
                 }                  }
                   if (!av_MakeExt(p, SEC_LINES_DELIM, &psSec, &psAttr))
                           psAttr = p;
   
                 /* *NEW PAIR* alloc new pair element */                  /* *NEW PAIR* alloc new pair element */
                av = io_malloc(sizeof(struct tagCfg));                av = e_malloc(sizeof(struct tagCfg));
                 if (!av) {                  if (!av) {
                         LOGERR;                          LOGERR;
                         return -1;                          return -1;
                 } else                  } else
                         memset(av, 0, sizeof(struct tagCfg));                          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)                  if (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);
                 /* find & delete duplicates */                  /* find & delete duplicates */
                 if ((d = RB_FIND(tagRC, cfg, av))) {                  if ((d = RB_FIND(tagRC, cfg, av))) {
                         RB_REMOVE(tagRC, cfg, d);                          RB_REMOVE(tagRC, cfg, d);
                        SLIST_REMOVE(cfg, d, tagCfg, cfg_next);                        TAILQ_REMOVE(cfg, d, cfg_next);
   
                         AIT_FREE_VAL(&d->cfg_val);                          AIT_FREE_VAL(&d->cfg_val);
                         AIT_FREE_VAL(&d->cfg_attr);                          AIT_FREE_VAL(&d->cfg_attr);
                         AIT_FREE_VAL(&d->cfg_sec);                          AIT_FREE_VAL(&d->cfg_sec);
                        io_free(d);                        e_free(d);
                 }                  }
   
                SLIST_INSERT_HEAD(cfg, av, cfg_next);                TAILQ_INSERT_TAIL(cfg, av, cfg_next);
                 RB_INSERT(tagRC, cfg, av);                  RB_INSERT(tagRC, cfg, av);
                 CFG_RC_UNLOCK(cfg);                  CFG_RC_UNLOCK(cfg);
         }          }
Line 420  cfgReadLines(FILE *f, const char *delim, const char *e Line 510  cfgReadLines(FILE *f, const char *delim, const char *e
         return 0;          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);
   
           TAILQ_FOREACH(av, cfg, cfg_next) {
                   if (section) {
                           if (!AIT_ISEMPTY(&av->cfg_sec) && *section)
                                   continue;
                           if (strcmp(section, AIT_GET_STRZ(&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);
                   }
                   if (!AIT_ISEMPTY(&av->cfg_attr)) {
                           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.9  
changed lines
  Added in v.1.19


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