diff options
Diffstat (limited to 'editors')
-rw-r--r-- | editors/awk.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/editors/awk.c b/editors/awk.c index 75f757dbb..17710e57e 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -2357,36 +2357,55 @@ static char *awk_printf(node *n, size_t *len) | |||
2357 | 2357 | ||
2358 | b = NULL; | 2358 | b = NULL; |
2359 | i = 0; | 2359 | i = 0; |
2360 | while (*f) { /* "print one format spec" loop */ | 2360 | while (1) { /* "print one format spec" loop */ |
2361 | char *s; | 2361 | char *s; |
2362 | char c; | 2362 | char c; |
2363 | char sv; | 2363 | char sv; |
2364 | var *arg; | 2364 | var *arg; |
2365 | size_t slen; | 2365 | size_t slen; |
2366 | 2366 | ||
2367 | /* Find end of the next format spec, or end of line */ | ||
2367 | s = f; | 2368 | s = f; |
2368 | while (*f && (*f != '%' || *++f == '%')) | 2369 | while (1) { |
2369 | f++; | 2370 | c = *f; |
2370 | while (*f && !isalpha(*f)) { | 2371 | if (!c) /* no percent chars found at all */ |
2371 | if (*f == '*') | 2372 | goto nul; |
2372 | syntax_error("%*x formats are not supported"); | ||
2373 | f++; | 2373 | f++; |
2374 | if (c == '%') | ||
2375 | break; | ||
2374 | } | 2376 | } |
2377 | /* we are past % in "....%..." */ | ||
2375 | c = *f; | 2378 | c = *f; |
2376 | if (!c) { | 2379 | if (!c) /* "....%" */ |
2377 | /* Tail of fmt with no percent chars, | 2380 | goto nul; |
2378 | * or "....%" (percent seen, but no format specifier char found) | 2381 | if (c == '%') { /* "....%%...." */ |
2379 | */ | 2382 | slen = f - s; |
2380 | slen = strlen(s); | 2383 | s = xstrndup(s, slen); |
2381 | goto tail; | 2384 | f++; |
2385 | goto append; /* print "....%" part verbatim */ | ||
2382 | } | 2386 | } |
2383 | sv = *++f; | 2387 | while (1) { |
2384 | *f = '\0'; | 2388 | if (isalpha(c)) |
2389 | break; | ||
2390 | if (c == '*') | ||
2391 | syntax_error("%*x formats are not supported"); | ||
2392 | c = *++f; | ||
2393 | if (!c) { /* "....%...." and no letter found after % */ | ||
2394 | /* Example: awk 'BEGIN { printf "^^^%^^^\n"; }' */ | ||
2395 | nul: | ||
2396 | slen = f - s; | ||
2397 | goto tail; /* print remaining string, exit loop */ | ||
2398 | } | ||
2399 | } | ||
2400 | /* we are at A in "....%...A..." */ | ||
2401 | |||
2385 | arg = evaluate(nextarg(&n), TMPVAR); | 2402 | arg = evaluate(nextarg(&n), TMPVAR); |
2386 | 2403 | ||
2387 | /* Result can be arbitrarily long. Example: | 2404 | /* Result can be arbitrarily long. Example: |
2388 | * printf "%99999s", "BOOM" | 2405 | * printf "%99999s", "BOOM" |
2389 | */ | 2406 | */ |
2407 | sv = *++f; | ||
2408 | *f = '\0'; | ||
2390 | if (c == 'c') { | 2409 | if (c == 'c') { |
2391 | char cc = is_numeric(arg) ? getvar_i(arg) : *getvar_s(arg); | 2410 | char cc = is_numeric(arg) ? getvar_i(arg) : *getvar_s(arg); |
2392 | char *r = xasprintf(s, cc ? cc : '^' /* else strlen will be wrong */); | 2411 | char *r = xasprintf(s, cc ? cc : '^' /* else strlen will be wrong */); |
@@ -2405,13 +2424,14 @@ static char *awk_printf(node *n, size_t *len) | |||
2405 | } else if (strchr("eEfFgGaA", c)) { | 2424 | } else if (strchr("eEfFgGaA", c)) { |
2406 | s = xasprintf(s, d); | 2425 | s = xasprintf(s, d); |
2407 | } else { | 2426 | } else { |
2427 | //TODO: GNU Awk 5.0.1: printf "%W" prints "%W", does not error out | ||
2408 | syntax_error(EMSG_INV_FMT); | 2428 | syntax_error(EMSG_INV_FMT); |
2409 | } | 2429 | } |
2410 | } | 2430 | } |
2411 | slen = strlen(s); | 2431 | slen = strlen(s); |
2412 | } | 2432 | } |
2413 | *f = sv; | 2433 | *f = sv; |
2414 | 2434 | append: | |
2415 | if (i == 0) { | 2435 | if (i == 0) { |
2416 | b = s; | 2436 | b = s; |
2417 | i = slen; | 2437 | i = slen; |
@@ -2421,7 +2441,7 @@ static char *awk_printf(node *n, size_t *len) | |||
2421 | b = xrealloc(b, i + slen + 1); | 2441 | b = xrealloc(b, i + slen + 1); |
2422 | strcpy(b + i, s); | 2442 | strcpy(b + i, s); |
2423 | i += slen; | 2443 | i += slen; |
2424 | if (!c) /* tail? */ | 2444 | if (!c) /* s is NOT allocated and this is the last part of string? */ |
2425 | break; | 2445 | break; |
2426 | free(s); | 2446 | free(s); |
2427 | } | 2447 | } |