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;
29 keyword_alloc(vector keywords, char *string, int (*handler) (vector))
31 struct keyword *keyword;
33 keyword = (struct keyword *) MALLOC(sizeof (struct keyword));
38 if (!vector_alloc_slot(keywords)) {
42 keyword->string = string;
43 keyword->handler = handler;
45 vector_set_slot(keywords, keyword);
51 install_keyword_root(char *string, int (*handler) (vector))
53 return keyword_alloc(keywords, string, handler);
57 install_sublevel(void)
63 install_sublevel_end(void)
69 install_keyword(char *string, int (*handler) (vector))
72 struct keyword *keyword;
74 /* fetch last keyword */
75 keyword = VECTOR_SLOT(keywords, VECTOR_SIZE(keywords) - 1);
77 /* position to last sub level */
78 for (i = 0; i < sublevel; i++)
80 VECTOR_SLOT(keyword->sub, VECTOR_SIZE(keyword->sub) - 1);
82 /* First sub level allocation */
84 keyword->sub = vector_alloc();
89 /* add new sub keyword */
90 return keyword_alloc(keyword->sub, string, handler);
94 free_keywords(vector keywords)
96 struct keyword *keyword;
99 for (i = 0; i < VECTOR_SIZE(keywords); i++) {
100 keyword = VECTOR_SLOT(keywords, i);
102 free_keywords(keyword->sub);
105 vector_free(keywords);
109 alloc_strvec(char *string)
111 char *cp, *start, *token;
121 /* Skip white spaces */
122 while (isspace((int) *cp) && *cp != '\0')
125 /* Return if there is only white spaces */
129 /* Return if string begin with a comment */
130 if (*cp == '!' || *cp == '#')
133 /* Create a vector and alloc each command piece */
134 strvec = vector_alloc();
141 if (!vector_alloc_slot(strvec))
160 while ((in_string || !isspace((int) *cp)) && *cp
161 != '\0' && *cp != '"')
164 token = MALLOC(strlen + 1);
169 memcpy(token, start, strlen);
170 *(token + strlen) = '\0';
172 vector_set_slot(strvec, token);
174 while (isspace((int) *cp) && *cp != '\0')
176 if (*cp == '\0' || *cp == '!' || *cp == '#')
185 read_line(char *buf, int size)
190 while ((ch = fgetc(stream)) != EOF && (int) ch != '\n'
191 && (int) ch != '\r') {
193 buf[count] = (int) ch;
198 return (ch == EOF) ? 0 : 1;
202 read_value_block(void)
209 vector elements = vector_alloc();
211 buf = (char *) MALLOC(MAXBUF);
219 while (read_line(buf, MAXBUF)) {
220 vec = alloc_strvec(buf);
222 str = VECTOR_SLOT(vec, 0);
223 if (!strcmp(str, EOB)) {
228 if (VECTOR_SIZE(vec))
229 for (i = 0; i < VECTOR_SIZE(vec); i++) {
230 str = VECTOR_SLOT(vec, i);
231 dup = (char *) MALLOC(strlen(str) + 1);
232 memcpy(dup, str, strlen(str));
234 if (!vector_alloc_slot(elements))
237 vector_set_slot(elements, dup);
241 memset(buf, 0, MAXBUF);
253 alloc_value_block(vector strvec, void (*alloc_func) (vector))
259 buf = (char *) MALLOC(MAXBUF);
264 while (read_line(buf, MAXBUF)) {
265 vec = alloc_strvec(buf);
267 str = VECTOR_SLOT(vec, 0);
268 if (!strcmp(str, EOB)) {
273 if (VECTOR_SIZE(vec))
278 memset(buf, 0, MAXBUF);
285 set_value(vector strvec)
287 char *str = VECTOR_SLOT(strvec, 1);
288 int size = strlen(str);
295 for (i = 2; i < VECTOR_SIZE(strvec); i++) {
296 str = VECTOR_SLOT(strvec, i);
300 (char *) MALLOC(sizeof (char *) *
304 REALLOC(alloc, sizeof (char *) * (len + 1));
305 tmp = VECTOR_SLOT(strvec, i-1);
306 if (*str != '"' && *tmp != '"')
307 strncat(alloc, " ", 1);
310 if (i != VECTOR_SIZE(strvec)-1)
311 strncat(alloc, str, strlen(str));
314 alloc = MALLOC(sizeof (char *) * (size + 1));
315 memcpy(alloc, str, size);
320 /* non-recursive configuration stream handler */
321 static int kw_level = 0;
323 process_stream(vector keywords)
327 struct keyword *keyword;
332 buf = MALLOC(MAXBUF);
337 while (read_line(buf, MAXBUF)) {
338 strvec = alloc_strvec(buf);
339 memset(buf,0, MAXBUF);
344 str = VECTOR_SLOT(strvec, 0);
346 if (!strcmp(str, EOB) && kw_level > 0) {
351 for (i = 0; i < VECTOR_SIZE(keywords); i++) {
352 keyword = VECTOR_SLOT(keywords, i);
354 if (!strcmp(keyword->string, str)) {
355 if (keyword->handler)
356 r += (*keyword->handler) (strvec);
360 r += process_stream(keyword->sub);
374 /* Data initialization */
376 init_data(char *conf_file, vector (*init_keywords) (void))
380 stream = fopen(conf_file, "r");
382 syslog(LOG_WARNING, "Configuration file open problem");
386 /* Init Keywords structure */
389 /* Dump configuration *
390 vector_dump(keywords);
391 dump_keywords(keywords, 0);
394 /* Stream handling */
395 r = process_stream(keywords);
397 free_keywords(keywords);