On Wednesday 09 July 2008 14:35:50 Rob Landley wrote:
> On Tuesday 08 July 2008 16:40:14 Vladimir Dronnikov wrote:
> > Cool!
> >
> > But we need to not just process continuations and comments but also to
> > parse the line into some (possibly variable) amount of
> > whitespaces-delimited tokens.
> 
> There's no obvious reason to mix these two issues.  A function that reads 
> comments and continuations and returns the next string from the file is 
> useful by itself, and you can feed the output of that into something that 
> tokenizes it.
> 
> You may need different tokenizers if you have different file formats.  (If 
> you 
> ever wind up caring about bind zone files you get into multiple nested 
> contexts.  Heck, even  something like "/etc/sudoers" is actually a bit more 
> complicated than it looks at first glance.)
> 
> Rob


Hi,
yes this is also my opinion:
parsing the config file in the sense to rip out the non option stuff
and pass only the options to the application is one thing
that could be done in a common libbb way supporting the various cases:
1) comments
2) indented comments
3) end of line comments
4) multiline comments
5) options
6) indented options
7) multiline options
8) empty lines
9) empty config files
10) missing config files

Trying to parse the contents of the options is not suitable to be done
in a common way as only the application knows:

1) the keywords
2) the separator between keyword and option value (SHELL=/bin/bash or PIPPO: 
PLUTO or SHELL = /bin/bash er PIPPO : PLUTO etc)
3) the number of fields in non-keyworded options:
        57 0 * * 0 root [ -x /usr/share/mdadm/checkarray ] && [ $(date +\%d) 
-le 7 ] && /usr/share/mdadm/checkarray --cron --all --quiet
        this for example is difficult to parse by whitespace or any other 
separator if you don't know the number of fields to expect
4) the type of values to expect in the fields so that they could be eventually 
sanitized

I can imagine a flow of events like this if we don't try to make one big 
monster function but break the problem
in more little pieces:

1) parse_config() readies the config file in a way suitable (linked list)  to 
be passed to the app
2) char * parse_named_options(const char *name, char separator, llist_t *list) 
parses option names and returns the values found for them 
    (removes them from the linked list and frees memory)
3)   parse_option_lines(int fields, ...)  parses the rest in the desired number 
of fields and passes the values to the desired number of varargs
    (removes them from the linked list and frees memory)

For example:

typedef struct crontab_t {
        char *min;
        char *hour;
        char *day;
        char *month;
        char *day_of_week;
        char *cmd;
        struct crontab_t *link;
} crontab_t;

int main(int argc, char**argv)
{

        char *shell;
        char *path;
        list_t *option_list;
        crontab_t *old_head = NULL;
        crontab_t *new_head = NULL;

        option_list = parse_config("/etc/crontab");
        shell = parse_named_option("SHELL", '=', &option_list);
        path = parse_named_option("PATH", '=', &option_list);
        while (option_list) {
                crontab_t *new_head = xmalloc(sizeof(crontab_t));
                parse_option_lines(7, &new_head->min, &new_head->hour, 
&new_head->day, &new_head->month, &new_head->day_of_week, &new_head->cmd);
                new_head->link = *old_head;
                *old_head = new_head;
        }
        free(option_list);
}

This obviously is only pseudo code not tested nor compile tested, just an idea.
Comments, hints, critics are welcome....


Ciao,
Tito
_______________________________________________
busybox mailing list
busybox@busybox.net
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to