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>
This commit is contained in:
parent
305a30d80b
commit
8a0adba9f6
@ -2345,38 +2345,49 @@ static char *awk_printf(node *n, size_t *len)
|
|||||||
var *arg;
|
var *arg;
|
||||||
size_t slen;
|
size_t slen;
|
||||||
|
|
||||||
|
/* Find end of the next format spec, or end of line */
|
||||||
s = f;
|
s = f;
|
||||||
while (*f && *f != '%')
|
while (1) {
|
||||||
|
c = *f;
|
||||||
|
if (!c) /* no percent chars found at all */
|
||||||
|
goto nul;
|
||||||
|
if (c == '%') {
|
||||||
|
c = *++f;
|
||||||
|
if (!c) /* we are past % in "....%" */
|
||||||
|
goto nul;
|
||||||
|
break;
|
||||||
|
}
|
||||||
f++;
|
f++;
|
||||||
if (*f) {
|
}
|
||||||
|
/* we are past % in "....%...", c == char after % */
|
||||||
|
if (c == '%') { /* double % */
|
||||||
|
slen = f - s;
|
||||||
|
s = xstrndup(s, slen);
|
||||||
|
f++;
|
||||||
|
goto tail; /* print "....%" part verbatim */
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
if (isalpha(c))
|
||||||
|
break;
|
||||||
|
if (c == '*')
|
||||||
|
syntax_error("%*x formats are not supported");
|
||||||
c = *++f;
|
c = *++f;
|
||||||
if (c == '%') { /* double % */
|
if (!c) { /* "....%...." and no letter found after % */
|
||||||
|
/* Example: awk 'BEGIN { printf "^^^%^^^\n"; }' */
|
||||||
|
nul:
|
||||||
slen = f - s;
|
slen = f - s;
|
||||||
s = xstrndup(s, slen);
|
goto tail; /* print remaining string, exit loop */
|
||||||
f++;
|
|
||||||
goto tail;
|
|
||||||
}
|
|
||||||
while (*f && !isalpha(*f)) {
|
|
||||||
if (*f == '*')
|
|
||||||
syntax_error("%*x formats are not supported");
|
|
||||||
f++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c = *f;
|
/* we are at A in "....%...A..." */
|
||||||
if (!c) {
|
|
||||||
/* Tail of fmt with no percent chars,
|
|
||||||
* or "....%" (percent seen, but no format specifier char found)
|
|
||||||
*/
|
|
||||||
slen = strlen(s);
|
|
||||||
goto tail;
|
|
||||||
}
|
|
||||||
sv = *++f;
|
|
||||||
*f = '\0';
|
|
||||||
arg = evaluate(nextarg(&n), TMPVAR);
|
arg = evaluate(nextarg(&n), TMPVAR);
|
||||||
|
|
||||||
/* Result can be arbitrarily long. Example:
|
/* Result can be arbitrarily long. Example:
|
||||||
* printf "%99999s", "BOOM"
|
* printf "%99999s", "BOOM"
|
||||||
*/
|
*/
|
||||||
|
sv = *++f;
|
||||||
|
*f = '\0';
|
||||||
if (c == 'c') {
|
if (c == 'c') {
|
||||||
char cc = is_numeric(arg) ? getvar_i(arg) : *getvar_s(arg);
|
char cc = is_numeric(arg) ? getvar_i(arg) : *getvar_s(arg);
|
||||||
char *r = xasprintf(s, cc ? cc : '^' /* else strlen will be wrong */);
|
char *r = xasprintf(s, cc ? cc : '^' /* else strlen will be wrong */);
|
||||||
@ -2395,6 +2406,7 @@ static char *awk_printf(node *n, size_t *len)
|
|||||||
} else if (strchr("eEfFgGaA", c)) {
|
} else if (strchr("eEfFgGaA", c)) {
|
||||||
s = xasprintf(s, d);
|
s = xasprintf(s, d);
|
||||||
} else {
|
} else {
|
||||||
|
//TODO: GNU Awk 5.0.1: printf "%W" prints "%W", does not error out
|
||||||
syntax_error(EMSG_INV_FMT);
|
syntax_error(EMSG_INV_FMT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user