Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/libbb/parse_config.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/libbb/parse_config.c
r2725 r3232 9 9 */ 10 10 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 11 33 #include "libbb.h" 12 34 … … 16 38 { 17 39 const char *delims = "# \t"; 40 char **t; 18 41 unsigned flags = PARSE_NORMAL; 19 42 int mintokens = 0, ntokens = 128; 43 unsigned noout; 20 44 21 45 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); 23 47 //argc -= optind; 24 48 argv += optind; 49 50 t = xmalloc(sizeof(t[0]) * ntokens); 25 51 while (*argv) { 52 int n; 26 53 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) { 31 56 for (int i = 0; i < n; ++i) 32 57 printf("[%s]", t[i]); 33 58 puts(""); 34 59 } 35 config_close(p);36 }60 } 61 config_close(p); 37 62 argv++; 38 63 } … … 40 65 } 41 66 #endif 42 43 /*44 45 Typical usage:46 47 ----- CUT -----48 char *t[3]; // tokens placeholder49 parser_t *p = config_open(filename);50 if (p) {51 // parse line-by-line52 while (config_read(p, t, 3, 0, delimiters, flags)) { // 1..3 tokens53 // use tokens54 bb_error_msg("TOKENS: [%s][%s][%s]", t[0], t[1], t[2]);55 }56 ...57 // free parser58 config_close(p);59 }60 ----- CUT -----61 62 */63 67 64 68 parser_t* FAST_FUNC config_open2(const char *filename, FILE* FAST_FUNC (*fopen_func)(const char *path)) … … 80 84 } 81 85 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 92 86 void FAST_FUNC config_close(parser_t *parser) 93 87 { 94 88 if (parser) { 95 config_free_data(parser); 89 if (PARSE_KEEP_COPY) /* compile-time constant */ 90 free(parser->data); 96 91 fclose(parser->fp); 92 free(parser->line); 93 free(parser->nline); 97 94 free(parser); 98 95 } 99 96 } 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 */ 103 static 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 100 137 101 138 /* … … 127 164 char *line; 128 165 int ntokens, mintokens; 129 int t, len; 166 int t; 167 168 if (!parser) 169 return 0; 130 170 131 171 ntokens = (uint8_t)flags; 132 172 mintokens = (uint8_t)(flags >> 8); 133 173 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) 135 179 return 0; 136 180 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; 150 182 151 183 /* Skip token in the start of line? */ … … 156 188 goto again; 157 189 158 if (flags & PARSE_KEEP_COPY) 190 if (flags & PARSE_KEEP_COPY) { 191 free(parser->data); 159 192 parser->data = xstrdup(line); 193 } 160 194 161 195 /* Tokenize the line */ … … 171 205 } else { 172 206 /* Combining, find comment char if any */ 173 line = strchrnul(line, delims[0]);207 line = strchrnul(line, PARSE_EOL_COMMENTS ? delims[0] : '\0'); 174 208 175 209 /* Trim any extra delimiters from the end */ … … 203 237 if (flags & PARSE_MIN_DIE) 204 238 xfunc_die(); 205 if (flags & PARSE_KEEP_COPY)206 free(parser->data);207 239 goto again; 208 240 }
Note:
See TracChangeset
for help on using the changeset viewer.