1 /* vi: set sw=4 ts=4: */
3 * config file parser helper
5 * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com>
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
17 char *t[3]; // tokens placeholder
18 parser_t p; // parser structure
20 if (config_open(filename, &p)) {
22 while (*config_read(&p, t, 3, 0, delimiters, comment_char) >= 0) { // 0..3 tokens
24 bb_error_msg("TOKENS: [%s][%s][%s]", t[0], t[1], t[2]);
34 parser_t* FAST_FUNC config_open(const char *filename)
36 parser_t *parser = xzalloc(sizeof(parser_t));
37 /* empty file configures nothing */
38 parser->fp = fopen_or_warn(filename, "r");
41 config_close (parser);
42 if (ENABLE_FEATURE_CLEAN_UP)
47 static void config_free_data(parser_t *const parser)
51 parser->line = parser->data = NULL;
53 void FAST_FUNC config_close(parser_t *parser)
55 config_free_data(parser);
59 int FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char*delims,char comment)
63 /* do not treat subsequent delimiters as one delimiter */
64 bool noreduce = (ntokens < 0);
68 memset(tokens, 0, sizeof(void *) * ntokens);
69 config_free_data(parser);
75 //TODO: speed up xmalloc_fgetline by internally using fgets, not fgetc
76 line = xmalloc_fgetline(parser->fp);
81 // handle continuations. Tito's code stolen :)
86 if (line[ii - 1] != '\\')
90 //TODO: add xmalloc_fgetline-like iface but with appending to existing str
91 q = xmalloc_fgetline(parser->fp);
94 line = xasprintf("%s%s", line, q);
100 q = strchrnul(line, comment);
104 // skip leading delimiters
105 n = strspn(line, delims);
108 strcpy(line, line + n);
114 /* skip empty line */
118 // non-empty line found, parse and return
121 parser->line = line = xrealloc(line, ii + 1);
122 parser->data = xstrdup(line);
124 // now split line to tokens
125 //TODO: discard consecutive delimiters?
127 ntokens--; // now it's max allowed token no
132 q = line + strcspn(line, delims);
137 if (noreduce || *line) {
139 //bb_info_msg("L[%d] T[%s]\n", ii, line);
144 // non-empty remainder is also a token,
145 // so if ntokens <= 1, we just return the whole line
146 if (noreduce || *line)
150 bb_error_msg_and_die("bad line %u: %d tokens found, %d needed",
151 parser->lineno, ii, mintokens);