2 * Part: Configuration file parser/reader. Place into the dynamic
3 * data structure representation the conf file
5 * Version: $Id: parser.c,v 1.0.3 2003/05/11 02:28:03 acassen Exp $
7 * Author: Alexandre Cassen, <acassen@linux-vs.org>
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
26 static int sublevel = 0;
27 vector keywords = NULL;
28 vector *keywords_addr = NULL;
30 void set_current_keywords (vector *k)
37 keyword_alloc(vector keywords, char *string, int (*handler) (vector),
38 int (*print) (char *, int, void *))
40 struct keyword *keyword;
42 keyword = (struct keyword *) MALLOC(sizeof (struct keyword));
47 if (!vector_alloc_slot(keywords)) {
51 keyword->string = string;
52 keyword->handler = handler;
53 keyword->print = print;
55 vector_set_slot(keywords, keyword);
61 install_keyword_root(char *string, int (*handler) (vector))
63 int r = keyword_alloc(keywords, string, handler, NULL);
65 *keywords_addr = keywords;
70 install_sublevel(void)
76 install_sublevel_end(void)
82 install_keyword(char *string, int (*handler) (vector),
83 int (*print) (char *, int, void *))
86 struct keyword *keyword;
88 /* fetch last keyword */
89 keyword = VECTOR_SLOT(keywords, VECTOR_SIZE(keywords) - 1);
91 /* position to last sub level */
92 for (i = 0; i < sublevel; i++)
94 VECTOR_SLOT(keyword->sub, VECTOR_SIZE(keyword->sub) - 1);
96 /* First sub level allocation */
98 keyword->sub = vector_alloc();
103 /* add new sub keyword */
104 return keyword_alloc(keyword->sub, string, handler, print);
108 free_keywords(vector keywords)
110 struct keyword *keyword;
116 for (i = 0; i < VECTOR_SIZE(keywords); i++) {
117 keyword = VECTOR_SLOT(keywords, i);
119 free_keywords(keyword->sub);
122 vector_free(keywords);
126 find_keyword(vector v, char * name)
128 struct keyword *keyword;
132 if (!name || !keywords)
140 for (i = 0; i < VECTOR_SIZE(v); i++) {
141 keyword = VECTOR_SLOT(v, i);
142 if ((strlen(keyword->string) == len) &&
143 !strcmp(keyword->string, name))
146 keyword = find_keyword(keyword->sub, name);
155 snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, void *data)
161 if (!kw || !kw->print)
165 if (fwd == len || *f == '\0')
175 fwd += snprintf(buff + fwd, len - fwd, "%s", kw->string);
178 r = kw->print(buff + fwd, len - fwd, data);
179 if (!r) { /* no output if no value */
193 alloc_strvec(char *string)
195 char *cp, *start, *token;
205 /* Skip white spaces */
206 while ((isspace((int) *cp) || !isascii((int) *cp)) && *cp != '\0')
209 /* Return if there is only white spaces */
213 /* Return if string begin with a comment */
214 if (*cp == '!' || *cp == '#')
217 /* Create a vector and alloc each command piece */
218 strvec = vector_alloc();
225 if (!vector_alloc_slot(strvec))
245 (!isspace((int) *cp) && isascii((int) *cp) &&
246 *cp != '!' && *cp != '#')) &&
247 *cp != '\0' && *cp != '"')
250 token = MALLOC(strlen + 1);
255 memcpy(token, start, strlen);
256 *(token + strlen) = '\0';
258 vector_set_slot(strvec, token);
260 while ((isspace((int) *cp) || !isascii((int) *cp))
263 if (*cp == '\0' || *cp == '!' || *cp == '#')
272 read_line(char *buf, int size)
277 while ((ch = fgetc(stream)) != EOF && (int) ch != '\n'
278 && (int) ch != '\r') {
280 buf[count] = (int) ch;
285 return (ch == EOF) ? 0 : 1;
289 read_value_block(void)
296 vector elements = vector_alloc();
298 buf = (char *) MALLOC(MAXBUF);
306 while (read_line(buf, MAXBUF)) {
307 vec = alloc_strvec(buf);
309 str = VECTOR_SLOT(vec, 0);
310 if (!strcmp(str, EOB)) {
315 if (VECTOR_SIZE(vec))
316 for (i = 0; i < VECTOR_SIZE(vec); i++) {
317 str = VECTOR_SLOT(vec, i);
318 dup = (char *) MALLOC(strlen(str) + 1);
319 memcpy(dup, str, strlen(str));
321 if (!vector_alloc_slot(elements))
324 vector_set_slot(elements, dup);
328 memset(buf, 0, MAXBUF);
340 alloc_value_block(vector strvec, void (*alloc_func) (vector))
346 buf = (char *) MALLOC(MAXBUF);
351 while (read_line(buf, MAXBUF)) {
352 vec = alloc_strvec(buf);
354 str = VECTOR_SLOT(vec, 0);
355 if (!strcmp(str, EOB)) {
360 if (VECTOR_SIZE(vec))
365 memset(buf, 0, MAXBUF);
372 set_value(vector strvec)
374 char *str = VECTOR_SLOT(strvec, 1);
375 int size = strlen(str);
382 for (i = 2; i < VECTOR_SIZE(strvec); i++) {
383 str = VECTOR_SLOT(strvec, i);
387 (char *) MALLOC(sizeof (char *) *
391 REALLOC(alloc, sizeof (char *) * (len + 1));
392 tmp = VECTOR_SLOT(strvec, i-1);
393 if (*str != '"' && *tmp != '"')
394 strncat(alloc, " ", 1);
397 if (i != VECTOR_SIZE(strvec)-1)
398 strncat(alloc, str, strlen(str));
401 alloc = MALLOC(sizeof (char *) * (size + 1));
402 memcpy(alloc, str, size);
407 /* non-recursive configuration stream handler */
408 static int kw_level = 0;
410 process_stream(vector keywords)
414 struct keyword *keyword;
419 buf = MALLOC(MAXBUF);
424 while (read_line(buf, MAXBUF)) {
425 strvec = alloc_strvec(buf);
426 memset(buf,0, MAXBUF);
431 str = VECTOR_SLOT(strvec, 0);
433 if (!strcmp(str, EOB) && kw_level > 0) {
438 for (i = 0; i < VECTOR_SIZE(keywords); i++) {
439 keyword = VECTOR_SLOT(keywords, i);
441 if (!strcmp(keyword->string, str)) {
442 if (keyword->handler)
443 r += (*keyword->handler) (strvec);
447 r += process_stream(keyword->sub);
461 /* Data initialization */
463 init_data(char *conf_file, void (*init_keywords) (void))
468 keywords = vector_alloc();
471 stream = fopen(conf_file, "r");
473 syslog(LOG_WARNING, "Configuration file open problem");
477 /* Init Keywords structure */
480 /* Dump configuration *
481 vector_dump(keywords);
482 dump_keywords(keywords, 0);
485 /* Stream handling */
486 r = process_stream(keywords);
488 //free_keywords(keywords);