From ce1fb41a6c33e5708b477e8b34c0aa49d6fc79ec Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 14 Jun 2024 09:30:28 +0200 Subject: [PATCH] kvprintf(): Fix '+' conversion handling For example, printf("%+i", 1) prints "+1". However, kvprintf() did print just "1" for this example. According to PRINTF(3): A sign must always be placed before a number produced by a signed conversion. For "%+r" radix conversions, keep the "+" handling as it is, since this is a non-standard conversion. For "%+p" pointer conversions, continue to ignore the sign modifier to be in line with libc. This change allows to support the ' conversion modifier in the future. Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1310 --- cpukit/dev/iovprintf.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/cpukit/dev/iovprintf.c b/cpukit/dev/iovprintf.c index 4394e4f052..a30e8633fc 100644 --- a/cpukit/dev/iovprintf.c +++ b/cpukit/dev/iovprintf.c @@ -95,9 +95,9 @@ _IO_Vprintf(IO_Put_char put_char, void *arg, char const *fmt, va_list ap) char nbuf[MAXNBUF]; const char *p, *percent, *q; u_char *up; - int ch, n; + int ch, n, sign; uintmax_t num; - int base, lflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + int base, lflag, tmp, width, ladjust, sharpflag, dot; int cflag, hflag, jflag; RTEMS_STATIC_ASSERT(sizeof(intmax_t) == sizeof(long long), _IO_Vprintf_j); #if __SIZEOF_PTRDIFF_T__ == __SIZEOF_LONG__ @@ -128,7 +128,7 @@ _IO_Vprintf(IO_Put_char put_char, void *arg, char const *fmt, va_list ap) PCHAR(ch); } percent = fmt - 1; - lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; + lflag = 0; ladjust = 0; sharpflag = 0; sign = 0; dot = 0; dwidth = 0; upper = 0; cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; reswitch: switch (ch = (u_char)*fmt++) { @@ -139,7 +139,7 @@ reswitch: switch (ch = (u_char)*fmt++) { sharpflag = 1; goto reswitch; case '+': - sign = 1; + sign = '+'; goto reswitch; case '-': ladjust = 1; @@ -205,7 +205,6 @@ reswitch: switch (ch = (u_char)*fmt++) { case 'd': case 'i': base = 10; - sign = 1; goto handle_sign; case 'h': if (hflag) { @@ -267,13 +266,11 @@ reswitch: switch (ch = (u_char)*fmt++) { goto handle_nosign; case 'y': base = 16; - sign = 1; goto handle_sign; case 'z': zflag = 1; goto reswitch; handle_nosign: - sign = 0; if (jflag) num = va_arg(ap, uintmax_t); #if __SIZEOF_PTRDIFF_T__ != __SIZEOF_LONG__ @@ -312,11 +309,11 @@ handle_sign: num = (signed char)va_arg(ap, int); else num = va_arg(ap, int); -number: - if (sign && (intmax_t)num < 0) { - neg = 1; + if ((intmax_t)num < 0) { + sign = '-'; num = -(intmax_t)num; } +number: p = ksprintn(nbuf, num, base, &n, upper); tmp = 0; if (sharpflag && num != 0) { @@ -325,7 +322,7 @@ number: else if (base == 16) tmp += 2; } - if (neg) + if (sign) tmp++; if (!ladjust && padc == '0') @@ -335,8 +332,8 @@ number: if (!ladjust) while (width-- > 0) PCHAR(' '); - if (neg) - PCHAR('-'); + if (sign) + PCHAR(sign); if (sharpflag && num != 0) { if (base == 8) { PCHAR('0');