Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/libbb/parse_config.c

    r2725 r3232  
    99 */
    1010
     11/* Uncomment to enable test applet */
     12////config:config PARSE
     13////config: bool "Uniform config file parser debugging applet: parse"
     14////config: default n
     15////config: help
     16////config:   Typical usage of parse API:
     17////config:     char *t[3];
     18////config:     parser_t *p = config_open(filename);
     19////config:     while (config_read(p, t, 3, 0, delimiters, flags)) { // 1..3 tokens
     20////config:         bb_error_msg("TOKENS: '%s''%s''%s'", t[0], t[1], t[2]);
     21////config:     }
     22////config:     config_close(p);
     23
     24////applet:IF_PARSE(APPLET(parse, BB_DIR_USR_BIN, BB_SUID_DROP))
     25
     26//kbuild:lib-y += parse_config.o
     27
     28//usage:#define parse_trivial_usage
     29//usage:       "[-x] [-n MAXTOKENS] [-m MINTOKENS] [-d DELIMS] [-f FLAGS] FILE..."
     30//usage:#define parse_full_usage "\n\n"
     31//usage:       "    -x  Suppress output (for benchmarking)"
     32
    1133#include "libbb.h"
    1234
     
    1638{
    1739    const char *delims = "# \t";
     40    char **t;
    1841    unsigned flags = PARSE_NORMAL;
    1942    int mintokens = 0, ntokens = 128;
     43    unsigned noout;
    2044
    2145    opt_complementary = "-1:n+:m+:f+";
    22     getopt32(argv, "n:m:d:f:", &ntokens, &mintokens, &delims, &flags);
     46    noout = 1 & getopt32(argv, "xn:m:d:f:", &ntokens, &mintokens, &delims, &flags);
    2347    //argc -= optind;
    2448    argv += optind;
     49
     50    t = xmalloc(sizeof(t[0]) * ntokens);
    2551    while (*argv) {
     52        int n;
    2653        parser_t *p = config_open(*argv);
    27         if (p) {
    28             int n;
    29             char **t = xmalloc(sizeof(char *) * ntokens);
    30             while ((n = config_read(p, t, ntokens, mintokens, delims, flags)) != 0) {
     54        while ((n = config_read(p, t, ntokens, mintokens, delims, flags)) != 0) {
     55            if (!noout) {
    3156                for (int i = 0; i < n; ++i)
    3257                    printf("[%s]", t[i]);
    3358                puts("");
    3459            }
    35             config_close(p);
    36         }
     60        }
     61        config_close(p);
    3762        argv++;
    3863    }
     
    4065}
    4166#endif
    42 
    43 /*
    44 
    45 Typical usage:
    46 
    47 ----- CUT -----
    48     char *t[3];  // tokens placeholder
    49     parser_t *p = config_open(filename);
    50     if (p) {
    51         // parse line-by-line
    52         while (config_read(p, t, 3, 0, delimiters, flags)) { // 1..3 tokens
    53             // use tokens
    54             bb_error_msg("TOKENS: [%s][%s][%s]", t[0], t[1], t[2]);
    55         }
    56         ...
    57         // free parser
    58         config_close(p);
    59     }
    60 ----- CUT -----
    61 
    62 */
    6367
    6468parser_t* FAST_FUNC config_open2(const char *filename, FILE* FAST_FUNC (*fopen_func)(const char *path))
     
    8084}
    8185
    82 static void config_free_data(parser_t *parser)
    83 {
    84     free(parser->line);
    85     parser->line = NULL;
    86     if (PARSE_KEEP_COPY) { /* compile-time constant */
    87         free(parser->data);
    88         parser->data = NULL;
    89     }
    90 }
    91 
    9286void FAST_FUNC config_close(parser_t *parser)
    9387{
    9488    if (parser) {
    95         config_free_data(parser);
     89        if (PARSE_KEEP_COPY) /* compile-time constant */
     90            free(parser->data);
    9691        fclose(parser->fp);
     92        free(parser->line);
     93        free(parser->nline);
    9794        free(parser);
    9895    }
    9996}
     97
     98/* This function reads an entire line from a text file,
     99 * up to a newline, exclusive.
     100 * Trailing '\' is recognized as line continuation.
     101 * Returns -1 if EOF/error.
     102 */
     103static int get_line_with_continuation(parser_t *parser)
     104{
     105    ssize_t len, nlen;
     106    char *line;
     107
     108    len = getline(&parser->line, &parser->line_alloc, parser->fp);
     109    if (len <= 0)
     110        return len;
     111
     112    line = parser->line;
     113    for (;;) {
     114        parser->lineno++;
     115        if (line[len - 1] == '\n')
     116            len--;
     117        if (len == 0 || line[len - 1] != '\\')
     118            break;
     119        len--;
     120
     121        nlen = getline(&parser->nline, &parser->nline_alloc, parser->fp);
     122        if (nlen <= 0)
     123            break;
     124
     125        if (parser->line_alloc < len + nlen + 1) {
     126            parser->line_alloc = len + nlen + 1;
     127            line = parser->line = xrealloc(line, parser->line_alloc);
     128        }
     129        memcpy(&line[len], parser->nline, nlen);
     130        len += nlen;
     131    }
     132
     133    line[len] = '\0';
     134    return len;
     135}
     136
    100137
    101138/*
     
    127164    char *line;
    128165    int ntokens, mintokens;
    129     int t, len;
     166    int t;
     167
     168    if (!parser)
     169        return 0;
    130170
    131171    ntokens = (uint8_t)flags;
    132172    mintokens = (uint8_t)(flags >> 8);
    133173
    134     if (parser == NULL)
     174 again:
     175    memset(tokens, 0, sizeof(tokens[0]) * ntokens);
     176
     177    /* Read one line (handling continuations with backslash) */
     178    if (get_line_with_continuation(parser) < 0)
    135179        return 0;
    136180
    137 again:
    138     memset(tokens, 0, sizeof(tokens[0]) * ntokens);
    139     config_free_data(parser);
    140 
    141     /* Read one line (handling continuations with backslash) */
    142     line = bb_get_chunk_with_continuation(parser->fp, &len, &parser->lineno);
    143     if (line == NULL)
    144         return 0;
    145     parser->line = line;
    146 
    147     /* Strip trailing line-feed if any */
    148     if (len && line[len-1] == '\n')
    149         line[len-1] = '\0';
     181    line = parser->line;
    150182
    151183    /* Skip token in the start of line? */
     
    156188        goto again;
    157189
    158     if (flags & PARSE_KEEP_COPY)
     190    if (flags & PARSE_KEEP_COPY) {
     191        free(parser->data);
    159192        parser->data = xstrdup(line);
     193    }
    160194
    161195    /* Tokenize the line */
     
    171205        } else {
    172206            /* Combining, find comment char if any */
    173             line = strchrnul(line, delims[0]);
     207            line = strchrnul(line, PARSE_EOL_COMMENTS ? delims[0] : '\0');
    174208
    175209            /* Trim any extra delimiters from the end */
     
    203237        if (flags & PARSE_MIN_DIE)
    204238            xfunc_die();
    205         if (flags & PARSE_KEEP_COPY)
    206             free(parser->data);
    207239        goto again;
    208240    }
Note: See TracChangeset for help on using the changeset viewer.