Re: [PATCH v4 next 16/23] tools/nolibc/printf: Handle "%s" with the numeric formats

From: Willy Tarreau

Date: Sat Mar 07 2026 - 05:33:34 EST


On Mon, Mar 02, 2026 at 10:18:08AM +0000, david.laight.linux@xxxxxxxxx wrote:
> From: David Laight <david.laight.linux@xxxxxxxxx>
>
> Avoids the extra va_arg() call with is non-trivial on a lot of
^^^^
s/with/which/ I guess :-)

> modern ABI.
>
> Signed-off-by: David Laight <david.laight.linux@xxxxxxxxx>

Acked-by: Willy Tarreau <w@xxxxxx>

thanks!
Willy

> ---
>
> Unchanched for v4.
>
> Changes for v3:
> - Moved to its own patch (part of patch 7 in v2)..
> - Fix 32bit compile.
>
> tools/include/nolibc/stdio.h | 22 ++++++++++++----------
> 1 file changed, 12 insertions(+), 10 deletions(-)
>
> diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
> index 4c7626dbd63f..484432ca87d5 100644
> --- a/tools/include/nolibc/stdio.h
> +++ b/tools/include/nolibc/stdio.h
> @@ -412,13 +412,13 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list
> */
> ch_flag = _NOLIBC_PF_FLAG(ch);
> if (((ch >= 'a' && ch <= 'z') || ch == 'X') &&
> - _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p')) {
> - /* 'long' is needed for pointer conversions and ltz lengths.
> + _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p', 's')) {
> + /* 'long' is needed for pointer/string conversions and ltz lengths.
> * A single test can be used provided 'p' (the same bit as '0')
> * is masked from flags.
> */
> if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag | (flags & ~_NOLIBC_PF_FLAG('p')),
> - 'p', 'l', 't', 'z')) {
> + 'p', 's', 'l', 't', 'z')) {
> v = va_arg(args, unsigned long);
> signed_v = (long)v;
> } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, 'j', 'q')) {
> @@ -437,6 +437,15 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list
> goto do_output;
> }
>
> + if (ch == 's') {
> + /* "%s" - character string. */
> + outstr = (const char *)(uintptr_t)v;
> + if (!outstr) {
> + outstr = "(null)";
> + }
> + goto do_strlen_output;
> + }
> +
> out = outbuf;
>
> if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i')) {
> @@ -465,13 +474,6 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list
> goto do_strlen_output;
> }
>
> - if (ch == 's') {
> - outstr = va_arg(args, char *);
> - if (!outstr)
> - outstr="(null)";
> - goto do_strlen_output;
> - }
> -
> if (ch == 'm') {
> #ifdef NOLIBC_IGNORE_ERRNO
> outstr = "unknown error";
> --
> 2.39.5