diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-08-09 17:16:40 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-08-09 17:16:40 +0000 |
commit | 69f4f9a6f40e2825c93fad4d3adf453c9b33d9bb (patch) | |
tree | 5e35a08d3b3db69b6dc212cbdf681d78bf4425ff /libbb/parse_config.c | |
parent | 3fd15e197e21aa313ce56126ee814f0ebc884dee (diff) | |
download | busybox-w32-69f4f9a6f40e2825c93fad4d3adf453c9b33d9bb.tar.gz busybox-w32-69f4f9a6f40e2825c93fad4d3adf453c9b33d9bb.tar.bz2 busybox-w32-69f4f9a6f40e2825c93fad4d3adf453c9b33d9bb.zip |
optimize config_read() (by Timo Teras <timo.teras AT iki.fi>)
function old new delta
bb_get_chunk_with_continuation - 176 +176
find_pair 169 187 +18
...
process_stdin 443 433 -10
config_read 549 456 -93
bb_get_chunk_from_file 139 7 -132
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 7/7 up/down: 215/-254) Total: -39 bytes
Diffstat (limited to 'libbb/parse_config.c')
-rw-r--r-- | libbb/parse_config.c | 175 |
1 files changed, 67 insertions, 108 deletions
diff --git a/libbb/parse_config.c b/libbb/parse_config.c index ace6f3ad3..a0599d4b4 100644 --- a/libbb/parse_config.c +++ b/libbb/parse_config.c | |||
@@ -123,137 +123,96 @@ mintokens > 0 make config_read() print error message if less than mintokens | |||
123 | #undef config_read | 123 | #undef config_read |
124 | int FAST_FUNC config_read(parser_t *parser, char **tokens, unsigned flags, const char *delims) | 124 | int FAST_FUNC config_read(parser_t *parser, char **tokens, unsigned flags, const char *delims) |
125 | { | 125 | { |
126 | char *line, *q; | 126 | char *line; |
127 | char comment; | 127 | int ntokens, mintokens; |
128 | int ii; | 128 | int t, len; |
129 | int ntokens; | ||
130 | int mintokens; | ||
131 | 129 | ||
132 | comment = *delims++; | ||
133 | ntokens = flags & 0xFF; | 130 | ntokens = flags & 0xFF; |
134 | mintokens = (flags & 0xFF00) >> 8; | 131 | mintokens = (flags & 0xFF00) >> 8; |
135 | 132 | ||
136 | again: | 133 | if (parser == NULL) |
137 | memset(tokens, 0, sizeof(tokens[0]) * ntokens); | ||
138 | if (!parser) | ||
139 | return 0; | 134 | return 0; |
135 | |||
136 | again: | ||
137 | memset(tokens, 0, sizeof(tokens[0]) * ntokens); | ||
140 | config_free_data(parser); | 138 | config_free_data(parser); |
141 | 139 | ||
142 | while (1) { | 140 | /* Read one line (handling continuations with backslash) */ |
143 | //TODO: speed up xmalloc_fgetline by internally using fgets, not fgetc | 141 | line = bb_get_chunk_with_continuation(parser->fp, &len, &parser->lineno); |
144 | line = xmalloc_fgetline(parser->fp); | 142 | if (line == NULL) |
145 | if (!line) | 143 | return 0; |
146 | return 0; | 144 | parser->line = line; |
147 | 145 | ||
148 | parser->lineno++; | 146 | /* Strip trailing line-feed if any */ |
149 | // handle continuations. Tito's code stolen :) | 147 | if (len && line[len-1] == '\n') |
150 | while (1) { | 148 | line[len-1] = '\0'; |
151 | ii = strlen(line); | ||
152 | if (!ii) | ||
153 | goto next_line; | ||
154 | if (line[ii - 1] != '\\') | ||
155 | break; | ||
156 | // multi-line object | ||
157 | line[--ii] = '\0'; | ||
158 | //TODO: add xmalloc_fgetline-like iface but with appending to existing str | ||
159 | q = xmalloc_fgetline(parser->fp); | ||
160 | if (!q) | ||
161 | break; | ||
162 | parser->lineno++; | ||
163 | line = xasprintf("%s%s", line, q); | ||
164 | free(q); | ||
165 | } | ||
166 | // discard comments | ||
167 | if (comment) { | ||
168 | q = strchrnul(line, comment); | ||
169 | *q = '\0'; | ||
170 | ii = q - line; | ||
171 | } | ||
172 | // skip leading and trailing delimiters | ||
173 | if (flags & PARSE_TRIM) { | ||
174 | // skip leading | ||
175 | int n = strspn(line, delims); | ||
176 | if (n) { | ||
177 | ii -= n; | ||
178 | overlapping_strcpy(line, line + n); | ||
179 | } | ||
180 | // cut trailing | ||
181 | if (ii) { | ||
182 | while (strchr(delims, line[--ii])) | ||
183 | continue; | ||
184 | line[++ii] = '\0'; | ||
185 | } | ||
186 | } | ||
187 | // if something still remains -> return it | ||
188 | if (ii) | ||
189 | break; | ||
190 | 149 | ||
191 | next_line: | 150 | /* Skip token in the start of line? */ |
192 | // skip empty line | 151 | if (flags & PARSE_TRIM) |
193 | free(line); | 152 | line += strspn(line, delims + 1); |
194 | } | ||
195 | // non-empty line found, parse and return the number of tokens | ||
196 | 153 | ||
197 | // store line | 154 | if (line[0] == '\0' || line[0] == delims[0]) |
198 | parser->line = line = xrealloc(line, ii + 1); | 155 | goto again; |
199 | if (flags & PARSE_KEEP_COPY) { | 156 | |
157 | if (flags & PARSE_KEEP_COPY) | ||
200 | parser->data = xstrdup(line); | 158 | parser->data = xstrdup(line); |
201 | } | ||
202 | 159 | ||
203 | // split line to tokens | 160 | /* Tokenize the line */ |
204 | ntokens--; // now it's max allowed token no | 161 | for (t = 0; *line && *line != delims[0] && t < ntokens; t++) { |
205 | // N.B. non-empty remainder is also a token, | 162 | /* Pin token */ |
206 | // so if ntokens <= 1, we just return the whole line | 163 | tokens[t] = line; |
207 | // N.B. if PARSE_GREEDY is set the remainder of the line is stuck to the last token | 164 | |
208 | ii = 0; | 165 | /* Combine remaining arguments? */ |
209 | while (*line && ii <= ntokens) { | 166 | if ((t != (ntokens-1)) || !(flags & PARSE_GREEDY)) { |
210 | //bb_info_msg("L[%s]", line); | 167 | /* Vanilla token, find next delimiter */ |
211 | // get next token | 168 | line += strcspn(line, delims[0] ? delims : delims + 1); |
212 | // at last token and need greedy token -> | ||
213 | if ((flags & PARSE_GREEDY) && (ii == ntokens)) { | ||
214 | // skip possible delimiters | ||
215 | if (flags & PARSE_COLLAPSE) | ||
216 | line += strspn(line, delims); | ||
217 | // don't cut the line | ||
218 | q = line + strlen(line); | ||
219 | } else { | 169 | } else { |
220 | // vanilla token. cut the line at the first delim | 170 | /* Combining, find comment char if any */ |
221 | q = line + strcspn(line, delims); | 171 | line = strchrnul(line, delims[0]); |
222 | if (*q) // watch out: do not step past the line end! | 172 | |
223 | *q++ = '\0'; | 173 | /* Trim any extra delimiters from the end */ |
174 | if (flags & PARSE_TRIM) { | ||
175 | while (strchr(delims + 1, line[-1]) != NULL) | ||
176 | line--; | ||
177 | } | ||
224 | } | 178 | } |
225 | // pin token | 179 | |
226 | if (!(flags & (PARSE_COLLAPSE | PARSE_TRIM)) || *line) { | 180 | /* Token not terminated? */ |
227 | //bb_info_msg("N[%d] T[%s]", ii, line); | 181 | if (line[0] == delims[0]) |
228 | tokens[ii++] = line; | 182 | *line = '\0'; |
229 | // process escapes in token | 183 | else if (line[0] != '\0') |
230 | #if 0 // unused so far | 184 | *(line++) = '\0'; |
231 | if (flags & PARSE_ESCAPE) { | 185 | |
232 | char *s = line; | 186 | #if 0 /* unused so far */ |
233 | while (*s) { | 187 | if (flags & PARSE_ESCAPE) { |
234 | if (*s == '\\') { | 188 | const char *from; |
235 | s++; | 189 | char *to; |
236 | *line++ = bb_process_escape_sequence((const char **)&s); | 190 | |
237 | } else { | 191 | from = to = tokens[t]; |
238 | *line++ = *s++; | 192 | while (*from) { |
239 | } | 193 | if (*from == '\\') { |
194 | from++; | ||
195 | *to++ = bb_process_escape_sequence(&from); | ||
196 | } else { | ||
197 | *to++ = *from++; | ||
240 | } | 198 | } |
241 | *line = '\0'; | ||
242 | } | 199 | } |
243 | #endif | 200 | *to = '\0'; |
244 | } | 201 | } |
245 | line = q; | 202 | #endif |
246 | //bb_info_msg("A[%s]", line); | 203 | |
204 | /* Skip possible delimiters */ | ||
205 | if (flags & PARSE_COLLAPSE) | ||
206 | line += strspn(line, delims + 1); | ||
247 | } | 207 | } |
248 | 208 | ||
249 | if (ii < mintokens) { | 209 | if (t < mintokens) { |
250 | bb_error_msg("bad line %u: %d tokens found, %d needed", | 210 | bb_error_msg("bad line %u: %d tokens found, %d needed", |
251 | parser->lineno, ii, mintokens); | 211 | parser->lineno, t, mintokens); |
252 | if (flags & PARSE_MIN_DIE) | 212 | if (flags & PARSE_MIN_DIE) |
253 | xfunc_die(); | 213 | xfunc_die(); |
254 | ntokens++; | ||
255 | goto again; | 214 | goto again; |
256 | } | 215 | } |
257 | 216 | ||
258 | return ii; | 217 | return t; |
259 | } | 218 | } |