--- libaitcfg/src/parse.c 2012/07/30 09:40:19 1.8.4.1 +++ libaitcfg/src/parse.c 2012/08/06 15:08:26 1.10.2.1 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: parse.c,v 1.8.4.1 2012/07/30 09:40:19 misho Exp $ +* $Id: parse.c,v 1.10.2.1 2012/08/06 15:08:26 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -116,7 +116,7 @@ cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) flg = 0; /* concat line to value */ 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)); continue; } @@ -211,7 +211,7 @@ cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i _invertQueue(cfg); SLIST_FOREACH(av, cfg, cfg_next) { /* 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)) { strlcpy(szSection, AIT_GET_STR(&av->cfg_sec), sizeof szSection); if (!cfg_Write(f, "\n[%s]\n", AIT_GET_STR(&av->cfg_sec))) { @@ -232,14 +232,14 @@ cfgWriteConfig(FILE *f, cfg_root_t * __restrict cfg, i /* build line */ memset(line, 0, sizeof line); 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) 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_STR(&av->cfg_val), sizeof line); + strlcat(line, AIT_GET_STRZ(&av->cfg_val), sizeof line); /* write */ if (!cfg_Write(f, "%s\n", line)) { @@ -306,7 +306,7 @@ cfgConcatConfig(cfg_root_t * __restrict cfg, cfg_root_ int 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; if (!cfg || !add_cfg) @@ -314,29 +314,30 @@ cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t CFG_RC_LOCK(add_cfg); CFG_RC_LOCK(cfg); + + /* merge lists */ SLIST_FOREACH_SAFE(item, add_cfg, cfg_next, add_next) { flg = 0; SLIST_FOREACH_SAFE(merge, cfg, cfg_next, next) { 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; break; } 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))) { - SLIST_INSERT_AFTER(merge, item, cfg_next); - RB_INSERT(tagRC, cfg, item); flg = 1; break; } } - if (!flg) { + if (!flg) + SLIST_INSERT_HEAD(cfg, item, cfg_next); + else SLIST_INSERT_AFTER(merge, item, cfg_next); - RB_INSERT(tagRC, cfg, item); - } + RB_INSERT(tagRC, cfg, item); } + CFG_RC_UNLOCK(cfg); CFG_RC_UNLOCK(add_cfg); @@ -359,15 +360,14 @@ int cfgReadLines(FILE *f, const char *delim, const char *end, cfg_root_t * __restrict cfg) { char line[BUFSIZ]; - struct tagCfg *av = NULL; + struct tagCfg *d, *av = NULL; char *psAttr, *psVal = NULL; - int ret; while (!feof(f)) { memset(line, 0, sizeof line); fgets(line, sizeof line - 1, f); /* check for user end-of-file */ - if (!strcmp(line, end)) + if (strspn(line, end)) break; if (!(psAttr = strpbrk(line, "\r\n"))) { @@ -376,33 +376,44 @@ cfgReadLines(FILE *f, const char *delim, const char *e } else { *psAttr = 0; io_TrimStr(line); + if (!*line) + continue; } - /* check for comment or empty line */ - if (!*line) + + if (!io_MakeAV2(line, delim, &psAttr, &psVal)) continue; + else { + io_LTrimStr(psVal); + io_RTrimStr(psAttr); + } - ret = io_MakeAV2((char**) &line, delim, psAttr, psVal); - io_LTrimStr(psVal); - io_RTrimStr(psAttr); - /* *NEW PAIR* alloc new pair element */ av = io_malloc(sizeof(struct tagCfg)); if (!av) { LOGERR; return -1; - } else { + } else memset(av, 0, sizeof(struct tagCfg)); - CFG_RC_LOCK(cfg); - SLIST_INSERT_HEAD(cfg, av, cfg_next); - CFG_RC_UNLOCK(cfg); - } - AIT_SET_STR(&av->cfg_val, psVal ? psVal : ""); + 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*), io_align(AIT_LEN(&av->cfg_attr) - 1, 1) / 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); + io_free(d); + } + + SLIST_INSERT_HEAD(cfg, av, cfg_next); RB_INSERT(tagRC, cfg, av); CFG_RC_UNLOCK(cfg); }