diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-09 18:57:07 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-09-30 00:15:44 +0200 |
commit | 5ec12fa657052ceebe02f98571402232ca411c3c (patch) | |
tree | 98130653b87d271c4dab3c0eb071c8315ab7c2bf | |
parent | 150986c922c7dac59d6ca7253c3a7bd2ff6ee5b8 (diff) | |
download | busybox-w32-5ec12fa657052ceebe02f98571402232ca411c3c.tar.gz busybox-w32-5ec12fa657052ceebe02f98571402232ca411c3c.tar.bz2 busybox-w32-5ec12fa657052ceebe02f98571402232ca411c3c.zip |
awk: code shrink: avoid duplicate NUL checks and strlen()
function old new delta
awk_printf 665 652 -13
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/editors/awk.c b/editors/awk.c index 3594717b1..46bda93b2 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -2345,38 +2345,49 @@ static char *awk_printf(node *n, size_t *len) | |||
2345 | var *arg; | 2345 | var *arg; |
2346 | size_t slen; | 2346 | size_t slen; |
2347 | 2347 | ||
2348 | /* Find end of the next format spec, or end of line */ | ||
2348 | s = f; | 2349 | s = f; |
2349 | while (*f && *f != '%') | 2350 | while (1) { |
2351 | c = *f; | ||
2352 | if (!c) /* no percent chars found at all */ | ||
2353 | goto nul; | ||
2354 | if (c == '%') { | ||
2355 | c = *++f; | ||
2356 | if (!c) /* we are past % in "....%" */ | ||
2357 | goto nul; | ||
2358 | break; | ||
2359 | } | ||
2360 | f++; | ||
2361 | } | ||
2362 | /* we are past % in "....%...", c == char after % */ | ||
2363 | if (c == '%') { /* double % */ | ||
2364 | slen = f - s; | ||
2365 | s = xstrndup(s, slen); | ||
2350 | f++; | 2366 | f++; |
2351 | if (*f) { | 2367 | goto tail; /* print "....%" part verbatim */ |
2368 | } | ||
2369 | while (1) { | ||
2370 | if (isalpha(c)) | ||
2371 | break; | ||
2372 | if (c == '*') | ||
2373 | syntax_error("%*x formats are not supported"); | ||
2352 | c = *++f; | 2374 | c = *++f; |
2353 | if (c == '%') { /* double % */ | 2375 | if (!c) { /* "....%...." and no letter found after % */ |
2376 | /* Example: awk 'BEGIN { printf "^^^%^^^\n"; }' */ | ||
2377 | nul: | ||
2354 | slen = f - s; | 2378 | slen = f - s; |
2355 | s = xstrndup(s, slen); | 2379 | goto tail; /* print remaining string, exit loop */ |
2356 | f++; | ||
2357 | goto tail; | ||
2358 | } | ||
2359 | while (*f && !isalpha(*f)) { | ||
2360 | if (*f == '*') | ||
2361 | syntax_error("%*x formats are not supported"); | ||
2362 | f++; | ||
2363 | } | 2380 | } |
2364 | } | 2381 | } |
2365 | c = *f; | 2382 | /* we are at A in "....%...A..." */ |
2366 | if (!c) { | 2383 | |
2367 | /* Tail of fmt with no percent chars, | ||
2368 | * or "....%" (percent seen, but no format specifier char found) | ||
2369 | */ | ||
2370 | slen = strlen(s); | ||
2371 | goto tail; | ||
2372 | } | ||
2373 | sv = *++f; | ||
2374 | *f = '\0'; | ||
2375 | arg = evaluate(nextarg(&n), TMPVAR); | 2384 | arg = evaluate(nextarg(&n), TMPVAR); |
2376 | 2385 | ||
2377 | /* Result can be arbitrarily long. Example: | 2386 | /* Result can be arbitrarily long. Example: |
2378 | * printf "%99999s", "BOOM" | 2387 | * printf "%99999s", "BOOM" |
2379 | */ | 2388 | */ |
2389 | sv = *++f; | ||
2390 | *f = '\0'; | ||
2380 | if (c == 'c') { | 2391 | if (c == 'c') { |
2381 | char cc = is_numeric(arg) ? getvar_i(arg) : *getvar_s(arg); | 2392 | char cc = is_numeric(arg) ? getvar_i(arg) : *getvar_s(arg); |
2382 | char *r = xasprintf(s, cc ? cc : '^' /* else strlen will be wrong */); | 2393 | char *r = xasprintf(s, cc ? cc : '^' /* else strlen will be wrong */); |
@@ -2395,6 +2406,7 @@ static char *awk_printf(node *n, size_t *len) | |||
2395 | } else if (strchr("eEfFgGaA", c)) { | 2406 | } else if (strchr("eEfFgGaA", c)) { |
2396 | s = xasprintf(s, d); | 2407 | s = xasprintf(s, d); |
2397 | } else { | 2408 | } else { |
2409 | //TODO: GNU Awk 5.0.1: printf "%W" prints "%W", does not error out | ||
2398 | syntax_error(EMSG_INV_FMT); | 2410 | syntax_error(EMSG_INV_FMT); |
2399 | } | 2411 | } |
2400 | } | 2412 | } |