Yet more printf de-duplication.

Bug: http://b/67371539
Test: ran tests
Change-Id: Iae38055426596919c0de4f5080c99eba95fac3a9
diff --git a/libc/stdio/vfwprintf.cpp b/libc/stdio/vfwprintf.cpp
index 97bfc0b..e4bbbba 100644
--- a/libc/stdio/vfwprintf.cpp
+++ b/libc/stdio/vfwprintf.cpp
@@ -33,103 +33,15 @@
 
 #define CHAR_TYPE wchar_t
 #define FUNCTION_NAME __vfwprintf
+#define CHAR_TYPE_STRLEN wcslen
+#define CHAR_TYPE_STRNLEN wcsnlen
+#define CHAR_TYPE_INF L"INF"
+#define CHAR_TYPE_inf L"inf"
+#define CHAR_TYPE_NAN L"NAN"
+#define CHAR_TYPE_nan L"nan"
+#define CHAR_TYPE_ORIENTATION 1
 #include "printf_common.h"
 
-/*
- * Like __fputwc_unlock, but handles fake string (__SSTR) files properly.
- * File must already be locked.
- */
-static wint_t __xfputwc(wchar_t wc, FILE* fp) {
-  mbstate_t mbs;
-  char buf[MB_LEN_MAX];
-  struct __suio uio;
-  struct __siov iov;
-  size_t len;
-
-  if ((fp->_flags & __SSTR) == 0) return (__fputwc_unlock(wc, fp));
-
-  bzero(&mbs, sizeof(mbs));
-  len = wcrtomb(buf, wc, &mbs);
-  if (len == (size_t)-1) {
-    fp->_flags |= __SERR;
-    errno = EILSEQ;
-    return (WEOF);
-  }
-  uio.uio_iov = &iov;
-  uio.uio_resid = len;
-  uio.uio_iovcnt = 1;
-  iov.iov_base = buf;
-  iov.iov_len = len;
-  return (__sfvwrite(fp, &uio) != EOF ? (wint_t)wc : WEOF);
-}
-
-/*
- * Convert a multibyte character string argument for the %s format to a wide
- * string representation. ``prec'' specifies the maximum number of bytes
- * to output. If ``prec'' is greater than or equal to zero, we can't assume
- * that the multibyte character string ends in a null character.
- *
- * Returns NULL on failure.
- * To find out what happened check errno for ENOMEM, EILSEQ and EINVAL.
- */
-static wchar_t* __mbsconv(char* mbsarg, int prec) {
-  mbstate_t mbs;
-  wchar_t *convbuf, *wcp;
-  const char* p;
-  size_t insize, nchars, nconv;
-
-  if (mbsarg == NULL) return (NULL);
-
-  /*
-   * Supplied argument is a multibyte string; convert it to wide
-   * characters first.
-   */
-  if (prec >= 0) {
-    /*
-     * String is not guaranteed to be NUL-terminated. Find the
-     * number of characters to print.
-     */
-    p = mbsarg;
-    insize = nchars = nconv = 0;
-    bzero(&mbs, sizeof(mbs));
-    while (nchars != (size_t)prec) {
-      nconv = mbrlen(p, MB_CUR_MAX, &mbs);
-      if (nconv == (size_t)0 || nconv == (size_t)-1 || nconv == (size_t)-2) break;
-      p += nconv;
-      nchars++;
-      insize += nconv;
-    }
-    if (nconv == (size_t)-1 || nconv == (size_t)-2) return (NULL);
-  } else
-    insize = strlen(mbsarg);
-
-  /*
-   * Allocate buffer for the result and perform the conversion,
-   * converting at most `size' bytes of the input multibyte string to
-   * wide characters for printing.
-   */
-  convbuf = static_cast<wchar_t*>(calloc(insize + 1, sizeof(*convbuf)));
-  if (convbuf == NULL) return (NULL);
-  wcp = convbuf;
-  p = mbsarg;
-  bzero(&mbs, sizeof(mbs));
-  nconv = 0;
-  while (insize != 0) {
-    nconv = mbrtowc(wcp, p, insize, &mbs);
-    if (nconv == 0 || nconv == (size_t)-1 || nconv == (size_t)-2) break;
-    wcp++;
-    p += nconv;
-    insize -= nconv;
-  }
-  if (nconv == (size_t)-1 || nconv == (size_t)-2) {
-    free(convbuf);
-    return (NULL);
-  }
-  *wcp = '\0';
-
-  return (convbuf);
-}
-
 int FUNCTION_NAME(FILE* fp, const CHAR_TYPE* fmt0, va_list ap) {
   wchar_t ch;    /* character from fmt */
   int n, n2, n3; /* handy integers (short term usage) */
@@ -206,11 +118,11 @@
 #define PRINT(ptr, len)                                   \
   do {                                                    \
     for (n3 = 0; n3 < (len); n3++) {                      \
-      if ((__xfputwc((ptr)[n3], fp)) == WEOF) goto error; \
+      if ((helpers::xfputwc((ptr)[n3], fp)) == WEOF) goto error; \
     }                                                     \
   } while (0)
 
-  _SET_ORIENTATION(fp, 1);
+  _SET_ORIENTATION(fp, CHAR_TYPE_ORIENTATION);
 
   // Writing "" to a read only file returns EOF, not 0.
   if (cantwrite(fp)) {
@@ -431,7 +343,7 @@
         if (prec < 0) prec = dtoaend - dtoaresult;
         if (expt == INT_MAX) ox[1] = '\0';
         free(convbuf);
-        cp = convbuf = __mbsconv(dtoaresult, -1);
+        cp = convbuf = helpers::mbsconv(dtoaresult, -1);
         if (cp == NULL) goto error;
         ndig = dtoaend - dtoaresult;
         goto fp_common;
@@ -471,16 +383,16 @@
           if (expt == 9999) expt = INT_MAX;
         }
         free(convbuf);
-        cp = convbuf = __mbsconv(dtoaresult, -1);
+        cp = convbuf = helpers::mbsconv(dtoaresult, -1);
         if (cp == NULL) goto error;
         ndig = dtoaend - dtoaresult;
       fp_common:
         if (signflag) sign = '-';
         if (expt == INT_MAX) { /* inf or nan */
           if (*cp == 'N') {
-            cp = const_cast<wchar_t*>((ch >= 'a') ? L"nan" : L"NAN");
+            cp = const_cast<CHAR_TYPE*>((ch >= 'a') ? CHAR_TYPE_nan : CHAR_TYPE_NAN);
           } else {
-            cp = const_cast<wchar_t*>((ch >= 'a') ? L"inf" : L"INF");
+            cp = const_cast<CHAR_TYPE*>((ch >= 'a') ? CHAR_TYPE_inf : CHAR_TYPE_INF);
           }
           size = 3;
           flags &= ~ZEROPAD;
@@ -569,7 +481,7 @@
           char* mbsarg;
           if ((mbsarg = GETARG(char*)) == NULL) mbsarg = const_cast<char*>("(null)");
           free(convbuf);
-          convbuf = __mbsconv(mbsarg, prec);
+          convbuf = helpers::mbsconv(mbsarg, prec);
           if (convbuf == NULL) {
             fp->_flags |= __SERR;
             goto error;
@@ -578,11 +490,11 @@
           }
         }
         if (prec >= 0) {
-          size = wcsnlen(cp, prec);
+          size = CHAR_TYPE_STRNLEN(cp, prec);
         } else {
           size_t len;
 
-          if ((len = wcslen(cp)) > INT_MAX) goto overflow;
+          if ((len = CHAR_TYPE_STRLEN(cp)) > INT_MAX) goto overflow;
           size = (int)len;
         }
         sign = '\0';