summaryrefslogtreecommitdiff
path: root/lib/printf/vfprintf.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2019-05-12 21:11:30 +0200
committerDavid Lamparter <equinox@diac24.net>2019-06-03 16:45:01 +0200
commitbf4d3d80219777e2bc8597f6543203abf49825ee (patch)
tree08f75574f2afedc0d9ae0e2991deeff5ac4b1da8 /lib/printf/vfprintf.c
parent60f1101d29bfa9a3ed261d61a851b35619ea92fe (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.c32
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;