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

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.5.2.1 ! misho       6: * $Id: parse.c,v 1.5 2010/03/22 15:15:48 misho Exp $
1.2       misho       7: *
                      8: *************************************************************************/
1.1       misho       9: #include "global.h"
                     10: #include "aitcfg.h"
                     11: 
                     12: 
                     13: // cfgDbg() Debug/Log operation
                     14: static inline int cfgDbg(FILE *f, char *fmt, ...)
                     15: {
                     16:        int ret = 0;
                     17:        va_list lst;
                     18: 
                     19:        va_start(lst, fmt);
                     20:        ret = vfprintf(f, fmt, lst);
                     21:        va_end(lst);
                     22: 
                     23:        return ret;
                     24: }
                     25: 
1.3       misho      26: /*
                     27:  * InvertQueue() InvertQueue order //{cfg} list of elements for revert
                     28:  * @cfg = Head list element for revert 
                     29: */
                     30: static inline void InvertQueue(sl_config * __restrict cfg)
                     31: {
                     32:        struct tagPair *item, *next, *prev = NULL;
                     33: 
                     34:        for (item = cfg->slh_first; item; item = next) {
                     35:                next = item->sle_next;
                     36:                item->sle_next = prev;
                     37:                prev = item;
                     38:        }
                     39:        cfg->slh_first = prev;
                     40: }
                     41: 
                     42: // cfgWrite() Write to file from config list
                     43: static inline int cfgWrite(FILE *f, sl_config * __restrict cfg, int whitespace)
                     44: {
                     45:        struct tagPair *av;
                     46:        time_t tim;
                     47:        char szTime[MAX_STR + 1];
                     48:        u_char szSection[MAX_STR + 1];
                     49: 
                     50:        bzero(szSection, MAX_STR + 1);
                     51: 
                     52:        bzero(szTime, MAX_STR + 1);
                     53:        time(&tim);
                     54:        strftime(szTime, MAX_STR, "(UTC) %Y-%m-%d %H:%M:%S", gmtime(&tim));
                     55:        if (!cfgDbg(f, "## Write Config :: %s\n#\n", szTime)) {
                     56:                LOGERR;
                     57:                return -1;
                     58:        }
                     59: 
                     60:        InvertQueue(cfg);
                     61:        for (av = cfg->slh_first; av; av = av->sle_next) {
                     62:                if (av->psSection && strcmp((char*) av->psSection, (char*) szSection)) {
                     63:                        strlcpy((char*) szSection, (char*) av->psSection, MAX_STR + 1);
                     64:                        if (!cfgDbg(f, "\n[%s]\n", av->psSection)) {
                     65:                                LOGERR;
                     66:                                return -1;
                     67:                        }
                     68:                }
                     69:                if (!av->psSection && *szSection) {
                     70:                        bzero(szSection, MAX_STR + 1);
                     71:                        if (!cfgDbg(f, "\n[]\n")) {
                     72:                                LOGERR;
                     73:                                return -1;
                     74:                        }
                     75:                }
                     76: 
                     77:                if (whitespace) {
                     78:                        if (!cfgDbg(f, "%s = %s\n", av->psAttribute, av->psValue)) {
                     79:                                LOGERR;
                     80:                                return -1;
                     81:                        }
                     82:                } else {
                     83:                        if (!cfgDbg(f, "%s=%s\n", av->psAttribute, av->psValue)) {
                     84:                                LOGERR;
                     85:                                return -1;
                     86:                        }
                     87:                }
                     88:        }
                     89:        InvertQueue(cfg);
                     90: 
                     91:        bzero(szTime, MAX_STR + 1);
                     92:        time(&tim);
                     93:        strftime(szTime, MAX_STR, "(UTC) %Y-%m-%d %H:%M:%S", gmtime(&tim));
                     94:        if (!cfgDbg(f, "\n#\n## Done. :: %s\n", szTime)) {
                     95:                LOGERR;
                     96:                return -1;
                     97:        }
                     98: 
                     99:        return 0;
                    100: }
                    101: 
                    102: // ---------------------------------------------------
1.1       misho     103: 
                    104: /*
                    105:  * ReadConfig() Read from file and add new item to config list
                    106:  * @f = file resource
                    107:  * @cfg = Head list element
                    108:  * return: 0 ok; -1 error:: can`t allocate memory
                    109: */
                    110: int ReadConfig(FILE *f, sl_config * __restrict cfg)
                    111: {
                    112:        u_char szLine[MAX_STR + 1];
                    113:        u_char szSection[MAX_STR + 1], *psAttr, *psVal;
                    114:        int pos;
                    115:        struct tagPair *av;
                    116: 
                    117:        memset(szSection, 0, MAX_STR + 1);
                    118:        while (!feof(f)) {
                    119:                memset(szLine, 0, MAX_STR + 1);
                    120:                fgets((char*) szLine, MAX_STR, f);
                    121:                trim(szLine);
                    122: #ifdef __DEBUG
                    123:                cfgDbg(stdout, "DEBUG:: RAW |%s|\n", szLine);
                    124: #endif
                    125: 
                    126:                // End of config
                    127:                if (*szLine == '.')
                    128:                        break;
                    129:                // Comment
                    130:                if (*szLine == '#' || *szLine == ';' || !*szLine)
                    131:                        continue;
                    132: 
                    133: #ifdef __DEBUG
                    134:                cfgDbg(stdout, "DEBUG:: Clean |%s|\n", szLine);
                    135: #endif
                    136: 
                    137:                // Section
                    138:                if (*szLine == '[') {
                    139:                        pos = strlen((char*) szLine) - 1;
                    140:                        if (szLine[pos] != ']') {
1.2       misho     141: #ifdef __DEBUG
1.1       misho     142:                                cfgDbg(stdout, "WARNING:: Ignore section %s ... not closed breket\n", szLine);
1.2       misho     143: #endif
1.1       misho     144:                        } else {
                    145:                                szLine[pos] = 0; 
                    146:                                strncpy((char*) szSection, (char*) szLine + 1, MAX_STR);
                    147: #ifdef __DEBUG
                    148:                                cfgDbg(stdout, "DEBUG:: Section %s\n", szSection);
                    149: #endif
                    150:                        }
                    151:                        continue;
                    152:                }
                    153: 
                    154:                // Devide pairs
                    155:                pos = strchr((char*) szLine, '=') ? strchr((char*) szLine, '=') - (char*) szLine : 0;
                    156:                if (!pos) {
1.2       misho     157: #ifdef __DEBUG
1.1       misho     158:                        cfgDbg(stdout, "WARNING:: Ignore a/v %s ... format error!\n", szLine);
1.2       misho     159: #endif
1.1       misho     160:                        continue;
                    161:                } else {
                    162:                        av = malloc(sizeof(struct tagPair));
                    163:                        if (!av) {
                    164:                                LOGERR;
                    165:                                return -1;
                    166:                        } else {
1.2       misho     167:                                memset(av, 0, sizeof(struct tagPair));
1.1       misho     168:                                // added new element
                    169:                                av->sle_next = cfg->slh_first;
                    170:                                cfg->slh_first = av;
                    171:                        }
                    172:                        // added section name to element
                    173:                        if (*szSection) {
                    174:                                av->psSection = malloc(strlen((char*) szSection) + 1);
                    175:                                if (!av->psSection) {
                    176:                                        LOGERR;
                    177:                                        free(av);
                    178:                                        return -1;
                    179:                                } else
1.2       misho     180:                                        strlcpy((char*) av->psSection, (char*) szSection, strlen((char*) szSection) + 1);
1.1       misho     181:                        } else
                    182:                                av->psSection = NULL;
                    183: 
                    184:                        psAttr = szLine;
                    185:                        psVal = (szLine + pos + 1);
                    186:                        szLine[pos] = 0;
                    187:                        rtrim(psAttr);
                    188:                        ltrim(psVal);
1.4       misho     189:                        unquot(psVal);
1.1       misho     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>