diff -Naur busybox.orig/include/libbb.h busybox/include/libbb.h --- busybox.orig/include/libbb.h 2008-07-06 09:04:14 +0000 +++ busybox/include/libbb.h 2008-07-07 22:52:04 +0000 @@ -974,6 +974,7 @@ int bb_ask_confirmation(void) FAST_FUNC; extern int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC; +extern char **parse_config(const char *filename, int ntokens, void **data) FAST_FUNC; /* Concatenate path and filename to new allocated buffer. * Add "/" only as needed (no duplicate "//" are produced). diff -Naur busybox.orig/libbb/Kbuild busybox/libbb/Kbuild --- busybox.orig/libbb/Kbuild 2008-07-01 20:50:48 +0000 +++ busybox/libbb/Kbuild 2008-07-07 20:00:28 +0000 @@ -62,6 +62,7 @@ lib-y += mtab_file.o lib-y += obscure.o lib-y += parse_mode.o +lib-y += parse_config.o lib-y += perror_msg.o lib-y += perror_msg_and_die.o lib-y += perror_nomsg.o diff -Naur busybox.orig/libbb/parse_config.c busybox/libbb/parse_config.c --- busybox.orig/libbb/parse_config.c 1970-01-01 00:00:00 +0000 +++ busybox/libbb/parse_config.c 2008-07-07 23:27:40 +0000 @@ -0,0 +1,115 @@ +/* vi: set sw=4 ts=4: */ +/* + * config file parser helper + * + * Copyright (C) 2008 by Vladimir Dronnikov + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" + +static void FAST_FUNC replace(char *s, char what, char with) +{ + while (*s) { + if (what == *s) + *s = with; + ++s; + } +} + +static char *next_field(char *s) +{ + // TODO: quoted tokens? + char *end = skip_non_whitespace(s); + s = skip_whitespace(end); + *end = '\0'; + if (*s == '\0') + s = NULL; + return s; +} + +/* + +Typical usage: + +----- CUT ----- +void *data; +char **token = parse_config(filename, 128, &data); // 128 tokens at most + +while (*token) { + bb_error_msg("LINE---------"); + while (*token) { + bb_error_msg("TOKEN [%s]", *token); + token++; + } + token++; +} + +free(token); +free(data); +----- CUT ----- + +*/ + +// returns newly allocated array of tokens. MUST be freed by caller +// N.B. array uses REFERENCES to, not copies of strings read to 'data' so free 'data' after all config is used +char FAST_FUNC **parse_config( + const char *filename, // name of config file to parse + int ntokens, // required amount of tokens, remainder to be returned verbatim + // just set to big number + void **data // OUT: config file image. MUST be freed by caller after config is used +) +{ + char *line, *s, *p; + + // empty array of tokens + //char **tokens = xzalloc(sizeof(char *)); + + // prepare room for 128 lines + // FIXME: realloc when pinning! + char **tokens = xzalloc(128 * sizeof(char *) * + (ntokens /* required tokens */ + 1 /* end-of-tokens-on-this-line marker*/)); + char **token = tokens; + + // empty file configures nothing! + *data = xmalloc_xopen_read_close(filename, NULL); + if (!*data) + return tokens; + + // first convert 0x5c 0x0a (backslashes at the very end of line) to 0x20 0x20 (spaces) + for (s = *data; (s = strchr(s, '\\')) != NULL; ++s) + if ('\n' == s[1]) { + s[0] = s[1] = ' '; + } + + // now split to lines + s = *data; + while (1) { + int token_num = 0; + line = strtok(s, "\n"); // N.B. s != NULL only the first time + if (!line) + break; + // comments mean EOLs + replace(line, '#', '\0'); + // skip comments and empty lines + line = skip_whitespace(line); + if (!line) + continue; + // now split line to tokens + s = line; + while (s) { + // get next token + p = (++token_num < ntokens) ? next_field(s) : NULL; + // pin token + // FIXME: realloc!!! +//bb_error_msg("L[%d:%d] T[%s]", line_num, token_num, s); + *token++ = s; + s = p; + } + token++; // xzmalloc guarantees NULL + } + //*token++ = NULL; // xzmalloc guarantees NULL + + return tokens; +}