summaryrefslogtreecommitdiff
path: root/lib/printf/vfprintf.c
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2023-09-07 06:14:44 +0000
committerDavid Lamparter <equinox@opensourcerouting.org>2024-03-10 15:29:17 +0100
commitc9170233809c149808389837be754c52b3bbdd74 (patch)
tree0fc8bf9b73ec40dd87f066e1805f3f7680967562 /lib/printf/vfprintf.c
parentaa6ceeeb5b1f92280ee79716e68d31c9a8686230 (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.c44
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;