Add %b and %B support to the printf/wprintf family.

Coming to C23 via WG14 N2630, and already in glibc.

We're still missing clang support for %b and %B in format string checking,
but it's probably easier to fix this first. (Apparently GCC already has
support because of glibc.)

Test: treehugger
Change-Id: Ie8bfe4630d00c50e1d047d6756a7f799205356db
diff --git a/libc/stdio/vfprintf.cpp b/libc/stdio/vfprintf.cpp
index d99d09c..d83a5bf 100644
--- a/libc/stdio/vfprintf.cpp
+++ b/libc/stdio/vfprintf.cpp
@@ -81,8 +81,8 @@
   char* dtoaresult = nullptr;
 
   uintmax_t _umax;             /* integer arguments %[diouxX] */
-  enum { OCT, DEC, HEX } base; /* base for %[diouxX] conversion */
-  int dprec;                   /* a copy of prec if %[diouxX], 0 otherwise */
+  enum { BIN, OCT, DEC, HEX } base; /* base for %[bBdiouxX] conversion */
+  int dprec;                   /* a copy of prec if %[bBdiouxX], 0 otherwise */
   int realsz;                  /* field size expanded by dprec */
   int size;                    /* size of converted field or string */
   const char* xdigs;           /* digits for %[xX] conversion */
@@ -304,6 +304,12 @@
       case 'z':
         flags |= SIZEINT;
         goto rflag;
+      case 'B':
+      case 'b':
+        _umax = UARG();
+        base = BIN;
+        if (flags & ALT && _umax != 0) ox[1] = ch;
+        goto nosign;
       case 'C':
         flags |= LONGINT;
         __BIONIC_FALLTHROUGH;
@@ -550,6 +556,13 @@
            * a variable; hence this switch.
            */
           switch (base) {
+            case BIN:
+              do {
+                *--cp = to_char(_umax & 1);
+                _umax >>= 1;
+              } while (_umax);
+              break;
+
             case OCT:
               do {
                 *--cp = to_char(_umax & 7);
@@ -599,7 +612,7 @@
      * first be prefixed by any sign or other prefix; otherwise,
      * it should be blank padded before the prefix is emitted.
      * After any left-hand padding and prefixing, emit zeroes
-     * required by a decimal %[diouxX] precision, then print the
+     * required by a decimal %[bBdiouxX] precision, then print the
      * string proper, then emit zeroes required by any leftover
      * floating precision; finally, if LADJUST, pad with blanks.
      *