123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- #if !defined _LIBC
- #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";
- unsigned flags = PARSE_NORMAL;
- int mintokens = 0, ntokens = 128;
- opt_complementary = "-1:n+:m+:f+";
- getopt32(argv, "n:m:d:f:", &ntokens, &mintokens, &delims, &flags);
-
- argv += optind;
- while (*argv) {
- parser_t *p = config_open(*argv);
- if (p) {
- int n;
- char **t = xmalloc(sizeof(char *) * ntokens);
- while ((n = config_read(p, t, ntokens, mintokens, delims, flags)) != 0) {
- for (int i = 0; i < n; ++i)
- printf("[%s]", t[i]);
- puts("");
- }
- config_close(p);
- }
- argv++;
- }
- return EXIT_SUCCESS;
- }
- #endif
- #else
- # include <unistd.h>
- # include <string.h>
- # include <malloc.h>
- # include <bits/uClibc_page.h>
- # include "internal/parse_config.h"
- # ifndef FAST_FUNC
- # define FAST_FUNC
- # endif
- # define fopen_or_warn_stdin fopen
- # define bb_error_msg(...)
- # define xstrdup strdup
- # define xfunc_die() return 0
- static off_t bb_get_chunk_with_continuation(parser_t* parsr)
- {
- off_t pos = 0;
- char *chp;
- while (1) {
- if (fgets(parsr->line + pos, parsr->line_len - pos, parsr->fp) == NULL) {
- memset(parsr->line, 0, parsr->line_len);
- pos = -1;
- break;
- }
- pos += strlen(parsr->line + pos);
- chp = strchr(parsr->line, '\n');
- if (chp) {
- --pos;
- if (--*chp == '\\')
- --pos;
- else
- break;
- } else if (parsr->allocated) {
- parsr->line_len += PAGE_SIZE;
- parsr->data = realloc(parsr->data,
- parsr->data_len + parsr->line_len);
- parsr->line = parsr->data + parsr->data_len;
- }
- }
- return pos;
- }
- #endif
- static __always_inline parser_t * FAST_FUNC config_open2(const char *filename,
- FILE* FAST_FUNC (*fopen_func)(const char *path, const char *mode))
- {
- parser_t *parser;
- FILE* fp;
- fp = fopen_func(filename, "r");
- if (!fp)
- return NULL;
- parser = calloc(1, sizeof(*parser));
- if (parser) {
- parser->fp = fp;
- }
- return parser;
- }
- parser_t attribute_hidden * FAST_FUNC config_open(const char *filename)
- {
- return config_open2(filename, fopen_or_warn_stdin);
- }
- #ifdef UNUSED
- static void config_free_data(parser_t *parser)
- {
- free(parser->data);
- parser->data = parser->line = NULL;
- }
- #endif
- void attribute_hidden FAST_FUNC config_close(parser_t *parser)
- {
- if (parser) {
- fclose(parser->fp);
- if (parser->allocated)
- free(parser->data);
- free(parser);
- }
- }
- #undef config_read
- int attribute_hidden FAST_FUNC config_read(parser_t *parser, char ***tokens,
- unsigned flags, const char *delims)
- {
- char *line;
- int ntokens, mintokens;
- off_t len;
- int t;
- if (parser == NULL)
- return 0;
- ntokens = flags & 0xFF;
- mintokens = (flags & 0xFF00) >> 8;
- again:
- if (parser->data == NULL) {
- if (parser->line_len == 0)
- parser->line_len = 81;
- if (parser->data_len == 0)
- parser->data_len += 1 + ntokens * sizeof(char *);
- parser->data = malloc(parser->data_len + parser->line_len);
- if (parser->data == NULL)
- return 0;
- parser->allocated |= 1;
- }
- parser->line = parser->data + parser->data_len;
-
-
- len = bb_get_chunk_with_continuation(parser);
- if (len == -1)
- return 0;
- *tokens = (char **) parser->data;
- memset(*tokens, 0, sizeof(*tokens[0]) * ntokens);
- line = parser->line;
-
- if (flags & PARSE_TRIM)
- line += strspn(line, delims + 1);
- if (line[0] == '\0' || line[0] == delims[0])
- goto again;
-
- for (t = 0; *line && *line != delims[0] && t < ntokens; t++) {
-
- *(*tokens + t) = line;
-
- if ((t != ntokens-1) || !(flags & PARSE_GREEDY)) {
-
- line += strcspn(line, delims[0] ? delims : delims + 1);
- } else {
-
- line = strchrnul(line, delims[0]);
-
- if (flags & PARSE_TRIM) {
- while (strchr(delims + 1, line[-1]) != NULL)
- line--;
- }
- }
-
- if (line[0] == delims[0])
- *line = '\0';
- else if (line[0] != '\0')
- *(line++) = '\0';
- #if 0
- if (flags & PARSE_ESCAPE) {
- const char *from;
- char *to;
- from = to = tokens[t];
- while (*from) {
- if (*from == '\\') {
- from++;
- *to++ = bb_process_escape_sequence(&from);
- } else {
- *to++ = *from++;
- }
- }
- *to = '\0';
- }
- #endif
-
- if (flags & PARSE_COLLAPSE)
- line += strspn(line, delims + 1);
- }
- if (t < mintokens) {
- bb_error_msg("%d tokens found, %d needed",
- t, mintokens);
- if (flags & PARSE_MIN_DIE)
- xfunc_die();
- goto again;
- }
- return t;
- }
|