Diff for /libaitcfg/src/parse.c between versions 1.13 and 1.18

version 1.13, 2014/01/29 23:48:34 version 1.18, 2019/11/21 14:30:02
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 - 2014Copyright 2004 - 2018
         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 46  SUCH DAMAGE. Line 46  SUCH DAMAGE.
 #include "global.h"  #include "global.h"
   
   
 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 69  _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) {          if (!f || !cfg) {
                 cfg_SetErr(EINVAL, "Invalid parameter(s)");                  cfg_SetErr(EINVAL, "Invalid parameter(s)");
Line 92  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;
                           strlcpy(origin, line, sizeof origin);
                         str_Trim(line);                          str_Trim(line);
                 }                  }
   
Line 109  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) Line 98  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)
                         AIT_SET_STRCAT(&av->cfg_val, line);                          AIT_SET_STRCAT(&av->cfg_val, line);
                         if (!flg && AIT_ADDR(&av->cfg_val))                          if (!flg && AIT_ADDR(&av->cfg_val))
                                 str_Unquot((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;
                 }                  }
   
Line 120  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) Line 122  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)
                 } 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 131  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 == '[') {
                         psAttr = line + strlen(line) - 1;                          psAttr = line + strlen(line) - 1;
Line 150  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) Line 153  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)
                 }                  }
                 /* 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);
                         EDEBUG(7, "Ignore a/v '%s' ... not found '='", line);                          EDEBUG(7, "Ignore a/v '%s' ... not found '='", line);
                         continue;                          continue;
                 } else {                  } else {
Line 178  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) Line 181  cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg)
                 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 195  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 ... STRSIZ - 1] = 0 };
   
         if (!f || !cfg) {          if (!f || !cfg) {
Line 204  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i Line 218  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i
         }          }
   
         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 */                  /* empty lines or comment */
                 if (AIT_ISEMPTY(&av->cfg_attr)) {                  if (AIT_ISEMPTY(&av->cfg_attr)) {
                         if (AIT_ISEMPTY(&av->cfg_val))                          if (AIT_ISEMPTY(&av->cfg_val))
Line 216  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i Line 229  cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i
   
                 /* section [] */                  /* section [] */
                 if (!AIT_ISEMPTY(&av->cfg_sec) && AIT_ADDR(&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_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, "[%s]\n", AIT_GET_STR(&av->cfg_sec))) {                        if (!cfg_Write(f, "\n[%s]\n", AIT_GET_STR(&av->cfg_sec))) {
                                 LOGERR;                                  LOGERR;
                                 _invertQueue(cfg);  
                                 CFG_RC_UNLOCK(cfg);                                  CFG_RC_UNLOCK(cfg);
                                 return -1;                                  return -1;
                         }                          }
                 } else if (AIT_ISEMPTY(&av->cfg_sec) && *szSection) {                  } else if (AIT_ISEMPTY(&av->cfg_sec) && *szSection) {
                         memset(szSection, 0, sizeof szSection);                          memset(szSection, 0, sizeof szSection);
                        if (!cfg_Write(f, "[]\n")) {                        if (!cfg_Write(f, "\n[]\n")) {
                                 LOGERR;                                  LOGERR;
                                 _invertQueue(cfg);  
                                 CFG_RC_UNLOCK(cfg);                                  CFG_RC_UNLOCK(cfg);
                                 return -1;                                  return -1;
                         }                          }
Line 249  skip_sec: Line 260  skip_sec:
                 /* 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;
                 }                  }
         }          }
         _invertQueue(cfg);  
         CFG_RC_UNLOCK(cfg);          CFG_RC_UNLOCK(cfg);
   
         if (whitespace) {  
                 time(&tim);  
                 memset(line, 0, sizeof line);  
                 strftime(line, sizeof line, "(UTC) %Y-%m-%d %H:%M:%S", gmtime(&tim));  
                 cfg_Write(f, "\n## Config was saved at :: %s ##\n", line);  
         }  
   
         return 0;          return 0;
 }  }
   
Line 285  cfgConcatConfig(cfg_root_t * __restrict cfg, cfg_root_ Line 287  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);
   
        add_cfg->slh_first = NULL;        TAILQ_INIT(add_cfg);
        add_cfg->rbh_root = NULL;        RB_INIT(add_cfg);
         CFG_RC_UNLOCK(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 322  cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t Line 322  cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t
         CFG_RC_LOCK(cfg);          CFG_RC_LOCK(cfg);
   
         /* merge lists */          /* merge lists */
        SLIST_FOREACH_SAFE(item, add_cfg, cfg_next, add_next) {        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)) {
                                 flg = 1;                                  flg = 1;
                                 break;                                  break;
Line 338  cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t Line 338  cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t
                 }                  }
   
                 if (!flg)                  if (!flg)
                        SLIST_INSERT_HEAD(cfg, item, cfg_next);                        TAILQ_INSERT_TAIL(cfg, item, cfg_next);
                 else                  else
                        SLIST_INSERT_AFTER(merge, item, cfg_next);                        TAILQ_INSERT_AFTER(cfg, merge, item, cfg_next);
                 RB_INSERT(tagRC, cfg, item);                  RB_INSERT(tagRC, cfg, item);
         }          }
   
         CFG_RC_UNLOCK(cfg);          CFG_RC_UNLOCK(cfg);
   
        add_cfg->slh_first = NULL;        TAILQ_INIT(add_cfg);
        add_cfg->rbh_root = NULL;        RB_INIT(add_cfg);
         CFG_RC_UNLOCK(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 424  cfgReadLines(FILE *f, const char *delim, const char *e Line 424  cfgReadLines(FILE *f, const char *delim, const char *e
                 /* 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);
Line 432  cfgReadLines(FILE *f, const char *delim, const char *e Line 432  cfgReadLines(FILE *f, const char *delim, const char *e
                         e_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 468  cfgWriteLines(FILE *f, const char *delim, const char * Line 468  cfgWriteLines(FILE *f, const char *delim, const char *
         } else          } else
                 AIT_INIT_VAL2(v, string);                  AIT_INIT_VAL2(v, string);
   
        SLIST_FOREACH(av, cfg, cfg_next) {        TAILQ_FOREACH(av, cfg, cfg_next) {
                if (AIT_ISEMPTY(&av->cfg_attr)) 
                        continue; 
                 if (section) {                  if (section) {
                         if (!AIT_ISEMPTY(&av->cfg_sec) && *section)                          if (!AIT_ISEMPTY(&av->cfg_sec) && *section)
                                 continue;                                  continue;
                        if (strcmp(section, AIT_GET_STR(&av->cfg_sec)))                        if (strcmp(section, AIT_GET_STRZ(&av->cfg_sec)))
                                 continue;                                  continue;
                 }                  }
   
Line 482  cfgWriteLines(FILE *f, const char *delim, const char * Line 480  cfgWriteLines(FILE *f, const char *delim, const char *
                         AIT_SET_STRCAT(v, AIT_GET_STR(&av->cfg_sec));                          AIT_SET_STRCAT(v, AIT_GET_STR(&av->cfg_sec));
                         AIT_SET_STRCAT(v, SEC_LINES_DELIM);                          AIT_SET_STRCAT(v, SEC_LINES_DELIM);
                 }                  }
                AIT_SET_STRCAT(v, AIT_GET_STR(&av->cfg_attr));                if (!AIT_ISEMPTY(&av->cfg_attr)) {
                AIT_SET_STRCAT(v, delim);                        AIT_SET_STRCAT(v, AIT_GET_STR(&av->cfg_attr));
                         AIT_SET_STRCAT(v, delim);
                 }
                 if (!AIT_ISEMPTY(&av->cfg_val))                  if (!AIT_ISEMPTY(&av->cfg_val))
                         AIT_SET_STRCAT(v, AIT_GET_STR(&av->cfg_val));                          AIT_SET_STRCAT(v, AIT_GET_STR(&av->cfg_val));
                 AIT_SET_STRCAT(v, eol);                  AIT_SET_STRCAT(v, eol);

Removed from v.1.13  
changed lines
  Added in v.1.18


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