From ec055aeff50e6b6311e3307fed436a89d01085da Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Fri, 16 Dec 2016 01:44:50 +0000 Subject: [PATCH] vfprintf(3): Add support for kernel %b format This is a direct port of the kernel %b format. I'm unclear on if (more) non-portable printf extensions will be a problem. I think it's desirable to have userspace formats include all kernel formats, but there may be competing goals I'm not aware of. Reviewed by: no one, unfortunately Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D8426 --- lib/libc/stdio/vfprintf.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index bf45bfb421ed..37b8f3f00d86 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -611,6 +611,37 @@ reswitch: switch (ch) { case 'z': flags |= SIZET; goto rflag; + case 'b': + { + const char *q; + int anybitset, bit; + + ulval = (u_int)GETARG(int); + cp = GETARG(char *); + + q = __ultoa(ulval, buf + BUF, *cp++, 0, xdigs_lower); + PRINT(q, buf + BUF - q); + + if (ulval == 0) + break; + + for (anybitset = 0; *cp;) { + bit = *cp++; + if (ulval & (1 << (bit - 1))) { + PRINT(anybitset ? "," : "<", 1); + q = cp; + for (; (bit = *cp) > ' '; ++cp) + continue; + PRINT(q, cp - q); + anybitset = 1; + } else + for (; *cp > ' '; ++cp) + continue; + } + if (anybitset) + PRINT(">", 1); + } + continue; case 'C': flags |= LONGINT; /*FALLTHROUGH*/