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>