git: 07d90ee0a621 - main - kvprintf(): Fix '+' conversion handling
Date: Fri, 06 Sep 2024 18:35:09 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=07d90ee0a62110e5161bb0b8a3a0b1b9d2beabad
commit 07d90ee0a62110e5161bb0b8a3a0b1b9d2beabad
Author: Sebastian Huber <sebastian.huber@embedded-brains.de>
AuthorDate: 2024-06-14 07:30:28 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-09-06 18:34:30 +0000
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
---
sys/kern/subr_prf.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index 4dc989e2d1f1..8ecabdec18d5 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -660,9 +660,9 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_lis
char *d;
const char *p, *percent, *q;
u_char *up;
- int ch, n;
+ int ch, n, sign;
uintmax_t num;
- int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+ int base, lflag, qflag, tmp, width, ladjust, sharpflag, dot;
int cflag, hflag, jflag, tflag, zflag;
int bconv, dwidth, upper;
char padc;
@@ -690,7 +690,7 @@ kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_lis
PCHAR(ch);
}
percent = fmt - 1;
- qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
+ qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0;
sign = 0; dot = 0; bconv = 0; dwidth = 0; upper = 0;
cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
reswitch: switch (ch = (u_char)*fmt++) {
@@ -701,7 +701,7 @@ reswitch: switch (ch = (u_char)*fmt++) {
sharpflag = 1;
goto reswitch;
case '+':
- sign = 1;
+ sign = '+';
goto reswitch;
case '-':
ladjust = 1;
@@ -771,7 +771,6 @@ reswitch: switch (ch = (u_char)*fmt++) {
case 'd':
case 'i':
base = 10;
- sign = 1;
goto handle_sign;
case 'h':
if (hflag) {
@@ -824,8 +823,10 @@ reswitch: switch (ch = (u_char)*fmt++) {
goto reswitch;
case 'r':
base = radix;
- if (sign)
+ if (sign) {
+ sign = 0;
goto handle_sign;
+ }
goto handle_nosign;
case 's':
p = va_arg(ap, char *);
@@ -862,13 +863,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);
else if (qflag)
@@ -907,11 +906,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) {
@@ -920,7 +919,7 @@ number:
else if (base == 16)
tmp += 2;
}
- if (neg)
+ if (sign)
tmp++;
if (!ladjust && padc == '0')
@@ -930,8 +929,8 @@ number:
if (!ladjust)
while (width-- > 0)
PCHAR(' ');
- if (neg)
- PCHAR('-');
+ if (sign)
+ PCHAR(sign);
if (sharpflag && num != 0) {
if (base == 8) {
PCHAR('0');