--- libaitcfg/src/parse.c 2023/01/23 21:03:50 1.20.2.1 +++ libaitcfg/src/parse.c 2025/08/14 10:35:52 1.21.6.1 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: parse.c,v 1.20.2.1 2023/01/23 21:03:50 misho Exp $ +* $Id: parse.c,v 1.21.6.1 2025/08/14 10:35:52 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004 - 2023 +Copyright 2004 - 2025 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -56,7 +56,7 @@ SUCH DAMAGE. int cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) { - char line[BUFSIZ], origin[BUFSIZ]; + char line[BUFSIZ], origin[BUFSIZ], chkattr[STRSIZ]; struct tagCfg *av = NULL; int flg = 0; char *psAttr, *psVal, szSection[STRSIZ] = { 0 }; @@ -77,8 +77,14 @@ cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) break; #endif if (!(psAttr = strpbrk(line, "\r\n"))) { - /* skip line, too long */ - continue; + if (feof(f) && strlen(line) > 0) { + /* last line without end of line */ + strlcpy(origin, line, sizeof origin); + str_Trim(line); + } else { + /* skip line, too long */ + continue; + } } else { *psAttr = 0; strlcpy(origin, line, sizeof origin); @@ -115,6 +121,16 @@ cfgReadConfig(FILE *f, cfg_root_t * __restrict cfg) continue; } + /* check for duplicated element */ + if (*line != '#' && *line != ';' && *line != '/' && *line != '%' && + (psAttr = strchr(line, '='))) { + strncpy(chkattr, line, psAttr - line); + chkattr[psAttr - line] = 0; + str_RTrim(chkattr); + if (cfg_findAttribute(cfg, szSection, chkattr)) + cfg_unsetAttribute(cfg, szSection, chkattr); + } + /* *NEW PAIR* alloc new pair element */ av = e_malloc(sizeof(struct tagCfg)); if (!av) { @@ -413,15 +429,21 @@ cfgMergeConfig(cfg_root_t * __restrict cfg, cfg_root_t 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))) { - flg = 1; + flg = -1; break; } } - if (!flg) - TAILQ_INSERT_TAIL(cfg, item, cfg_next); - else - TAILQ_INSERT_AFTER(cfg, merge, item, cfg_next); + switch (flg) { + case -1: + continue; /* skip duplicated element */ + case 1: + TAILQ_INSERT_AFTER(cfg, merge, item, cfg_next); + break; + case 0: + TAILQ_INSERT_TAIL(cfg, item, cfg_next); + break; + } RB_INSERT(tagRC, cfg, item); } @@ -482,6 +504,10 @@ cfgReadLines(FILE *f, const char *delim, const char *e } if (!av_MakeExt(p, SEC_LINES_DELIM, &psSec, &psAttr)) psAttr = p; + + /* check for duplicated element */ + if (psAttr && cfg_findAttribute(cfg, psSec, psAttr)) + cfg_unsetAttribute(cfg, psSec, psAttr); /* *NEW PAIR* alloc new pair element */ av = e_malloc(sizeof(struct tagCfg));