diff options
| author | David Lamparter <equinox@diac24.net> | 2019-05-12 21:11:30 +0200 |
|---|---|---|
| committer | David Lamparter <equinox@diac24.net> | 2019-06-03 16:45:01 +0200 |
| commit | bf4d3d80219777e2bc8597f6543203abf49825ee (patch) | |
| tree | 08f75574f2afedc0d9ae0e2991deeff5ac4b1da8 /lib/printf/vfprintf.c | |
| parent | 60f1101d29bfa9a3ed261d61a851b35619ea92fe (diff) | |
lib/printf: add extension support
Inspired by the Linux kernel, this allows us to do %pI4 and similar
things.
Signed-off-by: David Lamparter <equinox@diac24.net>
Diffstat (limited to 'lib/printf/vfprintf.c')
| -rw-r--r-- | lib/printf/vfprintf.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/lib/printf/vfprintf.c b/lib/printf/vfprintf.c index 3245da483b..07df6dd8fe 100644 --- a/lib/printf/vfprintf.c +++ b/lib/printf/vfprintf.c @@ -162,6 +162,7 @@ vbprintfrr(struct fbuf *cb, const char *fmt0, va_list ap) u_long ulval = 0; /* integer arguments %[diouxX] */ uintmax_t ujval = 0; /* %j, %ll, %q, %t, %z integers */ + void *ptrval; /* %p */ int base; /* base for [diouxX] conversion */ int dprec; /* a copy of prec if [diouxX], 0 otherwise */ int realsz; /* field size expanded by dprec, sign, etc */ @@ -431,14 +432,29 @@ reswitch: switch (ch) { /*FALLTHROUGH*/ case 'd': case 'i': - if (flags & INTMAX_SIZE) { + if (flags & INTMAX_SIZE) ujval = SJARG(); + else + ulval = SARG(); + + if (printfrr_ext_char(fmt[0])) { + n2 = printfrr_exti(buf, sizeof(buf), fmt, prec, + (flags & INTMAX_SIZE) ? ujval + : (uintmax_t)ulval); + if (n2 > 0) { + fmt += n2; + cp = buf; + size = strlen(cp); + sign = '\0'; + break; + } + } + if (flags & INTMAX_SIZE) { if ((intmax_t)ujval < 0) { ujval = -ujval; sign = '-'; } } else { - ulval = SARG(); if ((long)ulval < 0) { ulval = -ulval; sign = '-'; @@ -528,7 +544,17 @@ reswitch: switch (ch) { * defined manner.'' * -- ANSI X3J11 */ - ujval = (uintmax_t)(uintptr_t)GETARG(void *); + ptrval = GETARG(void *); + if (printfrr_ext_char(fmt[0]) && + (n2 = printfrr_extp(buf, sizeof(buf), + fmt, prec, ptrval)) > 0) { + fmt += n2; + cp = buf; + size = strlen(cp); + sign = '\0'; + break; + } + ujval = (uintmax_t)(uintptr_t)ptrval; base = 16; xdigs = xdigs_lower; flags = flags | INTMAXT; |
