This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4203be1f589d463088501a6e7736153646e835ef Author: Marco Casaroli <[email protected]> AuthorDate: Thu Nov 5 12:06:49 2026 +0100 libs/libc/stream: Add an option for the # flag in printf(). With LIBC_PRINTF_ALT_FORM off, the flag is parsed and ignored. %p keeps its 0x. FL_ALT_FORM is 0 then, so the compiler removes the code that tests it. The option is on in the Default and Full profiles. Part of https://github.com/apache/nuttx/issues/21467 Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- libs/libc/stdio/Kconfig | 8 +++++++ libs/libc/stream/lib_libvsprintf.c | 45 ++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/libs/libc/stdio/Kconfig b/libs/libc/stdio/Kconfig index a80eaa47a01..592d30e11f7 100644 --- a/libs/libc/stdio/Kconfig +++ b/libs/libc/stdio/Kconfig @@ -94,6 +94,14 @@ config LIBC_PRINTF_LONG_LONG because the timestamps of syslog and the times in /proc print with %jd. +config LIBC_PRINTF_ALT_FORM + bool "Enable the # flag in printf" + default !LIBC_PRINTF_MINIMAL + ---help--- + Enables the alternative form: 0x for %#x, 0 for %#o, and the point + for %#.0f. Without it, printf() ignores the flag, so %#x of 255 + prints "ff". %p keeps its 0x. + config LIBC_FLOATINGPOINT bool "Enable floating point in printf" default LIBC_PRINTF_FULL || (!DEFAULT_SMALL && ARCH_FPU && !LIBC_PRINTF_MINIMAL) diff --git a/libs/libc/stream/lib_libvsprintf.c b/libs/libc/stream/lib_libvsprintf.c index 617216ea2d1..4b1882255cf 100644 --- a/libs/libc/stream/lib_libvsprintf.c +++ b/libs/libc/stream/lib_libvsprintf.c @@ -97,6 +97,22 @@ #define FL_FLTEXP 0x4000 #define FL_FLTFIX 0x8000 +/* The # flag. FL_ALT stays for the prefix of %p. A flag that is 0 lets the + * compiler remove the code of its feature. + */ + +#ifdef CONFIG_LIBC_PRINTF_ALT_FORM +# define FL_ALT_FORM FL_ALT +# define FL_POINTER FL_ALT +#else +# define FL_ALT_FORM 0 +# define FL_POINTER (FL_ALT | FL_ALTHEX) +#endif + +/* Only %x, %X and %p have FL_ALT: then FL_ALTHEX needs no test */ + +#define FL_ALT_IS_HEX(f) (FL_ALT_FORM == 0 || ((f) & FL_ALTHEX) != 0) + /* A value longer than long has output only with this option */ #if defined(CONFIG_LIBC_PRINTF_LONG_LONG) || ULLONG_MAX == ULONG_MAX @@ -467,7 +483,7 @@ static int vsprintf_internal(FAR struct lib_outstream_s *stream, continue; case '#': - flags |= FL_ALT; + flags |= FL_ALT_FORM; continue; /* XSI thousands grouping: the C locale has no @@ -971,7 +987,7 @@ put_unavailable: { flen += prec + 1u; } - else if ((flags & FL_ALT) != 0) + else if ((flags & FL_ALT_FORM) != 0) { flen += 1; } @@ -1079,7 +1095,7 @@ put_unavailable: stream_putc(out, stream); - if ((flags & FL_ALT) != 0 && n == -1) + if ((flags & FL_ALT_FORM) != 0 && n == -1) { stream_putc('.', stream); } @@ -1114,7 +1130,7 @@ put_unavailable: stream_repeat('0', prec - nbytes, stream); } } - else if ((flags & FL_ALT) != 0) + else if ((flags & FL_ALT_FORM) != 0) { stream_putc('.', stream); } @@ -1383,7 +1399,7 @@ str_lpad: } } - flags &= ~(FL_NEGATIVE | FL_ALT); + flags &= ~(FL_NEGATIVE | FL_ALT_FORM); if (x < 0) { x = -(ultoa_uint_t)x; @@ -1483,7 +1499,7 @@ str_lpad: switch (c) { case 'u': - flags &= ~FL_ALT; + flags &= ~FL_ALT_FORM; base = 10; break; @@ -1556,12 +1572,12 @@ str_lpad: } #endif - flags |= FL_ALT; + flags |= FL_POINTER; /* no break */ case 'x': - if ((flags & FL_ALT) != 0) + if ((flags & FL_ALT_FORM) != 0) { flags |= FL_ALTHEX; } @@ -1570,7 +1586,7 @@ str_lpad: break; default: /* 'X' */ - if ((flags & FL_ALT) != 0) + if ((flags & FL_ALT_FORM) != 0) { flags |= (FL_ALTHEX | FL_ALTUPP); } @@ -1599,7 +1615,7 @@ str_lpad: if (len < prec) { len = prec; - if ((flags & FL_ALT) != 0 && (flags & FL_ALTHEX) == 0) + if ((flags & FL_ALT_FORM) != 0 && !FL_ALT_IS_HEX(flags)) { flags &= ~FL_ALT; } @@ -1612,14 +1628,14 @@ str_lpad: * "0" from the flag, and a hexadecimal value has no prefix. */ - if (c == 0 ? (flags & FL_ALTHEX) != 0 : buf[c - 1] == '0') + if (c == 0 ? FL_ALT_IS_HEX(flags) : buf[c - 1] == '0') { flags &= ~(FL_ALT | FL_ALTHEX | FL_ALTUPP); } else { len += 1; - if ((flags & FL_ALTHEX) != 0) + if (FL_ALT_IS_HEX(flags)) { len += 1; } @@ -1660,9 +1676,10 @@ str_lpad: if ((flags & FL_ALT) != 0) { stream_putc('0', stream); - if ((flags & FL_ALTHEX) != 0) + if (FL_ALT_IS_HEX(flags)) { - stream_putc(flags & FL_ALTUPP ? 'X' : 'x', stream); + stream_putc(FL_ALT_FORM != 0 && (flags & FL_ALTUPP) != 0 ? + 'X' : 'x', stream); } } else if ((flags & (FL_NEGATIVE | FL_PLUS | FL_SPACE)) != 0)
