123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- #include "libbb.h"
- #if defined ENABLE_PARSE && ENABLE_PARSE
- int parse_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
- int parse_main(int argc UNUSED_PARAM, char **argv)
- {
- const char *delims = "# \t";
- char **t;
- unsigned flags = PARSE_NORMAL;
- int mintokens = 0, ntokens = 128;
- unsigned noout;
- noout = 1 & getopt32(argv, "^" "xn:+m:+d:f:+" "\0" "-1",
- &ntokens, &mintokens, &delims, &flags
- );
-
- argv += optind;
- t = xmalloc(sizeof(t[0]) * ntokens);
- while (*argv) {
- int n;
- parser_t *p = config_open(*argv);
- while ((n = config_read(p, t, ntokens, mintokens, delims, flags)) != 0) {
- if (!noout) {
- for (int i = 0; i < n; ++i)
- printf("[%s]", t[i]);
- puts("");
- }
- }
- config_close(p);
- argv++;
- }
- return EXIT_SUCCESS;
- }
- #endif
- parser_t* FAST_FUNC config_open2(const char *filename, FILE* FAST_FUNC (*fopen_func)(const char *path))
- {
- FILE* fp;
- parser_t *parser;
- fp = fopen_func(filename);
- if (!fp)
- return NULL;
- parser = xzalloc(sizeof(*parser));
- parser->fp = fp;
- return parser;
- }
- parser_t* FAST_FUNC config_open(const char *filename)
- {
- return config_open2(filename, fopen_or_warn_stdin);
- }
- void FAST_FUNC config_close(parser_t *parser)
- {
- if (parser) {
- if (PARSE_KEEP_COPY)
- free(parser->data);
- fclose(parser->fp);
- free(parser->line);
- free(parser->nline);
- free(parser);
- }
- }
- static int get_line_with_continuation(parser_t *parser)
- {
- ssize_t len, nlen;
- char *line;
- len = getline(&parser->line, &parser->line_alloc, parser->fp);
- if (len <= 0)
- return len;
- line = parser->line;
- for (;;) {
- parser->lineno++;
- if (line[len - 1] == '\n')
- len--;
- if (len == 0 || line[len - 1] != '\\')
- break;
- len--;
- nlen = getline(&parser->nline, &parser->nline_alloc, parser->fp);
- if (nlen <= 0)
- break;
- if (parser->line_alloc < len + nlen + 1) {
- parser->line_alloc = len + nlen + 1;
- line = parser->line = xrealloc(line, parser->line_alloc);
- }
- memcpy(&line[len], parser->nline, nlen);
- len += nlen;
- }
- line[len] = '\0';
- return len;
- }
- #undef config_read
- int FAST_FUNC config_read(parser_t *parser, char **tokens, unsigned flags, const char *delims)
- {
- char *line, *p;
- int ntokens, mintokens;
- int t;
- char alt_comment_ch;
- if (!parser)
- return 0;
- alt_comment_ch = '\0';
- if (flags & PARSE_ALT_COMMENTS)
- alt_comment_ch = *delims++;
- ntokens = (uint8_t)flags;
- mintokens = (uint8_t)(flags >> 8);
- again:
- memset(tokens, 0, sizeof(tokens[0]) * ntokens);
-
- if (get_line_with_continuation(parser) < 0)
- return 0;
- line = parser->line;
-
- if (flags & PARSE_TRIM)
- line += strspn(line, delims + 1);
- p = line;
- if (flags & PARSE_WS_COMMENTS)
- p = skip_whitespace(p);
- if (p[0] == '\0' || p[0] == delims[0] || p[0] == alt_comment_ch)
- goto again;
- if (flags & PARSE_KEEP_COPY) {
- free(parser->data);
- parser->data = xstrdup(line);
- }
-
- t = 0;
- do {
-
- tokens[t] = line;
-
- if ((t != (ntokens-1)) || !(flags & PARSE_GREEDY)) {
-
- line += strcspn(line, (delims[0] && (flags & PARSE_EOL_COMMENTS)) ? delims : delims + 1);
- } else {
-
- line = strchrnul(line, (flags & PARSE_EOL_COMMENTS) ? delims[0] : '\0');
-
- if (flags & PARSE_TRIM) {
- while (strchr(delims + 1, line[-1]) != NULL)
- line--;
- }
- }
-
- if ((flags & PARSE_EOL_COMMENTS) && *line == delims[0])
- *line = '\0';
- else if (*line != '\0')
- *line++ = '\0';
- #if 0
- if (flags & PARSE_ESCAPE) {
- strcpy_and_process_escape_sequences(tokens[t], tokens[t]);
- }
- #endif
-
- if (flags & PARSE_COLLAPSE)
- line += strspn(line, delims + 1);
- t++;
- } while (*line && *line != delims[0] && t < ntokens);
- if (t < mintokens) {
- bb_error_msg("bad line %u: %d tokens found, %d needed",
- parser->lineno, t, mintokens);
- if (flags & PARSE_MIN_DIE)
- xfunc_die();
- goto again;
- }
- return t;
- }
|