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 consecutive delimiters as one delimiter */
64 bool noreduce = (ntokens < 0);
68 memset(tokens, 0, sizeof(tokens[0]) * ntokens);
69 config_free_data(parser);
72 //TODO: speed up xmalloc_fgetline by internally using fgets, not fgetc
73 line = xmalloc_fgetline(parser->fp);
78 // handle continuations. Tito's code stolen :)
83 if (line[ii - 1] != '\\')
87 //TODO: add xmalloc_fgetline-like iface but with appending to existing str
88 q = xmalloc_fgetline(parser->fp);
91 line = xasprintf("%s%s", line, q);
97 q = strchrnul(line, comment);
101 // skip leading delimiters
102 seen = strspn(line, delims);
105 strcpy(line, line + seen);
111 /* skip empty line */
115 // non-empty line found, parse and return
118 parser->line = line = xrealloc(line, ii + 1);
119 parser->data = xstrdup(line);
121 /* now split line to tokens */
122 ii = noreduce ? seen : 0;
123 ntokens--; // now it's max allowed token no
128 q = line + strcspn(line, delims);
133 if (noreduce || *line) {
135 //bb_info_msg("L[%d] T[%s]\n", ii, line);
140 // non-empty remainder is also a token,
141 // so if ntokens <= 1, we just return the whole line
142 if (noreduce || *line)
146 bb_error_msg_and_die("bad line %u: %d tokens found, %d needed",
147 parser->lineno, ii, mintokens);