diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2023-09-07 06:14:44 +0000 |
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2024-03-10 15:29:17 +0100 |
| commit | c9170233809c149808389837be754c52b3bbdd74 (patch) | |
| tree | 0fc8bf9b73ec40dd87f066e1805f3f7680967562 /lib/printf/vfprintf.c | |
| parent | aa6ceeeb5b1f92280ee79716e68d31c9a8686230 (diff) | |
lib/printf: Implement N2680.
This adds specific width length modifiers in the form of wN and wfN
(where N is 8, 16, 32, or 64) which allow printing intN_t and
int_fastN_t without resorting to casts or PRI macros.
Reviewed by: imp, emaste
Differential Revision: https://reviews.freebsd.org/D41725
FRR changes only include printf(), scanf/strtol are not locally
implemented in FRR. Also added "(void) 0" to empty "else ..." to
avoid a compiler warning.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from FreeBSD commit bce0bef3c6abab92c7ac8cc23b7cc632a382721e)
Diffstat (limited to 'lib/printf/vfprintf.c')
| -rw-r--r-- | lib/printf/vfprintf.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/printf/vfprintf.c b/lib/printf/vfprintf.c index 2083642d5e..3f6700c838 100644 --- a/lib/printf/vfprintf.c +++ b/lib/printf/vfprintf.c @@ -416,6 +416,49 @@ reswitch: switch (ch) { case 't': flags |= PTRDIFFT; goto rflag; + case 'w': + /* + * Fixed-width integer types. On all platforms we + * support, int8_t is equivalent to char, int16_t + * is equivalent to short, int32_t is equivalent + * to int, int64_t is equivalent to long long int. + * Furthermore, int_fast8_t, int_fast16_t and + * int_fast32_t are equivalent to int, and + * int_fast64_t is equivalent to long long int. + */ + flags &= ~(CHARINT|SHORTINT|LONGINT|LLONGINT|INTMAXT); + if (fmt[0] == 'f') { + flags |= FASTINT; + fmt++; + } else { + flags &= ~FASTINT; + } + if (fmt[0] == '8') { + if (!(flags & FASTINT)) + flags |= CHARINT; + else + (void) 0; /* no flag set = 32 */ + fmt += 1; + } else if (fmt[0] == '1' && fmt[1] == '6') { + if (!(flags & FASTINT)) + flags |= SHORTINT; + else + (void) 0; /* no flag set = 32 */ + fmt += 2; + } else if (fmt[0] == '3' && fmt[1] == '2') { + /* no flag set = 32 */ + fmt += 2; + } else if (fmt[0] == '6' && fmt[1] == '4') { + flags |= LLONGINT; + fmt += 2; + } else { + if (flags & FASTINT) { + flags &= ~FASTINT; + fmt--; + } + goto invalid; + } + goto rflag; case 'z': flags |= SIZET; goto rflag; @@ -684,6 +727,7 @@ number: if ((dprec = prec) >= 0) default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; +invalid: /* pretend it was %c with argument ch */ buf[0] = ch; cp = buf; |
