Annotation of libaitcfg/src/parse.c, revision 1.5

1.2       misho       1: /*************************************************************************
                      2: * (C) 2008 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
                      3: *  by Michael Pounov <misho@openbsd-bg.org>
                      4: *
                      5: * $Author: misho $
1.4       misho       6: * $Id: parse.c,v 1.3.2.1 2009/11/11 14:46:36 misho Exp $
1.2       misho       7: *
                      8: *************************************************************************/
1.1       misho       9: #include "global.h"
                     10: #include "aitcfg.h"
                     11: #include "tools.h"
                     12: 
                     13: 
                     14: // cfgDbg() Debug/Log operation
                     15: static inline int cfgDbg(FILE *f, char *fmt, ...)
                     16: {
                     17:        int ret = 0;
                     18:        va_list lst;
                     19: 
                     20:        va_start(lst, fmt);
                     21:        ret = vfprintf(f, fmt, lst);
                     22:        va_end(lst);
                     23: 
                     24:        return ret;
                     25: }
                     26: 
1.3       misho      27: /*
                     28:  * InvertQueue() InvertQueue order //{cfg} list of elements for revert
                     29:  * @cfg = Head list element for revert 
                     30: */
                     31: static inline void InvertQueue(sl_config * __restrict cfg)
                     32: {
                     33:        struct tagPair *item, *next, *prev = NULL;
                     34: 
                     35:        for (item = cfg->slh_first; item; item = next) {
                     36:                next = item->sle_next;
                     37:                item->sle_next = prev;
                     38:                prev = item;
                     39:        }
                     40:        cfg->slh_first = prev;
                     41: }
                     42: 
                     43: // cfgWrite() Write to file from config list
                     44: static inline int cfgWrite(FILE *f, sl_config * __restrict cfg, int whitespace)
                     45: {
                     46:        struct tagPair *av;
                     47:        time_t tim;
                     48:        char szTime[MAX_STR + 1];
                     49:        u_char szSection[MAX_STR + 1];
                     50: 
                     51:        bzero(szSection, MAX_STR + 1);
                     52: 
                     53:        bzero(szTime, MAX_STR + 1);
                     54:        time(&tim);
                     55:        strftime(szTime, MAX_STR, "(UTC) %Y-%m-%d %H:%M:%S", gmtime(&tim));
                     56:        if (!cfgDbg(f, "## Write Config :: %s\n#\n", szTime)) {
                     57:                LOGERR;
                     58:                return -1;
                     59:        }
                     60: 
                     61:        InvertQueue(cfg);
                     62:        for (av = cfg->slh_first; av; av = av->sle_next) {
                     63:                if (av->psSection && strcmp((char*) av->psSection, (char*) szSection)) {
                     64:                        strlcpy((char*) szSection, (char*) av->psSection, MAX_STR + 1);
                     65:                        if (!cfgDbg(f, "\n[%s]\n", av->psSection)) {
                     66:                                LOGERR;
                     67:                                return -1;
                     68:                        }
                     69:                }
                     70:                if (!av->psSection && *szSection) {
                     71:                        bzero(szSection, MAX_STR + 1);
                     72:                        if (!cfgDbg(f, "\n[]\n")) {
                     73:                                LOGERR;
                     74:                                return -1;
                     75:                        }
                     76:                }
                     77: 
                     78:                if (whitespace) {
                     79:                        if (!cfgDbg(f, "%s = %s\n", av->psAttribute, av->psValue)) {
                     80:                                LOGERR;
                     81:                                return -1;
                     82:                        }
                     83:                } else {
                     84:                        if (!cfgDbg(f, "%s=%s\n", av->psAttribute, av->psValue)) {
                     85:                                LOGERR;
                     86:                                return -1;
                     87:                        }
                     88:                }
                     89:        }
                     90:        InvertQueue(cfg);
                     91: 
                     92:        bzero(szTime, MAX_STR + 1);
                     93:        time(&tim);
                     94:        strftime(szTime, MAX_STR, "(UTC) %Y-%m-%d %H:%M:%S", gmtime(&tim));
                     95:        if (!cfgDbg(f, "\n#\n## Done. :: %s\n", szTime)) {
                     96:                LOGERR;
                     97:                return -1;
                     98:        }
                     99: 
                    100:        return 0;
                    101: }
                    102: 
                    103: // ---------------------------------------------------
1.1       misho     104: 
                    105: /*
                    106:  * ReadConfig() Read from file and add new item to config list
                    107:  * @f = file resource
                    108:  * @cfg = Head list element
                    109:  * return: 0 ok; -1 error:: can`t allocate memory
                    110: */
                    111: int ReadConfig(FILE *f, sl_config * __restrict cfg)
                    112: {
                    113:        u_char szLine[MAX_STR + 1];
                    114:        u_char szSection[MAX_STR + 1], *psAttr, *psVal;
                    115:        int pos;
                    116:        struct tagPair *av;
                    117: 
                    118:        memset(szSection, 0, MAX_STR + 1);
                    119:        while (!feof(f)) {
                    120:                memset(szLine, 0, MAX_STR + 1);
                    121:                fgets((char*) szLine, MAX_STR, f);
                    122:                trim(szLine);
                    123: #ifdef __DEBUG
                    124:                cfgDbg(stdout, "DEBUG:: RAW |%s|\n", szLine);
                    125: #endif
                    126: 
                    127:                // End of config
                    128:                if (*szLine == '.')
                    129:                        break;
                    130:                // Comment
                    131:                if (*szLine == '#' || *szLine == ';' || !*szLine)
                    132:                        continue;
                    133: 
                    134: #ifdef __DEBUG
                    135:                cfgDbg(stdout, "DEBUG:: Clean |%s|\n", szLine);
                    136: #endif
                    137: 
                    138:                // Section
                    139:                if (*szLine == '[') {
                    140:                        pos = strlen((char*) szLine) - 1;
                    141:                        if (szLine[pos] != ']') {
1.2       misho     142: #ifdef __DEBUG
1.1       misho     143:                                cfgDbg(stdout, "WARNING:: Ignore section %s ... not closed breket\n", szLine);
1.2       misho     144: #endif
1.1       misho     145:                        } else {
                    146:                                szLine[pos] = 0; 
                    147:                                strncpy((char*) szSection, (char*) szLine + 1, MAX_STR);
                    148: #ifdef __DEBUG
                    149:                                cfgDbg(stdout, "DEBUG:: Section %s\n", szSection);
                    150: #endif
                    151:                        }
                    152:                        continue;
                    153:                }
                    154: 
                    155:                // Devide pairs
                    156:                pos = strchr((char*) szLine, '=') ? strchr((char*) szLine, '=') - (char*) szLine : 0;
                    157:                if (!pos) {
1.2       misho     158: #ifdef __DEBUG
1.1       misho     159:                        cfgDbg(stdout, "WARNING:: Ignore a/v %s ... format error!\n", szLine);
1.2       misho     160: #endif
1.1       misho     161:                        continue;
                    162:                } else {
                    163:                        av = malloc(sizeof(struct tagPair));
                    164:                        if (!av) {
                    165:                                LOGERR;
                    166:                                return -1;
                    167:                        } else {
1.2       misho     168:                                memset(av, 0, sizeof(struct tagPair));
1.1       misho     169:                                // added new element
                    170:                                av->sle_next = cfg->slh_first;
                    171:                                cfg->slh_first = av;
                    172:                        }
                    173:                        // added section name to element
                    174:                        if (*szSection) {
                    175:                                av->psSection = malloc(strlen((char*) szSection) + 1);
                    176:                                if (!av->psSection) {
                    177:                                        LOGERR;
                    178:                                        free(av);
                    179:                                        return -1;
                    180:                                } else
1.2       misho     181:                                        strlcpy((char*) av->psSection, (char*) szSection, strlen((char*) szSection) + 1);
1.1       misho     182:                        } else
                    183:                                av->psSection = NULL;
                    184: 
                    185:                        psAttr = szLine;
                    186:                        psVal = (szLine + pos + 1);
                    187:                        szLine[pos] = 0;
                    188:                        rtrim(psAttr);
                    189:                        ltrim(psVal);
1.4       misho     190:                        unquot(psVal);
1.1       misho     191: #ifdef __DEBUG
                    192:                        cfgDbg(stdout, "DEBUG:: Attr(%p) ->%s size=%d Value(%p) ->%s size=%d\n", 
                    193:                                        psAttr, psAttr, strlen((char*) psAttr), psVal, psVal, strlen((char*) psVal));
                    194: #endif
                    195:                        // added attribute to element
                    196:                        av->psAttribute = malloc(strlen((char*) psAttr) + 1);
                    197:                        if (!av->psAttribute) {
                    198:                                LOGERR;
                    199:                                free(av->psSection);
                    200:                                free(av);
                    201:                                return -1;
                    202:                        } else
1.2       misho     203:                                strlcpy((char*) av->psAttribute, (char*) psAttr, strlen((char*) psAttr) + 1);
1.1       misho     204:                        // added value to element
                    205:                        av->psValue = malloc(strlen((char*) psVal) + 1);
                    206:                        if (!av->psValue) {
                    207:                                LOGERR;
                    208:                                free(av->psAttribute);
                    209:                                free(av->psSection);
                    210:                                free(av);
                    211:                                return -1;
                    212:                        } else
1.2       misho     213:                                strlcpy((char*) av->psValue, (char*) psVal, strlen((char*) psVal) + 1);
1.1       misho     214:                }
                    215:        }
                    216: 
                    217:        return 0;
                    218: }
                    219: 
                    220: /*
                    221:  * WriteConfig() Write to file from items in config list
                    222:  * @f = file resource
                    223:  * @cfg = Head list element
                    224:  * return: 0 ok; -1 error:: can`t write to file
                    225: */
                    226: int WriteConfig(FILE *f, sl_config * __restrict cfg)
                    227: {
1.3       misho     228:        return cfgWrite(f, cfg, 1);
                    229: }
                    230: 
                    231: /*
                    232:  * cfg_WriteConfig() Write to file from items in config list without whitespaces!
                    233:  * @f = file resource
                    234:  * @cfg = Head list element
                    235:  * return: 0 ok; -1 error:: can`t write to file
                    236: */
                    237: int cfg_WriteConfig(FILE *f, sl_config * __restrict cfg)
                    238: {
                    239:        return cfgWrite(f, cfg, 0);
                    240: }
                    241: 
                    242: /*
                    243:  * ConcatConfig() Concat two list in one
                    244:  * @cfg = Head list element of main list
                    245:  * @add_cfg = Head list element of added list
                    246:  * return: 0 ok; -1 error:: can`t concat lists
                    247: */
                    248: int ConcatConfig(sl_config * __restrict cfg, sl_config * __restrict add_cfg)
                    249: {
                    250:        struct tagPair *item;
                    251:        int ret = 0;
                    252: 
                    253:        if (!cfg || !add_cfg)
                    254:                return -1;
                    255: 
                    256:        for (item = cfg->slh_first; item->sle_next; item = item->sle_next);
                    257:        item->sle_next = add_cfg->slh_first;
                    258: 
                    259:        add_cfg->slh_first = NULL;
                    260: 
                    261:        return ret;
                    262: }
1.1       misho     263: 
1.3       misho     264: /*
                    265:  * MergeConfig() Marge two list in one cfg and destroy add_cfg
                    266:  * @cfg = Head list element of main list
                    267:  * @add_cfg = Head list element of merged list (destroy after all!)
                    268:  * return: 0 ok; -1 error:: can`t merge lists
                    269: */
                    270: int MergeConfig(sl_config * __restrict cfg, sl_config * __restrict add_cfg)
                    271: {
                    272:        struct tagPair *item, *merge, *add_next, *next = NULL;
                    273:        int flg;
1.1       misho     274: 
1.3       misho     275:        if (!cfg || !add_cfg)
1.1       misho     276:                return -1;
                    277: 
1.3       misho     278:        item = add_cfg->slh_first;
                    279:        while (item) {
                    280:                add_next = item->sle_next;
                    281: 
                    282:                for (flg = 0, merge = cfg->slh_first, next = merge->sle_next; next; 
                    283:                                merge = merge->sle_next, next = merge->sle_next) {
                    284:                        if (!merge->psSection && !item->psSection) {
                    285:                                flg = 1;
                    286:                                merge->sle_next = item;
                    287:                                item->sle_next = next;
                    288:                                break;
                    289:                        }
                    290:                        if (merge->psSection && item->psSection && 
                    291:                                        !strcmp((char*) merge->psSection, (char*) item->psSection)) {
                    292:                                flg = 1;
                    293:                                merge->sle_next = item;
                    294:                                item->sle_next = next;
                    295:                                break;
1.1       misho     296:                        }
                    297:                }
1.3       misho     298: 
                    299:                if (!flg) {
                    300:                        if (!merge->sle_next) {
                    301:                                merge->sle_next = item;
                    302:                                item->sle_next = NULL;
                    303:                        } else
1.1       misho     304:                                return -1;
                    305:                }
                    306: 
1.3       misho     307:                item = add_next;
1.1       misho     308:        }
                    309: 
1.3       misho     310:        add_cfg->slh_first = NULL;
1.1       misho     311: 
                    312:        return 0;
                    313: }

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