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

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.3     ! misho       6: * $Id: parse.c,v 1.2.2.4 2009/10/19 14:58:24 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);
                    190: #ifdef __DEBUG
                    191:                        cfgDbg(stdout, "DEBUG:: Attr(%p) ->%s size=%d Value(%p) ->%s size=%d\n", 
                    192:                                        psAttr, psAttr, strlen((char*) psAttr), psVal, psVal, strlen((char*) psVal));
                    193: #endif
                    194:                        // added attribute to element
                    195:                        av->psAttribute = malloc(strlen((char*) psAttr) + 1);
                    196:                        if (!av->psAttribute) {
                    197:                                LOGERR;
                    198:                                free(av->psSection);
                    199:                                free(av);
                    200:                                return -1;
                    201:                        } else
1.2       misho     202:                                strlcpy((char*) av->psAttribute, (char*) psAttr, strlen((char*) psAttr) + 1);
1.1       misho     203:                        // added value to element
                    204:                        av->psValue = malloc(strlen((char*) psVal) + 1);
                    205:                        if (!av->psValue) {
                    206:                                LOGERR;
                    207:                                free(av->psAttribute);
                    208:                                free(av->psSection);
                    209:                                free(av);
                    210:                                return -1;
                    211:                        } else
1.2       misho     212:                                strlcpy((char*) av->psValue, (char*) psVal, strlen((char*) psVal) + 1);
1.1       misho     213:                }
                    214:        }
                    215: 
                    216:        return 0;
                    217: }
                    218: 
                    219: /*
                    220:  * WriteConfig() Write to file from items in config list
                    221:  * @f = file resource
                    222:  * @cfg = Head list element
                    223:  * return: 0 ok; -1 error:: can`t write to file
                    224: */
                    225: int WriteConfig(FILE *f, sl_config * __restrict cfg)
                    226: {
1.3     ! misho     227:        return cfgWrite(f, cfg, 1);
        !           228: }
        !           229: 
        !           230: /*
        !           231:  * cfg_WriteConfig() Write to file from items in config list without whitespaces!
        !           232:  * @f = file resource
        !           233:  * @cfg = Head list element
        !           234:  * return: 0 ok; -1 error:: can`t write to file
        !           235: */
        !           236: int cfg_WriteConfig(FILE *f, sl_config * __restrict cfg)
        !           237: {
        !           238:        return cfgWrite(f, cfg, 0);
        !           239: }
        !           240: 
        !           241: /*
        !           242:  * ConcatConfig() Concat two list in one
        !           243:  * @cfg = Head list element of main list
        !           244:  * @add_cfg = Head list element of added list
        !           245:  * return: 0 ok; -1 error:: can`t concat lists
        !           246: */
        !           247: int ConcatConfig(sl_config * __restrict cfg, sl_config * __restrict add_cfg)
        !           248: {
        !           249:        struct tagPair *item;
        !           250:        int ret = 0;
        !           251: 
        !           252:        if (!cfg || !add_cfg)
        !           253:                return -1;
        !           254: 
        !           255:        for (item = cfg->slh_first; item->sle_next; item = item->sle_next);
        !           256:        item->sle_next = add_cfg->slh_first;
        !           257: 
        !           258:        add_cfg->slh_first = NULL;
        !           259: 
        !           260:        return ret;
        !           261: }
1.1       misho     262: 
1.3     ! misho     263: /*
        !           264:  * MergeConfig() Marge two list in one cfg and destroy add_cfg
        !           265:  * @cfg = Head list element of main list
        !           266:  * @add_cfg = Head list element of merged list (destroy after all!)
        !           267:  * return: 0 ok; -1 error:: can`t merge lists
        !           268: */
        !           269: int MergeConfig(sl_config * __restrict cfg, sl_config * __restrict add_cfg)
        !           270: {
        !           271:        struct tagPair *item, *merge, *add_next, *next = NULL;
        !           272:        int flg;
1.1       misho     273: 
1.3     ! misho     274:        if (!cfg || !add_cfg)
1.1       misho     275:                return -1;
                    276: 
1.3     ! misho     277:        item = add_cfg->slh_first;
        !           278:        while (item) {
        !           279:                add_next = item->sle_next;
        !           280: 
        !           281:                for (flg = 0, merge = cfg->slh_first, next = merge->sle_next; next; 
        !           282:                                merge = merge->sle_next, next = merge->sle_next) {
        !           283:                        if (!merge->psSection && !item->psSection) {
        !           284:                                flg = 1;
        !           285:                                merge->sle_next = item;
        !           286:                                item->sle_next = next;
        !           287:                                break;
        !           288:                        }
        !           289:                        if (merge->psSection && item->psSection && 
        !           290:                                        !strcmp((char*) merge->psSection, (char*) item->psSection)) {
        !           291:                                flg = 1;
        !           292:                                merge->sle_next = item;
        !           293:                                item->sle_next = next;
        !           294:                                break;
1.1       misho     295:                        }
                    296:                }
1.3     ! misho     297: 
        !           298:                if (!flg) {
        !           299:                        if (!merge->sle_next) {
        !           300:                                merge->sle_next = item;
        !           301:                                item->sle_next = NULL;
        !           302:                        } else
1.1       misho     303:                                return -1;
                    304:                }
                    305: 
1.3     ! misho     306:                item = add_next;
1.1       misho     307:        }
                    308: 
1.3     ! misho     309:        add_cfg->slh_first = NULL;
1.1       misho     310: 
                    311:        return 0;
                    312: }

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