Applied, thanks!
On Wed, Jan 27, 2021 at 12:19 PM Ron Yorston <[email protected]> wrote: > > Treat the output of printf as binary rather than a null-terminated > string so that NUL characters can be output. > > This is considered to be a GNU extension, though it's also available > in mawk and FreeBSD's awk. > > function old new delta > evaluate 3487 3504 +17 > awk_printf 504 519 +15 > ------------------------------------------------------------------------------ > (add/remove: 0/0 grow/shrink: 2/0 up/down: 32/0) Total: 32 bytes > > Signed-off-by: Ron Yorston <[email protected]> > --- > editors/awk.c | 18 +++++++++++++++--- > testsuite/awk.tests | 5 +++++ > 2 files changed, 20 insertions(+), 3 deletions(-) > > diff --git a/editors/awk.c b/editors/awk.c > index 2c15f9e4e..b4f6a3741 100644 > --- a/editors/awk.c > +++ b/editors/awk.c > @@ -2155,7 +2155,10 @@ static int fmt_num(char *b, int size, const char > *format, double n, int int_as_i > } > > /* formatted output into an allocated buffer, return ptr to buffer */ > -static char *awk_printf(node *n) > +#if !ENABLE_FEATURE_AWK_GNU_EXTENSIONS > +# define awk_printf(a, b) awk_printf(a) > +#endif > +static char *awk_printf(node *n, int *len) > { > char *b = NULL; > char *fmt, *s, *f; > @@ -2209,6 +2212,10 @@ static char *awk_printf(node *n) > nvfree(v); > b = xrealloc(b, i + 1); > b[i] = '\0'; > +#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS > + if (len) > + *len = i; > +#endif > return b; > } > > @@ -2666,6 +2673,7 @@ static var *evaluate(node *op, var *res) > case XC( OC_PRINT ): > case XC( OC_PRINTF ): { > FILE *F = stdout; > + IF_FEATURE_AWK_GNU_EXTENSIONS(int len;) > > if (op->r.n) { > rstream *rsm = newfile(R.s); > @@ -2703,8 +2711,12 @@ static var *evaluate(node *op, var *res) > fputs(getvar_s(intvar[ORS]), F); > > } else { /* OC_PRINTF */ > - char *s = awk_printf(op1); > + char *s = awk_printf(op1, &len); > +#if ENABLE_FEATURE_AWK_GNU_EXTENSIONS > + fwrite(s, len, 1, F); > +#else > fputs(s, F); > +#endif > free(s); > } > fflush(F); > @@ -2978,7 +2990,7 @@ static var *evaluate(node *op, var *res) > break; > > case XC( OC_SPRINTF ): > - setvar_p(res, awk_printf(op1)); > + setvar_p(res, awk_printf(op1, NULL)); > break; > > case XC( OC_UNARY ): { > diff --git a/testsuite/awk.tests b/testsuite/awk.tests > index 92c83d719..cf9b722dc 100755 > --- a/testsuite/awk.tests > +++ b/testsuite/awk.tests > @@ -383,6 +383,11 @@ testing "awk errors on missing delete arg" \ > "awk -e '{delete}' 2>&1" "awk: cmd. line:1: Too few arguments\n" "" "" > SKIP= > > +optional FEATURE_AWK_GNU_EXTENSIONS > +testing "awk printf('%c') can output NUL" \ > + "awk '{printf(\"hello%c null\n\", 0)}'" "hello\0 null\n" "" "\n" > +SKIP= > + > # testing "description" "command" "result" "infile" "stdin" > testing 'awk negative field access' \ > 'awk 2>&1 -- '\''{ $(-1) }'\' \ > -- > 2.29.2 > > _______________________________________________ > busybox mailing list > [email protected] > http://lists.busybox.net/mailman/listinfo/busybox _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
