LCOV - code coverage report
Current view: top level - home/branden/src/GIT/groff/lib - vasnprintf.c (source / functions) Hit Total Coverage
Test: GNU roff Lines: 127 639 19.9 %
Date: 2026-01-16 17:51:41 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* vsprintf with automatic memory allocation.
       2             :    Copyright (C) 1999, 2002-2025 Free Software Foundation, Inc.
       3             : 
       4             :    This file is free software: you can redistribute it and/or modify
       5             :    it under the terms of the GNU Lesser General Public License as
       6             :    published by the Free Software Foundation; either version 2.1 of the
       7             :    License, or (at your option) any later version.
       8             : 
       9             :    This file is distributed in the hope that it will be useful,
      10             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :    GNU Lesser General Public License for more details.
      13             : 
      14             :    You should have received a copy of the GNU Lesser General Public License
      15             :    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16             : 
      17             : /* This file can be parametrized with the following macros:
      18             :      VASNPRINTF         The name of the function being defined.
      19             :      FCHAR_T            The element type of the format string.
      20             :      DCHAR_T            The element type of the destination (result) string.
      21             :      FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
      22             :                         in the format string are ASCII. MUST be set if
      23             :                         FCHAR_T and DCHAR_T are not the same type.
      24             :      DIRECTIVE          Structure denoting a format directive.
      25             :                         Depends on FCHAR_T.
      26             :      DIRECTIVES         Structure denoting the set of format directives of a
      27             :                         format string.  Depends on FCHAR_T.
      28             :      PRINTF_PARSE       Function that parses a format string.
      29             :                         Depends on FCHAR_T.
      30             :      DCHAR_CPY          memcpy like function for DCHAR_T[] arrays.
      31             :      DCHAR_SET          memset like function for DCHAR_T[] arrays.
      32             :      DCHAR_STRLEN       strlen like function for DCHAR_T[] arrays.
      33             :      DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
      34             :      SNPRINTF           The system's snprintf (or similar) function.
      35             :                         This may be either snprintf or swprintf.
      36             :      TCHAR_T            The element type of the argument and result string
      37             :                         of the said SNPRINTF function.  This may be either
      38             :                         char or wchar_t.  The code exploits that
      39             :                         sizeof (TCHAR_T) | sizeof (DCHAR_T) and
      40             :                         alignof (TCHAR_T) <= alignof (DCHAR_T).
      41             :      DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
      42             :      DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
      43             :      DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
      44             :      DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
      45             :      DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.
      46             :      ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.
      47             :      ENABLE_WCHAR_FALLBACK  Set to 1 to avoid EILSEQ during conversion of wide
      48             :                         characters (wchar_t) and wide character strings
      49             :                         (wchar_t[]) to multibyte sequences.  The fallback is the
      50             :                         hexadecimal escape syntax (\unnnn or \Unnnnnnnn) or,
      51             :                         if wchar_t is not Unicode encoded, \wnnnn or \Wnnnnnnnn.
      52             :  */
      53             : 
      54             : /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
      55             :    This must come before <config.h> because <config.h> may include
      56             :    <features.h>, and once <features.h> has been included, it's too late.  */
      57             : #ifndef _GNU_SOURCE
      58             : # define _GNU_SOURCE    1
      59             : #endif
      60             : 
      61             : #ifndef VASNPRINTF
      62             : # include <config.h>
      63             : #endif
      64             : 
      65             : /* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's
      66             :    use of CHECK macros expands to code that is too complicated for gcc
      67             :    -fanalyzer.  Suppress the resulting bogus warnings.  */
      68             : #if _GL_GNUC_PREREQ (10, 0)
      69             : # pragma GCC diagnostic ignored "-Wanalyzer-null-argument"
      70             : #endif
      71             : 
      72             : #include <alloca.h>
      73             : 
      74             : /* Specification.  */
      75             : #ifndef VASNPRINTF
      76             : # if WIDE_CHAR_VERSION
      77             : #  include "vasnwprintf.h"
      78             : # else
      79             : #  include "vasnprintf.h"
      80             : # endif
      81             : #endif
      82             : 
      83             : #include <locale.h>     /* localeconv() */
      84             : #include <stdint.h>     /* PTRDIFF_MAX */
      85             : #include <stdio.h>      /* snprintf(), sprintf() */
      86             : #include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
      87             : #include <string.h>     /* memcpy(), strlen() */
      88             : #include <wchar.h>      /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb(), mbszero() */
      89             : #include <errno.h>      /* errno */
      90             : #include <limits.h>     /* CHAR_BIT, INT_MAX, INT_WIDTH, LONG_WIDTH */
      91             : #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP, LDBL_MANT_DIG */
      92             : #if HAVE_NL_LANGINFO || __GLIBC__ >= 2 || defined __CYGWIN__
      93             : # include <langinfo.h>
      94             : #endif
      95             : #ifndef VASNPRINTF
      96             : # if WIDE_CHAR_VERSION
      97             : #  include "wprintf-parse.h"
      98             : # else
      99             : #  include "printf-parse.h"
     100             : # endif
     101             : #endif
     102             : 
     103             : /* Checked size_t computations.  */
     104             : #include "xsize.h"
     105             : 
     106             : #include "attribute.h"
     107             : 
     108             : #if NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
     109             : # include <math.h>
     110             : # include "float+.h"
     111             : #endif
     112             : 
     113             : #if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
     114             : # include <math.h>
     115             : # include "isnand-nolibm.h"
     116             : #endif
     117             : 
     118             : #if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
     119             : # include <math.h>
     120             : # include "isnanl-nolibm.h"
     121             : # include "fpucw.h"
     122             : #endif
     123             : 
     124             : #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
     125             : # include <math.h>
     126             : # include "isnand-nolibm.h"
     127             : # include "printf-frexp.h"
     128             : #endif
     129             : 
     130             : #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
     131             : # include <math.h>
     132             : # include "isnanl-nolibm.h"
     133             : # include "printf-frexpl.h"
     134             : # include "fpucw.h"
     135             : #endif
     136             : 
     137             : /* Default parameters.  */
     138             : #ifndef VASNPRINTF
     139             : # if WIDE_CHAR_VERSION
     140             : #  define VASNPRINTF vasnwprintf
     141             : #  define FCHAR_T wchar_t
     142             : #  define DCHAR_T wchar_t
     143             : #  define DIRECTIVE wchar_t_directive
     144             : #  define DIRECTIVES wchar_t_directives
     145             : #  define PRINTF_PARSE wprintf_parse
     146             : #  define DCHAR_CPY wmemcpy
     147             : #  define DCHAR_SET wmemset
     148             : # else
     149             : #  define VASNPRINTF vasnprintf
     150             : #  define FCHAR_T char
     151             : #  define DCHAR_T char
     152             : #  define TCHAR_T char
     153             : #  define DCHAR_IS_TCHAR 1
     154             : #  define DIRECTIVE char_directive
     155             : #  define DIRECTIVES char_directives
     156             : #  define PRINTF_PARSE printf_parse
     157             : #  define DCHAR_CPY memcpy
     158             : #  define DCHAR_SET memset
     159             : # endif
     160             : #endif
     161             : #if WIDE_CHAR_VERSION
     162             :   /* DCHAR_T is wchar_t.  */
     163             : # if HAVE_DECL__SNWPRINTF || (HAVE_SWPRINTF && HAVE_WORKING_SWPRINTF)
     164             : #  define TCHAR_T wchar_t
     165             : #  define DCHAR_IS_TCHAR 1
     166             : #  define USE_SNPRINTF 1
     167             : #  if HAVE_DECL__SNWPRINTF
     168             :     /* On Windows, the function swprintf() has a different signature than
     169             :        on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
     170             :        instead.  The mingw function snwprintf() has fewer bugs than the
     171             :        MSVCRT function _snwprintf(), so prefer that.  */
     172             : #   if defined __MINGW32__
     173             : #    define SNPRINTF snwprintf
     174             : #   else
     175             : #    define SNPRINTF _snwprintf
     176             : #    define USE_MSVC__SNPRINTF 1
     177             : #   endif
     178             : #  else
     179             :     /* Unix.  */
     180             : #   define SNPRINTF swprintf
     181             : #  endif
     182             : # else
     183             :    /* Old platforms such as NetBSD 3.0, OpenBSD 3.8, HP-UX 11.00, IRIX 6.5.  */
     184             : #   define TCHAR_T char
     185             : # endif
     186             : #endif
     187             : #ifndef DCHAR_STRLEN
     188             : # if WIDE_CHAR_VERSION
     189             : #  define DCHAR_STRLEN local_wcslen
     190             : # else
     191             : #  define DCHAR_STRLEN strlen
     192             : # endif
     193             : #endif
     194             : #ifndef DCHAR_MBSNLEN
     195             : # if WIDE_CHAR_VERSION
     196             : #  define DCHAR_MBSNLEN wcsnlen
     197             : # else
     198             : #  define DCHAR_MBSNLEN mbsnlen
     199             : # endif
     200             : #endif
     201             : #if !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR
     202             :   /* TCHAR_T is char.  */
     203             :   /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
     204             :      But don't use it on BeOS, since BeOS snprintf produces no output if the
     205             :      size argument is >= 0x3000000.
     206             :      Also don't use it on Linux libc5, since there snprintf with size = 1
     207             :      writes any output without bounds, like sprintf.  */
     208             : # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
     209             : #  define USE_SNPRINTF 1
     210             : # else
     211             : #  define USE_SNPRINTF 0
     212             : # endif
     213             : # if HAVE_DECL__SNPRINTF
     214             :    /* Windows.  The mingw function snprintf() has fewer bugs than the MSVCRT
     215             :       function _snprintf(), so prefer that.  */
     216             : #  if defined __MINGW32__
     217             : #   define SNPRINTF snprintf
     218             :     /* Here we need to call the native snprintf, not rpl_snprintf.  */
     219             : #   undef snprintf
     220             : #  else
     221             :     /* MSVC versions < 14 did not have snprintf, only _snprintf.  */
     222             : #   define SNPRINTF _snprintf
     223             : #   define USE_MSVC__SNPRINTF 1
     224             : #  endif
     225             : # else
     226             :    /* Unix.  */
     227             : #  define SNPRINTF snprintf
     228             :    /* Here we need to call the native snprintf, not rpl_snprintf.  */
     229             : #  undef snprintf
     230             : # endif
     231             : #endif
     232             : /* Here we need to call the native sprintf, not rpl_sprintf.  */
     233             : #undef sprintf
     234             : 
     235             : /* macOS 12's "warning: 'sprintf' is deprecated" is pointless,
     236             :    as sprintf is used safely here.  */
     237             : #if defined __APPLE__ && defined __MACH__ && _GL_GNUC_PREREQ (4, 2)
     238             : # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     239             : #endif
     240             : 
     241             : /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
     242             :    warnings in this file.  Use -Dlint to suppress them.  */
     243             : #if defined GCC_LINT || defined lint
     244             : # define IF_LINT(Code) Code
     245             : #else
     246             : # define IF_LINT(Code) /* empty */
     247             : #endif
     248             : 
     249             : /* Here we need only the most basic fields of 'struct lconv', and can
     250             :    therefore use the system's localeconv() function, without needing a
     251             :    dependency on module 'localeconv'.  */
     252             : #undef localeconv
     253             : 
     254             : /* Avoid some warnings from "gcc -Wshadow".
     255             :    This file doesn't use the exp() and remainder() functions.  */
     256             : #undef exp
     257             : #define exp expo
     258             : #undef remainder
     259             : #define remainder rem
     260             : 
     261             : #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (PTRDIFF_MAX > INT_MAX)) && !WIDE_CHAR_VERSION
     262             : # if (HAVE_STRNLEN && !defined _AIX)
     263             : #  define local_strnlen strnlen
     264             : # else
     265             : #  ifndef local_strnlen_defined
     266             : #   define local_strnlen_defined 1
     267             : static size_t
     268             : local_strnlen (const char *string, size_t maxlen)
     269             : {
     270             :   const char *end = memchr (string, '\0', maxlen);
     271             :   return end ? (size_t) (end - string) : maxlen;
     272             : }
     273             : #  endif
     274             : # endif
     275             : #endif
     276             : 
     277             : #if ((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)
     278             : # if HAVE_WCSLEN
     279             : #  define local_wcslen wcslen
     280             : # else
     281             :    /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
     282             :       a dependency towards this library, here is a local substitute.
     283             :       Define this substitute only once, even if this file is included
     284             :       twice in the same compilation unit.  */
     285             : #  ifndef local_wcslen_defined
     286             : #   define local_wcslen_defined 1
     287             : static size_t
     288             : local_wcslen (const wchar_t *s)
     289             : {
     290             :   const wchar_t *ptr;
     291             : 
     292             :   for (ptr = s; *ptr != (wchar_t) 0; ptr++)
     293             :     ;
     294             :   return ptr - s;
     295             : }
     296             : #  endif
     297             : # endif
     298             : #endif
     299             : 
     300             : #if (!USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION
     301             : # if HAVE_WCSNLEN && HAVE_DECL_WCSNLEN
     302             : #  define local_wcsnlen wcsnlen
     303             : # else
     304             : #  ifndef local_wcsnlen_defined
     305             : #   define local_wcsnlen_defined 1
     306             : static size_t
     307             : local_wcsnlen (const wchar_t *s, size_t maxlen)
     308             : {
     309             :   const wchar_t *ptr;
     310             : 
     311             :   for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
     312             :     ;
     313             :   return ptr - s;
     314             : }
     315             : #  endif
     316             : # endif
     317             : #endif
     318             : 
     319             : #if ((!USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T)) && !WIDE_CHAR_VERSION
     320             : # if ENABLE_WCHAR_FALLBACK
     321             : static size_t
     322             : wctomb_fallback (char *s, wchar_t wc)
     323             : {
     324             :   static char const hex[16] = "0123456789ABCDEF";
     325             : 
     326             :   s[0] = '\\';
     327             :   if (sizeof (wchar_t) > 2 && wc > 0xffff)
     328             :     {
     329             : #  if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
     330             :       s[1] = 'U';
     331             : #  else
     332             :       s[1] = 'W';
     333             : #  endif
     334             :       s[2] = hex[(wc & 0xf0000000U) >> 28];
     335             :       s[3] = hex[(wc & 0xf000000U) >> 24];
     336             :       s[4] = hex[(wc & 0xf00000U) >> 20];
     337             :       s[5] = hex[(wc & 0xf0000U) >> 16];
     338             :       s[6] = hex[(wc & 0xf000U) >> 12];
     339             :       s[7] = hex[(wc & 0xf00U) >> 8];
     340             :       s[8] = hex[(wc & 0xf0U) >> 4];
     341             :       s[9] = hex[wc & 0xfU];
     342             :       return 10;
     343             :     }
     344             :   else
     345             :     {
     346             : #  if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
     347             :       s[1] = 'u';
     348             : #  else
     349             :       s[1] = 'w';
     350             : #  endif
     351             :       s[2] = hex[(wc & 0xf000U) >> 12];
     352             :       s[3] = hex[(wc & 0xf00U) >> 8];
     353             :       s[4] = hex[(wc & 0xf0U) >> 4];
     354             :       s[5] = hex[wc & 0xfU];
     355             :       return 6;
     356             :     }
     357             : }
     358             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
     359             : static size_t
     360             : local_wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
     361             : {
     362             :   size_t count = wcrtomb (s, wc, ps);
     363             :   if (count == (size_t)(-1))
     364             :     count = wctomb_fallback (s, wc);
     365             :   return count;
     366             : }
     367             : #  else
     368             : static int
     369             : local_wctomb (char *s, wchar_t wc)
     370             : {
     371             :   int count = wctomb (s, wc);
     372             :   if (count < 0)
     373             :     count = wctomb_fallback (s, wc);
     374             :   return count;
     375             : }
     376             : #   define local_wcrtomb(S, WC, PS)  local_wctomb ((S), (WC))
     377             : #  endif
     378             : # else
     379             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
     380             : #   define local_wcrtomb(S, WC, PS)  wcrtomb ((S), (WC), (PS))
     381             : #  else
     382             : #   define local_wcrtomb(S, WC, PS)  wctomb ((S), (WC))
     383             : #  endif
     384             : # endif
     385             : #endif
     386             : 
     387             : #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION) || (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT)
     388             : /* Determine the decimal-point character according to the current locale.  */
     389             : # ifndef decimal_point_char_defined
     390             : #  define decimal_point_char_defined 1
     391             : static char
     392             : decimal_point_char (void)
     393             : {
     394             :   const char *point;
     395             :   /* Determine it in a multithread-safe way.  We know nl_langinfo is
     396             :      multithread-safe on glibc systems and Mac OS X systems, but is not required
     397             :      to be multithread-safe by POSIX.  sprintf(), however, is multithread-safe.
     398             :      localeconv() is rarely multithread-safe.  */
     399             : #  if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
     400             :   point = nl_langinfo (RADIXCHAR);
     401             : #  elif 1
     402             :   char pointbuf[5];
     403             :   sprintf (pointbuf, "%#.0f", 1.0);
     404             :   point = &pointbuf[1];
     405             : #  else
     406             :   point = localeconv () -> decimal_point;
     407             : #  endif
     408             :   /* The decimal point is always a single byte: either '.' or ','.  */
     409             :   return (point[0] != '\0' ? point[0] : '.');
     410             : }
     411             : # endif
     412             : #endif
     413             : 
     414             : #if (!WIDE_CHAR_VERSION && (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE)) || ((!WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR) && (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT))
     415             : /* Determine the thousands-separator character according to the current
     416             :    locale.
     417             :    It is a single multibyte character.
     418             :    In glibc: 35x ".", 90x ",", 23x U+202F, 1x U+2019, 1x U+066C, on other
     419             :    systems also U+00A0.  */
     420             : # ifndef thousands_separator_char_defined
     421             : #  define thousands_separator_char_defined 1
     422             : static const char *
     423             : thousands_separator_char (char stackbuf[10])
     424             : {
     425             :   /* Determine it in a multithread-safe way.
     426             :      We know nl_langinfo is multithread-safe on glibc systems, on Mac OS X
     427             :      systems, and on NetBSD, but is not required to be multithread-safe by
     428             :      POSIX.
     429             :      localeconv() is not guaranteed to be multithread-safe by POSIX either;
     430             :      however, on native Windows it is (cf. test-localeconv-mt).
     431             :      sprintf(), however, is multithread-safe.  */
     432             : #  if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__) || defined __NetBSD__)
     433             :   return nl_langinfo (THOUSEP);
     434             : #  elif defined _WIN32 && !defined __CYGWIN__
     435             :   return localeconv () -> thousands_sep;
     436             : #  else
     437             :   sprintf (stackbuf, "%'.0f", 1000.0);
     438             :   /* Now stackbuf = "1<thousep>000".  */
     439             :   stackbuf[strlen (stackbuf) - 3] = '\0';
     440             : #   if defined __sun
     441             :   /* Solaris specific hack: Replace wrong result (0xC2 means U+00A0).  */
     442             :   if (strcmp (&stackbuf[1], "\302") == 0)
     443             :     strcpy (&stackbuf[1], MB_CUR_MAX > 1 ? "\302\240" : "\240");
     444             : #   endif
     445             :   return &stackbuf[1];
     446             : #  endif
     447             : }
     448             : # endif
     449             : #endif
     450             : #if !WIDE_CHAR_VERSION && defined DCHAR_CONV_FROM_ENCODING && (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE)
     451             : /* Determine the thousands-separator character, as a DCHAR_T[] array,
     452             :    according to the current locale.
     453             :    It is a single Unicode character.  */
     454             : # ifndef thousands_separator_DCHAR_defined
     455             : #  define thousands_separator_DCHAR_defined 1
     456             : static const DCHAR_T *
     457             : thousands_separator_DCHAR (DCHAR_T stackbuf[10])
     458             : {
     459             :   /* Determine it in a multithread-safe way.  */
     460             :   char tmpbuf[10];
     461             :   const char *tmp = thousands_separator_char (tmpbuf);
     462             :   if (*tmp != '\0')
     463             :     {
     464             :       /* Convert it from char[] to DCHAR_T[].  */
     465             :       size_t converted_len = 10;
     466             :       DCHAR_T *converted =
     467             :         DCHAR_CONV_FROM_ENCODING (locale_charset (),
     468             :                                   iconveh_question_mark,
     469             :                                   tmp, strlen (tmp) + 1,
     470             :                                   NULL,
     471             :                                   stackbuf, &converted_len);
     472             :       if (converted != NULL)
     473             :         {
     474             :           if (converted != stackbuf)
     475             :             /* It should not be so long.  */
     476             :             abort ();
     477             :           return stackbuf;
     478             :         }
     479             :     }
     480             :   stackbuf[0] = 0;
     481             :   return stackbuf;
     482             : }
     483             : # endif
     484             : #endif
     485             : /* Maximum number of 'char' in the char[] or DCHAR_T[] representation of the
     486             :    thousands separator.  */
     487             : #define THOUSEP_CHAR_MAXLEN 3
     488             : 
     489             : #if WIDE_CHAR_VERSION && ((NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) || ((NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT) && DCHAR_IS_TCHAR))
     490             : /* Determine the thousands-separator character, as a wide character, according
     491             :    to the current locale.
     492             :    It is a single wide character.  */
     493             : # ifndef thousands_separator_wchar_defined
     494             : #  define thousands_separator_wchar_defined 1
     495             : static const wchar_t *
     496             : thousands_separator_wchar (wchar_t stackbuf[10])
     497             : {
     498             : #  if __GLIBC__ >= 2 || defined __CYGWIN__
     499             :   /* On glibc, in the unibyte locale fr_FR, the *wprintf routines use U+202F
     500             :      as separator, which cannot be represented in the locale encoding.  */
     501             :   stackbuf[0] =
     502             :     (wchar_t) (unsigned long) nl_langinfo (_NL_NUMERIC_THOUSANDS_SEP_WC);
     503             :   stackbuf[1] = L'\0';
     504             :   return stackbuf;
     505             : #  elif defined _WIN32 && !defined __CYGWIN__
     506             :   const char *tmp = localeconv () -> thousands_sep;
     507             :   if (*tmp != '\0')
     508             :     {
     509             :       mbstate_t state;
     510             :       mbszero (&state);
     511             :       if ((int) mbrtowc (&stackbuf[0], tmp, strlen (tmp), &state) > 0)
     512             :         stackbuf[1] = L'\0';
     513             :       else
     514             :         stackbuf[0] = L'\0';
     515             :     }
     516             :   else
     517             :     stackbuf[0] = L'\0';
     518             :   return stackbuf;
     519             : #  elif defined __sun
     520             :   /* Use sprintf, because swprintf retrieves a wrong value for the
     521             :      thousands-separator wide character (e.g. (wchar_t) 0xffffffa0).  */
     522             :   char tmp[10];
     523             :   sprintf (tmp, "%'.0f", 1000.0);
     524             :   /* Now tmp = L"1<thousep>000".  */
     525             :   tmp[strlen (tmp) - 3] = '\0';
     526             :   /* Solaris specific hack: Replace wrong result (0xC2 means U+00A0).  */
     527             :   if (strcmp (&tmp[1], "\302") == 0)
     528             :     strcpy (&tmp[1], MB_CUR_MAX > 1 ? "\302\240" : "\240");
     529             :   if (tmp[1] != '\0')
     530             :     {
     531             :       mbstate_t state;
     532             :       mbszero (&state);
     533             :       if ((int) mbrtowc (&stackbuf[0], &tmp[1], strlen (&tmp[1]), &state) > 0)
     534             :         stackbuf[1] = L'\0';
     535             :       else
     536             :         stackbuf[0] = L'\0';
     537             :     }
     538             :   else
     539             :     stackbuf[0] = L'\0';
     540             :   return stackbuf;
     541             : #  else
     542             :   swprintf (stackbuf, 10, L"%'.0f", 1000.0);
     543             :   /* Now stackbuf = L"1<thousep>000".  */
     544             :   stackbuf[local_wcslen (stackbuf) - 3] = '\0';
     545             :   return &stackbuf[1];
     546             : #  endif
     547             : }
     548             : # endif
     549             : #endif
     550             : /* Maximum number of 'wchar_t' in the wchar_t[] representation of the thousands
     551             :    separator.  */
     552             : #define THOUSEP_WCHAR_MAXLEN 1
     553             : 
     554             : #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) || (NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT)
     555             : # ifndef grouping_rule_defined
     556             : #  define grouping_rule_defined 1
     557             : /* Determine the grouping rule.
     558             :  * As specified in POSIX
     559             :  * <https://pubs.opengroup.org/onlinepubs/9799919799/functions/localeconv.html>
     560             :  * <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap07.html#tag_07_03_04>
     561             :  * it is a string whose elements are 'signed char' values, where
     562             :  * "Each integer specifies the number of digits in each group, with the initial
     563             :  *  integer defining the size of the group immediately preceding the decimal
     564             :  *  delimiter, and the following integers defining the preceding groups.  If
     565             :  *  the last integer is not -1, then the size of the previous group (if any)
     566             :  *  shall be repeatedly used for the remainder of the digits.  If the last
     567             :  *  integer is -1, then no further grouping shall be performed."
     568             :  * Platforms that have locales with grouping:
     569             :  *   glibc, FreeBSD, NetBSD, AIX, Solaris, Cygwin, Haiku.
     570             :  * Platforms that don't:
     571             :  *   musl libc, macOS, OpenBSD, Android, mingw, MSVC.
     572             :  * Typical grouping rules on glibc:
     573             :  *   136x 3     (fr_FR etc.)
     574             :  *   4x 4       (cmn_TW etc.)
     575             :  *   9x 3;2     (ta_IN etc.)
     576             :  *   1x 2;2;2;3 (umn_US)
     577             :  *   21x -1     (C etc.)
     578             :  */
     579             : static const signed char *
     580             : grouping_rule (void)
     581             : {
     582             :   /* We know nl_langinfo is multithread-safe on glibc systems and on Cygwin,
     583             :      but is not required to be multithread-safe by POSIX.
     584             :      localeconv() is not guaranteed to be multithread-safe by POSIX either;
     585             :      however, on all known systems it is (cf. test-localeconv-mt).  */
     586             : #  if __GLIBC__ >= 2
     587             :   return (const signed char *) nl_langinfo (GROUPING);
     588             : #  elif defined __CYGWIN__
     589             :   return (const signed char *) nl_langinfo (_NL_NUMERIC_GROUPING);
     590             : #  else
     591             :   return (const signed char *) localeconv () -> grouping;
     592             : #  endif
     593             : }
     594             : /* Determines the number of thousands-separators to be inserted in a digit
     595             :    sequence with ndigits digits (before the decimal point).  */
     596             : static size_t
     597             : num_thousands_separators (const signed char *grouping, size_t ndigits)
     598             : {
     599             :   const signed char *g = grouping;
     600             :   int h = *g;
     601             :   if (h <= 0 || ndigits == 0)
     602             :     return 0;
     603             :   size_t insert = 0;
     604             :   for (;;)
     605             :     {
     606             :       /* Invariant: here h == *g, h > 0, ndigits > 0.  */
     607             :       if (g[1] == 0)
     608             :         /* h repeats endlessly.  */
     609             :         return insert + (ndigits - 1) / h;
     610             :       /* h does not repeat.  */
     611             :       if (ndigits <= h)
     612             :         return insert;
     613             :       ndigits -= h;
     614             :       insert++;
     615             :       g++;
     616             :       h = *g;
     617             :       if (h < 0)
     618             :         /* No further grouping.  */
     619             :         return insert;
     620             :     }
     621             : }
     622             : # endif
     623             : #endif
     624             : 
     625             : #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE
     626             : 
     627             : /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
     628             : static int
     629             : is_infinite_or_zero (double x)
     630             : {
     631             :   return isnand (x) || x + x == x;
     632             : }
     633             : 
     634             : #endif
     635             : 
     636             : #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE
     637             : 
     638             : /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
     639             : static int
     640             : is_infinite_or_zerol (long double x)
     641             : {
     642             :   return isnanl (x) || x + x == x;
     643             : }
     644             : 
     645             : #endif
     646             : 
     647             : #if NEED_PRINTF_LONG_DOUBLE
     648             : 
     649             : /* Like frexpl, except that it supports even "unsupported" numbers.  */
     650             : # if (LDBL_MANT_DIG == 64 && (defined __ia64 || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_))) && (defined __APPLE__ && defined __MACH__)
     651             : /* Don't assume that frexpl can handle pseudo-denormals; it does not on
     652             :    macOS 12/x86_64.  Therefore test for a pseudo-denormal explicitly.  */
     653             : 
     654             : static
     655             : long double safe_frexpl (long double x, int *exp)
     656             : {
     657             :   union
     658             :     {
     659             :       long double value;
     660             :       struct { unsigned int mant_word[2]; unsigned short sign_exp_word; } r;
     661             :     }
     662             :   u;
     663             :   u.value = x;
     664             :   if (u.r.sign_exp_word == 0 && (u.r.mant_word[1] & 0x80000000u) != 0)
     665             :     {
     666             :       /* Pseudo-Denormal.  */
     667             :       *exp = LDBL_MIN_EXP;
     668             :       u.r.sign_exp_word = 1 - LDBL_MIN_EXP;
     669             :       return u.value;
     670             :     }
     671             :   else
     672             :     return frexpl (x, exp);
     673             : }
     674             : 
     675             : # else
     676             : #  define safe_frexpl frexpl
     677             : # endif
     678             : 
     679             : #endif
     680             : 
     681             : #if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE
     682             : 
     683             : /* An indicator for a failed memory allocation.  */
     684             : # define NOMEM_PTR ((void *) (-1))
     685             : 
     686             : /* Converting 'long double' to decimal without rare rounding bugs requires
     687             :    real bignums.  We use the naming conventions of GNU gmp, but vastly simpler
     688             :    (and slower) algorithms.  */
     689             : 
     690             : typedef unsigned int mp_limb_t;
     691             : # define GMP_LIMB_BITS 32
     692             : static_assert (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
     693             : 
     694             : typedef unsigned long long mp_twolimb_t;
     695             : # define GMP_TWOLIMB_BITS 64
     696             : static_assert (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
     697             : 
     698             : /* Representation of a bignum >= 0.  */
     699             : typedef struct
     700             : {
     701             :   size_t nlimbs;
     702             :   mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc().  */
     703             : } mpn_t;
     704             : 
     705             : /* Compute the product of two bignums >= 0.
     706             :    Return the allocated memory (possibly NULL) in case of success, NOMEM_PTR
     707             :    in case of memory allocation failure.  */
     708             : static void *
     709             : multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
     710             : {
     711             :   const mp_limb_t *p1;
     712             :   const mp_limb_t *p2;
     713             :   size_t len1;
     714             :   size_t len2;
     715             : 
     716             :   if (src1.nlimbs <= src2.nlimbs)
     717             :     {
     718             :       len1 = src1.nlimbs;
     719             :       p1 = src1.limbs;
     720             :       len2 = src2.nlimbs;
     721             :       p2 = src2.limbs;
     722             :     }
     723             :   else
     724             :     {
     725             :       len1 = src2.nlimbs;
     726             :       p1 = src2.limbs;
     727             :       len2 = src1.nlimbs;
     728             :       p2 = src1.limbs;
     729             :     }
     730             :   /* Now 0 <= len1 <= len2.  */
     731             :   if (len1 == 0)
     732             :     {
     733             :       /* src1 or src2 is zero.  */
     734             :       dest->nlimbs = 0;
     735             :       dest->limbs = NULL;
     736             :     }
     737             :   else
     738             :     {
     739             :       /* Here 1 <= len1 <= len2.  */
     740             :       size_t dlen;
     741             :       mp_limb_t *dp;
     742             :       size_t k, i, j;
     743             : 
     744             :       dlen = len1 + len2;
     745             :       dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
     746             :       if (dp == NULL)
     747             :         return NOMEM_PTR;
     748             :       for (k = len2; k > 0; )
     749             :         dp[--k] = 0;
     750             :       for (i = 0; i < len1; i++)
     751             :         {
     752             :           mp_limb_t digit1 = p1[i];
     753             :           mp_twolimb_t carry = 0;
     754             :           for (j = 0; j < len2; j++)
     755             :             {
     756             :               mp_limb_t digit2 = p2[j];
     757             :               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
     758             :               carry += dp[i + j];
     759             :               dp[i + j] = (mp_limb_t) carry;
     760             :               carry = carry >> GMP_LIMB_BITS;
     761             :             }
     762             :           dp[i + len2] = (mp_limb_t) carry;
     763             :         }
     764             :       /* Normalise.  */
     765             :       while (dlen > 0 && dp[dlen - 1] == 0)
     766             :         dlen--;
     767             :       dest->nlimbs = dlen;
     768             :       dest->limbs = dp;
     769             :     }
     770             :   return dest->limbs;
     771             : }
     772             : 
     773             : /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
     774             :    a is written as  a = q * b + r  with 0 <= r < b.  q is the quotient, r
     775             :    the remainder.
     776             :    Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
     777             :    q is incremented.
     778             :    Return the allocated memory (possibly NULL) in case of success, NOMEM_PTR
     779             :    in case of memory allocation failure.  */
     780             : static void *
     781             : divide (mpn_t a, mpn_t b, mpn_t *q)
     782             : {
     783             :   /* Algorithm:
     784             :      First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
     785             :      with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
     786             :      If m<n, then q:=0 and r:=a.
     787             :      If m>=n=1, perform a single-precision division:
     788             :        r:=0, j:=m,
     789             :        while j>0 do
     790             :          {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
     791             :                = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
     792             :          j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
     793             :        Normalise [q[m-1],...,q[0]], yields q.
     794             :      If m>=n>1, perform a multiple-precision division:
     795             :        We have a/b < beta^(m-n+1).
     796             :        s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
     797             :        Shift a and b left by s bits, copying them. r:=a.
     798             :        r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
     799             :        For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
     800             :          Compute q* :
     801             :            q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
     802             :            In case of overflow (q* >= beta) set q* := beta-1.
     803             :            Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
     804             :            and c3 := b[n-2] * q*.
     805             :            {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
     806             :             occurred.  Furthermore 0 <= c3 < beta^2.
     807             :             If there was overflow and
     808             :             r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
     809             :             the next test can be skipped.}
     810             :            While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
     811             :              Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
     812             :            If q* > 0:
     813             :              Put r := r - b * q* * beta^j. In detail:
     814             :                [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
     815             :                hence: u:=0, for i:=0 to n-1 do
     816             :                               u := u + q* * b[i],
     817             :                               r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
     818             :                               u:=u div beta (+ 1, if carry in subtraction)
     819             :                       r[n+j]:=r[n+j]-u.
     820             :                {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
     821             :                                < q* + 1 <= beta,
     822             :                 the carry u does not overflow.}
     823             :              If a negative carry occurs, put q* := q* - 1
     824             :                and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
     825             :          Set q[j] := q*.
     826             :        Normalise [q[m-n],..,q[0]]; this yields the quotient q.
     827             :        Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
     828             :        rest r.
     829             :        The room for q[j] can be allocated at the memory location of r[n+j].
     830             :      Finally, round-to-even:
     831             :        Shift r left by 1 bit.
     832             :        If r > b or if r = b and q[0] is odd, q := q+1.
     833             :    */
     834             :   const mp_limb_t *a_ptr = a.limbs;
     835             :   size_t a_len = a.nlimbs;
     836             :   const mp_limb_t *b_ptr = b.limbs;
     837             :   size_t b_len = b.nlimbs;
     838             :   mp_limb_t *roomptr;
     839             :   mp_limb_t *tmp_roomptr = NULL;
     840             :   mp_limb_t *q_ptr;
     841             :   size_t q_len;
     842             :   mp_limb_t *r_ptr;
     843             :   size_t r_len;
     844             : 
     845             :   /* Allocate room for a_len+2 digits.
     846             :      (Need a_len+1 digits for the real division and 1 more digit for the
     847             :      final rounding of q.)  */
     848             :   roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
     849             :   if (roomptr == NULL)
     850             :     return NOMEM_PTR;
     851             : 
     852             :   /* Normalise a.  */
     853             :   while (a_len > 0 && a_ptr[a_len - 1] == 0)
     854             :     a_len--;
     855             : 
     856             :   /* Normalise b.  */
     857             :   for (;;)
     858             :     {
     859             :       if (b_len == 0)
     860             :         /* Division by zero.  */
     861             :         abort ();
     862             :       if (b_ptr[b_len - 1] == 0)
     863             :         b_len--;
     864             :       else
     865             :         break;
     866             :     }
     867             : 
     868             :   /* Here m = a_len >= 0 and n = b_len > 0.  */
     869             : 
     870             :   if (a_len < b_len)
     871             :     {
     872             :       /* m<n: trivial case.  q=0, r := copy of a.  */
     873             :       r_ptr = roomptr;
     874             :       r_len = a_len;
     875             :       memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
     876             :       q_ptr = roomptr + a_len;
     877             :       q_len = 0;
     878             :     }
     879             :   else if (b_len == 1)
     880             :     {
     881             :       /* n=1: single precision division.
     882             :          beta^(m-1) <= a < beta^m  ==>  beta^(m-2) <= a/b < beta^m  */
     883             :       r_ptr = roomptr;
     884             :       q_ptr = roomptr + 1;
     885             :       {
     886             :         mp_limb_t den = b_ptr[0];
     887             :         mp_limb_t remainder = 0;
     888             :         const mp_limb_t *sourceptr = a_ptr + a_len;
     889             :         mp_limb_t *destptr = q_ptr + a_len;
     890             :         size_t count;
     891             :         for (count = a_len; count > 0; count--)
     892             :           {
     893             :             mp_twolimb_t num =
     894             :               ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
     895             :             *--destptr = num / den;
     896             :             remainder = num % den;
     897             :           }
     898             :         /* Normalise and store r.  */
     899             :         if (remainder > 0)
     900             :           {
     901             :             r_ptr[0] = remainder;
     902             :             r_len = 1;
     903             :           }
     904             :         else
     905             :           r_len = 0;
     906             :         /* Normalise q.  */
     907             :         q_len = a_len;
     908             :         if (q_ptr[q_len - 1] == 0)
     909             :           q_len--;
     910             :       }
     911             :     }
     912             :   else
     913             :     {
     914             :       /* n>1: multiple precision division.
     915             :          beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n  ==>
     916             :          beta^(m-n-1) <= a/b < beta^(m-n+1).  */
     917             :       /* Determine s.  */
     918             :       size_t s;
     919             :       {
     920             :         mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
     921             :         /* Determine s = GMP_LIMB_BITS - integer_length (msd).
     922             :            Code copied from gnulib's integer_length.c.  */
     923             : # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
     924             :      || (__clang_major__ >= 4)
     925             :         s = __builtin_clz (msd);
     926             : # else
     927             : #  if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
     928             :         if (GMP_LIMB_BITS <= DBL_MANT_BIT)
     929             :           {
     930             :             /* Use 'double' operations.
     931             :                Assumes an IEEE 754 'double' implementation.  */
     932             : #   define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
     933             : #   define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
     934             : #   define NWORDS \
     935             :      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
     936             :             union { double value; unsigned int word[NWORDS]; } m;
     937             : 
     938             :             /* Use a single integer to floating-point conversion.  */
     939             :             m.value = msd;
     940             : 
     941             :             s = GMP_LIMB_BITS
     942             :                 - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
     943             :                    - DBL_EXP_BIAS);
     944             :           }
     945             :         else
     946             : #   undef NWORDS
     947             : #  endif
     948             :           {
     949             :             s = 31;
     950             :             if (msd >= 0x10000)
     951             :               {
     952             :                 msd = msd >> 16;
     953             :                 s -= 16;
     954             :               }
     955             :             if (msd >= 0x100)
     956             :               {
     957             :                 msd = msd >> 8;
     958             :                 s -= 8;
     959             :               }
     960             :             if (msd >= 0x10)
     961             :               {
     962             :                 msd = msd >> 4;
     963             :                 s -= 4;
     964             :               }
     965             :             if (msd >= 0x4)
     966             :               {
     967             :                 msd = msd >> 2;
     968             :                 s -= 2;
     969             :               }
     970             :             if (msd >= 0x2)
     971             :               {
     972             :                 msd = msd >> 1;
     973             :                 s -= 1;
     974             :               }
     975             :           }
     976             : # endif
     977             :       }
     978             :       /* 0 <= s < GMP_LIMB_BITS.
     979             :          Copy b, shifting it left by s bits.  */
     980             :       if (s > 0)
     981             :         {
     982             :           tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
     983             :           if (tmp_roomptr == NULL)
     984             :             {
     985             :               free (roomptr);
     986             :               return NOMEM_PTR;
     987             :             }
     988             :           {
     989             :             const mp_limb_t *sourceptr = b_ptr;
     990             :             mp_limb_t *destptr = tmp_roomptr;
     991             :             mp_twolimb_t accu = 0;
     992             :             size_t count;
     993             :             for (count = b_len; count > 0; count--)
     994             :               {
     995             :                 accu += (mp_twolimb_t) *sourceptr++ << s;
     996             :                 *destptr++ = (mp_limb_t) accu;
     997             :                 accu = accu >> GMP_LIMB_BITS;
     998             :               }
     999             :             /* accu must be zero, since that was how s was determined.  */
    1000             :             if (accu != 0)
    1001             :               abort ();
    1002             :           }
    1003             :           b_ptr = tmp_roomptr;
    1004             :         }
    1005             :       /* Copy a, shifting it left by s bits, yields r.
    1006             :          Memory layout:
    1007             :          At the beginning: r = roomptr[0..a_len],
    1008             :          at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len]  */
    1009             :       r_ptr = roomptr;
    1010             :       if (s == 0)
    1011             :         {
    1012             :           memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
    1013             :           r_ptr[a_len] = 0;
    1014             :         }
    1015             :       else
    1016             :         {
    1017             :           const mp_limb_t *sourceptr = a_ptr;
    1018             :           mp_limb_t *destptr = r_ptr;
    1019             :           mp_twolimb_t accu = 0;
    1020             :           size_t count;
    1021             :           for (count = a_len; count > 0; count--)
    1022             :             {
    1023             :               accu += (mp_twolimb_t) *sourceptr++ << s;
    1024             :               *destptr++ = (mp_limb_t) accu;
    1025             :               accu = accu >> GMP_LIMB_BITS;
    1026             :             }
    1027             :           *destptr++ = (mp_limb_t) accu;
    1028             :         }
    1029             :       q_ptr = roomptr + b_len;
    1030             :       q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
    1031             :       {
    1032             :         size_t j = a_len - b_len; /* m-n */
    1033             :         mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
    1034             :         mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
    1035             :         mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
    1036             :           ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
    1037             :         /* Division loop, traversed m-n+1 times.
    1038             :            j counts down, b is unchanged, beta/2 <= b[n-1] < beta.  */
    1039             :         for (;;)
    1040             :           {
    1041             :             mp_limb_t q_star;
    1042             :             mp_limb_t c1;
    1043             :             if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
    1044             :               {
    1045             :                 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow.  */
    1046             :                 mp_twolimb_t num =
    1047             :                   ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
    1048             :                   | r_ptr[j + b_len - 1];
    1049             :                 q_star = num / b_msd;
    1050             :                 c1 = num % b_msd;
    1051             :               }
    1052             :             else
    1053             :               {
    1054             :                 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1].  */
    1055             :                 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
    1056             :                 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
    1057             :                    <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
    1058             :                    <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
    1059             :                         {<= beta !}.
    1060             :                    If yes, jump directly to the subtraction loop.
    1061             :                    (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
    1062             :                     <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
    1063             :                 if (r_ptr[j + b_len] > b_msd
    1064             :                     || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
    1065             :                   /* r[j+n] >= b[n-1]+1 or
    1066             :                      r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
    1067             :                      carry.  */
    1068             :                   goto subtract;
    1069             :               }
    1070             :             /* q_star = q*,
    1071             :                c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta).  */
    1072             :             {
    1073             :               mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
    1074             :                 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
    1075             :               mp_twolimb_t c3 = /* b[n-2] * q* */
    1076             :                 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
    1077             :               /* While c2 < c3, increase c2 and decrease c3.
    1078             :                  Consider c3-c2.  While it is > 0, decrease it by
    1079             :                  b[n-1]*beta+b[n-2].  Because of b[n-1]*beta+b[n-2] >= beta^2/2
    1080             :                  this can happen only twice.  */
    1081             :               if (c3 > c2)
    1082             :                 {
    1083             :                   q_star = q_star - 1; /* q* := q* - 1 */
    1084             :                   if (c3 - c2 > b_msdd)
    1085             :                     q_star = q_star - 1; /* q* := q* - 1 */
    1086             :                 }
    1087             :             }
    1088             :             if (q_star > 0)
    1089             :               subtract:
    1090             :               {
    1091             :                 /* Subtract r := r - b * q* * beta^j.  */
    1092             :                 mp_limb_t cr;
    1093             :                 {
    1094             :                   const mp_limb_t *sourceptr = b_ptr;
    1095             :                   mp_limb_t *destptr = r_ptr + j;
    1096             :                   mp_twolimb_t carry = 0;
    1097             :                   size_t count;
    1098             :                   for (count = b_len; count > 0; count--)
    1099             :                     {
    1100             :                       /* Here 0 <= carry <= q*.  */
    1101             :                       carry =
    1102             :                         carry
    1103             :                         + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
    1104             :                         + (mp_limb_t) ~(*destptr);
    1105             :                       /* Here 0 <= carry <= beta*q* + beta-1.  */
    1106             :                       *destptr++ = ~(mp_limb_t) carry;
    1107             :                       carry = carry >> GMP_LIMB_BITS; /* <= q* */
    1108             :                     }
    1109             :                   cr = (mp_limb_t) carry;
    1110             :                 }
    1111             :                 /* Subtract cr from r_ptr[j + b_len], then forget about
    1112             :                    r_ptr[j + b_len].  */
    1113             :                 if (cr > r_ptr[j + b_len])
    1114             :                   {
    1115             :                     /* Subtraction gave a carry.  */
    1116             :                     q_star = q_star - 1; /* q* := q* - 1 */
    1117             :                     /* Add b back.  */
    1118             :                     {
    1119             :                       const mp_limb_t *sourceptr = b_ptr;
    1120             :                       mp_limb_t *destptr = r_ptr + j;
    1121             :                       mp_limb_t carry = 0;
    1122             :                       size_t count;
    1123             :                       for (count = b_len; count > 0; count--)
    1124             :                         {
    1125             :                           mp_limb_t source1 = *sourceptr++;
    1126             :                           mp_limb_t source2 = *destptr;
    1127             :                           *destptr++ = source1 + source2 + carry;
    1128             :                           carry =
    1129             :                             (carry
    1130             :                              ? source1 >= (mp_limb_t) ~source2
    1131             :                              : source1 > (mp_limb_t) ~source2);
    1132             :                         }
    1133             :                     }
    1134             :                     /* Forget about the carry and about r[j+n].  */
    1135             :                   }
    1136             :               }
    1137             :             /* q* is determined.  Store it as q[j].  */
    1138             :             q_ptr[j] = q_star;
    1139             :             if (j == 0)
    1140             :               break;
    1141             :             j--;
    1142             :           }
    1143             :       }
    1144             :       r_len = b_len;
    1145             :       /* Normalise q.  */
    1146             :       if (q_ptr[q_len - 1] == 0)
    1147             :         q_len--;
    1148             : # if 0 /* Not needed here, since we need r only to compare it with b/2, and
    1149             :           b is shifted left by s bits.  */
    1150             :       /* Shift r right by s bits.  */
    1151             :       if (s > 0)
    1152             :         {
    1153             :           mp_limb_t ptr = r_ptr + r_len;
    1154             :           mp_twolimb_t accu = 0;
    1155             :           size_t count;
    1156             :           for (count = r_len; count > 0; count--)
    1157             :             {
    1158             :               accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
    1159             :               accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
    1160             :               *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
    1161             :             }
    1162             :         }
    1163             : # endif
    1164             :       /* Normalise r.  */
    1165             :       while (r_len > 0 && r_ptr[r_len - 1] == 0)
    1166             :         r_len--;
    1167             :     }
    1168             :   /* Compare r << 1 with b.  */
    1169             :   if (r_len > b_len)
    1170             :     goto increment_q;
    1171             :   {
    1172             :     size_t i;
    1173             :     for (i = b_len;;)
    1174             :       {
    1175             :         mp_limb_t r_i =
    1176             :           (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
    1177             :           | (i < r_len ? r_ptr[i] << 1 : 0);
    1178             :         mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
    1179             :         if (r_i > b_i)
    1180             :           goto increment_q;
    1181             :         if (r_i < b_i)
    1182             :           goto keep_q;
    1183             :         if (i == 0)
    1184             :           break;
    1185             :         i--;
    1186             :       }
    1187             :   }
    1188             :   if (q_len > 0 && ((q_ptr[0] & 1) != 0))
    1189             :     /* q is odd.  */
    1190             :     increment_q:
    1191             :     {
    1192             :       size_t i;
    1193             :       for (i = 0; i < q_len; i++)
    1194             :         if (++(q_ptr[i]) != 0)
    1195             :           goto keep_q;
    1196             :       q_ptr[q_len++] = 1;
    1197             :     }
    1198             :   keep_q:
    1199             :   free (tmp_roomptr);
    1200             :   q->limbs = q_ptr;
    1201             :   q->nlimbs = q_len;
    1202             :   return roomptr;
    1203             : }
    1204             : 
    1205             : /* Avoid pointless GCC warning "argument 1 value '18446744073709551615' exceeds
    1206             :    maximum object size 9223372036854775807", triggered by the use of xsum as
    1207             :    argument of malloc.  */
    1208             : # if _GL_GNUC_PREREQ (7, 0)
    1209             : #  pragma GCC diagnostic push
    1210             : #  pragma GCC diagnostic ignored "-Walloc-size-larger-than="
    1211             : # endif
    1212             : 
    1213             : /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
    1214             :    representation.
    1215             :    Destroys the contents of a.
    1216             :    Return the allocated memory - containing the decimal digits in low-to-high
    1217             :    order, terminated with a NUL character - in case of success, NULL in case
    1218             :    of memory allocation failure.  */
    1219             : static char *
    1220             : convert_to_decimal (mpn_t a, size_t extra_zeroes)
    1221             : {
    1222             :   mp_limb_t *a_ptr = a.limbs;
    1223             :   size_t a_len = a.nlimbs;
    1224             :   /* 0.03345 is slightly larger than log(2)/(9*log(10)).  */
    1225             :   size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
    1226             :   /* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the
    1227             :      digits of a, followed by 1 byte for the terminating NUL.  */
    1228             :   char *c_ptr = (char *) malloc (xsum (xsum (extra_zeroes, c_len), 1));
    1229             :   if (c_ptr != NULL)
    1230             :     {
    1231             :       char *d_ptr = c_ptr;
    1232             :       for (; extra_zeroes > 0; extra_zeroes--)
    1233             :         *d_ptr++ = '0';
    1234             :       while (a_len > 0)
    1235             :         {
    1236             :           /* Divide a by 10^9, in-place.  */
    1237             :           mp_limb_t remainder = 0;
    1238             :           mp_limb_t *ptr = a_ptr + a_len;
    1239             :           size_t count;
    1240             :           for (count = a_len; count > 0; count--)
    1241             :             {
    1242             :               mp_twolimb_t num =
    1243             :                 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
    1244             :               *ptr = num / 1000000000;
    1245             :               remainder = num % 1000000000;
    1246             :             }
    1247             :           /* Store the remainder as 9 decimal digits.  */
    1248             :           for (count = 9; count > 0; count--)
    1249             :             {
    1250             :               *d_ptr++ = '0' + (remainder % 10);
    1251             :               remainder = remainder / 10;
    1252             :             }
    1253             :           /* Normalize a.  */
    1254             :           if (a_ptr[a_len - 1] == 0)
    1255             :             a_len--;
    1256             :         }
    1257             :       /* Remove leading zeroes.  */
    1258             :       while (d_ptr > c_ptr && d_ptr[-1] == '0')
    1259             :         d_ptr--;
    1260             :       /* But keep at least one zero.  */
    1261             :       if (d_ptr == c_ptr)
    1262             :         *d_ptr++ = '0';
    1263             :       /* Terminate the string.  */
    1264             :       *d_ptr = '\0';
    1265             :     }
    1266             :   return c_ptr;
    1267             : }
    1268             : 
    1269             : # if _GL_GNUC_PREREQ (7, 0)
    1270             : #  pragma GCC diagnostic pop
    1271             : # endif
    1272             : 
    1273             : # if NEED_PRINTF_LONG_DOUBLE
    1274             : 
    1275             : /* Assuming x is finite and >= 0:
    1276             :    write x as x = 2^e * m, where m is a bignum.
    1277             :    Return the allocated memory in case of success, NULL in case of memory
    1278             :    allocation failure.  */
    1279             : static void *
    1280             : decode_long_double (long double x, int *ep, mpn_t *mp)
    1281             : {
    1282             :   mpn_t m;
    1283             :   int exp;
    1284             :   long double y;
    1285             :   size_t i;
    1286             : 
    1287             :   /* Allocate memory for result.  */
    1288             :   m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
    1289             :   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
    1290             :   if (m.limbs == NULL)
    1291             :     return NULL;
    1292             :   /* Split into exponential part and mantissa.  */
    1293             :   y = safe_frexpl (x, &exp);
    1294             :   if (!(y >= 0.0L && y < 1.0L))
    1295             :     abort ();
    1296             :   /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
    1297             :      latter is an integer.  */
    1298             :   /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
    1299             :      I'm not sure whether it's safe to cast a 'long double' value between
    1300             :      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
    1301             :      'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
    1302             :      doesn't matter).  */
    1303             : #  if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
    1304             : #   if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
    1305             :     {
    1306             :       mp_limb_t hi, lo;
    1307             :       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
    1308             :       hi = (int) y;
    1309             :       y -= hi;
    1310             :       if (!(y >= 0.0L && y < 1.0L))
    1311             :         abort ();
    1312             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
    1313             :       lo = (int) y;
    1314             :       y -= lo;
    1315             :       if (!(y >= 0.0L && y < 1.0L))
    1316             :         abort ();
    1317             :       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
    1318             :     }
    1319             : #   else
    1320             :     {
    1321             :       mp_limb_t d;
    1322             :       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
    1323             :       d = (int) y;
    1324             :       y -= d;
    1325             :       if (!(y >= 0.0L && y < 1.0L))
    1326             :         abort ();
    1327             :       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
    1328             :     }
    1329             : #   endif
    1330             : #  endif
    1331             :   for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
    1332             :     {
    1333             :       mp_limb_t hi, lo;
    1334             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
    1335             :       hi = (int) y;
    1336             :       y -= hi;
    1337             :       if (!(y >= 0.0L && y < 1.0L))
    1338             :         abort ();
    1339             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
    1340             :       lo = (int) y;
    1341             :       y -= lo;
    1342             :       if (!(y >= 0.0L && y < 1.0L))
    1343             :         abort ();
    1344             :       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
    1345             :     }
    1346             : #  if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
    1347             :            precision.  */
    1348             :   if (!(y == 0.0L))
    1349             :     abort ();
    1350             : #  endif
    1351             :   /* Normalise.  */
    1352             :   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
    1353             :     m.nlimbs--;
    1354             :   *mp = m;
    1355             :   *ep = exp - LDBL_MANT_BIT;
    1356             :   return m.limbs;
    1357             : }
    1358             : 
    1359             : # endif
    1360             : 
    1361             : # if NEED_PRINTF_DOUBLE
    1362             : 
    1363             : /* Assuming x is finite and >= 0:
    1364             :    write x as x = 2^e * m, where m is a bignum.
    1365             :    Return the allocated memory in case of success, NULL in case of memory
    1366             :    allocation failure.  */
    1367             : static void *
    1368             : decode_double (double x, int *ep, mpn_t *mp)
    1369             : {
    1370             :   mpn_t m;
    1371             :   int exp;
    1372             :   double y;
    1373             :   size_t i;
    1374             : 
    1375             :   /* Allocate memory for result.  */
    1376             :   m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
    1377             :   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
    1378             :   if (m.limbs == NULL)
    1379             :     return NULL;
    1380             :   /* Split into exponential part and mantissa.  */
    1381             :   y = frexp (x, &exp);
    1382             :   if (!(y >= 0.0 && y < 1.0))
    1383             :     abort ();
    1384             :   /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
    1385             :      latter is an integer.  */
    1386             :   /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
    1387             :      I'm not sure whether it's safe to cast a 'double' value between
    1388             :      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
    1389             :      'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
    1390             :      doesn't matter).  */
    1391             : #  if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
    1392             : #   if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
    1393             :     {
    1394             :       mp_limb_t hi, lo;
    1395             :       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
    1396             :       hi = (int) y;
    1397             :       y -= hi;
    1398             :       if (!(y >= 0.0 && y < 1.0))
    1399             :         abort ();
    1400             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
    1401             :       lo = (int) y;
    1402             :       y -= lo;
    1403             :       if (!(y >= 0.0 && y < 1.0))
    1404             :         abort ();
    1405             :       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
    1406             :     }
    1407             : #   else
    1408             :     {
    1409             :       mp_limb_t d;
    1410             :       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
    1411             :       d = (int) y;
    1412             :       y -= d;
    1413             :       if (!(y >= 0.0 && y < 1.0))
    1414             :         abort ();
    1415             :       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
    1416             :     }
    1417             : #   endif
    1418             : #  endif
    1419             :   for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
    1420             :     {
    1421             :       mp_limb_t hi, lo;
    1422             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
    1423             :       hi = (int) y;
    1424             :       y -= hi;
    1425             :       if (!(y >= 0.0 && y < 1.0))
    1426             :         abort ();
    1427             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
    1428             :       lo = (int) y;
    1429             :       y -= lo;
    1430             :       if (!(y >= 0.0 && y < 1.0))
    1431             :         abort ();
    1432             :       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
    1433             :     }
    1434             :   if (!(y == 0.0))
    1435             :     abort ();
    1436             :   /* Normalise.  */
    1437             :   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
    1438             :     m.nlimbs--;
    1439             :   *mp = m;
    1440             :   *ep = exp - DBL_MANT_BIT;
    1441             :   return m.limbs;
    1442             : }
    1443             : 
    1444             : # endif
    1445             : 
    1446             : /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
    1447             :    Returns the decimal representation of round (x * 10^n).
    1448             :    Return the allocated memory - containing the decimal digits in low-to-high
    1449             :    order, terminated with a NUL character - in case of success, NULL in case
    1450             :    of memory allocation failure.  */
    1451             : static char *
    1452             : scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
    1453             : {
    1454             :   int s;
    1455             :   size_t extra_zeroes;
    1456             :   unsigned int abs_n;
    1457             :   unsigned int abs_s;
    1458             :   mp_limb_t *pow5_ptr;
    1459             :   size_t pow5_len;
    1460             :   unsigned int s_limbs;
    1461             :   unsigned int s_bits;
    1462             :   mpn_t pow5;
    1463             :   mpn_t z;
    1464             :   void *z_memory;
    1465             :   char *digits;
    1466             : 
    1467             :   /* x = 2^e * m, hence
    1468             :      y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
    1469             :        = round (2^s * 5^n * m).  */
    1470             :   s = e + n;
    1471             :   extra_zeroes = 0;
    1472             :   /* Factor out a common power of 10 if possible.  */
    1473             :   if (s > 0 && n > 0)
    1474             :     {
    1475             :       extra_zeroes = (s < n ? s : n);
    1476             :       s -= extra_zeroes;
    1477             :       n -= extra_zeroes;
    1478             :     }
    1479             :   /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
    1480             :      Before converting to decimal, we need to compute
    1481             :      z = round (2^s * 5^n * m).  */
    1482             :   /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
    1483             :      sign.  2.322 is slightly larger than log(5)/log(2).  */
    1484             :   abs_n = (n >= 0 ? n : -n);
    1485             :   abs_s = (s >= 0 ? s : -s);
    1486             :   pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
    1487             :                                     + abs_s / GMP_LIMB_BITS + 1)
    1488             :                                    * sizeof (mp_limb_t));
    1489             :   if (pow5_ptr == NULL)
    1490             :     {
    1491             :       free (memory);
    1492             :       return NULL;
    1493             :     }
    1494             :   /* Initialize with 1.  */
    1495             :   pow5_ptr[0] = 1;
    1496             :   pow5_len = 1;
    1497             :   /* Multiply with 5^|n|.  */
    1498             :   if (abs_n > 0)
    1499             :     {
    1500             :       static mp_limb_t const small_pow5[13 + 1] =
    1501             :         {
    1502             :           1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
    1503             :           48828125, 244140625, 1220703125
    1504             :         };
    1505             :       unsigned int n13;
    1506             :       for (n13 = 0; n13 <= abs_n; n13 += 13)
    1507             :         {
    1508             :           mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
    1509             :           size_t j;
    1510             :           mp_twolimb_t carry = 0;
    1511             :           for (j = 0; j < pow5_len; j++)
    1512             :             {
    1513             :               mp_limb_t digit2 = pow5_ptr[j];
    1514             :               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
    1515             :               pow5_ptr[j] = (mp_limb_t) carry;
    1516             :               carry = carry >> GMP_LIMB_BITS;
    1517             :             }
    1518             :           if (carry > 0)
    1519             :             pow5_ptr[pow5_len++] = (mp_limb_t) carry;
    1520             :         }
    1521             :     }
    1522             :   s_limbs = abs_s / GMP_LIMB_BITS;
    1523             :   s_bits = abs_s % GMP_LIMB_BITS;
    1524             :   if (n >= 0 ? s >= 0 : s <= 0)
    1525             :     {
    1526             :       /* Multiply with 2^|s|.  */
    1527             :       if (s_bits > 0)
    1528             :         {
    1529             :           mp_limb_t *ptr = pow5_ptr;
    1530             :           mp_twolimb_t accu = 0;
    1531             :           size_t count;
    1532             :           for (count = pow5_len; count > 0; count--)
    1533             :             {
    1534             :               accu += (mp_twolimb_t) *ptr << s_bits;
    1535             :               *ptr++ = (mp_limb_t) accu;
    1536             :               accu = accu >> GMP_LIMB_BITS;
    1537             :             }
    1538             :           if (accu > 0)
    1539             :             {
    1540             :               *ptr = (mp_limb_t) accu;
    1541             :               pow5_len++;
    1542             :             }
    1543             :         }
    1544             :       if (s_limbs > 0)
    1545             :         {
    1546             :           size_t count;
    1547             :           for (count = pow5_len; count > 0;)
    1548             :             {
    1549             :               count--;
    1550             :               pow5_ptr[s_limbs + count] = pow5_ptr[count];
    1551             :             }
    1552             :           for (count = s_limbs; count > 0;)
    1553             :             {
    1554             :               count--;
    1555             :               pow5_ptr[count] = 0;
    1556             :             }
    1557             :           pow5_len += s_limbs;
    1558             :         }
    1559             :       pow5.limbs = pow5_ptr;
    1560             :       pow5.nlimbs = pow5_len;
    1561             :       if (n >= 0)
    1562             :         {
    1563             :           /* Multiply m with pow5.  No division needed.  */
    1564             :           z_memory = multiply (m, pow5, &z);
    1565             :         }
    1566             :       else
    1567             :         {
    1568             :           /* Divide m by pow5 and round.  */
    1569             :           z_memory = divide (m, pow5, &z);
    1570             :         }
    1571             :     }
    1572             :   else
    1573             :     {
    1574             :       pow5.limbs = pow5_ptr;
    1575             :       pow5.nlimbs = pow5_len;
    1576             :       if (n >= 0)
    1577             :         {
    1578             :           /* n >= 0, s < 0.
    1579             :              Multiply m with pow5, then divide by 2^|s|.  */
    1580             :           mpn_t numerator;
    1581             :           mpn_t denominator;
    1582             :           void *tmp_memory;
    1583             :           tmp_memory = multiply (m, pow5, &numerator);
    1584             :           if (tmp_memory == NOMEM_PTR)
    1585             :             {
    1586             :               free (pow5_ptr);
    1587             :               free (memory);
    1588             :               return NULL;
    1589             :             }
    1590             :           /* Construct 2^|s|.  */
    1591             :           {
    1592             :             mp_limb_t *ptr = pow5_ptr + pow5_len;
    1593             :             size_t i;
    1594             :             for (i = 0; i < s_limbs; i++)
    1595             :               ptr[i] = 0;
    1596             :             ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
    1597             :             denominator.limbs = ptr;
    1598             :             denominator.nlimbs = s_limbs + 1;
    1599             :           }
    1600             :           z_memory = divide (numerator, denominator, &z);
    1601             :           free (tmp_memory);
    1602             :         }
    1603             :       else
    1604             :         {
    1605             :           /* n < 0, s > 0.
    1606             :              Multiply m with 2^s, then divide by pow5.  */
    1607             :           mpn_t numerator;
    1608             :           mp_limb_t *num_ptr;
    1609             :           num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
    1610             :                                           * sizeof (mp_limb_t));
    1611             :           if (num_ptr == NULL)
    1612             :             {
    1613             :               free (pow5_ptr);
    1614             :               free (memory);
    1615             :               return NULL;
    1616             :             }
    1617             :           {
    1618             :             mp_limb_t *destptr = num_ptr;
    1619             :             {
    1620             :               size_t i;
    1621             :               for (i = 0; i < s_limbs; i++)
    1622             :                 *destptr++ = 0;
    1623             :             }
    1624             :             if (s_bits > 0)
    1625             :               {
    1626             :                 const mp_limb_t *sourceptr = m.limbs;
    1627             :                 mp_twolimb_t accu = 0;
    1628             :                 size_t count;
    1629             :                 for (count = m.nlimbs; count > 0; count--)
    1630             :                   {
    1631             :                     accu += (mp_twolimb_t) *sourceptr++ << s_bits;
    1632             :                     *destptr++ = (mp_limb_t) accu;
    1633             :                     accu = accu >> GMP_LIMB_BITS;
    1634             :                   }
    1635             :                 if (accu > 0)
    1636             :                   *destptr++ = (mp_limb_t) accu;
    1637             :               }
    1638             :             else
    1639             :               {
    1640             :                 const mp_limb_t *sourceptr = m.limbs;
    1641             :                 size_t count;
    1642             :                 for (count = m.nlimbs; count > 0; count--)
    1643             :                   *destptr++ = *sourceptr++;
    1644             :               }
    1645             :             numerator.limbs = num_ptr;
    1646             :             numerator.nlimbs = destptr - num_ptr;
    1647             :           }
    1648             :           z_memory = divide (numerator, pow5, &z);
    1649             :           free (num_ptr);
    1650             :         }
    1651             :     }
    1652             :   free (pow5_ptr);
    1653             :   free (memory);
    1654             : 
    1655             :   /* Here y = round (x * 10^n) = z * 10^extra_zeroes.  */
    1656             : 
    1657             :   if (z_memory == NOMEM_PTR)
    1658             :     return NULL;
    1659             :   digits = convert_to_decimal (z, extra_zeroes);
    1660             :   free (z_memory);
    1661             :   return digits;
    1662             : }
    1663             : 
    1664             : # if NEED_PRINTF_LONG_DOUBLE
    1665             : 
    1666             : /* Assuming x is finite and >= 0, and n is an integer:
    1667             :    Returns the decimal representation of round (x * 10^n).
    1668             :    Return the allocated memory - containing the decimal digits in low-to-high
    1669             :    order, terminated with a NUL character - in case of success, NULL in case
    1670             :    of memory allocation failure.  */
    1671             : static char *
    1672             : scale10_round_decimal_long_double (long double x, int n)
    1673             : {
    1674             :   int e;
    1675             :   mpn_t m;
    1676             :   void *memory = decode_long_double (x, &e, &m);
    1677             :   if (memory != NULL)
    1678             :     return scale10_round_decimal_decoded (e, m, memory, n);
    1679             :   else
    1680             :     return NULL;
    1681             : }
    1682             : 
    1683             : # endif
    1684             : 
    1685             : # if NEED_PRINTF_DOUBLE
    1686             : 
    1687             : /* Assuming x is finite and >= 0, and n is an integer:
    1688             :    Returns the decimal representation of round (x * 10^n).
    1689             :    Return the allocated memory - containing the decimal digits in low-to-high
    1690             :    order, terminated with a NUL character - in case of success, NULL in case
    1691             :    of memory allocation failure.  */
    1692             : static char *
    1693             : scale10_round_decimal_double (double x, int n)
    1694             : {
    1695             :   int e;
    1696             :   mpn_t m;
    1697             :   void *memory = decode_double (x, &e, &m);
    1698             :   if (memory != NULL)
    1699             :     return scale10_round_decimal_decoded (e, m, memory, n);
    1700             :   else
    1701             :     return NULL;
    1702             : }
    1703             : 
    1704             : # endif
    1705             : 
    1706             : # if NEED_PRINTF_LONG_DOUBLE
    1707             : 
    1708             : /* Assuming x is finite and > 0:
    1709             :    Return an approximation for n with 10^n <= x < 10^(n+1).
    1710             :    The approximation is usually the right n, but may be off by 1 sometimes.  */
    1711             : static int
    1712             : floorlog10l (long double x)
    1713             : {
    1714             :   int exp;
    1715             :   long double y;
    1716             :   double z;
    1717             :   double l;
    1718             : 
    1719             :   /* Split into exponential part and mantissa.  */
    1720             :   y = safe_frexpl (x, &exp);
    1721             :   if (!(y >= 0.0L && y < 1.0L))
    1722             :     abort ();
    1723             :   if (y == 0.0L)
    1724             :     return INT_MIN;
    1725             :   if (y < 0.5L)
    1726             :     {
    1727             :       while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
    1728             :         {
    1729             :           y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
    1730             :           exp -= GMP_LIMB_BITS;
    1731             :         }
    1732             :       if (y < (1.0L / (1 << 16)))
    1733             :         {
    1734             :           y *= 1.0L * (1 << 16);
    1735             :           exp -= 16;
    1736             :         }
    1737             :       if (y < (1.0L / (1 << 8)))
    1738             :         {
    1739             :           y *= 1.0L * (1 << 8);
    1740             :           exp -= 8;
    1741             :         }
    1742             :       if (y < (1.0L / (1 << 4)))
    1743             :         {
    1744             :           y *= 1.0L * (1 << 4);
    1745             :           exp -= 4;
    1746             :         }
    1747             :       if (y < (1.0L / (1 << 2)))
    1748             :         {
    1749             :           y *= 1.0L * (1 << 2);
    1750             :           exp -= 2;
    1751             :         }
    1752             :       if (y < (1.0L / (1 << 1)))
    1753             :         {
    1754             :           y *= 1.0L * (1 << 1);
    1755             :           exp -= 1;
    1756             :         }
    1757             :     }
    1758             :   if (!(y >= 0.5L && y < 1.0L))
    1759             :     abort ();
    1760             :   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
    1761             :   l = exp;
    1762             :   z = y;
    1763             :   if (z < 0.70710678118654752444)
    1764             :     {
    1765             :       z *= 1.4142135623730950488;
    1766             :       l -= 0.5;
    1767             :     }
    1768             :   if (z < 0.8408964152537145431)
    1769             :     {
    1770             :       z *= 1.1892071150027210667;
    1771             :       l -= 0.25;
    1772             :     }
    1773             :   if (z < 0.91700404320467123175)
    1774             :     {
    1775             :       z *= 1.0905077326652576592;
    1776             :       l -= 0.125;
    1777             :     }
    1778             :   if (z < 0.9576032806985736469)
    1779             :     {
    1780             :       z *= 1.0442737824274138403;
    1781             :       l -= 0.0625;
    1782             :     }
    1783             :   /* Now 0.95 <= z <= 1.01.  */
    1784             :   z = 1 - z;
    1785             :   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
    1786             :      Four terms are enough to get an approximation with error < 10^-7.  */
    1787             :   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
    1788             :   /* Finally multiply with log(2)/log(10), yields an approximation for
    1789             :      log10(x).  */
    1790             :   l *= 0.30102999566398119523;
    1791             :   /* Round down to the next integer.  */
    1792             :   return (int) l + (l < 0 ? -1 : 0);
    1793             : }
    1794             : 
    1795             : # endif
    1796             : 
    1797             : # if NEED_PRINTF_DOUBLE
    1798             : 
    1799             : /* Assuming x is finite and > 0:
    1800             :    Return an approximation for n with 10^n <= x < 10^(n+1).
    1801             :    The approximation is usually the right n, but may be off by 1 sometimes.  */
    1802             : static int
    1803             : floorlog10 (double x)
    1804             : {
    1805             :   int exp;
    1806             :   double y;
    1807             :   double z;
    1808             :   double l;
    1809             : 
    1810             :   /* Split into exponential part and mantissa.  */
    1811             :   y = frexp (x, &exp);
    1812             :   if (!(y >= 0.0 && y < 1.0))
    1813             :     abort ();
    1814             :   if (y == 0.0)
    1815             :     return INT_MIN;
    1816             :   if (y < 0.5)
    1817             :     {
    1818             :       while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
    1819             :         {
    1820             :           y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
    1821             :           exp -= GMP_LIMB_BITS;
    1822             :         }
    1823             :       if (y < (1.0 / (1 << 16)))
    1824             :         {
    1825             :           y *= 1.0 * (1 << 16);
    1826             :           exp -= 16;
    1827             :         }
    1828             :       if (y < (1.0 / (1 << 8)))
    1829             :         {
    1830             :           y *= 1.0 * (1 << 8);
    1831             :           exp -= 8;
    1832             :         }
    1833             :       if (y < (1.0 / (1 << 4)))
    1834             :         {
    1835             :           y *= 1.0 * (1 << 4);
    1836             :           exp -= 4;
    1837             :         }
    1838             :       if (y < (1.0 / (1 << 2)))
    1839             :         {
    1840             :           y *= 1.0 * (1 << 2);
    1841             :           exp -= 2;
    1842             :         }
    1843             :       if (y < (1.0 / (1 << 1)))
    1844             :         {
    1845             :           y *= 1.0 * (1 << 1);
    1846             :           exp -= 1;
    1847             :         }
    1848             :     }
    1849             :   if (!(y >= 0.5 && y < 1.0))
    1850             :     abort ();
    1851             :   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
    1852             :   l = exp;
    1853             :   z = y;
    1854             :   if (z < 0.70710678118654752444)
    1855             :     {
    1856             :       z *= 1.4142135623730950488;
    1857             :       l -= 0.5;
    1858             :     }
    1859             :   if (z < 0.8408964152537145431)
    1860             :     {
    1861             :       z *= 1.1892071150027210667;
    1862             :       l -= 0.25;
    1863             :     }
    1864             :   if (z < 0.91700404320467123175)
    1865             :     {
    1866             :       z *= 1.0905077326652576592;
    1867             :       l -= 0.125;
    1868             :     }
    1869             :   if (z < 0.9576032806985736469)
    1870             :     {
    1871             :       z *= 1.0442737824274138403;
    1872             :       l -= 0.0625;
    1873             :     }
    1874             :   /* Now 0.95 <= z <= 1.01.  */
    1875             :   z = 1 - z;
    1876             :   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
    1877             :      Four terms are enough to get an approximation with error < 10^-7.  */
    1878             :   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
    1879             :   /* Finally multiply with log(2)/log(10), yields an approximation for
    1880             :      log10(x).  */
    1881             :   l *= 0.30102999566398119523;
    1882             :   /* Round down to the next integer.  */
    1883             :   return (int) l + (l < 0 ? -1 : 0);
    1884             : }
    1885             : 
    1886             : # endif
    1887             : 
    1888             : /* Tests whether a string of digits consists of exactly PRECISION zeroes and
    1889             :    a single '1' digit.  */
    1890             : static int
    1891             : is_borderline (const char *digits, size_t precision)
    1892             : {
    1893             :   for (; precision > 0; precision--, digits++)
    1894             :     if (*digits != '0')
    1895             :       return 0;
    1896             :   if (*digits != '1')
    1897             :     return 0;
    1898             :   digits++;
    1899             :   return *digits == '\0';
    1900             : }
    1901             : 
    1902             : #endif
    1903             : 
    1904             : #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
    1905             : 
    1906             : /* Use a different function name, to make it possible that the 'wchar_t'
    1907             :    parametrization and the 'char' parametrization get compiled in the same
    1908             :    translation unit.  */
    1909             : # if WIDE_CHAR_VERSION
    1910             : #  define MAX_ROOM_NEEDED wmax_room_needed
    1911             : # else
    1912             : #  define MAX_ROOM_NEEDED max_room_needed
    1913             : # endif
    1914             : 
    1915             : /* Returns the number of TCHAR_T units needed as temporary space for the result
    1916             :    of sprintf or SNPRINTF of a single conversion directive.  */
    1917             : static size_t
    1918             : MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
    1919             :                  arg_type type, int flags, size_t width, int has_precision,
    1920             :                  size_t precision, int pad_ourselves)
    1921             : {
    1922             :   size_t tmp_length;
    1923             : 
    1924             :   switch (conversion)
    1925             :     {
    1926             :     case 'd': case 'i': case 'u':
    1927             :       switch (type)
    1928             :         {
    1929             :         default:
    1930             :           tmp_length =
    1931             :             (unsigned int) (sizeof (unsigned int) * CHAR_BIT
    1932             :                             * 0.30103 /* binary -> decimal */
    1933             :                            )
    1934             :             + 1; /* turn floor into ceil */
    1935             :           break;
    1936             :         case TYPE_LONGINT:
    1937             :           tmp_length =
    1938             :             (unsigned int) (sizeof (long int) * CHAR_BIT
    1939             :                             * 0.30103 /* binary -> decimal */
    1940             :                            )
    1941             :             + 1; /* turn floor into ceil */
    1942             :           break;
    1943             :         case TYPE_ULONGINT:
    1944             :           tmp_length =
    1945             :             (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
    1946             :                             * 0.30103 /* binary -> decimal */
    1947             :                            )
    1948             :             + 1; /* turn floor into ceil */
    1949             :           break;
    1950             :         case TYPE_LONGLONGINT:
    1951             :           tmp_length =
    1952             :             (unsigned int) (sizeof (long long int) * CHAR_BIT
    1953             :                             * 0.30103 /* binary -> decimal */
    1954             :                            )
    1955             :             + 1; /* turn floor into ceil */
    1956             :           break;
    1957             :         case TYPE_ULONGLONGINT:
    1958             :           tmp_length =
    1959             :             (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
    1960             :                             * 0.30103 /* binary -> decimal */
    1961             :                            )
    1962             :             + 1; /* turn floor into ceil */
    1963             :           break;
    1964             :         case TYPE_INT8_T:
    1965             :           tmp_length =
    1966             :             (unsigned int) (sizeof (int8_t) * CHAR_BIT
    1967             :                             * 0.30103 /* binary -> decimal */
    1968             :                            )
    1969             :             + 1; /* turn floor into ceil */
    1970             :           break;
    1971             :         case TYPE_UINT8_T:
    1972             :           tmp_length =
    1973             :             (unsigned int) (sizeof (uint8_t) * CHAR_BIT
    1974             :                             * 0.30103 /* binary -> decimal */
    1975             :                            )
    1976             :             + 1; /* turn floor into ceil */
    1977             :           break;
    1978             :         case TYPE_INT16_T:
    1979             :           tmp_length =
    1980             :             (unsigned int) (sizeof (int16_t) * CHAR_BIT
    1981             :                             * 0.30103 /* binary -> decimal */
    1982             :                            )
    1983             :             + 1; /* turn floor into ceil */
    1984             :           break;
    1985             :         case TYPE_UINT16_T:
    1986             :           tmp_length =
    1987             :             (unsigned int) (sizeof (uint16_t) * CHAR_BIT
    1988             :                             * 0.30103 /* binary -> decimal */
    1989             :                            )
    1990             :             + 1; /* turn floor into ceil */
    1991             :           break;
    1992             :         case TYPE_INT32_T:
    1993             :           tmp_length =
    1994             :             (unsigned int) (sizeof (int32_t) * CHAR_BIT
    1995             :                             * 0.30103 /* binary -> decimal */
    1996             :                            )
    1997             :             + 1; /* turn floor into ceil */
    1998             :           break;
    1999             :         case TYPE_UINT32_T:
    2000             :           tmp_length =
    2001             :             (unsigned int) (sizeof (uint32_t) * CHAR_BIT
    2002             :                             * 0.30103 /* binary -> decimal */
    2003             :                            )
    2004             :             + 1; /* turn floor into ceil */
    2005             :           break;
    2006             :         case TYPE_INT64_T:
    2007             :           tmp_length =
    2008             :             (unsigned int) (sizeof (int64_t) * CHAR_BIT
    2009             :                             * 0.30103 /* binary -> decimal */
    2010             :                            )
    2011             :             + 1; /* turn floor into ceil */
    2012             :           break;
    2013             :         case TYPE_UINT64_T:
    2014             :           tmp_length =
    2015             :             (unsigned int) (sizeof (uint64_t) * CHAR_BIT
    2016             :                             * 0.30103 /* binary -> decimal */
    2017             :                            )
    2018             :             + 1; /* turn floor into ceil */
    2019             :           break;
    2020             :         case TYPE_INT_FAST8_T:
    2021             :           tmp_length =
    2022             :             (unsigned int) (sizeof (int_fast8_t) * CHAR_BIT
    2023             :                             * 0.30103 /* binary -> decimal */
    2024             :                            )
    2025             :             + 1; /* turn floor into ceil */
    2026             :           break;
    2027             :         case TYPE_UINT_FAST8_T:
    2028             :           tmp_length =
    2029             :             (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
    2030             :                             * 0.30103 /* binary -> decimal */
    2031             :                            )
    2032             :             + 1; /* turn floor into ceil */
    2033             :           break;
    2034             :         case TYPE_INT_FAST16_T:
    2035             :           tmp_length =
    2036             :             (unsigned int) (sizeof (int_fast16_t) * CHAR_BIT
    2037             :                             * 0.30103 /* binary -> decimal */
    2038             :                            )
    2039             :             + 1; /* turn floor into ceil */
    2040             :           break;
    2041             :         case TYPE_UINT_FAST16_T:
    2042             :           tmp_length =
    2043             :             (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
    2044             :                             * 0.30103 /* binary -> decimal */
    2045             :                            )
    2046             :             + 1; /* turn floor into ceil */
    2047             :           break;
    2048             :         case TYPE_INT_FAST32_T:
    2049             :           tmp_length =
    2050             :             (unsigned int) (sizeof (int_fast32_t) * CHAR_BIT
    2051             :                             * 0.30103 /* binary -> decimal */
    2052             :                            )
    2053             :             + 1; /* turn floor into ceil */
    2054             :           break;
    2055             :         case TYPE_UINT_FAST32_T:
    2056             :           tmp_length =
    2057             :             (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
    2058             :                             * 0.30103 /* binary -> decimal */
    2059             :                            )
    2060             :             + 1; /* turn floor into ceil */
    2061             :           break;
    2062             :         case TYPE_INT_FAST64_T:
    2063             :           tmp_length =
    2064             :             (unsigned int) (sizeof (int_fast64_t) * CHAR_BIT
    2065             :                             * 0.30103 /* binary -> decimal */
    2066             :                            )
    2067             :             + 1; /* turn floor into ceil */
    2068             :           break;
    2069             :         case TYPE_UINT_FAST64_T:
    2070             :           tmp_length =
    2071             :             (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
    2072             :                             * 0.30103 /* binary -> decimal */
    2073             :                            )
    2074             :             + 1; /* turn floor into ceil */
    2075             :           break;
    2076             :         }
    2077             :       if (tmp_length < precision)
    2078             :         tmp_length = precision;
    2079             :       /* Account for thousands separators.  */
    2080             :       if (flags & FLAG_GROUP)
    2081             :         {
    2082             :           /* A thousands separator needs to be inserted at most every 2 digits.
    2083             :              This is the case in the ta_IN locale.  */
    2084             : # if WIDE_CHAR_VERSION
    2085             :           tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_WCHAR_MAXLEN);
    2086             : # else
    2087             :           tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_CHAR_MAXLEN);
    2088             : # endif
    2089             :         }
    2090             :       /* Add 1, to account for a leading sign.  */
    2091             :       tmp_length = xsum (tmp_length, 1);
    2092             :       break;
    2093             : 
    2094             :     case 'b':
    2095             :     #if SUPPORT_GNU_PRINTF_DIRECTIVES \
    2096             :         || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
    2097             :     case 'B':
    2098             :     #endif
    2099             :       switch (type)
    2100             :         {
    2101             :         default:
    2102             :           tmp_length =
    2103             :             (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
    2104             :             + 1; /* turn floor into ceil */
    2105             :           break;
    2106             :         case TYPE_ULONGINT:
    2107             :           tmp_length =
    2108             :             (unsigned int) (sizeof (unsigned long int) * CHAR_BIT)
    2109             :             + 1; /* turn floor into ceil */
    2110             :           break;
    2111             :         case TYPE_ULONGLONGINT:
    2112             :           tmp_length =
    2113             :             (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT)
    2114             :             + 1; /* turn floor into ceil */
    2115             :           break;
    2116             :         case TYPE_UINT8_T:
    2117             :           tmp_length =
    2118             :             (unsigned int) (sizeof (uint8_t) * CHAR_BIT)
    2119             :             + 1; /* turn floor into ceil */
    2120             :           break;
    2121             :         case TYPE_UINT16_T:
    2122             :           tmp_length =
    2123             :             (unsigned int) (sizeof (uint16_t) * CHAR_BIT)
    2124             :             + 1; /* turn floor into ceil */
    2125             :           break;
    2126             :         case TYPE_UINT32_T:
    2127             :           tmp_length =
    2128             :             (unsigned int) (sizeof (uint32_t) * CHAR_BIT)
    2129             :             + 1; /* turn floor into ceil */
    2130             :           break;
    2131             :         case TYPE_UINT64_T:
    2132             :           tmp_length =
    2133             :             (unsigned int) (sizeof (uint64_t) * CHAR_BIT)
    2134             :             + 1; /* turn floor into ceil */
    2135             :           break;
    2136             :         case TYPE_UINT_FAST8_T:
    2137             :           tmp_length =
    2138             :             (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT)
    2139             :             + 1; /* turn floor into ceil */
    2140             :           break;
    2141             :         case TYPE_UINT_FAST16_T:
    2142             :           tmp_length =
    2143             :             (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT)
    2144             :             + 1; /* turn floor into ceil */
    2145             :           break;
    2146             :         case TYPE_UINT_FAST32_T:
    2147             :           tmp_length =
    2148             :             (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT)
    2149             :             + 1; /* turn floor into ceil */
    2150             :           break;
    2151             :         case TYPE_UINT_FAST64_T:
    2152             :           tmp_length =
    2153             :             (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT)
    2154             :             + 1; /* turn floor into ceil */
    2155             :           break;
    2156             :         }
    2157             :       if (tmp_length < precision)
    2158             :         tmp_length = precision;
    2159             :       /* Add 2, to account for a prefix from the alternate form.  */
    2160             :       tmp_length = xsum (tmp_length, 2);
    2161             :       break;
    2162             : 
    2163             :     case 'o':
    2164             :       switch (type)
    2165             :         {
    2166             :         default:
    2167             :           tmp_length =
    2168             :             (unsigned int) (sizeof (unsigned int) * CHAR_BIT
    2169             :                             * 0.333334 /* binary -> octal */
    2170             :                            )
    2171             :             + 1; /* turn floor into ceil */
    2172             :           break;
    2173             :         case TYPE_ULONGINT:
    2174             :           tmp_length =
    2175             :             (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
    2176             :                             * 0.333334 /* binary -> octal */
    2177             :                            )
    2178             :             + 1; /* turn floor into ceil */
    2179             :           break;
    2180             :         case TYPE_ULONGLONGINT:
    2181             :           tmp_length =
    2182             :             (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
    2183             :                             * 0.333334 /* binary -> octal */
    2184             :                            )
    2185             :             + 1; /* turn floor into ceil */
    2186             :           break;
    2187             :         case TYPE_UINT8_T:
    2188             :           tmp_length =
    2189             :             (unsigned int) (sizeof (uint8_t) * CHAR_BIT
    2190             :                             * 0.333334 /* binary -> octal */
    2191             :                            )
    2192             :             + 1; /* turn floor into ceil */
    2193             :           break;
    2194             :         case TYPE_UINT16_T:
    2195             :           tmp_length =
    2196             :             (unsigned int) (sizeof (uint16_t) * CHAR_BIT
    2197             :                             * 0.333334 /* binary -> octal */
    2198             :                            )
    2199             :             + 1; /* turn floor into ceil */
    2200             :           break;
    2201             :         case TYPE_UINT32_T:
    2202             :           tmp_length =
    2203             :             (unsigned int) (sizeof (uint32_t) * CHAR_BIT
    2204             :                             * 0.333334 /* binary -> octal */
    2205             :                            )
    2206             :             + 1; /* turn floor into ceil */
    2207             :           break;
    2208             :         case TYPE_UINT64_T:
    2209             :           tmp_length =
    2210             :             (unsigned int) (sizeof (uint64_t) * CHAR_BIT
    2211             :                             * 0.333334 /* binary -> octal */
    2212             :                            )
    2213             :             + 1; /* turn floor into ceil */
    2214             :           break;
    2215             :         case TYPE_UINT_FAST8_T:
    2216             :           tmp_length =
    2217             :             (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
    2218             :                             * 0.333334 /* binary -> octal */
    2219             :                            )
    2220             :             + 1; /* turn floor into ceil */
    2221             :           break;
    2222             :         case TYPE_UINT_FAST16_T:
    2223             :           tmp_length =
    2224             :             (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
    2225             :                             * 0.333334 /* binary -> octal */
    2226             :                            )
    2227             :             + 1; /* turn floor into ceil */
    2228             :           break;
    2229             :         case TYPE_UINT_FAST32_T:
    2230             :           tmp_length =
    2231             :             (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
    2232             :                             * 0.333334 /* binary -> octal */
    2233             :                            )
    2234             :             + 1; /* turn floor into ceil */
    2235             :           break;
    2236             :         case TYPE_UINT_FAST64_T:
    2237             :           tmp_length =
    2238             :             (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
    2239             :                             * 0.333334 /* binary -> octal */
    2240             :                            )
    2241             :             + 1; /* turn floor into ceil */
    2242             :           break;
    2243             :         }
    2244             :       if (tmp_length < precision)
    2245             :         tmp_length = precision;
    2246             :       /* Add 1, to account for a leading sign.  */
    2247             :       tmp_length = xsum (tmp_length, 1);
    2248             :       break;
    2249             : 
    2250             :     case 'x': case 'X':
    2251             :       switch (type)
    2252             :         {
    2253             :         default:
    2254             :           tmp_length =
    2255             :             (unsigned int) (sizeof (unsigned int) * CHAR_BIT
    2256             :                             * 0.25 /* binary -> hexadecimal */
    2257             :                            )
    2258             :             + 1; /* turn floor into ceil */
    2259             :           break;
    2260             :         case TYPE_ULONGINT:
    2261             :           tmp_length =
    2262             :             (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
    2263             :                             * 0.25 /* binary -> hexadecimal */
    2264             :                            )
    2265             :             + 1; /* turn floor into ceil */
    2266             :           break;
    2267             :         case TYPE_ULONGLONGINT:
    2268             :           tmp_length =
    2269             :             (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
    2270             :                             * 0.25 /* binary -> hexadecimal */
    2271             :                            )
    2272             :             + 1; /* turn floor into ceil */
    2273             :           break;
    2274             :         case TYPE_UINT8_T:
    2275             :           tmp_length =
    2276             :             (unsigned int) (sizeof (uint8_t) * CHAR_BIT
    2277             :                             * 0.25 /* binary -> hexadecimal */
    2278             :                            )
    2279             :             + 1; /* turn floor into ceil */
    2280             :           break;
    2281             :         case TYPE_UINT16_T:
    2282             :           tmp_length =
    2283             :             (unsigned int) (sizeof (uint16_t) * CHAR_BIT
    2284             :                             * 0.25 /* binary -> hexadecimal */
    2285             :                            )
    2286             :             + 1; /* turn floor into ceil */
    2287             :           break;
    2288             :         case TYPE_UINT32_T:
    2289             :           tmp_length =
    2290             :             (unsigned int) (sizeof (uint32_t) * CHAR_BIT
    2291             :                             * 0.25 /* binary -> hexadecimal */
    2292             :                            )
    2293             :             + 1; /* turn floor into ceil */
    2294             :           break;
    2295             :         case TYPE_UINT64_T:
    2296             :           tmp_length =
    2297             :             (unsigned int) (sizeof (uint64_t) * CHAR_BIT
    2298             :                             * 0.25 /* binary -> hexadecimal */
    2299             :                            )
    2300             :             + 1; /* turn floor into ceil */
    2301             :           break;
    2302             :         case TYPE_UINT_FAST8_T:
    2303             :           tmp_length =
    2304             :             (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
    2305             :                             * 0.25 /* binary -> hexadecimal */
    2306             :                            )
    2307             :             + 1; /* turn floor into ceil */
    2308             :           break;
    2309             :         case TYPE_UINT_FAST16_T:
    2310             :           tmp_length =
    2311             :             (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
    2312             :                             * 0.25 /* binary -> hexadecimal */
    2313             :                            )
    2314             :             + 1; /* turn floor into ceil */
    2315             :           break;
    2316             :         case TYPE_UINT_FAST32_T:
    2317             :           tmp_length =
    2318             :             (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
    2319             :                             * 0.25 /* binary -> hexadecimal */
    2320             :                            )
    2321             :             + 1; /* turn floor into ceil */
    2322             :           break;
    2323             :         case TYPE_UINT_FAST64_T:
    2324             :           tmp_length =
    2325             :             (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
    2326             :                             * 0.25 /* binary -> hexadecimal */
    2327             :                            )
    2328             :             + 1; /* turn floor into ceil */
    2329             :           break;
    2330             :         }
    2331             :       if (tmp_length < precision)
    2332             :         tmp_length = precision;
    2333             :       /* Add 2, to account for a prefix from the alternate form.  */
    2334             :       tmp_length = xsum (tmp_length, 2);
    2335             :       break;
    2336             : 
    2337             :     case 'e': case 'E':
    2338             :       tmp_length =
    2339             :         12; /* sign, decimal point, exponent etc. */
    2340             :       tmp_length = xsum (tmp_length, precision);
    2341             :       break;
    2342             : 
    2343             :     case 'f': case 'F':
    2344             :       if (type == TYPE_LONGDOUBLE)
    2345             :         tmp_length =
    2346             :           (unsigned int) (LDBL_MAX_EXP
    2347             :                           * 0.30103 /* binary -> decimal */
    2348             :                           * 0.5 * 3 /* estimate for FLAG_GROUP */
    2349             :                          )
    2350             :           + 1 /* turn floor into ceil */
    2351             :           + 10; /* sign, decimal point etc. */
    2352             :       else
    2353             :         tmp_length =
    2354             :           (unsigned int) (DBL_MAX_EXP
    2355             :                           * 0.30103 /* binary -> decimal */
    2356             :                           * 0.5 * 3 /* estimate for FLAG_GROUP */
    2357             :                          )
    2358             :           + 1 /* turn floor into ceil */
    2359             :           + 10; /* sign, decimal point etc. */
    2360             :       tmp_length = xsum (tmp_length, precision);
    2361             :       break;
    2362             : 
    2363             :     case 'g': case 'G':
    2364             :       tmp_length =
    2365             :         12; /* sign, decimal point, exponent etc. */
    2366             :       tmp_length = xsum (tmp_length,
    2367             :                          precision
    2368             :                          * 0.5 * 3 /* estimate for FLAG_GROUP */
    2369             :                         );
    2370             :       break;
    2371             : 
    2372             :     case 'a': case 'A':
    2373             :       if (type == TYPE_LONGDOUBLE)
    2374             :         tmp_length =
    2375             :           (unsigned int) (LDBL_DIG
    2376             :                           * 0.831 /* decimal -> hexadecimal */
    2377             :                          )
    2378             :           + 1; /* turn floor into ceil */
    2379             :       else
    2380             :         tmp_length =
    2381             :           (unsigned int) (DBL_DIG
    2382             :                           * 0.831 /* decimal -> hexadecimal */
    2383             :                          )
    2384             :           + 1; /* turn floor into ceil */
    2385             :       if (tmp_length < precision)
    2386             :         tmp_length = precision;
    2387             :       /* Account for sign, decimal point etc. */
    2388             :       tmp_length = xsum (tmp_length, 12);
    2389             :       break;
    2390             : 
    2391             :     case 'c':
    2392             : # if HAVE_WINT_T && !WIDE_CHAR_VERSION
    2393             :       if (type == TYPE_WIDE_CHAR)
    2394             :         {
    2395             :           tmp_length = MB_CUR_MAX;
    2396             : #  if ENABLE_WCHAR_FALLBACK
    2397             :           if (tmp_length < (sizeof (wchar_t) > 2 ? 10 : 6))
    2398             :             tmp_length = (sizeof (wchar_t) > 2 ? 10 : 6);
    2399             : #  endif
    2400             :         }
    2401             :       else
    2402             : # endif
    2403             :         tmp_length = 1;
    2404             :       break;
    2405             : 
    2406             :     case 's':
    2407             :       if (type == TYPE_WIDE_STRING)
    2408             :         {
    2409             : # if WIDE_CHAR_VERSION
    2410             :           /* ISO C says about %ls in fwprintf:
    2411             :                "If the precision is not specified or is greater than the size
    2412             :                 of the array, the array shall contain a null wide character."
    2413             :              So if there is a precision, we must not use wcslen.  */
    2414             :           const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
    2415             : 
    2416             :           if (has_precision)
    2417             :             tmp_length = local_wcsnlen (arg, precision);
    2418             :           else
    2419             :             tmp_length = local_wcslen (arg);
    2420             : # else
    2421             :           /* ISO C says about %ls in fprintf:
    2422             :                "If a precision is specified, no more than that many bytes are
    2423             :                 written (including shift sequences, if any), and the array
    2424             :                 shall contain a null wide character if, to equal the multibyte
    2425             :                 character sequence length given by the precision, the function
    2426             :                 would need to access a wide character one past the end of the
    2427             :                 array."
    2428             :              So if there is a precision, we must not use wcslen.  */
    2429             :           /* This case has already been handled separately in VASNPRINTF.  */
    2430             :           abort ();
    2431             : # endif
    2432             :         }
    2433             :       else
    2434             :         {
    2435             : # if WIDE_CHAR_VERSION
    2436             :           /* ISO C says about %s in fwprintf:
    2437             :                "If the precision is not specified or is greater than the size
    2438             :                 of the converted array, the converted array shall contain a
    2439             :                 null wide character."
    2440             :              So if there is a precision, we must not use strlen.  */
    2441             :           /* This case has already been handled separately in VASNPRINTF.  */
    2442             :           abort ();
    2443             : # else
    2444             :           /* ISO C says about %s in fprintf:
    2445             :                "If the precision is not specified or greater than the size of
    2446             :                 the array, the array shall contain a null character."
    2447             :              So if there is a precision, we must not use strlen.  */
    2448             :           const char *arg = ap->arg[arg_index].a.a_string;
    2449             : 
    2450             :           if (has_precision)
    2451             :             tmp_length = local_strnlen (arg, precision);
    2452             :           else
    2453             :             tmp_length = strlen (arg);
    2454             : # endif
    2455             :         }
    2456             :       break;
    2457             : 
    2458             :     case 'p':
    2459             :       tmp_length =
    2460             :         (unsigned int) (sizeof (void *) * CHAR_BIT
    2461             :                         * 0.25 /* binary -> hexadecimal */
    2462             :                        )
    2463             :           + 1 /* turn floor into ceil */
    2464             :           + 2; /* account for leading 0x */
    2465             :       break;
    2466             : 
    2467             :     default:
    2468             :       abort ();
    2469             :     }
    2470             : 
    2471             :   if (!pad_ourselves)
    2472             :     {
    2473             : # if ENABLE_UNISTDIO
    2474             :       /* Padding considers the number of characters, therefore the number of
    2475             :          elements after padding may be
    2476             :            > max (tmp_length, width)
    2477             :          but is certainly
    2478             :            <= tmp_length + width.  */
    2479             :       tmp_length = xsum (tmp_length, width);
    2480             : # else
    2481             :       /* Padding considers the number of elements, says POSIX.  */
    2482             :       if (tmp_length < width)
    2483             :         tmp_length = width;
    2484             : # endif
    2485             :     }
    2486             : 
    2487             :   tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
    2488             : 
    2489             :   return tmp_length;
    2490             : }
    2491             : 
    2492             : #endif
    2493             : 
    2494             : DCHAR_T *
    2495       14391 : VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
    2496             :             const FCHAR_T *format, va_list args)
    2497             : {
    2498             :   DIRECTIVES d;
    2499             :   arguments a;
    2500             : 
    2501       14391 :   if (PRINTF_PARSE (format, &d, &a) < 0)
    2502             :     /* errno is already set.  */
    2503           0 :     return NULL;
    2504             : 
    2505             :   /* Frees the memory allocated by this function.  Preserves errno.  */
    2506             : #define CLEANUP() \
    2507             :   if (d.dir != d.direct_alloc_dir)                                      \
    2508             :     free (d.dir);                                                       \
    2509             :   if (a.arg != a.direct_alloc_arg)                                      \
    2510             :     free (a.arg);
    2511             : 
    2512       14391 :   if (PRINTF_FETCHARGS (args, &a) < 0)
    2513           0 :     goto fail_1_with_EINVAL;
    2514             : 
    2515             :   {
    2516             :     size_t buf_neededlength;
    2517             :     TCHAR_T *buf;
    2518             :     TCHAR_T *buf_malloced;
    2519             :     const FCHAR_T *cp;
    2520             :     size_t di;
    2521             :     DIRECTIVE *dp;
    2522             :     /* Output string accumulator.  */
    2523             :     DCHAR_T *result;
    2524             :     size_t allocated;
    2525             :     size_t length;
    2526             : 
    2527             :     /* Allocate a small buffer that will hold a directive passed to
    2528             :        sprintf or snprintf.  */
    2529             :     buf_neededlength =
    2530       14391 :       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
    2531             : #if HAVE_ALLOCA
    2532       14391 :     if (buf_neededlength < 4000 / sizeof (TCHAR_T))
    2533             :       {
    2534       14391 :         buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
    2535       14391 :         buf_malloced = NULL;
    2536             :       }
    2537             :     else
    2538             : #endif
    2539             :       {
    2540           0 :         size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
    2541           0 :         if (size_overflow_p (buf_memsize))
    2542           0 :           goto out_of_memory_1;
    2543           0 :         buf = (TCHAR_T *) malloc (buf_memsize);
    2544           0 :         if (buf == NULL)
    2545           0 :           goto out_of_memory_1;
    2546           0 :         buf_malloced = buf;
    2547             :       }
    2548             : 
    2549       14391 :     result = resultbuf;
    2550       14391 :     allocated = (resultbuf != NULL ? *lengthp : 0);
    2551       14391 :     length = 0;
    2552             :     /* Invariants:
    2553             :        result is either == resultbuf or malloc-allocated.
    2554             :        If result == NULL, resultbuf is == NULL as well.
    2555             :        If length > 0, then result != NULL.  */
    2556             : 
    2557             :     /* Ensures that allocated >= needed.  Aborts through a jump to
    2558             :        out_of_memory if needed is SIZE_MAX or otherwise too big.  */
    2559             : #define ENSURE_ALLOCATION_ELSE(needed, oom_statement) \
    2560             :     if ((needed) > allocated)                                                \
    2561             :       {                                                                      \
    2562             :         size_t memory_size;                                                  \
    2563             :         DCHAR_T *memory;                                                     \
    2564             :                                                                              \
    2565             :         allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
    2566             :         if ((needed) > allocated)                                            \
    2567             :           allocated = (needed);                                              \
    2568             :         memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
    2569             :         if (size_overflow_p (memory_size))                                   \
    2570             :           oom_statement                                                      \
    2571             :         if (result == resultbuf)                                             \
    2572             :           memory = (DCHAR_T *) malloc (memory_size);                         \
    2573             :         else                                                                 \
    2574             :           memory = (DCHAR_T *) realloc (result, memory_size);                \
    2575             :         if (memory == NULL)                                                  \
    2576             :           oom_statement                                                      \
    2577             :         if (result == resultbuf && length > 0)                               \
    2578             :           DCHAR_CPY (memory, result, length);                                \
    2579             :         result = memory;                                                     \
    2580             :       }
    2581             : #define ENSURE_ALLOCATION(needed) \
    2582             :   ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; )
    2583             : 
    2584       29798 :     for (cp = format, di = 0, dp = &d.dir[0]; ; cp = dp->dir_end, di++, dp++)
    2585             :       {
    2586       29798 :         if (cp != dp->dir_start)
    2587             :           {
    2588        4477 :             size_t n = dp->dir_start - cp;
    2589        4477 :             size_t augmented_length = xsum (length, n);
    2590             : 
    2591        4477 :             ENSURE_ALLOCATION (augmented_length);
    2592             :             /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
    2593             :                need that the format string contains only ASCII characters
    2594             :                if FCHAR_T and DCHAR_T are not the same type.  */
    2595             :             if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
    2596             :               {
    2597        4477 :                 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
    2598        4477 :                 length = augmented_length;
    2599             :               }
    2600             :             else
    2601             :               {
    2602             :                 do
    2603             :                   result[length++] = *cp++;
    2604             :                 while (--n > 0);
    2605             :               }
    2606             :           }
    2607       29798 :         if (di == d.count)
    2608       14391 :           break;
    2609             : 
    2610             :         /* Execute a single directive.  */
    2611       15407 :         if (dp->conversion == '%')
    2612             :           {
    2613             :             size_t augmented_length;
    2614             : 
    2615         160 :             if (!(dp->arg_index == ARG_NONE))
    2616           0 :               abort ();
    2617         160 :             augmented_length = xsum (length, 1);
    2618         160 :             ENSURE_ALLOCATION (augmented_length);
    2619         160 :             result[length] = '%';
    2620         160 :             length = augmented_length;
    2621             :           }
    2622             :         else
    2623             :           {
    2624       15247 :             if (!(dp->arg_index != ARG_NONE))
    2625           0 :               abort ();
    2626             : 
    2627       15247 :             if (dp->conversion == 'n')
    2628             :               {
    2629             : #if NEED_PRINTF_WITH_N_DIRECTIVE
    2630             :                 switch (a.arg[dp->arg_index].type)
    2631             :                   {
    2632             :                   case TYPE_COUNT_SCHAR_POINTER:
    2633             :                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
    2634             :                     break;
    2635             :                   case TYPE_COUNT_SHORT_POINTER:
    2636             :                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
    2637             :                     break;
    2638             :                   case TYPE_COUNT_INT_POINTER:
    2639             :                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
    2640             :                     break;
    2641             :                   case TYPE_COUNT_LONGINT_POINTER:
    2642             :                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
    2643             :                     break;
    2644             :                   case TYPE_COUNT_LONGLONGINT_POINTER:
    2645             :                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
    2646             :                     break;
    2647             :                   case TYPE_COUNT_INT8_T_POINTER:
    2648             :                     *a.arg[dp->arg_index].a.a_count_int8_t_pointer = length;
    2649             :                     break;
    2650             :                   case TYPE_COUNT_INT16_T_POINTER:
    2651             :                     *a.arg[dp->arg_index].a.a_count_int16_t_pointer = length;
    2652             :                     break;
    2653             :                   case TYPE_COUNT_INT32_T_POINTER:
    2654             :                     *a.arg[dp->arg_index].a.a_count_int32_t_pointer = length;
    2655             :                     break;
    2656             :                   case TYPE_COUNT_INT64_T_POINTER:
    2657             :                     *a.arg[dp->arg_index].a.a_count_int64_t_pointer = length;
    2658             :                     break;
    2659             :                   case TYPE_COUNT_INT_FAST8_T_POINTER:
    2660             :                     *a.arg[dp->arg_index].a.a_count_int_fast8_t_pointer = length;
    2661             :                     break;
    2662             :                   case TYPE_COUNT_INT_FAST16_T_POINTER:
    2663             :                     *a.arg[dp->arg_index].a.a_count_int_fast16_t_pointer = length;
    2664             :                     break;
    2665             :                   case TYPE_COUNT_INT_FAST32_T_POINTER:
    2666             :                     *a.arg[dp->arg_index].a.a_count_int_fast32_t_pointer = length;
    2667             :                     break;
    2668             :                   case TYPE_COUNT_INT_FAST64_T_POINTER:
    2669             :                     *a.arg[dp->arg_index].a.a_count_int_fast64_t_pointer = length;
    2670             :                     break;
    2671             :                   default:
    2672             :                     abort ();
    2673             :                   }
    2674             : #else
    2675           0 :                 abort ();
    2676             : #endif
    2677             :               }
    2678             : #if ENABLE_UNISTDIO
    2679             :             /* The unistdio extensions.  */
    2680             :             else if (dp->conversion == 'U')
    2681             :               {
    2682             :                 arg_type type = a.arg[dp->arg_index].type;
    2683             :                 int flags = dp->flags;
    2684             :                 int has_width;
    2685             :                 size_t width;
    2686             :                 int has_precision;
    2687             :                 size_t precision;
    2688             : 
    2689             :                 has_width = 0;
    2690             :                 width = 0;
    2691             :                 if (dp->width_start != dp->width_end)
    2692             :                   {
    2693             :                     if (dp->width_arg_index != ARG_NONE)
    2694             :                       {
    2695             :                         int arg;
    2696             : 
    2697             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    2698             :                           abort ();
    2699             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    2700             :                         width = arg;
    2701             :                         if (arg < 0)
    2702             :                           {
    2703             :                             /* "A negative field width is taken as a '-' flag
    2704             :                                 followed by a positive field width."  */
    2705             :                             flags |= FLAG_LEFT;
    2706             :                             width = -width;
    2707             :                           }
    2708             :                       }
    2709             :                     else
    2710             :                       {
    2711             :                         const FCHAR_T *digitp = dp->width_start;
    2712             : 
    2713             :                         do
    2714             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    2715             :                         while (digitp != dp->width_end);
    2716             :                       }
    2717             :                     if (width > (size_t) INT_MAX)
    2718             :                       goto overflow;
    2719             :                     has_width = 1;
    2720             :                   }
    2721             : 
    2722             :                 has_precision = 0;
    2723             :                 precision = 0;
    2724             :                 if (dp->precision_start != dp->precision_end)
    2725             :                   {
    2726             :                     if (dp->precision_arg_index != ARG_NONE)
    2727             :                       {
    2728             :                         int arg;
    2729             : 
    2730             :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    2731             :                           abort ();
    2732             :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    2733             :                         /* "A negative precision is taken as if the precision
    2734             :                             were omitted."  */
    2735             :                         if (arg >= 0)
    2736             :                           {
    2737             :                             precision = arg;
    2738             :                             has_precision = 1;
    2739             :                           }
    2740             :                       }
    2741             :                     else
    2742             :                       {
    2743             :                         const FCHAR_T *digitp = dp->precision_start + 1;
    2744             : 
    2745             :                         precision = 0;
    2746             :                         while (digitp != dp->precision_end)
    2747             :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    2748             :                         has_precision = 1;
    2749             :                       }
    2750             :                   }
    2751             : 
    2752             :                 switch (type)
    2753             :                   {
    2754             :                   case TYPE_U8_STRING:
    2755             :                     {
    2756             :                       const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
    2757             :                       const uint8_t *arg_end;
    2758             :                       size_t characters;
    2759             : 
    2760             :                       if (has_precision)
    2761             :                         {
    2762             :                           /* Use only PRECISION characters, from the left.  */
    2763             :                           arg_end = arg;
    2764             :                           characters = 0;
    2765             :                           for (; precision > 0; precision--)
    2766             :                             {
    2767             :                               int count = u8_strmblen (arg_end);
    2768             :                               if (count == 0)
    2769             :                                 break;
    2770             :                               if (count < 0)
    2771             :                                 goto fail_with_EILSEQ;
    2772             :                               arg_end += count;
    2773             :                               characters++;
    2774             :                             }
    2775             :                         }
    2776             :                       else if (has_width)
    2777             :                         {
    2778             :                           /* Use the entire string, and count the number of
    2779             :                              characters.  */
    2780             :                           arg_end = arg;
    2781             :                           characters = 0;
    2782             :                           for (;;)
    2783             :                             {
    2784             :                               int count = u8_strmblen (arg_end);
    2785             :                               if (count == 0)
    2786             :                                 break;
    2787             :                               if (count < 0)
    2788             :                                 goto fail_with_EILSEQ;
    2789             :                               arg_end += count;
    2790             :                               characters++;
    2791             :                             }
    2792             :                         }
    2793             :                       else
    2794             :                         {
    2795             :                           /* Use the entire string.  */
    2796             :                           arg_end = arg + u8_strlen (arg);
    2797             :                           /* The number of characters doesn't matter,
    2798             :                              because !has_width and therefore width==0.  */
    2799             :                           characters = 0;
    2800             :                         }
    2801             : 
    2802             :                       if (characters < width && !(flags & FLAG_LEFT))
    2803             :                         {
    2804             :                           size_t n = width - characters;
    2805             :                           ENSURE_ALLOCATION (xsum (length, n));
    2806             :                           DCHAR_SET (result + length, ' ', n);
    2807             :                           length += n;
    2808             :                         }
    2809             : 
    2810             : # if DCHAR_IS_UINT8_T
    2811             :                       {
    2812             :                         size_t n = arg_end - arg;
    2813             :                         ENSURE_ALLOCATION (xsum (length, n));
    2814             :                         DCHAR_CPY (result + length, arg, n);
    2815             :                         length += n;
    2816             :                       }
    2817             : # else
    2818             :                       { /* Convert.  */
    2819             :                         DCHAR_T *converted = result + length;
    2820             :                         size_t converted_len = allocated - length;
    2821             : #  if DCHAR_IS_TCHAR
    2822             :                         /* Convert from UTF-8 to locale encoding.  */
    2823             :                         converted =
    2824             :                           u8_conv_to_encoding (locale_charset (),
    2825             :                                                iconveh_question_mark,
    2826             :                                                arg, arg_end - arg, NULL,
    2827             :                                                converted, &converted_len);
    2828             : #  else
    2829             :                         /* Convert from UTF-8 to UTF-16/UTF-32.  */
    2830             :                         converted =
    2831             :                           U8_TO_DCHAR (arg, arg_end - arg,
    2832             :                                        converted, &converted_len);
    2833             : #  endif
    2834             :                         if (converted == NULL)
    2835             :                           goto fail_with_errno;
    2836             :                         if (converted != result + length)
    2837             :                           {
    2838             :                             ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
    2839             :                               { free (converted); goto out_of_memory; });
    2840             :                             DCHAR_CPY (result + length, converted, converted_len);
    2841             :                             free (converted);
    2842             :                           }
    2843             :                         length += converted_len;
    2844             :                       }
    2845             : # endif
    2846             : 
    2847             :                       if (characters < width && (flags & FLAG_LEFT))
    2848             :                         {
    2849             :                           size_t n = width - characters;
    2850             :                           ENSURE_ALLOCATION (xsum (length, n));
    2851             :                           DCHAR_SET (result + length, ' ', n);
    2852             :                           length += n;
    2853             :                         }
    2854             :                     }
    2855             :                     break;
    2856             : 
    2857             :                   case TYPE_U16_STRING:
    2858             :                     {
    2859             :                       const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
    2860             :                       const uint16_t *arg_end;
    2861             :                       size_t characters;
    2862             : 
    2863             :                       if (has_precision)
    2864             :                         {
    2865             :                           /* Use only PRECISION characters, from the left.  */
    2866             :                           arg_end = arg;
    2867             :                           characters = 0;
    2868             :                           for (; precision > 0; precision--)
    2869             :                             {
    2870             :                               int count = u16_strmblen (arg_end);
    2871             :                               if (count == 0)
    2872             :                                 break;
    2873             :                               if (count < 0)
    2874             :                                 goto fail_with_EILSEQ;
    2875             :                               arg_end += count;
    2876             :                               characters++;
    2877             :                             }
    2878             :                         }
    2879             :                       else if (has_width)
    2880             :                         {
    2881             :                           /* Use the entire string, and count the number of
    2882             :                              characters.  */
    2883             :                           arg_end = arg;
    2884             :                           characters = 0;
    2885             :                           for (;;)
    2886             :                             {
    2887             :                               int count = u16_strmblen (arg_end);
    2888             :                               if (count == 0)
    2889             :                                 break;
    2890             :                               if (count < 0)
    2891             :                                 goto fail_with_EILSEQ;
    2892             :                               arg_end += count;
    2893             :                               characters++;
    2894             :                             }
    2895             :                         }
    2896             :                       else
    2897             :                         {
    2898             :                           /* Use the entire string.  */
    2899             :                           arg_end = arg + u16_strlen (arg);
    2900             :                           /* The number of characters doesn't matter,
    2901             :                              because !has_width and therefore width==0.  */
    2902             :                           characters = 0;
    2903             :                         }
    2904             : 
    2905             :                       if (characters < width && !(flags & FLAG_LEFT))
    2906             :                         {
    2907             :                           size_t n = width - characters;
    2908             :                           ENSURE_ALLOCATION (xsum (length, n));
    2909             :                           DCHAR_SET (result + length, ' ', n);
    2910             :                           length += n;
    2911             :                         }
    2912             : 
    2913             : # if DCHAR_IS_UINT16_T
    2914             :                       {
    2915             :                         size_t n = arg_end - arg;
    2916             :                         ENSURE_ALLOCATION (xsum (length, n));
    2917             :                         DCHAR_CPY (result + length, arg, n);
    2918             :                         length += n;
    2919             :                       }
    2920             : # else
    2921             :                       { /* Convert.  */
    2922             :                         DCHAR_T *converted = result + length;
    2923             :                         size_t converted_len = allocated - length;
    2924             : #  if DCHAR_IS_TCHAR
    2925             :                         /* Convert from UTF-16 to locale encoding.  */
    2926             :                         converted =
    2927             :                           u16_conv_to_encoding (locale_charset (),
    2928             :                                                 iconveh_question_mark,
    2929             :                                                 arg, arg_end - arg, NULL,
    2930             :                                                 converted, &converted_len);
    2931             : #  else
    2932             :                         /* Convert from UTF-16 to UTF-8/UTF-32.  */
    2933             :                         converted =
    2934             :                           U16_TO_DCHAR (arg, arg_end - arg,
    2935             :                                         converted, &converted_len);
    2936             : #  endif
    2937             :                         if (converted == NULL)
    2938             :                           goto fail_with_errno;
    2939             :                         if (converted != result + length)
    2940             :                           {
    2941             :                             ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
    2942             :                               { free (converted); goto out_of_memory; });
    2943             :                             DCHAR_CPY (result + length, converted, converted_len);
    2944             :                             free (converted);
    2945             :                           }
    2946             :                         length += converted_len;
    2947             :                       }
    2948             : # endif
    2949             : 
    2950             :                       if (characters < width && (flags & FLAG_LEFT))
    2951             :                         {
    2952             :                           size_t n = width - characters;
    2953             :                           ENSURE_ALLOCATION (xsum (length, n));
    2954             :                           DCHAR_SET (result + length, ' ', n);
    2955             :                           length += n;
    2956             :                         }
    2957             :                     }
    2958             :                     break;
    2959             : 
    2960             :                   case TYPE_U32_STRING:
    2961             :                     {
    2962             :                       const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
    2963             :                       const uint32_t *arg_end;
    2964             :                       size_t characters;
    2965             : 
    2966             :                       if (has_precision)
    2967             :                         {
    2968             :                           /* Use only PRECISION characters, from the left.  */
    2969             :                           arg_end = arg;
    2970             :                           characters = 0;
    2971             :                           for (; precision > 0; precision--)
    2972             :                             {
    2973             :                               int count = u32_strmblen (arg_end);
    2974             :                               if (count == 0)
    2975             :                                 break;
    2976             :                               if (count < 0)
    2977             :                                 goto fail_with_EILSEQ;
    2978             :                               arg_end += count;
    2979             :                               characters++;
    2980             :                             }
    2981             :                         }
    2982             :                       else if (has_width)
    2983             :                         {
    2984             :                           /* Use the entire string, and count the number of
    2985             :                              characters.  */
    2986             :                           arg_end = arg;
    2987             :                           characters = 0;
    2988             :                           for (;;)
    2989             :                             {
    2990             :                               int count = u32_strmblen (arg_end);
    2991             :                               if (count == 0)
    2992             :                                 break;
    2993             :                               if (count < 0)
    2994             :                                 goto fail_with_EILSEQ;
    2995             :                               arg_end += count;
    2996             :                               characters++;
    2997             :                             }
    2998             :                         }
    2999             :                       else
    3000             :                         {
    3001             :                           /* Use the entire string.  */
    3002             :                           arg_end = arg + u32_strlen (arg);
    3003             :                           /* The number of characters doesn't matter,
    3004             :                              because !has_width and therefore width==0.  */
    3005             :                           characters = 0;
    3006             :                         }
    3007             : 
    3008             :                       if (characters < width && !(flags & FLAG_LEFT))
    3009             :                         {
    3010             :                           size_t n = width - characters;
    3011             :                           ENSURE_ALLOCATION (xsum (length, n));
    3012             :                           DCHAR_SET (result + length, ' ', n);
    3013             :                           length += n;
    3014             :                         }
    3015             : 
    3016             : # if DCHAR_IS_UINT32_T
    3017             :                       {
    3018             :                         size_t n = arg_end - arg;
    3019             :                         ENSURE_ALLOCATION (xsum (length, n));
    3020             :                         DCHAR_CPY (result + length, arg, n);
    3021             :                         length += n;
    3022             :                       }
    3023             : # else
    3024             :                       { /* Convert.  */
    3025             :                         DCHAR_T *converted = result + length;
    3026             :                         size_t converted_len = allocated - length;
    3027             : #  if DCHAR_IS_TCHAR
    3028             :                         /* Convert from UTF-32 to locale encoding.  */
    3029             :                         converted =
    3030             :                           u32_conv_to_encoding (locale_charset (),
    3031             :                                                 iconveh_question_mark,
    3032             :                                                 arg, arg_end - arg, NULL,
    3033             :                                                 converted, &converted_len);
    3034             : #  else
    3035             :                         /* Convert from UTF-32 to UTF-8/UTF-16.  */
    3036             :                         converted =
    3037             :                           U32_TO_DCHAR (arg, arg_end - arg,
    3038             :                                         converted, &converted_len);
    3039             : #  endif
    3040             :                         if (converted == NULL)
    3041             :                           goto fail_with_errno;
    3042             :                         if (converted != result + length)
    3043             :                           {
    3044             :                             ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
    3045             :                               { free (converted); goto out_of_memory; });
    3046             :                             DCHAR_CPY (result + length, converted, converted_len);
    3047             :                             free (converted);
    3048             :                           }
    3049             :                         length += converted_len;
    3050             :                       }
    3051             : # endif
    3052             : 
    3053             :                       if (characters < width && (flags & FLAG_LEFT))
    3054             :                         {
    3055             :                           size_t n = width - characters;
    3056             :                           ENSURE_ALLOCATION (xsum (length, n));
    3057             :                           DCHAR_SET (result + length, ' ', n);
    3058             :                           length += n;
    3059             :                         }
    3060             :                     }
    3061             :                     break;
    3062             : 
    3063             :                   default:
    3064             :                     abort ();
    3065             :                   }
    3066             :               }
    3067             : #endif
    3068             : #if !WIDE_CHAR_VERSION && (PTRDIFF_MAX > INT_MAX)
    3069       15247 :             else if (dp->conversion == 's'
    3070         713 :                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING)
    3071         713 :               {
    3072             :                 /* %s in vasnprintf.  See the specification of fprintf.
    3073             :                    We handle it ourselves here, because the string may be longer
    3074             :                    than INT_MAX characters, whence snprintf or sprintf would
    3075             :                    fail to process it.  */
    3076         713 :                 int flags = dp->flags;
    3077             :                 int has_width;
    3078             :                 size_t width;
    3079             :                 int has_precision;
    3080             :                 size_t precision;
    3081             : 
    3082         713 :                 has_width = 0;
    3083         713 :                 width = 0;
    3084         713 :                 if (dp->width_start != dp->width_end)
    3085             :                   {
    3086           0 :                     if (dp->width_arg_index != ARG_NONE)
    3087             :                       {
    3088             :                         int arg;
    3089             : 
    3090           0 :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    3091           0 :                           abort ();
    3092           0 :                         arg = a.arg[dp->width_arg_index].a.a_int;
    3093           0 :                         width = arg;
    3094           0 :                         if (arg < 0)
    3095             :                           {
    3096             :                             /* "A negative field width is taken as a '-' flag
    3097             :                                 followed by a positive field width."  */
    3098           0 :                             flags |= FLAG_LEFT;
    3099           0 :                             width = -width;
    3100             :                           }
    3101             :                       }
    3102             :                     else
    3103             :                       {
    3104           0 :                         const FCHAR_T *digitp = dp->width_start;
    3105             : 
    3106             :                         do
    3107           0 :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    3108           0 :                         while (digitp != dp->width_end);
    3109             :                       }
    3110           0 :                     if (width > (size_t) INT_MAX)
    3111           0 :                       goto overflow;
    3112           0 :                     has_width = 1;
    3113             :                   }
    3114             : 
    3115         713 :                 has_precision = 0;
    3116         713 :                 precision = 6;
    3117         713 :                 if (dp->precision_start != dp->precision_end)
    3118             :                   {
    3119           0 :                     if (dp->precision_arg_index != ARG_NONE)
    3120             :                       {
    3121             :                         int arg;
    3122             : 
    3123           0 :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    3124           0 :                           abort ();
    3125           0 :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    3126             :                         /* "A negative precision is taken as if the precision
    3127             :                             were omitted."  */
    3128           0 :                         if (arg >= 0)
    3129             :                           {
    3130           0 :                             precision = arg;
    3131           0 :                             has_precision = 1;
    3132             :                           }
    3133             :                       }
    3134             :                     else
    3135             :                       {
    3136           0 :                         const FCHAR_T *digitp = dp->precision_start + 1;
    3137             : 
    3138           0 :                         precision = 0;
    3139           0 :                         while (digitp != dp->precision_end)
    3140           0 :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    3141           0 :                         has_precision = 1;
    3142             :                       }
    3143             :                   }
    3144             : 
    3145             :                 {
    3146         713 :                   const char *arg = a.arg[dp->arg_index].a.a_string;
    3147             :                   size_t bytes;
    3148             : # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
    3149             :                   size_t characters;
    3150             : # endif
    3151             : # if !DCHAR_IS_TCHAR
    3152             :                   /* This code assumes that TCHAR_T is 'char'.  */
    3153             :                   static_assert (sizeof (TCHAR_T) == 1);
    3154             :                   DCHAR_T *tmpdst;
    3155             :                   size_t tmpdst_len;
    3156             : # endif
    3157             :                   size_t w;
    3158             : 
    3159         713 :                   if (has_precision)
    3160             :                     {
    3161             :                       /* Use only at most PRECISION bytes, from the left.  */
    3162           0 :                       bytes = local_strnlen (arg, precision);
    3163             :                     }
    3164             :                   else
    3165             :                     {
    3166             :                       /* Use the entire string, and count the number of
    3167             :                          bytes.  */
    3168         713 :                       bytes = strlen (arg);
    3169             :                     }
    3170             : 
    3171             : # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
    3172             :                   if (has_width)
    3173             :                     characters = mbsnlen (arg, bytes);
    3174             :                   else
    3175             :                     {
    3176             :                       /* The number of characters doesn't matter,
    3177             :                          because !has_width and therefore width==0.  */
    3178             :                       characters = 0;
    3179             :                     }
    3180             : # endif
    3181             : 
    3182             : # if !DCHAR_IS_TCHAR
    3183             :                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
    3184             :                   tmpdst =
    3185             :                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
    3186             :                                               iconveh_question_mark,
    3187             :                                               arg, bytes,
    3188             :                                               NULL,
    3189             :                                               NULL, &tmpdst_len);
    3190             :                   if (tmpdst == NULL)
    3191             :                     goto fail_with_errno;
    3192             : # endif
    3193             : 
    3194         713 :                   if (has_width)
    3195             :                     {
    3196             : # if ENABLE_UNISTDIO
    3197             :                       /* Outside POSIX, it's preferable to compare the width
    3198             :                          against the number of _characters_ of the converted
    3199             :                          value.  */
    3200             : #  if DCHAR_IS_TCHAR
    3201             :                       w = characters;
    3202             : #  else
    3203             :                       w = DCHAR_MBSNLEN (tmpdst, tmpdst_len);
    3204             : #  endif
    3205             : # else
    3206             :                       /* The width is compared against the number of _bytes_
    3207             :                          of the converted value, says POSIX.  */
    3208           0 :                       w = bytes;
    3209             : # endif
    3210             :                     }
    3211             :                   else
    3212             :                     /* w doesn't matter.  */
    3213         713 :                     w = 0;
    3214             : 
    3215             :                   {
    3216             : # if DCHAR_IS_TCHAR
    3217         713 :                     size_t total = bytes + (w < width ? width - w : 0);
    3218         713 :                     ENSURE_ALLOCATION (xsum (length, total));
    3219             : # else
    3220             :                     size_t total = tmpdst_len + (w < width ? width - w : 0);
    3221             :                     ENSURE_ALLOCATION_ELSE (xsum (length, total),
    3222             :                       { free (tmpdst); goto out_of_memory; });
    3223             : # endif
    3224             : 
    3225         713 :                     if (w < width && !(flags & FLAG_LEFT))
    3226             :                       {
    3227           0 :                         size_t n = width - w;
    3228           0 :                         DCHAR_SET (result + length, ' ', n);
    3229           0 :                         length += n;
    3230             :                       }
    3231             : 
    3232             : # if DCHAR_IS_TCHAR
    3233         713 :                     memcpy (result + length, arg, bytes);
    3234         713 :                     length += bytes;
    3235             : # else
    3236             :                     DCHAR_CPY (result + length, tmpdst, tmpdst_len);
    3237             :                     free (tmpdst);
    3238             :                     length += tmpdst_len;
    3239             : # endif
    3240             : 
    3241         713 :                     if (w < width && (flags & FLAG_LEFT))
    3242             :                       {
    3243           0 :                         size_t n = width - w;
    3244           0 :                         DCHAR_SET (result + length, ' ', n);
    3245           0 :                         length += n;
    3246             :                       }
    3247             :                   }
    3248             :                 }
    3249             :               }
    3250             : #endif
    3251             : #if WIDE_CHAR_VERSION && ((PTRDIFF_MAX > INT_MAX) || !DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC)
    3252             :             else if ((dp->conversion == 's'
    3253             :                       && a.arg[dp->arg_index].type == TYPE_WIDE_STRING)
    3254             :                      || (dp->conversion == 'c'
    3255             :                          && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR))
    3256             :               {
    3257             :                 /* %ls or %lc in vasnwprintf.  See the specification of
    3258             :                    fwprintf.  */
    3259             :                 /* It would be silly to use snprintf ("%ls", ...) and then
    3260             :                    convert back the result from a char[] to a wchar_t[].
    3261             :                    Instead, just copy the argument wchar_t[] to the result.  */
    3262             :                 int flags = dp->flags;
    3263             :                 size_t width;
    3264             : 
    3265             :                 width = 0;
    3266             :                 if (dp->width_start != dp->width_end)
    3267             :                   {
    3268             :                     if (dp->width_arg_index != ARG_NONE)
    3269             :                       {
    3270             :                         int arg;
    3271             : 
    3272             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    3273             :                           abort ();
    3274             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    3275             :                         width = arg;
    3276             :                         if (arg < 0)
    3277             :                           {
    3278             :                             /* "A negative field width is taken as a '-' flag
    3279             :                                 followed by a positive field width."  */
    3280             :                             flags |= FLAG_LEFT;
    3281             :                             width = -width;
    3282             :                           }
    3283             :                       }
    3284             :                     else
    3285             :                       {
    3286             :                         const FCHAR_T *digitp = dp->width_start;
    3287             : 
    3288             :                         do
    3289             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    3290             :                         while (digitp != dp->width_end);
    3291             :                       }
    3292             :                     if (width > (size_t) INT_MAX)
    3293             :                       goto overflow;
    3294             :                   }
    3295             : 
    3296             :                 {
    3297             :                   const wchar_t *ls_arg;
    3298             :                   wchar_t lc_arg[1];
    3299             :                   size_t characters;
    3300             : 
    3301             :                   if (dp->conversion == 's')
    3302             :                     {
    3303             :                       int has_precision;
    3304             :                       size_t precision;
    3305             : 
    3306             :                       has_precision = 0;
    3307             :                       precision = 6;
    3308             :                       if (dp->precision_start != dp->precision_end)
    3309             :                         {
    3310             :                           if (dp->precision_arg_index != ARG_NONE)
    3311             :                             {
    3312             :                               int arg;
    3313             : 
    3314             :                               if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    3315             :                                 abort ();
    3316             :                               arg = a.arg[dp->precision_arg_index].a.a_int;
    3317             :                               /* "A negative precision is taken as if the precision
    3318             :                                   were omitted."  */
    3319             :                               if (arg >= 0)
    3320             :                                 {
    3321             :                                   precision = arg;
    3322             :                                   has_precision = 1;
    3323             :                                 }
    3324             :                             }
    3325             :                           else
    3326             :                             {
    3327             :                               const FCHAR_T *digitp = dp->precision_start + 1;
    3328             : 
    3329             :                               precision = 0;
    3330             :                               while (digitp != dp->precision_end)
    3331             :                                 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    3332             :                               has_precision = 1;
    3333             :                             }
    3334             :                         }
    3335             : 
    3336             :                       ls_arg = a.arg[dp->arg_index].a.a_wide_string;
    3337             : 
    3338             :                       if (has_precision)
    3339             :                         {
    3340             :                           /* Use only at most PRECISION wide characters, from
    3341             :                              the left.  */
    3342             :                           const wchar_t *ls_arg_end;
    3343             : 
    3344             :                           ls_arg_end = ls_arg;
    3345             :                           characters = 0;
    3346             :                           for (; precision > 0; precision--)
    3347             :                             {
    3348             :                               if (*ls_arg_end == 0)
    3349             :                                 /* Found the terminating null wide character.  */
    3350             :                                 break;
    3351             :                               ls_arg_end++;
    3352             :                               characters++;
    3353             :                             }
    3354             :                         }
    3355             :                       else
    3356             :                         {
    3357             :                           /* Use the entire string, and count the number of wide
    3358             :                              characters.  */
    3359             :                           characters = local_wcslen (ls_arg);
    3360             :                         }
    3361             :                     }
    3362             :                   else /* dp->conversion == 'c' */
    3363             :                     {
    3364             :                       lc_arg[0] = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
    3365             :                       ls_arg = lc_arg;
    3366             :                       characters = 1;
    3367             :                     }
    3368             : 
    3369             :                   {
    3370             :                     size_t total = (characters < width ? width : characters);
    3371             :                     ENSURE_ALLOCATION (xsum (length, total));
    3372             : 
    3373             :                     if (characters < width && !(flags & FLAG_LEFT))
    3374             :                       {
    3375             :                         size_t n = width - characters;
    3376             :                         DCHAR_SET (result + length, ' ', n);
    3377             :                         length += n;
    3378             :                       }
    3379             : 
    3380             :                     if (characters > 0)
    3381             :                       {
    3382             :                         DCHAR_CPY (result + length, ls_arg, characters);
    3383             :                         length += characters;
    3384             :                       }
    3385             : 
    3386             :                     if (characters < width && (flags & FLAG_LEFT))
    3387             :                       {
    3388             :                         size_t n = width - characters;
    3389             :                         DCHAR_SET (result + length, ' ', n);
    3390             :                         length += n;
    3391             :                       }
    3392             :                   }
    3393             :                 }
    3394             :               }
    3395             : #endif
    3396             : #if WIDE_CHAR_VERSION || !USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK
    3397       14534 :             else if (dp->conversion == 's'
    3398             : # if WIDE_CHAR_VERSION
    3399             :                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
    3400             : # else
    3401           0 :                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
    3402             : # endif
    3403             :                     )
    3404           0 :               {
    3405             :                 /* The normal handling of the 's' directive below requires
    3406             :                    allocating a temporary buffer.  The determination of its
    3407             :                    length (tmp_length), in the case when a precision is
    3408             :                    specified, below requires a conversion between a char[]
    3409             :                    string and a wchar_t[] wide string.  It could be done, but
    3410             :                    we have no guarantee that the implementation of sprintf will
    3411             :                    use the exactly same algorithm.  Without this guarantee, it
    3412             :                    is possible to have buffer overrun bugs.  In order to avoid
    3413             :                    such bugs, we implement the entire processing of the 's'
    3414             :                    directive ourselves.  */
    3415           0 :                 int flags = dp->flags;
    3416             :                 int has_width;
    3417             :                 size_t width;
    3418             :                 int has_precision;
    3419             :                 size_t precision;
    3420             : 
    3421           0 :                 has_width = 0;
    3422           0 :                 width = 0;
    3423           0 :                 if (dp->width_start != dp->width_end)
    3424             :                   {
    3425           0 :                     if (dp->width_arg_index != ARG_NONE)
    3426             :                       {
    3427             :                         int arg;
    3428             : 
    3429           0 :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    3430           0 :                           abort ();
    3431           0 :                         arg = a.arg[dp->width_arg_index].a.a_int;
    3432           0 :                         width = arg;
    3433           0 :                         if (arg < 0)
    3434             :                           {
    3435             :                             /* "A negative field width is taken as a '-' flag
    3436             :                                 followed by a positive field width."  */
    3437           0 :                             flags |= FLAG_LEFT;
    3438           0 :                             width = -width;
    3439             :                           }
    3440             :                       }
    3441             :                     else
    3442             :                       {
    3443           0 :                         const FCHAR_T *digitp = dp->width_start;
    3444             : 
    3445             :                         do
    3446           0 :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    3447           0 :                         while (digitp != dp->width_end);
    3448             :                       }
    3449           0 :                     if (width > (size_t) INT_MAX)
    3450           0 :                       goto overflow;
    3451           0 :                     has_width = 1;
    3452             :                   }
    3453             : 
    3454           0 :                 has_precision = 0;
    3455           0 :                 precision = 6;
    3456           0 :                 if (dp->precision_start != dp->precision_end)
    3457             :                   {
    3458           0 :                     if (dp->precision_arg_index != ARG_NONE)
    3459             :                       {
    3460             :                         int arg;
    3461             : 
    3462           0 :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    3463           0 :                           abort ();
    3464           0 :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    3465             :                         /* "A negative precision is taken as if the precision
    3466             :                             were omitted."  */
    3467           0 :                         if (arg >= 0)
    3468             :                           {
    3469           0 :                             precision = arg;
    3470           0 :                             has_precision = 1;
    3471             :                           }
    3472             :                       }
    3473             :                     else
    3474             :                       {
    3475           0 :                         const FCHAR_T *digitp = dp->precision_start + 1;
    3476             : 
    3477           0 :                         precision = 0;
    3478           0 :                         while (digitp != dp->precision_end)
    3479           0 :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    3480           0 :                         has_precision = 1;
    3481             :                       }
    3482             :                   }
    3483             : 
    3484             : # if WIDE_CHAR_VERSION
    3485             :                 /* %s in vasnwprintf.  See the specification of fwprintf.  */
    3486             :                 {
    3487             :                   const char *arg = a.arg[dp->arg_index].a.a_string;
    3488             :                   const char *arg_end;
    3489             :                   size_t characters;
    3490             : 
    3491             :                   if (has_precision)
    3492             :                     {
    3493             :                       /* Use only as many bytes as needed to produce PRECISION
    3494             :                          wide characters, from the left.  */
    3495             : #  if HAVE_MBRTOWC
    3496             :                       mbstate_t state;
    3497             :                       mbszero (&state);
    3498             : #  endif
    3499             :                       arg_end = arg;
    3500             :                       characters = 0;
    3501             :                       for (; precision > 0; precision--)
    3502             :                         {
    3503             :                           int count;
    3504             : #  if HAVE_MBRTOWC
    3505             :                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
    3506             : #  else
    3507             :                           count = mblen (arg_end, MB_CUR_MAX);
    3508             : #  endif
    3509             :                           if (count == 0)
    3510             :                             /* Found the terminating NUL.  */
    3511             :                             break;
    3512             :                           if (count < 0)
    3513             :                             /* Invalid or incomplete multibyte character.  */
    3514             :                             goto fail_with_EILSEQ;
    3515             :                           arg_end += count;
    3516             :                           characters++;
    3517             :                         }
    3518             :                     }
    3519             :                   else if (has_width)
    3520             :                     {
    3521             :                       /* Use the entire string, and count the number of wide
    3522             :                          characters.  */
    3523             : #  if HAVE_MBRTOWC
    3524             :                       mbstate_t state;
    3525             :                       mbszero (&state);
    3526             : #  endif
    3527             :                       arg_end = arg;
    3528             :                       characters = 0;
    3529             :                       for (;;)
    3530             :                         {
    3531             :                           int count;
    3532             : #  if HAVE_MBRTOWC
    3533             :                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
    3534             : #  else
    3535             :                           count = mblen (arg_end, MB_CUR_MAX);
    3536             : #  endif
    3537             :                           if (count == 0)
    3538             :                             /* Found the terminating NUL.  */
    3539             :                             break;
    3540             :                           if (count < 0)
    3541             :                             /* Invalid or incomplete multibyte character.  */
    3542             :                             goto fail_with_EILSEQ;
    3543             :                           arg_end += count;
    3544             :                           characters++;
    3545             :                         }
    3546             :                     }
    3547             :                   else
    3548             :                     {
    3549             :                       /* Use the entire string.  */
    3550             :                       arg_end = arg + strlen (arg);
    3551             :                       /* The number of characters doesn't matter.  */
    3552             :                       characters = 0;
    3553             :                     }
    3554             : 
    3555             :                   if (characters < width && !(flags & FLAG_LEFT))
    3556             :                     {
    3557             :                       size_t n = width - characters;
    3558             :                       ENSURE_ALLOCATION (xsum (length, n));
    3559             :                       DCHAR_SET (result + length, ' ', n);
    3560             :                       length += n;
    3561             :                     }
    3562             : 
    3563             :                   if (has_precision || has_width)
    3564             :                     {
    3565             :                       /* We know the number of wide characters in advance.  */
    3566             :                       size_t remaining;
    3567             : #  if HAVE_MBRTOWC
    3568             :                       mbstate_t state;
    3569             :                       mbszero (&state);
    3570             : #  endif
    3571             :                       ENSURE_ALLOCATION (xsum (length, characters));
    3572             :                       for (remaining = characters; remaining > 0; remaining--)
    3573             :                         {
    3574             :                           wchar_t wc;
    3575             :                           int count;
    3576             : #  if HAVE_MBRTOWC
    3577             :                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
    3578             : #  else
    3579             :                           count = mbtowc (&wc, arg, arg_end - arg);
    3580             : #  endif
    3581             :                           if (count <= 0)
    3582             :                             /* mbrtowc not consistent with mbrlen, or mbtowc
    3583             :                                not consistent with mblen.  */
    3584             :                             abort ();
    3585             :                           result[length++] = wc;
    3586             :                           arg += count;
    3587             :                         }
    3588             :                       if (!(arg == arg_end))
    3589             :                         abort ();
    3590             :                     }
    3591             :                   else
    3592             :                     {
    3593             : #  if HAVE_MBRTOWC
    3594             :                       mbstate_t state;
    3595             :                       mbszero (&state);
    3596             : #  endif
    3597             :                       while (arg < arg_end)
    3598             :                         {
    3599             :                           wchar_t wc;
    3600             :                           int count;
    3601             : #  if HAVE_MBRTOWC
    3602             :                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
    3603             : #  else
    3604             :                           count = mbtowc (&wc, arg, arg_end - arg);
    3605             : #  endif
    3606             :                           if (count == 0)
    3607             :                             /* mbrtowc not consistent with strlen.  */
    3608             :                             abort ();
    3609             :                           if (count < 0)
    3610             :                             /* Invalid or incomplete multibyte character.  */
    3611             :                             goto fail_with_EILSEQ;
    3612             :                           ENSURE_ALLOCATION (xsum (length, 1));
    3613             :                           result[length++] = wc;
    3614             :                           arg += count;
    3615             :                         }
    3616             :                     }
    3617             : 
    3618             :                   if (characters < width && (flags & FLAG_LEFT))
    3619             :                     {
    3620             :                       size_t n = width - characters;
    3621             :                       ENSURE_ALLOCATION (xsum (length, n));
    3622             :                       DCHAR_SET (result + length, ' ', n);
    3623             :                       length += n;
    3624             :                     }
    3625             :                 }
    3626             : # else
    3627             :                 /* %ls in vasnprintf.  See the specification of fprintf.  */
    3628             :                 {
    3629           0 :                   const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
    3630             :                   const wchar_t *arg_end;
    3631             :                   size_t bytes;
    3632             : #  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
    3633             :                   size_t characters;
    3634             : #  endif
    3635             : #  if !DCHAR_IS_TCHAR
    3636             :                   /* This code assumes that TCHAR_T is 'char'.  */
    3637             :                   static_assert (sizeof (TCHAR_T) == 1);
    3638             :                   DCHAR_T *tmpdst;
    3639             :                   size_t tmpdst_len;
    3640             : #  endif
    3641             :                   size_t w;
    3642             : 
    3643           0 :                   if (has_precision)
    3644             :                     {
    3645             :                       /* Use only as many wide characters as needed to produce
    3646             :                          at most PRECISION bytes, from the left.  */
    3647             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    3648             :                       mbstate_t state;
    3649           0 :                       mbszero (&state);
    3650             : #  endif
    3651           0 :                       arg_end = arg;
    3652           0 :                       bytes = 0;
    3653             : #  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
    3654             :                       characters = 0;
    3655             : #  endif
    3656           0 :                       while (precision > 0)
    3657             :                         {
    3658             :                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    3659             :                           int count;
    3660             : 
    3661           0 :                           if (*arg_end == 0)
    3662             :                             /* Found the terminating null wide character.  */
    3663           0 :                             break;
    3664           0 :                           count = local_wcrtomb (cbuf, *arg_end, &state);
    3665           0 :                           if (count < 0)
    3666             :                             /* Cannot convert.  */
    3667           0 :                             goto fail_with_EILSEQ;
    3668           0 :                           if (precision < (unsigned int) count)
    3669           0 :                             break;
    3670           0 :                           arg_end++;
    3671           0 :                           bytes += count;
    3672             : #  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
    3673             :                           characters += mbsnlen (cbuf, count);
    3674             : #  endif
    3675           0 :                           precision -= count;
    3676             :                         }
    3677             :                     }
    3678             : #  if DCHAR_IS_TCHAR
    3679           0 :                   else if (has_width)
    3680             : #  else
    3681             :                   else
    3682             : #  endif
    3683             :                     {
    3684             :                       /* Use the entire string, and count the number of
    3685             :                          bytes.  */
    3686             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    3687             :                       mbstate_t state;
    3688           0 :                       mbszero (&state);
    3689             : #  endif
    3690           0 :                       arg_end = arg;
    3691           0 :                       bytes = 0;
    3692             : #  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
    3693             :                       characters = 0;
    3694             : #  endif
    3695             :                       for (;;)
    3696           0 :                         {
    3697             :                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    3698             :                           int count;
    3699             : 
    3700           0 :                           if (*arg_end == 0)
    3701             :                             /* Found the terminating null wide character.  */
    3702           0 :                             break;
    3703           0 :                           count = local_wcrtomb (cbuf, *arg_end, &state);
    3704           0 :                           if (count < 0)
    3705             :                             /* Cannot convert.  */
    3706           0 :                             goto fail_with_EILSEQ;
    3707           0 :                           arg_end++;
    3708           0 :                           bytes += count;
    3709             : #  if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
    3710             :                           characters += mbsnlen (cbuf, count);
    3711             : #  endif
    3712             :                         }
    3713             :                     }
    3714             : #  if DCHAR_IS_TCHAR
    3715             :                   else
    3716             :                     {
    3717             :                       /* Use the entire string.  */
    3718           0 :                       arg_end = arg + local_wcslen (arg);
    3719             :                       /* The number of bytes and characters doesn't matter,
    3720             :                          because !has_width and therefore width==0.  */
    3721           0 :                       bytes = 0;
    3722             : #   if ENABLE_UNISTDIO
    3723             :                       characters = 0;
    3724             : #   endif
    3725             :                     }
    3726             : #  endif
    3727             : 
    3728             : #  if !DCHAR_IS_TCHAR
    3729             :                   {
    3730             :                     TCHAR_T *tmpsrc;
    3731             : 
    3732             :                     /* Convert the string into a piece of temporary memory.  */
    3733             :                     tmpsrc = (TCHAR_T *) malloc (bytes * sizeof (TCHAR_T));
    3734             :                     if (tmpsrc == NULL)
    3735             :                       goto out_of_memory;
    3736             :                     {
    3737             :                       TCHAR_T *tmpptr = tmpsrc;
    3738             :                       size_t remaining;
    3739             : #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    3740             :                       mbstate_t state;
    3741             :                       mbszero (&state);
    3742             : #   endif
    3743             :                       for (remaining = bytes; remaining > 0; )
    3744             :                         {
    3745             :                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    3746             :                           int count;
    3747             : 
    3748             :                           if (*arg == 0)
    3749             :                             abort ();
    3750             :                           count = local_wcrtomb (cbuf, *arg, &state);
    3751             :                           if (count <= 0)
    3752             :                             /* Inconsistency.  */
    3753             :                             abort ();
    3754             :                           memcpy (tmpptr, cbuf, count);
    3755             :                           tmpptr += count;
    3756             :                           arg++;
    3757             :                           remaining -= count;
    3758             :                         }
    3759             :                       if (!(arg == arg_end))
    3760             :                         abort ();
    3761             :                     }
    3762             : 
    3763             :                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
    3764             :                     tmpdst =
    3765             :                       DCHAR_CONV_FROM_ENCODING (locale_charset (),
    3766             :                                                 iconveh_question_mark,
    3767             :                                                 tmpsrc, bytes,
    3768             :                                                 NULL,
    3769             :                                                 NULL, &tmpdst_len);
    3770             :                     if (tmpdst == NULL)
    3771             :                       {
    3772             :                         free (tmpsrc);
    3773             :                         goto fail_with_errno;
    3774             :                       }
    3775             :                     free (tmpsrc);
    3776             :                   }
    3777             : #  endif
    3778             : 
    3779           0 :                   if (has_width)
    3780             :                     {
    3781             : #  if ENABLE_UNISTDIO
    3782             :                       /* Outside POSIX, it's preferable to compare the width
    3783             :                          against the number of _characters_ of the converted
    3784             :                          value.  */
    3785             : #   if DCHAR_IS_TCHAR
    3786             :                       w = characters;
    3787             : #   else
    3788             :                       w = DCHAR_MBSNLEN (tmpdst, tmpdst_len);
    3789             : #   endif
    3790             : #  else
    3791             :                       /* The width is compared against the number of _bytes_
    3792             :                          of the converted value, says POSIX.  */
    3793           0 :                       w = bytes;
    3794             : #  endif
    3795             :                     }
    3796             :                   else
    3797             :                     /* w doesn't matter.  */
    3798           0 :                     w = 0;
    3799             : 
    3800           0 :                   if (w < width && !(flags & FLAG_LEFT))
    3801             :                     {
    3802           0 :                       size_t n = width - w;
    3803             : #  if DCHAR_IS_TCHAR
    3804           0 :                       ENSURE_ALLOCATION (xsum (length, n));
    3805             : #  else
    3806             :                       ENSURE_ALLOCATION_ELSE (xsum (length, n),
    3807             :                         { free (tmpdst); goto out_of_memory; });
    3808             : #  endif
    3809           0 :                       DCHAR_SET (result + length, ' ', n);
    3810           0 :                       length += n;
    3811             :                     }
    3812             : 
    3813             : #  if DCHAR_IS_TCHAR
    3814           0 :                   if (has_precision || has_width)
    3815           0 :                     {
    3816             :                       /* We know the number of bytes in advance.  */
    3817             :                       size_t remaining;
    3818             : #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    3819             :                       mbstate_t state;
    3820           0 :                       mbszero (&state);
    3821             : #   endif
    3822           0 :                       ENSURE_ALLOCATION (xsum (length, bytes));
    3823           0 :                       for (remaining = bytes; remaining > 0; )
    3824             :                         {
    3825             :                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    3826             :                           int count;
    3827             : 
    3828           0 :                           if (*arg == 0)
    3829           0 :                             abort ();
    3830           0 :                           count = local_wcrtomb (cbuf, *arg, &state);
    3831           0 :                           if (count <= 0)
    3832             :                             /* Inconsistency.  */
    3833           0 :                             abort ();
    3834           0 :                           memcpy (result + length, cbuf, count);
    3835           0 :                           length += count;
    3836           0 :                           arg++;
    3837           0 :                           remaining -= count;
    3838             :                         }
    3839           0 :                       if (!(arg == arg_end))
    3840           0 :                         abort ();
    3841             :                     }
    3842             :                   else
    3843             :                     {
    3844             : #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    3845             :                       mbstate_t state;
    3846           0 :                       mbszero (&state);
    3847             : #   endif
    3848           0 :                       while (arg < arg_end)
    3849             :                         {
    3850             :                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    3851             :                           int count;
    3852             : 
    3853           0 :                           if (*arg == 0)
    3854           0 :                             abort ();
    3855           0 :                           count = local_wcrtomb (cbuf, *arg, &state);
    3856           0 :                           if (count <= 0)
    3857             :                             /* Cannot convert.  */
    3858           0 :                             goto fail_with_EILSEQ;
    3859           0 :                           ENSURE_ALLOCATION (xsum (length, count));
    3860           0 :                           memcpy (result + length, cbuf, count);
    3861           0 :                           length += count;
    3862           0 :                           arg++;
    3863             :                         }
    3864             :                     }
    3865             : #  else
    3866             :                   ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
    3867             :                     { free (tmpdst); goto out_of_memory; });
    3868             :                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
    3869             :                   free (tmpdst);
    3870             :                   length += tmpdst_len;
    3871             : #  endif
    3872             : 
    3873           0 :                   if (w < width && (flags & FLAG_LEFT))
    3874             :                     {
    3875           0 :                       size_t n = width - w;
    3876           0 :                       ENSURE_ALLOCATION (xsum (length, n));
    3877           0 :                       DCHAR_SET (result + length, ' ', n);
    3878           0 :                       length += n;
    3879             :                     }
    3880             :                 }
    3881             : # endif
    3882             :               }
    3883             : #endif
    3884             : #if (NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION
    3885             :             else if (dp->conversion == 'c'
    3886             :                      && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR)
    3887             :               {
    3888             :                 /* Implement the 'lc' directive ourselves, in order to provide
    3889             :                    a correct behaviour for the null wint_t argument and/or the
    3890             :                    fallback that avoids EILSEQ.  */
    3891             :                 int flags = dp->flags;
    3892             :                 int has_width;
    3893             :                 size_t width;
    3894             : 
    3895             :                 has_width = 0;
    3896             :                 width = 0;
    3897             :                 if (dp->width_start != dp->width_end)
    3898             :                   {
    3899             :                     if (dp->width_arg_index != ARG_NONE)
    3900             :                       {
    3901             :                         int arg;
    3902             : 
    3903             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    3904             :                           abort ();
    3905             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    3906             :                         width = arg;
    3907             :                         if (arg < 0)
    3908             :                           {
    3909             :                             /* "A negative field width is taken as a '-' flag
    3910             :                                 followed by a positive field width."  */
    3911             :                             flags |= FLAG_LEFT;
    3912             :                             width = -width;
    3913             :                           }
    3914             :                       }
    3915             :                     else
    3916             :                       {
    3917             :                         const FCHAR_T *digitp = dp->width_start;
    3918             : 
    3919             :                         do
    3920             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    3921             :                         while (digitp != dp->width_end);
    3922             :                       }
    3923             :                     if (width > (size_t) INT_MAX)
    3924             :                       goto overflow;
    3925             :                     has_width = 1;
    3926             :                   }
    3927             : 
    3928             :                 /* %lc in vasnprintf.  See the specification of fprintf.  */
    3929             :                 {
    3930             :                   wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
    3931             :                   size_t bytes;
    3932             : # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
    3933             :                   size_t characters;
    3934             : # endif
    3935             : # if !DCHAR_IS_TCHAR
    3936             :                   /* This code assumes that TCHAR_T is 'char'.  */
    3937             :                   static_assert (sizeof (TCHAR_T) == 1);
    3938             :                   DCHAR_T *tmpdst;
    3939             :                   size_t tmpdst_len;
    3940             : # endif
    3941             :                   size_t w;
    3942             : 
    3943             : # if DCHAR_IS_TCHAR
    3944             :                   if (has_width)
    3945             : # endif
    3946             :                     {
    3947             :                       /* Count the number of bytes.  */
    3948             :                       char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    3949             :                       int count;
    3950             : # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    3951             :                       mbstate_t state;
    3952             :                       mbszero (&state);
    3953             : # endif
    3954             : 
    3955             :                       count = local_wcrtomb (cbuf, arg, &state);
    3956             :                       if (count < 0)
    3957             :                         /* Cannot convert.  */
    3958             :                         goto fail_with_EILSEQ;
    3959             :                       bytes = count;
    3960             : # if ENABLE_UNISTDIO && DCHAR_IS_TCHAR
    3961             :                       characters = mbsnlen (cbuf, count);
    3962             : # endif
    3963             :                     }
    3964             : # if DCHAR_IS_TCHAR
    3965             :                   else
    3966             :                     {
    3967             :                       /* The number of bytes and characters doesn't matter,
    3968             :                          because !has_width and therefore width==0.  */
    3969             :                       bytes = 0;
    3970             : #  if ENABLE_UNISTDIO
    3971             :                       characters = 0;
    3972             : #  endif
    3973             :                     }
    3974             : # endif
    3975             : 
    3976             : # if !DCHAR_IS_TCHAR
    3977             :                   {
    3978             :                     TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64.  */
    3979             : 
    3980             :                     /* Convert the string into a piece of temporary memory.  */
    3981             :                     if (bytes > 0)
    3982             :                       {
    3983             :                         char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    3984             :                         int count;
    3985             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    3986             :                         mbstate_t state;
    3987             :                         mbszero (&state);
    3988             : #  endif
    3989             : 
    3990             :                         count = local_wcrtomb (cbuf, arg, &state);
    3991             :                         if (count <= 0)
    3992             :                           /* Inconsistency.  */
    3993             :                           abort ();
    3994             :                         memcpy (tmpsrc, cbuf, count);
    3995             :                       }
    3996             : 
    3997             :                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
    3998             :                     tmpdst =
    3999             :                       DCHAR_CONV_FROM_ENCODING (locale_charset (),
    4000             :                                                 iconveh_question_mark,
    4001             :                                                 tmpsrc, bytes,
    4002             :                                                 NULL,
    4003             :                                                 NULL, &tmpdst_len);
    4004             :                     if (tmpdst == NULL)
    4005             :                       goto fail_with_errno;
    4006             :                   }
    4007             : # endif
    4008             : 
    4009             :                   if (has_width)
    4010             :                     {
    4011             : # if ENABLE_UNISTDIO
    4012             :                       /* Outside POSIX, it's preferable to compare the width
    4013             :                          against the number of _characters_ of the converted
    4014             :                          value.  */
    4015             : #  if DCHAR_IS_TCHAR
    4016             :                       w = characters;
    4017             : #  else
    4018             :                       w = DCHAR_MBSNLEN (tmpdst, tmpdst_len);
    4019             : #  endif
    4020             : # else
    4021             :                       /* The width is compared against the number of _bytes_
    4022             :                          of the converted value, says POSIX.  */
    4023             :                       w = bytes;
    4024             : # endif
    4025             :                     }
    4026             :                   else
    4027             :                     /* w doesn't matter.  */
    4028             :                     w = 0;
    4029             : 
    4030             :                   if (w < width && !(flags & FLAG_LEFT))
    4031             :                     {
    4032             :                       size_t n = width - w;
    4033             : #  if DCHAR_IS_TCHAR
    4034             :                       ENSURE_ALLOCATION (xsum (length, n));
    4035             : #  else
    4036             :                       ENSURE_ALLOCATION_ELSE (xsum (length, n),
    4037             :                         { free (tmpdst); goto out_of_memory; });
    4038             : #  endif
    4039             :                       DCHAR_SET (result + length, ' ', n);
    4040             :                       length += n;
    4041             :                     }
    4042             : 
    4043             : # if DCHAR_IS_TCHAR
    4044             :                   if (has_width)
    4045             :                     {
    4046             :                       /* We know the number of bytes in advance.  */
    4047             :                       ENSURE_ALLOCATION (xsum (length, bytes));
    4048             :                       if (bytes > 0)
    4049             :                         {
    4050             :                           int count;
    4051             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    4052             :                           mbstate_t state;
    4053             :                           mbszero (&state);
    4054             : #  endif
    4055             : 
    4056             :                           count = local_wcrtomb (result + length, arg, &state);
    4057             :                           if (count <= 0)
    4058             :                             /* Inconsistency.  */
    4059             :                             abort ();
    4060             :                           length += count;
    4061             :                         }
    4062             :                     }
    4063             :                   else
    4064             :                     {
    4065             :                       char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    4066             :                       int count;
    4067             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    4068             :                       mbstate_t state;
    4069             :                       mbszero (&state);
    4070             : #  endif
    4071             : 
    4072             :                       count = local_wcrtomb (cbuf, arg, &state);
    4073             :                       if (count < 0)
    4074             :                         /* Cannot convert.  */
    4075             :                         goto fail_with_EILSEQ;
    4076             :                       ENSURE_ALLOCATION (xsum (length, count));
    4077             :                       memcpy (result + length, cbuf, count);
    4078             :                       length += count;
    4079             :                     }
    4080             : # else
    4081             :                   ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
    4082             :                     { free (tmpdst); goto out_of_memory; });
    4083             :                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
    4084             :                   free (tmpdst);
    4085             :                   length += tmpdst_len;
    4086             : # endif
    4087             : 
    4088             :                   if (w < width && (flags & FLAG_LEFT))
    4089             :                     {
    4090             :                       size_t n = width - w;
    4091             :                       ENSURE_ALLOCATION (xsum (length, n));
    4092             :                       DCHAR_SET (result + length, ' ', n);
    4093             :                       length += n;
    4094             :                     }
    4095             :                 }
    4096             :               }
    4097             : #endif
    4098             : #if NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION
    4099             :             else if (dp->conversion == 'c'
    4100             :                      && a.arg[dp->arg_index].type != TYPE_WIDE_CHAR)
    4101             :               {
    4102             :                 /* Implement the 'c' directive ourselves, in order to avoid
    4103             :                    EILSEQ in the "C" locale.  */
    4104             :                 int flags = dp->flags;
    4105             :                 size_t width;
    4106             : 
    4107             :                 width = 0;
    4108             :                 if (dp->width_start != dp->width_end)
    4109             :                   {
    4110             :                     if (dp->width_arg_index != ARG_NONE)
    4111             :                       {
    4112             :                         int arg;
    4113             : 
    4114             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    4115             :                           abort ();
    4116             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    4117             :                         width = arg;
    4118             :                         if (arg < 0)
    4119             :                           {
    4120             :                             /* "A negative field width is taken as a '-' flag
    4121             :                                 followed by a positive field width."  */
    4122             :                             flags |= FLAG_LEFT;
    4123             :                             width = -width;
    4124             :                           }
    4125             :                       }
    4126             :                     else
    4127             :                       {
    4128             :                         const FCHAR_T *digitp = dp->width_start;
    4129             : 
    4130             :                         do
    4131             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    4132             :                         while (digitp != dp->width_end);
    4133             :                       }
    4134             :                     if (width > (size_t) INT_MAX)
    4135             :                       goto overflow;
    4136             :                   }
    4137             : 
    4138             :                 /* %c in vasnwprintf.  See the specification of fwprintf.  */
    4139             :                 {
    4140             :                   char arg = (char) a.arg[dp->arg_index].a.a_char;
    4141             :                   mbstate_t state;
    4142             :                   wchar_t wc;
    4143             : 
    4144             :                   mbszero (&state);
    4145             :                   int count = mbrtowc (&wc, &arg, 1, &state);
    4146             :                   if (count < 0)
    4147             :                     /* Invalid or incomplete multibyte character.  */
    4148             :                     goto fail_with_EILSEQ;
    4149             : 
    4150             :                   {
    4151             :                     size_t total = (1 < width ? width : 1);
    4152             :                     ENSURE_ALLOCATION (xsum (length, total));
    4153             : 
    4154             :                     if (1 < width && !(flags & FLAG_LEFT))
    4155             :                       {
    4156             :                         size_t n = width - 1;
    4157             :                         DCHAR_SET (result + length, ' ', n);
    4158             :                         length += n;
    4159             :                       }
    4160             : 
    4161             :                     result[length++] = wc;
    4162             : 
    4163             :                     if (1 < width && (flags & FLAG_LEFT))
    4164             :                       {
    4165             :                         size_t n = width - 1;
    4166             :                         DCHAR_SET (result + length, ' ', n);
    4167             :                         length += n;
    4168             :                       }
    4169             :                   }
    4170             :                 }
    4171             :               }
    4172             : #endif
    4173             : #if NEED_PRINTF_DIRECTIVE_B || NEED_PRINTF_DIRECTIVE_UPPERCASE_B
    4174       14534 :             else if (0
    4175             : # if NEED_PRINTF_DIRECTIVE_B
    4176       14534 :                      || (dp->conversion == 'b')
    4177             : # endif
    4178             : # if NEED_PRINTF_DIRECTIVE_UPPERCASE_B
    4179             :                      || (dp->conversion == 'B')
    4180             : # endif
    4181             :                     )
    4182             :               {
    4183           0 :                 arg_type type = a.arg[dp->arg_index].type;
    4184           0 :                 int flags = dp->flags;
    4185             :                 int has_width;
    4186             :                 size_t width;
    4187             :                 int has_precision;
    4188             :                 size_t precision;
    4189             :                 size_t tmp_length;
    4190             :                 size_t count;
    4191             :                 DCHAR_T tmpbuf[700];
    4192             :                 DCHAR_T *tmp;
    4193             :                 DCHAR_T *tmp_end;
    4194             :                 DCHAR_T *tmp_start;
    4195             :                 DCHAR_T *pad_ptr;
    4196             :                 DCHAR_T *p;
    4197             : 
    4198           0 :                 has_width = 0;
    4199           0 :                 width = 0;
    4200           0 :                 if (dp->width_start != dp->width_end)
    4201             :                   {
    4202           0 :                     if (dp->width_arg_index != ARG_NONE)
    4203             :                       {
    4204             :                         int arg;
    4205             : 
    4206           0 :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    4207           0 :                           abort ();
    4208           0 :                         arg = a.arg[dp->width_arg_index].a.a_int;
    4209           0 :                         width = arg;
    4210           0 :                         if (arg < 0)
    4211             :                           {
    4212             :                             /* "A negative field width is taken as a '-' flag
    4213             :                                 followed by a positive field width."  */
    4214           0 :                             flags |= FLAG_LEFT;
    4215           0 :                             width = -width;
    4216             :                           }
    4217             :                       }
    4218             :                     else
    4219             :                       {
    4220           0 :                         const FCHAR_T *digitp = dp->width_start;
    4221             : 
    4222             :                         do
    4223           0 :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    4224           0 :                         while (digitp != dp->width_end);
    4225             :                       }
    4226           0 :                     if (width > (size_t) INT_MAX)
    4227           0 :                       goto overflow;
    4228           0 :                     has_width = 1;
    4229             :                   }
    4230             : 
    4231           0 :                 has_precision = 0;
    4232           0 :                 precision = 1;
    4233           0 :                 if (dp->precision_start != dp->precision_end)
    4234             :                   {
    4235           0 :                     if (dp->precision_arg_index != ARG_NONE)
    4236             :                       {
    4237             :                         int arg;
    4238             : 
    4239           0 :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    4240           0 :                           abort ();
    4241           0 :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    4242             :                         /* "A negative precision is taken as if the precision
    4243             :                             were omitted."  */
    4244           0 :                         if (arg >= 0)
    4245             :                           {
    4246           0 :                             precision = arg;
    4247           0 :                             has_precision = 1;
    4248             :                           }
    4249             :                       }
    4250             :                     else
    4251             :                       {
    4252           0 :                         const FCHAR_T *digitp = dp->precision_start + 1;
    4253             : 
    4254           0 :                         precision = 0;
    4255           0 :                         while (digitp != dp->precision_end)
    4256           0 :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    4257           0 :                         has_precision = 1;
    4258             :                       }
    4259             :                   }
    4260             : 
    4261             :                 /* Allocate a temporary buffer of sufficient size.  */
    4262           0 :                 switch (type)
    4263             :                   {
    4264           0 :                   default:
    4265           0 :                     tmp_length =
    4266             :                       (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
    4267             :                       + 1; /* turn floor into ceil */
    4268           0 :                     break;
    4269           0 :                   case TYPE_ULONGINT:
    4270           0 :                     tmp_length =
    4271             :                       (unsigned int) (sizeof (unsigned long int) * CHAR_BIT)
    4272             :                       + 1; /* turn floor into ceil */
    4273           0 :                     break;
    4274           0 :                   case TYPE_ULONGLONGINT:
    4275           0 :                     tmp_length =
    4276             :                       (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT)
    4277             :                       + 1; /* turn floor into ceil */
    4278           0 :                     break;
    4279           0 :                   case TYPE_UINT8_T:
    4280           0 :                     tmp_length =
    4281             :                       (unsigned int) (sizeof (uint8_t) * CHAR_BIT)
    4282             :                       + 1; /* turn floor into ceil */
    4283           0 :                     break;
    4284           0 :                   case TYPE_UINT16_T:
    4285           0 :                     tmp_length =
    4286             :                       (unsigned int) (sizeof (uint16_t) * CHAR_BIT)
    4287             :                       + 1; /* turn floor into ceil */
    4288           0 :                     break;
    4289           0 :                   case TYPE_UINT32_T:
    4290           0 :                     tmp_length =
    4291             :                       (unsigned int) (sizeof (uint32_t) * CHAR_BIT)
    4292             :                       + 1; /* turn floor into ceil */
    4293           0 :                     break;
    4294           0 :                   case TYPE_UINT64_T:
    4295           0 :                     tmp_length =
    4296             :                       (unsigned int) (sizeof (uint64_t) * CHAR_BIT)
    4297             :                       + 1; /* turn floor into ceil */
    4298           0 :                     break;
    4299           0 :                   case TYPE_UINT_FAST8_T:
    4300           0 :                     tmp_length =
    4301             :                       (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT)
    4302             :                       + 1; /* turn floor into ceil */
    4303           0 :                     break;
    4304           0 :                   case TYPE_UINT_FAST16_T:
    4305           0 :                     tmp_length =
    4306             :                       (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT)
    4307             :                       + 1; /* turn floor into ceil */
    4308           0 :                     break;
    4309           0 :                   case TYPE_UINT_FAST32_T:
    4310           0 :                     tmp_length =
    4311             :                       (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT)
    4312             :                       + 1; /* turn floor into ceil */
    4313           0 :                     break;
    4314           0 :                   case TYPE_UINT_FAST64_T:
    4315           0 :                     tmp_length =
    4316             :                       (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT)
    4317             :                       + 1; /* turn floor into ceil */
    4318           0 :                     break;
    4319             :                   }
    4320           0 :                 if (tmp_length < precision)
    4321           0 :                   tmp_length = precision;
    4322             :                 /* Add 2, to account for a prefix from the alternate form.  */
    4323           0 :                 tmp_length = xsum (tmp_length, 2);
    4324             : 
    4325           0 :                 if (tmp_length < width)
    4326           0 :                   tmp_length = width;
    4327             : 
    4328           0 :                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
    4329           0 :                   tmp = tmpbuf;
    4330             :                 else
    4331             :                   {
    4332           0 :                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
    4333             : 
    4334           0 :                     if (size_overflow_p (tmp_memsize))
    4335             :                       /* Overflow, would lead to out of memory.  */
    4336           0 :                       goto out_of_memory;
    4337           0 :                     tmp = (DCHAR_T *) malloc (tmp_memsize);
    4338           0 :                     if (tmp == NULL)
    4339             :                       /* Out of memory.  */
    4340           0 :                       goto out_of_memory;
    4341             :                   }
    4342             : 
    4343           0 :                 tmp_end = tmp + tmp_length;
    4344             : 
    4345             :                 unsigned long long arg;
    4346           0 :                 switch (type)
    4347             :                   {
    4348           0 :                   case TYPE_UCHAR:
    4349           0 :                     arg = a.arg[dp->arg_index].a.a_uchar;
    4350           0 :                     break;
    4351           0 :                   case TYPE_USHORT:
    4352           0 :                     arg = a.arg[dp->arg_index].a.a_ushort;
    4353           0 :                     break;
    4354           0 :                   case TYPE_UINT:
    4355           0 :                     arg = a.arg[dp->arg_index].a.a_uint;
    4356           0 :                     break;
    4357           0 :                   case TYPE_ULONGINT:
    4358           0 :                     arg = a.arg[dp->arg_index].a.a_ulongint;
    4359           0 :                     break;
    4360           0 :                   case TYPE_ULONGLONGINT:
    4361           0 :                     arg = a.arg[dp->arg_index].a.a_ulonglongint;
    4362           0 :                     break;
    4363           0 :                   case TYPE_UINT8_T:
    4364           0 :                     arg = a.arg[dp->arg_index].a.a_uint8_t;
    4365           0 :                     break;
    4366           0 :                   case TYPE_UINT16_T:
    4367           0 :                     arg = a.arg[dp->arg_index].a.a_uint16_t;
    4368           0 :                     break;
    4369           0 :                   case TYPE_UINT32_T:
    4370           0 :                     arg = a.arg[dp->arg_index].a.a_uint32_t;
    4371           0 :                     break;
    4372           0 :                   case TYPE_UINT64_T:
    4373           0 :                     arg = a.arg[dp->arg_index].a.a_uint64_t;
    4374           0 :                     break;
    4375           0 :                   case TYPE_UINT_FAST8_T:
    4376           0 :                     arg = a.arg[dp->arg_index].a.a_uint_fast8_t;
    4377           0 :                     break;
    4378           0 :                   case TYPE_UINT_FAST16_T:
    4379           0 :                     arg = a.arg[dp->arg_index].a.a_uint_fast16_t;
    4380           0 :                     break;
    4381           0 :                   case TYPE_UINT_FAST32_T:
    4382           0 :                     arg = a.arg[dp->arg_index].a.a_uint_fast32_t;
    4383           0 :                     break;
    4384           0 :                   case TYPE_UINT_FAST64_T:
    4385           0 :                     arg = a.arg[dp->arg_index].a.a_uint_fast64_t;
    4386           0 :                     break;
    4387           0 :                   default:
    4388           0 :                     abort ();
    4389             :                   }
    4390           0 :                 int need_prefix = ((flags & FLAG_ALT) && arg != 0);
    4391             : 
    4392           0 :                 p = tmp_end;
    4393             :                 /* "The result of converting a zero value with a precision
    4394             :                    of zero is no characters."  */
    4395           0 :                 if (!(has_precision && precision == 0 && arg == 0))
    4396             :                   {
    4397             :                     do
    4398             :                       {
    4399           0 :                         *--p = '0' + (arg & 1);
    4400           0 :                         arg = arg >> 1;
    4401             :                       }
    4402           0 :                     while (arg != 0);
    4403             :                   }
    4404             : 
    4405           0 :                 if (has_precision)
    4406             :                   {
    4407           0 :                     DCHAR_T *digits_start = tmp_end - precision;
    4408           0 :                     while (p > digits_start)
    4409           0 :                       *--p = '0';
    4410             :                   }
    4411             : 
    4412           0 :                 pad_ptr = p;
    4413             : 
    4414           0 :                 if (need_prefix)
    4415             :                   {
    4416             : # if NEED_PRINTF_DIRECTIVE_B && !NEED_PRINTF_DIRECTIVE_UPPERCASE_B
    4417           0 :                     *--p = 'b';
    4418             : # elif NEED_PRINTF_DIRECTIVE_UPPERCASE_B && !NEED_PRINTF_DIRECTIVE_B
    4419             :                     *--p = 'B';
    4420             : # else
    4421             :                     *--p = dp->conversion;
    4422             : # endif
    4423           0 :                     *--p = '0';
    4424             :                   }
    4425           0 :                 tmp_start = p;
    4426             : 
    4427             :                 /* The generated string now extends from tmp_start to tmp_end,
    4428             :                    with the zero padding insertion point being at pad_ptr,
    4429             :                    tmp_start <= pad_ptr <= tmp_end.  */
    4430           0 :                 count = tmp_end - tmp_start;
    4431             : 
    4432           0 :                 if (count < width)
    4433             :                   {
    4434           0 :                     size_t pad = width - count;
    4435             : 
    4436           0 :                     if (flags & FLAG_LEFT)
    4437             :                       {
    4438             :                         /* Pad with spaces on the right.  */
    4439           0 :                         for (p = tmp_start; p < tmp_end; p++)
    4440           0 :                           *(p - pad) = *p;
    4441           0 :                         for (p = tmp_end - pad; p < tmp_end; p++)
    4442           0 :                           *p = ' ';
    4443             :                       }
    4444           0 :                     else if ((flags & FLAG_ZERO)
    4445             :                              /* Neither ISO C nor POSIX specify that the '0'
    4446             :                                 flag is ignored when a width and a precision
    4447             :                                 are both present.  But most implementations
    4448             :                                 do so.  */
    4449           0 :                              && !(has_width && has_precision))
    4450             :                       {
    4451             :                         /* Pad with zeroes.  */
    4452           0 :                         for (p = tmp_start; p < pad_ptr; p++)
    4453           0 :                           *(p - pad) = *p;
    4454           0 :                         for (p = pad_ptr - pad; p < pad_ptr; p++)
    4455           0 :                           *p = '0';
    4456             :                       }
    4457             :                     else
    4458             :                       {
    4459             :                         /* Pad with spaces on the left.  */
    4460           0 :                         for (p = tmp_start - pad; p < tmp_start; p++)
    4461           0 :                           *p = ' ';
    4462             :                       }
    4463             : 
    4464           0 :                     tmp_start = tmp_start - pad;
    4465             :                   }
    4466             : 
    4467           0 :                 count = tmp_end - tmp_start;
    4468             : 
    4469           0 :                 if (count > tmp_length)
    4470             :                   /* tmp_length was incorrectly calculated - fix the
    4471             :                      code above!  */
    4472           0 :                   abort ();
    4473             : 
    4474             :                 /* Make room for the result.  */
    4475           0 :                 if (count >= allocated - length)
    4476             :                   {
    4477           0 :                     size_t n = xsum (length, count);
    4478             : 
    4479           0 :                     ENSURE_ALLOCATION_ELSE (n,
    4480             :                       { if (tmp != tmpbuf) free (tmp); goto out_of_memory; });
    4481             :                   }
    4482             : 
    4483             :                 /* Append the result.  */
    4484           0 :                 memcpy (result + length, tmp_start, count * sizeof (DCHAR_T));
    4485           0 :                 if (tmp != tmpbuf)
    4486           0 :                   free (tmp);
    4487           0 :                 length += count;
    4488             :               }
    4489             : #endif
    4490             : #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
    4491             :             else if ((dp->conversion == 'a' || dp->conversion == 'A')
    4492             : # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
    4493             :                      && (0
    4494             : #  if NEED_PRINTF_DOUBLE
    4495             :                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
    4496             : #  endif
    4497             : #  if NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
    4498             :                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
    4499             : #  endif
    4500             :                         )
    4501             : # endif
    4502             :                     )
    4503             :               {
    4504             :                 arg_type type = a.arg[dp->arg_index].type;
    4505             :                 int flags = dp->flags;
    4506             :                 size_t width;
    4507             :                 int has_precision;
    4508             :                 size_t precision;
    4509             :                 size_t tmp_length;
    4510             :                 size_t count;
    4511             :                 DCHAR_T tmpbuf[700];
    4512             :                 DCHAR_T *tmp;
    4513             :                 DCHAR_T *pad_ptr;
    4514             :                 DCHAR_T *p;
    4515             : 
    4516             :                 width = 0;
    4517             :                 if (dp->width_start != dp->width_end)
    4518             :                   {
    4519             :                     if (dp->width_arg_index != ARG_NONE)
    4520             :                       {
    4521             :                         int arg;
    4522             : 
    4523             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    4524             :                           abort ();
    4525             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    4526             :                         width = arg;
    4527             :                         if (arg < 0)
    4528             :                           {
    4529             :                             /* "A negative field width is taken as a '-' flag
    4530             :                                 followed by a positive field width."  */
    4531             :                             flags |= FLAG_LEFT;
    4532             :                             width = -width;
    4533             :                           }
    4534             :                       }
    4535             :                     else
    4536             :                       {
    4537             :                         const FCHAR_T *digitp = dp->width_start;
    4538             : 
    4539             :                         do
    4540             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    4541             :                         while (digitp != dp->width_end);
    4542             :                       }
    4543             :                     if (width > (size_t) INT_MAX)
    4544             :                       goto overflow;
    4545             :                   }
    4546             : 
    4547             :                 has_precision = 0;
    4548             :                 precision = 0;
    4549             :                 if (dp->precision_start != dp->precision_end)
    4550             :                   {
    4551             :                     if (dp->precision_arg_index != ARG_NONE)
    4552             :                       {
    4553             :                         int arg;
    4554             : 
    4555             :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    4556             :                           abort ();
    4557             :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    4558             :                         /* "A negative precision is taken as if the precision
    4559             :                             were omitted."  */
    4560             :                         if (arg >= 0)
    4561             :                           {
    4562             :                             precision = arg;
    4563             :                             has_precision = 1;
    4564             :                           }
    4565             :                       }
    4566             :                     else
    4567             :                       {
    4568             :                         const FCHAR_T *digitp = dp->precision_start + 1;
    4569             : 
    4570             :                         precision = 0;
    4571             :                         while (digitp != dp->precision_end)
    4572             :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    4573             :                         has_precision = 1;
    4574             :                       }
    4575             :                   }
    4576             : 
    4577             :                 /* Allocate a temporary buffer of sufficient size.  */
    4578             :                 if (type == TYPE_LONGDOUBLE)
    4579             :                   tmp_length =
    4580             :                     (unsigned int) ((LDBL_DIG + 1)
    4581             :                                     * 0.831 /* decimal -> hexadecimal */
    4582             :                                    )
    4583             :                     + 1; /* turn floor into ceil */
    4584             :                 else
    4585             :                   tmp_length =
    4586             :                     (unsigned int) ((DBL_DIG + 1)
    4587             :                                     * 0.831 /* decimal -> hexadecimal */
    4588             :                                    )
    4589             :                     + 1; /* turn floor into ceil */
    4590             :                 if (tmp_length < precision)
    4591             :                   tmp_length = precision;
    4592             :                 /* Account for sign, decimal point etc. */
    4593             :                 tmp_length = xsum (tmp_length, 12);
    4594             : 
    4595             :                 if (tmp_length < width)
    4596             :                   tmp_length = width;
    4597             : 
    4598             :                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
    4599             : 
    4600             :                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
    4601             :                   tmp = tmpbuf;
    4602             :                 else
    4603             :                   {
    4604             :                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
    4605             : 
    4606             :                     if (size_overflow_p (tmp_memsize))
    4607             :                       /* Overflow, would lead to out of memory.  */
    4608             :                       goto out_of_memory;
    4609             :                     tmp = (DCHAR_T *) malloc (tmp_memsize);
    4610             :                     if (tmp == NULL)
    4611             :                       /* Out of memory.  */
    4612             :                       goto out_of_memory;
    4613             :                   }
    4614             : 
    4615             :                 pad_ptr = NULL;
    4616             :                 p = tmp;
    4617             :                 if (type == TYPE_LONGDOUBLE)
    4618             :                   {
    4619             : # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
    4620             :                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
    4621             : 
    4622             :                     if (isnanl (arg))
    4623             :                       {
    4624             :                         if (dp->conversion == 'A')
    4625             :                           {
    4626             :                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
    4627             :                           }
    4628             :                         else
    4629             :                           {
    4630             :                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
    4631             :                           }
    4632             :                       }
    4633             :                     else
    4634             :                       {
    4635             :                         int sign = 0;
    4636             :                         DECL_LONG_DOUBLE_ROUNDING
    4637             : 
    4638             :                         BEGIN_LONG_DOUBLE_ROUNDING ();
    4639             : 
    4640             :                         if (signbit (arg)) /* arg < 0.0L or negative zero */
    4641             :                           {
    4642             :                             sign = -1;
    4643             :                             arg = -arg;
    4644             :                           }
    4645             : 
    4646             :                         if (sign < 0)
    4647             :                           *p++ = '-';
    4648             :                         else if (flags & FLAG_SHOWSIGN)
    4649             :                           *p++ = '+';
    4650             :                         else if (flags & FLAG_SPACE)
    4651             :                           *p++ = ' ';
    4652             : 
    4653             :                         if (arg > 0.0L && arg + arg == arg)
    4654             :                           {
    4655             :                             if (dp->conversion == 'A')
    4656             :                               {
    4657             :                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
    4658             :                               }
    4659             :                             else
    4660             :                               {
    4661             :                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
    4662             :                               }
    4663             :                           }
    4664             :                         else
    4665             :                           {
    4666             :                             int exponent;
    4667             :                             long double mantissa;
    4668             : 
    4669             :                             if (arg > 0.0L)
    4670             :                               mantissa = printf_frexpl (arg, &exponent);
    4671             :                             else
    4672             :                               {
    4673             :                                 exponent = 0;
    4674             :                                 mantissa = 0.0L;
    4675             :                               }
    4676             : 
    4677             :                             if (has_precision
    4678             :                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
    4679             :                               {
    4680             :                                 /* Round the mantissa.  */
    4681             :                                 long double tail = mantissa;
    4682             :                                 size_t q;
    4683             : 
    4684             :                                 for (q = precision; ; q--)
    4685             :                                   {
    4686             :                                     int digit = (int) tail;
    4687             :                                     tail -= digit;
    4688             :                                     if (q == 0)
    4689             :                                       {
    4690             :                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
    4691             :                                           tail = 1 - tail;
    4692             :                                         else
    4693             :                                           tail = - tail;
    4694             :                                         break;
    4695             :                                       }
    4696             :                                     tail *= 16.0L;
    4697             :                                   }
    4698             :                                 if (tail != 0.0L)
    4699             :                                   for (q = precision; q > 0; q--)
    4700             :                                     tail *= 0.0625L;
    4701             :                                 mantissa += tail;
    4702             :                               }
    4703             : 
    4704             :                             *p++ = '0';
    4705             :                             *p++ = dp->conversion - 'A' + 'X';
    4706             :                             pad_ptr = p;
    4707             :                             {
    4708             :                               int digit;
    4709             : 
    4710             :                               digit = (int) mantissa;
    4711             :                               mantissa -= digit;
    4712             :                               *p++ = '0' + digit;
    4713             :                               if ((flags & FLAG_ALT)
    4714             :                                   || mantissa > 0.0L || precision > 0)
    4715             :                                 {
    4716             :                                   *p++ = decimal_point_char ();
    4717             :                                   /* This loop terminates because we assume
    4718             :                                      that FLT_RADIX is a power of 2.  */
    4719             :                                   while (mantissa > 0.0L)
    4720             :                                     {
    4721             :                                       mantissa *= 16.0L;
    4722             :                                       digit = (int) mantissa;
    4723             :                                       mantissa -= digit;
    4724             :                                       *p++ = digit
    4725             :                                              + (digit < 10
    4726             :                                                 ? '0'
    4727             :                                                 : dp->conversion - 10);
    4728             :                                       if (precision > 0)
    4729             :                                         precision--;
    4730             :                                     }
    4731             :                                   while (precision > 0)
    4732             :                                     {
    4733             :                                       *p++ = '0';
    4734             :                                       precision--;
    4735             :                                     }
    4736             :                                 }
    4737             :                               }
    4738             :                               *p++ = dp->conversion - 'A' + 'P';
    4739             : #  if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
    4740             :                               {
    4741             :                                 static const wchar_t decimal_format[] =
    4742             :                                   { '%', '+', 'd', '\0' };
    4743             :                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
    4744             :                               }
    4745             :                               while (*p != '\0')
    4746             :                                 p++;
    4747             : #  else
    4748             :                               if (sizeof (DCHAR_T) == 1)
    4749             :                                 {
    4750             :                                   sprintf ((char *) p, "%+d", exponent);
    4751             :                                   while (*p != '\0')
    4752             :                                     p++;
    4753             :                                 }
    4754             :                               else
    4755             :                                 {
    4756             :                                   char expbuf[6 + 1];
    4757             :                                   const char *ep;
    4758             :                                   sprintf (expbuf, "%+d", exponent);
    4759             :                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    4760             :                                     p++;
    4761             :                                 }
    4762             : #  endif
    4763             :                           }
    4764             : 
    4765             :                         END_LONG_DOUBLE_ROUNDING ();
    4766             :                       }
    4767             : # else
    4768             :                     abort ();
    4769             : # endif
    4770             :                   }
    4771             :                 else
    4772             :                   {
    4773             : # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
    4774             :                     double arg = a.arg[dp->arg_index].a.a_double;
    4775             : 
    4776             :                     if (isnand (arg))
    4777             :                       {
    4778             :                         if (dp->conversion == 'A')
    4779             :                           {
    4780             :                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
    4781             :                           }
    4782             :                         else
    4783             :                           {
    4784             :                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
    4785             :                           }
    4786             :                       }
    4787             :                     else
    4788             :                       {
    4789             :                         int sign = 0;
    4790             : 
    4791             :                         if (signbit (arg)) /* arg < 0.0 or negative zero */
    4792             :                           {
    4793             :                             sign = -1;
    4794             :                             arg = -arg;
    4795             :                           }
    4796             : 
    4797             :                         if (sign < 0)
    4798             :                           *p++ = '-';
    4799             :                         else if (flags & FLAG_SHOWSIGN)
    4800             :                           *p++ = '+';
    4801             :                         else if (flags & FLAG_SPACE)
    4802             :                           *p++ = ' ';
    4803             : 
    4804             :                         if (arg > 0.0 && arg + arg == arg)
    4805             :                           {
    4806             :                             if (dp->conversion == 'A')
    4807             :                               {
    4808             :                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
    4809             :                               }
    4810             :                             else
    4811             :                               {
    4812             :                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
    4813             :                               }
    4814             :                           }
    4815             :                         else
    4816             :                           {
    4817             :                             int exponent;
    4818             :                             double mantissa;
    4819             : 
    4820             :                             if (arg > 0.0)
    4821             :                               mantissa = printf_frexp (arg, &exponent);
    4822             :                             else
    4823             :                               {
    4824             :                                 exponent = 0;
    4825             :                                 mantissa = 0.0;
    4826             :                               }
    4827             : 
    4828             :                             if (has_precision
    4829             :                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
    4830             :                               {
    4831             :                                 /* Round the mantissa.  */
    4832             :                                 double tail = mantissa;
    4833             :                                 size_t q;
    4834             : 
    4835             :                                 for (q = precision; ; q--)
    4836             :                                   {
    4837             :                                     int digit = (int) tail;
    4838             :                                     tail -= digit;
    4839             :                                     if (q == 0)
    4840             :                                       {
    4841             :                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
    4842             :                                           tail = 1 - tail;
    4843             :                                         else
    4844             :                                           tail = - tail;
    4845             :                                         break;
    4846             :                                       }
    4847             :                                     tail *= 16.0;
    4848             :                                   }
    4849             :                                 if (tail != 0.0)
    4850             :                                   for (q = precision; q > 0; q--)
    4851             :                                     tail *= 0.0625;
    4852             :                                 mantissa += tail;
    4853             :                               }
    4854             : 
    4855             :                             *p++ = '0';
    4856             :                             *p++ = dp->conversion - 'A' + 'X';
    4857             :                             pad_ptr = p;
    4858             :                             {
    4859             :                               int digit;
    4860             : 
    4861             :                               digit = (int) mantissa;
    4862             :                               mantissa -= digit;
    4863             :                               *p++ = '0' + digit;
    4864             :                               if ((flags & FLAG_ALT)
    4865             :                                   || mantissa > 0.0 || precision > 0)
    4866             :                                 {
    4867             :                                   *p++ = decimal_point_char ();
    4868             :                                   /* This loop terminates because we assume
    4869             :                                      that FLT_RADIX is a power of 2.  */
    4870             :                                   while (mantissa > 0.0)
    4871             :                                     {
    4872             :                                       mantissa *= 16.0;
    4873             :                                       digit = (int) mantissa;
    4874             :                                       mantissa -= digit;
    4875             :                                       *p++ = digit
    4876             :                                              + (digit < 10
    4877             :                                                 ? '0'
    4878             :                                                 : dp->conversion - 10);
    4879             :                                       if (precision > 0)
    4880             :                                         precision--;
    4881             :                                     }
    4882             :                                   while (precision > 0)
    4883             :                                     {
    4884             :                                       *p++ = '0';
    4885             :                                       precision--;
    4886             :                                     }
    4887             :                                 }
    4888             :                               }
    4889             :                               *p++ = dp->conversion - 'A' + 'P';
    4890             : #  if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
    4891             :                               {
    4892             :                                 static const wchar_t decimal_format[] =
    4893             :                                   { '%', '+', 'd', '\0' };
    4894             :                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
    4895             :                               }
    4896             :                               while (*p != '\0')
    4897             :                                 p++;
    4898             : #  else
    4899             :                               if (sizeof (DCHAR_T) == 1)
    4900             :                                 {
    4901             :                                   sprintf ((char *) p, "%+d", exponent);
    4902             :                                   while (*p != '\0')
    4903             :                                     p++;
    4904             :                                 }
    4905             :                               else
    4906             :                                 {
    4907             :                                   char expbuf[6 + 1];
    4908             :                                   const char *ep;
    4909             :                                   sprintf (expbuf, "%+d", exponent);
    4910             :                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    4911             :                                     p++;
    4912             :                                 }
    4913             : #  endif
    4914             :                           }
    4915             :                       }
    4916             : # else
    4917             :                     abort ();
    4918             : # endif
    4919             :                   }
    4920             : 
    4921             :                 /* The generated string now extends from tmp to p, with the
    4922             :                    zero padding insertion point being at pad_ptr.  */
    4923             :                 count = p - tmp;
    4924             : 
    4925             :                 if (count < width)
    4926             :                   {
    4927             :                     size_t pad = width - count;
    4928             :                     DCHAR_T *end = p + pad;
    4929             : 
    4930             :                     if (flags & FLAG_LEFT)
    4931             :                       {
    4932             :                         /* Pad with spaces on the right.  */
    4933             :                         for (; pad > 0; pad--)
    4934             :                           *p++ = ' ';
    4935             :                       }
    4936             :                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
    4937             :                       {
    4938             :                         /* Pad with zeroes.  */
    4939             :                         DCHAR_T *q = end;
    4940             : 
    4941             :                         while (p > pad_ptr)
    4942             :                           *--q = *--p;
    4943             :                         for (; pad > 0; pad--)
    4944             :                           *p++ = '0';
    4945             :                       }
    4946             :                     else
    4947             :                       {
    4948             :                         /* Pad with spaces on the left.  */
    4949             :                         DCHAR_T *q = end;
    4950             : 
    4951             :                         while (p > tmp)
    4952             :                           *--q = *--p;
    4953             :                         for (; pad > 0; pad--)
    4954             :                           *p++ = ' ';
    4955             :                       }
    4956             : 
    4957             :                     p = end;
    4958             :                   }
    4959             : 
    4960             :                 count = p - tmp;
    4961             : 
    4962             :                 if (count >= tmp_length)
    4963             :                   /* tmp_length was incorrectly calculated - fix the
    4964             :                      code above!  */
    4965             :                   abort ();
    4966             : 
    4967             :                 /* Make room for the result.  */
    4968             :                 if (count >= allocated - length)
    4969             :                   {
    4970             :                     size_t n = xsum (length, count);
    4971             : 
    4972             :                     ENSURE_ALLOCATION_ELSE (n,
    4973             :                       { if (tmp != tmpbuf) free (tmp); goto out_of_memory; });
    4974             :                   }
    4975             : 
    4976             :                 /* Append the result.  */
    4977             :                 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
    4978             :                 if (tmp != tmpbuf)
    4979             :                   free (tmp);
    4980             :                 length += count;
    4981             :               }
    4982             : #endif
    4983             : #if NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE
    4984             :             else if ((dp->conversion == 'f' || dp->conversion == 'F'
    4985             :                       || dp->conversion == 'e' || dp->conversion == 'E'
    4986             :                       || dp->conversion == 'g' || dp->conversion == 'G'
    4987             :                       || dp->conversion == 'a' || dp->conversion == 'A')
    4988             :                      && (0
    4989             : # if NEED_PRINTF_DOUBLE
    4990             :                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
    4991             : # elif NEED_PRINTF_INFINITE_DOUBLE
    4992             :                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
    4993             :                              /* The systems (mingw) which produce wrong output
    4994             :                                 for Inf, -Inf, and NaN also do so for -0.0.
    4995             :                                 Therefore we treat this case here as well.  */
    4996             :                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
    4997             : # endif
    4998             : # if NEED_PRINTF_LONG_DOUBLE
    4999             :                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
    5000             : # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
    5001             :                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
    5002             :                              /* Some systems produce wrong output for Inf,
    5003             :                                 -Inf, and NaN.  Some systems in this category
    5004             :                                 (IRIX 5.3) also do so for -0.0.  Therefore we
    5005             :                                 treat this case here as well.  */
    5006             :                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
    5007             : # endif
    5008             :                         ))
    5009             :               {
    5010             : # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
    5011             :                 arg_type type = a.arg[dp->arg_index].type;
    5012             : # endif
    5013             :                 int flags = dp->flags;
    5014             :                 size_t width;
    5015             :                 size_t count;
    5016             :                 int has_precision;
    5017             :                 size_t precision;
    5018             :                 size_t tmp_length;
    5019             :                 DCHAR_T tmpbuf[700];
    5020             :                 DCHAR_T *tmp;
    5021             :                 DCHAR_T *pad_ptr;
    5022             :                 DCHAR_T *p;
    5023             : 
    5024             :                 width = 0;
    5025             :                 if (dp->width_start != dp->width_end)
    5026             :                   {
    5027             :                     if (dp->width_arg_index != ARG_NONE)
    5028             :                       {
    5029             :                         int arg;
    5030             : 
    5031             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    5032             :                           abort ();
    5033             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    5034             :                         width = arg;
    5035             :                         if (arg < 0)
    5036             :                           {
    5037             :                             /* "A negative field width is taken as a '-' flag
    5038             :                                 followed by a positive field width."  */
    5039             :                             flags |= FLAG_LEFT;
    5040             :                             width = -width;
    5041             :                           }
    5042             :                       }
    5043             :                     else
    5044             :                       {
    5045             :                         const FCHAR_T *digitp = dp->width_start;
    5046             : 
    5047             :                         do
    5048             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    5049             :                         while (digitp != dp->width_end);
    5050             :                       }
    5051             :                     if (width > (size_t) INT_MAX)
    5052             :                       goto overflow;
    5053             :                   }
    5054             : 
    5055             :                 has_precision = 0;
    5056             :                 precision = 0;
    5057             :                 if (dp->precision_start != dp->precision_end)
    5058             :                   {
    5059             :                     if (dp->precision_arg_index != ARG_NONE)
    5060             :                       {
    5061             :                         int arg;
    5062             : 
    5063             :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    5064             :                           abort ();
    5065             :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    5066             :                         /* "A negative precision is taken as if the precision
    5067             :                             were omitted."  */
    5068             :                         if (arg >= 0)
    5069             :                           {
    5070             :                             precision = arg;
    5071             :                             has_precision = 1;
    5072             :                           }
    5073             :                       }
    5074             :                     else
    5075             :                       {
    5076             :                         const FCHAR_T *digitp = dp->precision_start + 1;
    5077             : 
    5078             :                         precision = 0;
    5079             :                         while (digitp != dp->precision_end)
    5080             :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    5081             :                         has_precision = 1;
    5082             :                       }
    5083             :                   }
    5084             : 
    5085             :                 /* POSIX specifies the default precision to be 6 for %f, %F,
    5086             :                    %e, %E, but not for %g, %G.  Implementations appear to use
    5087             :                    the same default precision also for %g, %G.  But for %a, %A,
    5088             :                    the default precision is 0.  */
    5089             :                 if (!has_precision)
    5090             :                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
    5091             :                     precision = 6;
    5092             : 
    5093             :                 /* Allocate a temporary buffer of sufficient size.  */
    5094             : # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
    5095             :                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
    5096             : # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
    5097             :                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
    5098             : # elif NEED_PRINTF_LONG_DOUBLE
    5099             :                 tmp_length = LDBL_DIG + 1;
    5100             : # elif NEED_PRINTF_DOUBLE
    5101             :                 tmp_length = DBL_DIG + 1;
    5102             : # else
    5103             :                 tmp_length = 0;
    5104             : # endif
    5105             :                 if (tmp_length < precision)
    5106             :                   tmp_length = precision;
    5107             : # if NEED_PRINTF_LONG_DOUBLE
    5108             : #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
    5109             :                 if (type == TYPE_LONGDOUBLE)
    5110             : #  endif
    5111             :                   if (dp->conversion == 'f' || dp->conversion == 'F')
    5112             :                     {
    5113             :                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
    5114             :                       if (!(isnanl (arg) || arg + arg == arg))
    5115             :                         {
    5116             :                           /* arg is finite and nonzero.  */
    5117             :                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
    5118             :                           if (exponent >= 0 && tmp_length < exponent + precision)
    5119             :                             tmp_length = exponent + precision;
    5120             :                         }
    5121             :                     }
    5122             : # endif
    5123             : # if NEED_PRINTF_DOUBLE
    5124             : #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
    5125             :                 if (type == TYPE_DOUBLE)
    5126             : #  endif
    5127             :                   if (dp->conversion == 'f' || dp->conversion == 'F')
    5128             :                     {
    5129             :                       double arg = a.arg[dp->arg_index].a.a_double;
    5130             :                       if (!(isnand (arg) || arg + arg == arg))
    5131             :                         {
    5132             :                           /* arg is finite and nonzero.  */
    5133             :                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
    5134             :                           if (exponent >= 0 && tmp_length < exponent + precision)
    5135             :                             tmp_length = exponent + precision;
    5136             :                         }
    5137             :                     }
    5138             : # endif
    5139             :                 /* Account for thousands separators.  */
    5140             :                 if (flags & FLAG_GROUP)
    5141             :                   {
    5142             :                     /* A thousands separator needs to be inserted at most every 2 digits.
    5143             :                        This is the case in the ta_IN locale.  */
    5144             : # if WIDE_CHAR_VERSION
    5145             :                     tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_WCHAR_MAXLEN);
    5146             : # else
    5147             :                     tmp_length = xsum (tmp_length, tmp_length / 2 * THOUSEP_CHAR_MAXLEN);
    5148             : # endif
    5149             :                   }
    5150             :                 /* Account for sign, decimal point etc. */
    5151             :                 tmp_length = xsum (tmp_length, 12);
    5152             : 
    5153             :                 if (tmp_length < width)
    5154             :                   tmp_length = width;
    5155             : 
    5156             :                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
    5157             : 
    5158             :                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
    5159             :                   tmp = tmpbuf;
    5160             :                 else
    5161             :                   {
    5162             :                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
    5163             : 
    5164             :                     if (size_overflow_p (tmp_memsize))
    5165             :                       /* Overflow, would lead to out of memory.  */
    5166             :                       goto out_of_memory;
    5167             :                     tmp = (DCHAR_T *) malloc (tmp_memsize);
    5168             :                     if (tmp == NULL)
    5169             :                       /* Out of memory.  */
    5170             :                       goto out_of_memory;
    5171             :                   }
    5172             : 
    5173             :                 pad_ptr = NULL;
    5174             :                 p = tmp;
    5175             : 
    5176             : # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
    5177             : #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
    5178             :                 if (type == TYPE_LONGDOUBLE)
    5179             : #  endif
    5180             :                   {
    5181             :                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
    5182             : 
    5183             :                     if (isnanl (arg))
    5184             :                       {
    5185             :                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
    5186             :                           {
    5187             :                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
    5188             :                           }
    5189             :                         else
    5190             :                           {
    5191             :                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
    5192             :                           }
    5193             :                       }
    5194             :                     else
    5195             :                       {
    5196             :                         int sign = 0;
    5197             :                         DECL_LONG_DOUBLE_ROUNDING
    5198             : 
    5199             :                         BEGIN_LONG_DOUBLE_ROUNDING ();
    5200             : 
    5201             :                         if (signbit (arg)) /* arg < 0.0L or negative zero */
    5202             :                           {
    5203             :                             sign = -1;
    5204             :                             arg = -arg;
    5205             :                           }
    5206             : 
    5207             :                         if (sign < 0)
    5208             :                           *p++ = '-';
    5209             :                         else if (flags & FLAG_SHOWSIGN)
    5210             :                           *p++ = '+';
    5211             :                         else if (flags & FLAG_SPACE)
    5212             :                           *p++ = ' ';
    5213             : 
    5214             :                         if (arg > 0.0L && arg + arg == arg)
    5215             :                           {
    5216             :                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
    5217             :                               {
    5218             :                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
    5219             :                               }
    5220             :                             else
    5221             :                               {
    5222             :                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
    5223             :                               }
    5224             :                           }
    5225             :                         else
    5226             :                           {
    5227             : #  if NEED_PRINTF_LONG_DOUBLE
    5228             :                             pad_ptr = p;
    5229             : 
    5230             :                             if (dp->conversion == 'f' || dp->conversion == 'F')
    5231             :                               {
    5232             :                                 char *digits;
    5233             :                                 size_t ndigits;
    5234             : 
    5235             :                                 digits =
    5236             :                                   scale10_round_decimal_long_double (arg, precision);
    5237             :                                 if (digits == NULL)
    5238             :                                   {
    5239             :                                     END_LONG_DOUBLE_ROUNDING ();
    5240             :                                     goto out_of_memory;
    5241             :                                   }
    5242             :                                 ndigits = strlen (digits);
    5243             : 
    5244             :                                 if (ndigits > precision)
    5245             :                                   {
    5246             :                                     /* Number of digits before the decimal point.  */
    5247             :                                     size_t intpart_digits = ndigits - precision;
    5248             : 
    5249             :                                     const DCHAR_T *thousep = NULL;
    5250             :                                     DCHAR_T thousep_buf[10];
    5251             : #   if !WIDE_CHAR_VERSION
    5252             :                                     size_t thousep_len = 0;
    5253             : #   endif
    5254             :                                     const signed char *grouping;
    5255             :                                     size_t insert = 0;
    5256             : 
    5257             :                                     if ((flags & FLAG_GROUP) && (intpart_digits > 1))
    5258             :                                       {
    5259             :                                         /* Determine the thousands separator and
    5260             :                                            the grouping rule of the current locale.  */
    5261             : #   if WIDE_CHAR_VERSION
    5262             :                                         /* DCHAR_T is wchar_t.  */
    5263             :                                         thousep = thousands_separator_wchar (thousep_buf);
    5264             : #                                       define thousep_len 1
    5265             : #   elif defined DCHAR_CONV_FROM_ENCODING
    5266             :                                         /* DCHAR_T is uintN_t.  */
    5267             :                                         thousep = thousands_separator_DCHAR (thousep_buf);
    5268             :                                         thousep_len = DCHAR_STRLEN (thousep);
    5269             : #   else
    5270             :                                         /* DCHAR_T is char.  */
    5271             :                                         thousep = thousands_separator_char (thousep_buf);
    5272             :                                         thousep_len = strlen (thousep);
    5273             : #   endif
    5274             :                                         if (*thousep == 0)
    5275             :                                           thousep = NULL;
    5276             :                                         if (thousep != NULL)
    5277             :                                           {
    5278             :                                             grouping = grouping_rule ();
    5279             :                                             insert =
    5280             :                                               num_thousands_separators (grouping, intpart_digits);
    5281             :                                           }
    5282             :                                       }
    5283             : 
    5284             :                                     const char *digitp = digits + precision;
    5285             :                                     DCHAR_T *p_before_intpart = p;
    5286             :                                     p += intpart_digits + insert * thousep_len;
    5287             :                                     DCHAR_T *p_after_intpart = p;
    5288             :                                     if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */
    5289             :                                       {
    5290             :                                         const signed char *g = grouping;
    5291             :                                         for (;;)
    5292             :                                           {
    5293             :                                             int h = *g;
    5294             :                                             if (h <= 0)
    5295             :                                               abort ();
    5296             :                                             int i = h;
    5297             :                                             do
    5298             :                                               *--p = *digitp++;
    5299             :                                             while (--i > 0);
    5300             : #   if WIDE_CHAR_VERSION
    5301             :                                             *--p = thousep[0];
    5302             : #   else
    5303             :                                             p -= thousep_len;
    5304             :                                             DCHAR_CPY (p, thousep, thousep_len);
    5305             : #   endif
    5306             :                                             insert--;
    5307             :                                             if (insert == 0)
    5308             :                                               break;
    5309             :                                             if (g[1] != 0)
    5310             :                                               g++;
    5311             :                                           }
    5312             :                                       }
    5313             :                                     for (;;)
    5314             :                                       {
    5315             :                                         *--p = *digitp++;
    5316             :                                         if (p == p_before_intpart)
    5317             :                                           break;
    5318             :                                       }
    5319             :                                     p = p_after_intpart;
    5320             :                                     ndigits = precision;
    5321             : #   undef thousep_len
    5322             :                                   }
    5323             :                                 else
    5324             :                                   *p++ = '0';
    5325             :                                 /* Here ndigits <= precision.  */
    5326             :                                 if ((flags & FLAG_ALT) || precision > 0)
    5327             :                                   {
    5328             :                                     *p++ = decimal_point_char ();
    5329             :                                     for (; precision > ndigits; precision--)
    5330             :                                       *p++ = '0';
    5331             :                                     while (ndigits > 0)
    5332             :                                       {
    5333             :                                         --ndigits;
    5334             :                                         *p++ = digits[ndigits];
    5335             :                                       }
    5336             :                                   }
    5337             : 
    5338             :                                 free (digits);
    5339             :                               }
    5340             :                             else if (dp->conversion == 'e' || dp->conversion == 'E')
    5341             :                               {
    5342             :                                 int exponent;
    5343             : 
    5344             :                                 if (arg == 0.0L)
    5345             :                                   {
    5346             :                                     exponent = 0;
    5347             :                                     *p++ = '0';
    5348             :                                     if ((flags & FLAG_ALT) || precision > 0)
    5349             :                                       {
    5350             :                                         *p++ = decimal_point_char ();
    5351             :                                         for (; precision > 0; precision--)
    5352             :                                           *p++ = '0';
    5353             :                                       }
    5354             :                                   }
    5355             :                                 else
    5356             :                                   {
    5357             :                                     /* arg > 0.0L.  */
    5358             :                                     int adjusted;
    5359             :                                     char *digits;
    5360             :                                     size_t ndigits;
    5361             : 
    5362             :                                     exponent = floorlog10l (arg);
    5363             :                                     adjusted = 0;
    5364             :                                     for (;;)
    5365             :                                       {
    5366             :                                         digits =
    5367             :                                           scale10_round_decimal_long_double (arg,
    5368             :                                                                              (int)precision - exponent);
    5369             :                                         if (digits == NULL)
    5370             :                                           {
    5371             :                                             END_LONG_DOUBLE_ROUNDING ();
    5372             :                                             goto out_of_memory;
    5373             :                                           }
    5374             :                                         ndigits = strlen (digits);
    5375             : 
    5376             :                                         if (ndigits == precision + 1)
    5377             :                                           break;
    5378             :                                         if (ndigits < precision
    5379             :                                             || ndigits > precision + 2)
    5380             :                                           /* The exponent was not guessed
    5381             :                                              precisely enough.  */
    5382             :                                           abort ();
    5383             :                                         if (adjusted)
    5384             :                                           /* None of two values of exponent is
    5385             :                                              the right one.  Prevent an endless
    5386             :                                              loop.  */
    5387             :                                           abort ();
    5388             :                                         free (digits);
    5389             :                                         if (ndigits == precision)
    5390             :                                           exponent -= 1;
    5391             :                                         else
    5392             :                                           exponent += 1;
    5393             :                                         adjusted = 1;
    5394             :                                       }
    5395             :                                     /* Here ndigits = precision+1.  */
    5396             :                                     if (is_borderline (digits, precision))
    5397             :                                       {
    5398             :                                         /* Maybe the exponent guess was too high
    5399             :                                            and a smaller exponent can be reached
    5400             :                                            by turning a 10...0 into 9...9x.  */
    5401             :                                         char *digits2 =
    5402             :                                           scale10_round_decimal_long_double (arg,
    5403             :                                                                              (int)precision - exponent + 1);
    5404             :                                         if (digits2 == NULL)
    5405             :                                           {
    5406             :                                             free (digits);
    5407             :                                             END_LONG_DOUBLE_ROUNDING ();
    5408             :                                             goto out_of_memory;
    5409             :                                           }
    5410             :                                         if (strlen (digits2) == precision + 1)
    5411             :                                           {
    5412             :                                             free (digits);
    5413             :                                             digits = digits2;
    5414             :                                             exponent -= 1;
    5415             :                                           }
    5416             :                                         else
    5417             :                                           free (digits2);
    5418             :                                       }
    5419             :                                     /* Here ndigits = precision+1.  */
    5420             : 
    5421             :                                     *p++ = digits[--ndigits];
    5422             :                                     if ((flags & FLAG_ALT) || precision > 0)
    5423             :                                       {
    5424             :                                         *p++ = decimal_point_char ();
    5425             :                                         while (ndigits > 0)
    5426             :                                           {
    5427             :                                             --ndigits;
    5428             :                                             *p++ = digits[ndigits];
    5429             :                                           }
    5430             :                                       }
    5431             : 
    5432             :                                     free (digits);
    5433             :                                   }
    5434             : 
    5435             :                                 *p++ = dp->conversion; /* 'e' or 'E' */
    5436             : #   if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
    5437             :                                 {
    5438             :                                   static const wchar_t decimal_format[] =
    5439             :                                     { '%', '+', '.', '2', 'd', '\0' };
    5440             :                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
    5441             :                                 }
    5442             :                                 while (*p != '\0')
    5443             :                                   p++;
    5444             : #   else
    5445             :                                 if (sizeof (DCHAR_T) == 1)
    5446             :                                   {
    5447             :                                     sprintf ((char *) p, "%+.2d", exponent);
    5448             :                                     while (*p != '\0')
    5449             :                                       p++;
    5450             :                                   }
    5451             :                                 else
    5452             :                                   {
    5453             :                                     char expbuf[6 + 1];
    5454             :                                     const char *ep;
    5455             :                                     sprintf (expbuf, "%+.2d", exponent);
    5456             :                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    5457             :                                       p++;
    5458             :                                   }
    5459             : #   endif
    5460             :                               }
    5461             :                             else if (dp->conversion == 'g' || dp->conversion == 'G')
    5462             :                               {
    5463             :                                 if (precision == 0)
    5464             :                                   precision = 1;
    5465             :                                 /* precision >= 1.  */
    5466             : 
    5467             :                                 if (arg == 0.0L)
    5468             :                                   /* The exponent is 0, >= -4, < precision.
    5469             :                                      Use fixed-point notation.  */
    5470             :                                   {
    5471             :                                     size_t ndigits = precision;
    5472             :                                     /* Number of trailing zeroes that have to be
    5473             :                                        dropped.  */
    5474             :                                     size_t nzeroes =
    5475             :                                       (flags & FLAG_ALT ? 0 : precision - 1);
    5476             : 
    5477             :                                     --ndigits;
    5478             :                                     *p++ = '0';
    5479             :                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
    5480             :                                       {
    5481             :                                         *p++ = decimal_point_char ();
    5482             :                                         while (ndigits > nzeroes)
    5483             :                                           {
    5484             :                                             --ndigits;
    5485             :                                             *p++ = '0';
    5486             :                                           }
    5487             :                                       }
    5488             :                                   }
    5489             :                                 else
    5490             :                                   {
    5491             :                                     /* arg > 0.0L.  */
    5492             :                                     int exponent;
    5493             :                                     int adjusted;
    5494             :                                     char *digits;
    5495             :                                     size_t ndigits;
    5496             :                                     size_t nzeroes;
    5497             : 
    5498             :                                     exponent = floorlog10l (arg);
    5499             :                                     adjusted = 0;
    5500             :                                     for (;;)
    5501             :                                       {
    5502             :                                         digits =
    5503             :                                           scale10_round_decimal_long_double (arg,
    5504             :                                                                              (int)(precision - 1) - exponent);
    5505             :                                         if (digits == NULL)
    5506             :                                           {
    5507             :                                             END_LONG_DOUBLE_ROUNDING ();
    5508             :                                             goto out_of_memory;
    5509             :                                           }
    5510             :                                         ndigits = strlen (digits);
    5511             : 
    5512             :                                         if (ndigits == precision)
    5513             :                                           break;
    5514             :                                         if (ndigits < precision - 1
    5515             :                                             || ndigits > precision + 1)
    5516             :                                           /* The exponent was not guessed
    5517             :                                              precisely enough.  */
    5518             :                                           abort ();
    5519             :                                         if (adjusted)
    5520             :                                           /* None of two values of exponent is
    5521             :                                              the right one.  Prevent an endless
    5522             :                                              loop.  */
    5523             :                                           abort ();
    5524             :                                         free (digits);
    5525             :                                         if (ndigits < precision)
    5526             :                                           exponent -= 1;
    5527             :                                         else
    5528             :                                           exponent += 1;
    5529             :                                         adjusted = 1;
    5530             :                                       }
    5531             :                                     /* Here ndigits = precision.  */
    5532             :                                     if (is_borderline (digits, precision - 1))
    5533             :                                       {
    5534             :                                         /* Maybe the exponent guess was too high
    5535             :                                            and a smaller exponent can be reached
    5536             :                                            by turning a 10...0 into 9...9x.  */
    5537             :                                         char *digits2 =
    5538             :                                           scale10_round_decimal_long_double (arg,
    5539             :                                                                              (int)(precision - 1) - exponent + 1);
    5540             :                                         if (digits2 == NULL)
    5541             :                                           {
    5542             :                                             free (digits);
    5543             :                                             END_LONG_DOUBLE_ROUNDING ();
    5544             :                                             goto out_of_memory;
    5545             :                                           }
    5546             :                                         if (strlen (digits2) == precision)
    5547             :                                           {
    5548             :                                             free (digits);
    5549             :                                             digits = digits2;
    5550             :                                             exponent -= 1;
    5551             :                                           }
    5552             :                                         else
    5553             :                                           free (digits2);
    5554             :                                       }
    5555             :                                     /* Here ndigits = precision.  */
    5556             : 
    5557             :                                     /* Determine the number of trailing zeroes
    5558             :                                        that have to be dropped.  */
    5559             :                                     nzeroes = 0;
    5560             :                                     if ((flags & FLAG_ALT) == 0)
    5561             :                                       while (nzeroes < ndigits
    5562             :                                              && digits[nzeroes] == '0')
    5563             :                                         nzeroes++;
    5564             : 
    5565             :                                     /* The exponent is now determined.  */
    5566             :                                     if (exponent >= -4
    5567             :                                         && exponent < (long)precision)
    5568             :                                       {
    5569             :                                         /* Fixed-point notation:
    5570             :                                            max(exponent,0)+1 digits, then the
    5571             :                                            decimal point, then the remaining
    5572             :                                            digits without trailing zeroes.  */
    5573             :                                         if (exponent >= 0)
    5574             :                                           {
    5575             :                                             /* Number of digits before the decimal point.  */
    5576             :                                             size_t intpart_digits = exponent + 1;
    5577             :                                             /* Note: intpart_digits <= precision = ndigits.  */
    5578             : 
    5579             :                                             const DCHAR_T *thousep = NULL;
    5580             :                                             DCHAR_T thousep_buf[10];
    5581             : #   if !WIDE_CHAR_VERSION
    5582             :                                             size_t thousep_len = 0;
    5583             : #   endif
    5584             :                                             const signed char *grouping;
    5585             :                                             size_t insert = 0;
    5586             : 
    5587             :                                             if ((flags & FLAG_GROUP) && (intpart_digits > 1))
    5588             :                                               {
    5589             :                                                 /* Determine the thousands separator and
    5590             :                                                    the grouping rule of the current locale.  */
    5591             : #   if WIDE_CHAR_VERSION
    5592             :                                                 /* DCHAR_T is wchar_t.  */
    5593             :                                                 thousep = thousands_separator_wchar (thousep_buf);
    5594             : #                                               define thousep_len 1
    5595             : #   elif defined DCHAR_CONV_FROM_ENCODING
    5596             :                                                 /* DCHAR_T is uintN_t.  */
    5597             :                                                 thousep = thousands_separator_DCHAR (thousep_buf);
    5598             :                                                 thousep_len = DCHAR_STRLEN (thousep);
    5599             : #   else
    5600             :                                                 /* DCHAR_T is char.  */
    5601             :                                                 thousep = thousands_separator_char (thousep_buf);
    5602             :                                                 thousep_len = strlen (thousep);
    5603             : #   endif
    5604             :                                                 if (*thousep == 0)
    5605             :                                                   thousep = NULL;
    5606             :                                                 if (thousep != NULL)
    5607             :                                                   {
    5608             :                                                     grouping = grouping_rule ();
    5609             :                                                     insert =
    5610             :                                                       num_thousands_separators (grouping, intpart_digits);
    5611             :                                                   }
    5612             :                                               }
    5613             : 
    5614             :                                             const char *digitp = digits + ndigits - intpart_digits;
    5615             :                                             DCHAR_T *p_before_intpart = p;
    5616             :                                             p += intpart_digits + insert * thousep_len;
    5617             :                                             DCHAR_T *p_after_intpart = p;
    5618             :                                             if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */
    5619             :                                               {
    5620             :                                                 const signed char *g = grouping;
    5621             :                                                 for (;;)
    5622             :                                                   {
    5623             :                                                     int h = *g;
    5624             :                                                     if (h <= 0)
    5625             :                                                       abort ();
    5626             :                                                     int i = h;
    5627             :                                                     do
    5628             :                                                       *--p = *digitp++;
    5629             :                                                     while (--i > 0);
    5630             : #   if WIDE_CHAR_VERSION
    5631             :                                                     *--p = thousep[0];
    5632             : #   else
    5633             :                                                     p -= thousep_len;
    5634             :                                                     DCHAR_CPY (p, thousep, thousep_len);
    5635             : #   endif
    5636             :                                                     insert--;
    5637             :                                                     if (insert == 0)
    5638             :                                                       break;
    5639             :                                                     if (g[1] != 0)
    5640             :                                                       g++;
    5641             :                                                   }
    5642             :                                               }
    5643             :                                             for (;;)
    5644             :                                               {
    5645             :                                                 *--p = *digitp++;
    5646             :                                                 if (p == p_before_intpart)
    5647             :                                                   break;
    5648             :                                               }
    5649             :                                             p = p_after_intpart;
    5650             :                                             ndigits -= intpart_digits;
    5651             : #   undef thousep_len
    5652             : 
    5653             :                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
    5654             :                                               {
    5655             :                                                 *p++ = decimal_point_char ();
    5656             :                                                 while (ndigits > nzeroes)
    5657             :                                                   {
    5658             :                                                     --ndigits;
    5659             :                                                     *p++ = digits[ndigits];
    5660             :                                                   }
    5661             :                                               }
    5662             :                                           }
    5663             :                                         else
    5664             :                                           {
    5665             :                                             size_t ecount = -exponent - 1;
    5666             :                                             *p++ = '0';
    5667             :                                             *p++ = decimal_point_char ();
    5668             :                                             for (; ecount > 0; ecount--)
    5669             :                                               *p++ = '0';
    5670             :                                             while (ndigits > nzeroes)
    5671             :                                               {
    5672             :                                                 --ndigits;
    5673             :                                                 *p++ = digits[ndigits];
    5674             :                                               }
    5675             :                                           }
    5676             :                                       }
    5677             :                                     else
    5678             :                                       {
    5679             :                                         /* Exponential notation.  */
    5680             :                                         *p++ = digits[--ndigits];
    5681             :                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
    5682             :                                           {
    5683             :                                             *p++ = decimal_point_char ();
    5684             :                                             while (ndigits > nzeroes)
    5685             :                                               {
    5686             :                                                 --ndigits;
    5687             :                                                 *p++ = digits[ndigits];
    5688             :                                               }
    5689             :                                           }
    5690             :                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
    5691             : #   if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
    5692             :                                         {
    5693             :                                           static const wchar_t decimal_format[] =
    5694             :                                             { '%', '+', '.', '2', 'd', '\0' };
    5695             :                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
    5696             :                                         }
    5697             :                                         while (*p != '\0')
    5698             :                                           p++;
    5699             : #   else
    5700             :                                         if (sizeof (DCHAR_T) == 1)
    5701             :                                           {
    5702             :                                             sprintf ((char *) p, "%+.2d", exponent);
    5703             :                                             while (*p != '\0')
    5704             :                                               p++;
    5705             :                                           }
    5706             :                                         else
    5707             :                                           {
    5708             :                                             char expbuf[6 + 1];
    5709             :                                             const char *ep;
    5710             :                                             sprintf (expbuf, "%+.2d", exponent);
    5711             :                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    5712             :                                               p++;
    5713             :                                           }
    5714             : #   endif
    5715             :                                       }
    5716             : 
    5717             :                                     free (digits);
    5718             :                                   }
    5719             :                               }
    5720             :                             else
    5721             :                               abort ();
    5722             : #  else
    5723             :                             /* arg is finite.  */
    5724             :                             if (!(arg == 0.0L))
    5725             :                               abort ();
    5726             : 
    5727             :                             pad_ptr = p;
    5728             : 
    5729             :                             if (dp->conversion == 'f' || dp->conversion == 'F')
    5730             :                               {
    5731             :                                 *p++ = '0';
    5732             :                                 if ((flags & FLAG_ALT) || precision > 0)
    5733             :                                   {
    5734             :                                     *p++ = decimal_point_char ();
    5735             :                                     for (; precision > 0; precision--)
    5736             :                                       *p++ = '0';
    5737             :                                   }
    5738             :                               }
    5739             :                             else if (dp->conversion == 'e' || dp->conversion == 'E')
    5740             :                               {
    5741             :                                 *p++ = '0';
    5742             :                                 if ((flags & FLAG_ALT) || precision > 0)
    5743             :                                   {
    5744             :                                     *p++ = decimal_point_char ();
    5745             :                                     for (; precision > 0; precision--)
    5746             :                                       *p++ = '0';
    5747             :                                   }
    5748             :                                 *p++ = dp->conversion; /* 'e' or 'E' */
    5749             :                                 *p++ = '+';
    5750             :                                 *p++ = '0';
    5751             :                                 *p++ = '0';
    5752             :                               }
    5753             :                             else if (dp->conversion == 'g' || dp->conversion == 'G')
    5754             :                               {
    5755             :                                 *p++ = '0';
    5756             :                                 if (flags & FLAG_ALT)
    5757             :                                   {
    5758             :                                     size_t ndigits =
    5759             :                                       (precision > 0 ? precision - 1 : 0);
    5760             :                                     *p++ = decimal_point_char ();
    5761             :                                     for (; ndigits > 0; --ndigits)
    5762             :                                       *p++ = '0';
    5763             :                                   }
    5764             :                               }
    5765             :                             else if (dp->conversion == 'a' || dp->conversion == 'A')
    5766             :                               {
    5767             :                                 *p++ = '0';
    5768             :                                 *p++ = dp->conversion - 'A' + 'X';
    5769             :                                 pad_ptr = p;
    5770             :                                 *p++ = '0';
    5771             :                                 if ((flags & FLAG_ALT) || precision > 0)
    5772             :                                   {
    5773             :                                     *p++ = decimal_point_char ();
    5774             :                                     for (; precision > 0; precision--)
    5775             :                                       *p++ = '0';
    5776             :                                   }
    5777             :                                 *p++ = dp->conversion - 'A' + 'P';
    5778             :                                 *p++ = '+';
    5779             :                                 *p++ = '0';
    5780             :                               }
    5781             :                             else
    5782             :                               abort ();
    5783             : #  endif
    5784             :                           }
    5785             : 
    5786             :                         END_LONG_DOUBLE_ROUNDING ();
    5787             :                       }
    5788             :                   }
    5789             : #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
    5790             :                 else
    5791             : #  endif
    5792             : # endif
    5793             : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
    5794             :                   {
    5795             :                     double arg = a.arg[dp->arg_index].a.a_double;
    5796             : 
    5797             :                     if (isnand (arg))
    5798             :                       {
    5799             :                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
    5800             :                           {
    5801             :                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
    5802             :                           }
    5803             :                         else
    5804             :                           {
    5805             :                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
    5806             :                           }
    5807             :                       }
    5808             :                     else
    5809             :                       {
    5810             :                         int sign = 0;
    5811             : 
    5812             :                         if (signbit (arg)) /* arg < 0.0 or negative zero */
    5813             :                           {
    5814             :                             sign = -1;
    5815             :                             arg = -arg;
    5816             :                           }
    5817             : 
    5818             :                         if (sign < 0)
    5819             :                           *p++ = '-';
    5820             :                         else if (flags & FLAG_SHOWSIGN)
    5821             :                           *p++ = '+';
    5822             :                         else if (flags & FLAG_SPACE)
    5823             :                           *p++ = ' ';
    5824             : 
    5825             :                         if (arg > 0.0 && arg + arg == arg)
    5826             :                           {
    5827             :                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
    5828             :                               {
    5829             :                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
    5830             :                               }
    5831             :                             else
    5832             :                               {
    5833             :                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
    5834             :                               }
    5835             :                           }
    5836             :                         else
    5837             :                           {
    5838             : #  if NEED_PRINTF_DOUBLE
    5839             :                             pad_ptr = p;
    5840             : 
    5841             :                             if (dp->conversion == 'f' || dp->conversion == 'F')
    5842             :                               {
    5843             :                                 char *digits;
    5844             :                                 size_t ndigits;
    5845             : 
    5846             :                                 digits =
    5847             :                                   scale10_round_decimal_double (arg, precision);
    5848             :                                 if (digits == NULL)
    5849             :                                   goto out_of_memory;
    5850             :                                 ndigits = strlen (digits);
    5851             : 
    5852             :                                 if (ndigits > precision)
    5853             :                                   {
    5854             :                                     /* Number of digits before the decimal point.  */
    5855             :                                     size_t intpart_digits = ndigits - precision;
    5856             : 
    5857             :                                     const DCHAR_T *thousep = NULL;
    5858             :                                     DCHAR_T thousep_buf[10];
    5859             : #   if !WIDE_CHAR_VERSION
    5860             :                                     size_t thousep_len = 0;
    5861             : #   endif
    5862             :                                     const signed char *grouping;
    5863             :                                     size_t insert = 0;
    5864             : 
    5865             :                                     if ((flags & FLAG_GROUP) && (intpart_digits > 1))
    5866             :                                       {
    5867             :                                         /* Determine the thousands separator and
    5868             :                                            the grouping rule of the current locale.  */
    5869             : #   if WIDE_CHAR_VERSION
    5870             :                                         /* DCHAR_T is wchar_t.  */
    5871             :                                         thousep = thousands_separator_wchar (thousep_buf);
    5872             : #                                       define thousep_len 1
    5873             : #   elif defined DCHAR_CONV_FROM_ENCODING
    5874             :                                         /* DCHAR_T is uintN_t.  */
    5875             :                                         thousep = thousands_separator_DCHAR (thousep_buf);
    5876             :                                         thousep_len = DCHAR_STRLEN (thousep);
    5877             : #   else
    5878             :                                         /* DCHAR_T is char.  */
    5879             :                                         thousep = thousands_separator_char (thousep_buf);
    5880             :                                         thousep_len = strlen (thousep);
    5881             : #   endif
    5882             :                                         if (*thousep == 0)
    5883             :                                           thousep = NULL;
    5884             :                                         if (thousep != NULL)
    5885             :                                           {
    5886             :                                             grouping = grouping_rule ();
    5887             :                                             insert =
    5888             :                                               num_thousands_separators (grouping, intpart_digits);
    5889             :                                           }
    5890             :                                       }
    5891             : 
    5892             :                                     const char *digitp = digits + precision;
    5893             :                                     DCHAR_T *p_before_intpart = p;
    5894             :                                     p += intpart_digits + insert * thousep_len;
    5895             :                                     DCHAR_T *p_after_intpart = p;
    5896             :                                     if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */
    5897             :                                       {
    5898             :                                         const signed char *g = grouping;
    5899             :                                         for (;;)
    5900             :                                           {
    5901             :                                             int h = *g;
    5902             :                                             if (h <= 0)
    5903             :                                               abort ();
    5904             :                                             int i = h;
    5905             :                                             do
    5906             :                                               *--p = *digitp++;
    5907             :                                             while (--i > 0);
    5908             : #   if WIDE_CHAR_VERSION
    5909             :                                             *--p = thousep[0];
    5910             : #   else
    5911             :                                             p -= thousep_len;
    5912             :                                             DCHAR_CPY (p, thousep, thousep_len);
    5913             : #   endif
    5914             :                                             insert--;
    5915             :                                             if (insert == 0)
    5916             :                                               break;
    5917             :                                             if (g[1] != 0)
    5918             :                                               g++;
    5919             :                                           }
    5920             :                                       }
    5921             :                                     for (;;)
    5922             :                                       {
    5923             :                                         *--p = *digitp++;
    5924             :                                         if (p == p_before_intpart)
    5925             :                                           break;
    5926             :                                       }
    5927             :                                     p = p_after_intpart;
    5928             :                                     ndigits = precision;
    5929             : #   undef thousep_len
    5930             :                                   }
    5931             :                                 else
    5932             :                                   *p++ = '0';
    5933             :                                 /* Here ndigits <= precision.  */
    5934             :                                 if ((flags & FLAG_ALT) || precision > 0)
    5935             :                                   {
    5936             :                                     *p++ = decimal_point_char ();
    5937             :                                     for (; precision > ndigits; precision--)
    5938             :                                       *p++ = '0';
    5939             :                                     while (ndigits > 0)
    5940             :                                       {
    5941             :                                         --ndigits;
    5942             :                                         *p++ = digits[ndigits];
    5943             :                                       }
    5944             :                                   }
    5945             : 
    5946             :                                 free (digits);
    5947             :                               }
    5948             :                             else if (dp->conversion == 'e' || dp->conversion == 'E')
    5949             :                               {
    5950             :                                 int exponent;
    5951             : 
    5952             :                                 if (arg == 0.0)
    5953             :                                   {
    5954             :                                     exponent = 0;
    5955             :                                     *p++ = '0';
    5956             :                                     if ((flags & FLAG_ALT) || precision > 0)
    5957             :                                       {
    5958             :                                         *p++ = decimal_point_char ();
    5959             :                                         for (; precision > 0; precision--)
    5960             :                                           *p++ = '0';
    5961             :                                       }
    5962             :                                   }
    5963             :                                 else
    5964             :                                   {
    5965             :                                     /* arg > 0.0.  */
    5966             :                                     int adjusted;
    5967             :                                     char *digits;
    5968             :                                     size_t ndigits;
    5969             : 
    5970             :                                     exponent = floorlog10 (arg);
    5971             :                                     adjusted = 0;
    5972             :                                     for (;;)
    5973             :                                       {
    5974             :                                         digits =
    5975             :                                           scale10_round_decimal_double (arg,
    5976             :                                                                         (int)precision - exponent);
    5977             :                                         if (digits == NULL)
    5978             :                                           goto out_of_memory;
    5979             :                                         ndigits = strlen (digits);
    5980             : 
    5981             :                                         if (ndigits == precision + 1)
    5982             :                                           break;
    5983             :                                         if (ndigits < precision
    5984             :                                             || ndigits > precision + 2)
    5985             :                                           /* The exponent was not guessed
    5986             :                                              precisely enough.  */
    5987             :                                           abort ();
    5988             :                                         if (adjusted)
    5989             :                                           /* None of two values of exponent is
    5990             :                                              the right one.  Prevent an endless
    5991             :                                              loop.  */
    5992             :                                           abort ();
    5993             :                                         free (digits);
    5994             :                                         if (ndigits == precision)
    5995             :                                           exponent -= 1;
    5996             :                                         else
    5997             :                                           exponent += 1;
    5998             :                                         adjusted = 1;
    5999             :                                       }
    6000             :                                     /* Here ndigits = precision+1.  */
    6001             :                                     if (is_borderline (digits, precision))
    6002             :                                       {
    6003             :                                         /* Maybe the exponent guess was too high
    6004             :                                            and a smaller exponent can be reached
    6005             :                                            by turning a 10...0 into 9...9x.  */
    6006             :                                         char *digits2 =
    6007             :                                           scale10_round_decimal_double (arg,
    6008             :                                                                         (int)precision - exponent + 1);
    6009             :                                         if (digits2 == NULL)
    6010             :                                           {
    6011             :                                             free (digits);
    6012             :                                             goto out_of_memory;
    6013             :                                           }
    6014             :                                         if (strlen (digits2) == precision + 1)
    6015             :                                           {
    6016             :                                             free (digits);
    6017             :                                             digits = digits2;
    6018             :                                             exponent -= 1;
    6019             :                                           }
    6020             :                                         else
    6021             :                                           free (digits2);
    6022             :                                       }
    6023             :                                     /* Here ndigits = precision+1.  */
    6024             : 
    6025             :                                     *p++ = digits[--ndigits];
    6026             :                                     if ((flags & FLAG_ALT) || precision > 0)
    6027             :                                       {
    6028             :                                         *p++ = decimal_point_char ();
    6029             :                                         while (ndigits > 0)
    6030             :                                           {
    6031             :                                             --ndigits;
    6032             :                                             *p++ = digits[ndigits];
    6033             :                                           }
    6034             :                                       }
    6035             : 
    6036             :                                     free (digits);
    6037             :                                   }
    6038             : 
    6039             :                                 *p++ = dp->conversion; /* 'e' or 'E' */
    6040             : #   if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
    6041             :                                 {
    6042             :                                   static const wchar_t decimal_format[] =
    6043             :                                     /* Produce the same number of exponent digits
    6044             :                                        as the native printf implementation.  */
    6045             : #    if defined _WIN32 && ! defined __CYGWIN__
    6046             :                                     { '%', '+', '.', '3', 'd', '\0' };
    6047             : #    else
    6048             :                                     { '%', '+', '.', '2', 'd', '\0' };
    6049             : #    endif
    6050             :                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
    6051             :                                 }
    6052             :                                 while (*p != '\0')
    6053             :                                   p++;
    6054             : #   else
    6055             :                                 {
    6056             :                                   static const char decimal_format[] =
    6057             :                                     /* Produce the same number of exponent digits
    6058             :                                        as the native printf implementation.  */
    6059             : #    if defined _WIN32 && ! defined __CYGWIN__
    6060             :                                     "%+.3d";
    6061             : #    else
    6062             :                                     "%+.2d";
    6063             : #    endif
    6064             :                                   if (sizeof (DCHAR_T) == 1)
    6065             :                                     {
    6066             :                                       sprintf ((char *) p, decimal_format, exponent);
    6067             :                                       while (*p != '\0')
    6068             :                                         p++;
    6069             :                                     }
    6070             :                                   else
    6071             :                                     {
    6072             :                                       char expbuf[6 + 1];
    6073             :                                       const char *ep;
    6074             :                                       sprintf (expbuf, decimal_format, exponent);
    6075             :                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    6076             :                                         p++;
    6077             :                                     }
    6078             :                                 }
    6079             : #   endif
    6080             :                               }
    6081             :                             else if (dp->conversion == 'g' || dp->conversion == 'G')
    6082             :                               {
    6083             :                                 if (precision == 0)
    6084             :                                   precision = 1;
    6085             :                                 /* precision >= 1.  */
    6086             : 
    6087             :                                 if (arg == 0.0)
    6088             :                                   /* The exponent is 0, >= -4, < precision.
    6089             :                                      Use fixed-point notation.  */
    6090             :                                   {
    6091             :                                     size_t ndigits = precision;
    6092             :                                     /* Number of trailing zeroes that have to be
    6093             :                                        dropped.  */
    6094             :                                     size_t nzeroes =
    6095             :                                       (flags & FLAG_ALT ? 0 : precision - 1);
    6096             : 
    6097             :                                     --ndigits;
    6098             :                                     *p++ = '0';
    6099             :                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
    6100             :                                       {
    6101             :                                         *p++ = decimal_point_char ();
    6102             :                                         while (ndigits > nzeroes)
    6103             :                                           {
    6104             :                                             --ndigits;
    6105             :                                             *p++ = '0';
    6106             :                                           }
    6107             :                                       }
    6108             :                                   }
    6109             :                                 else
    6110             :                                   {
    6111             :                                     /* arg > 0.0.  */
    6112             :                                     int exponent;
    6113             :                                     int adjusted;
    6114             :                                     char *digits;
    6115             :                                     size_t ndigits;
    6116             :                                     size_t nzeroes;
    6117             : 
    6118             :                                     exponent = floorlog10 (arg);
    6119             :                                     adjusted = 0;
    6120             :                                     for (;;)
    6121             :                                       {
    6122             :                                         digits =
    6123             :                                           scale10_round_decimal_double (arg,
    6124             :                                                                         (int)(precision - 1) - exponent);
    6125             :                                         if (digits == NULL)
    6126             :                                           goto out_of_memory;
    6127             :                                         ndigits = strlen (digits);
    6128             : 
    6129             :                                         if (ndigits == precision)
    6130             :                                           break;
    6131             :                                         if (ndigits < precision - 1
    6132             :                                             || ndigits > precision + 1)
    6133             :                                           /* The exponent was not guessed
    6134             :                                              precisely enough.  */
    6135             :                                           abort ();
    6136             :                                         if (adjusted)
    6137             :                                           /* None of two values of exponent is
    6138             :                                              the right one.  Prevent an endless
    6139             :                                              loop.  */
    6140             :                                           abort ();
    6141             :                                         free (digits);
    6142             :                                         if (ndigits < precision)
    6143             :                                           exponent -= 1;
    6144             :                                         else
    6145             :                                           exponent += 1;
    6146             :                                         adjusted = 1;
    6147             :                                       }
    6148             :                                     /* Here ndigits = precision.  */
    6149             :                                     if (is_borderline (digits, precision - 1))
    6150             :                                       {
    6151             :                                         /* Maybe the exponent guess was too high
    6152             :                                            and a smaller exponent can be reached
    6153             :                                            by turning a 10...0 into 9...9x.  */
    6154             :                                         char *digits2 =
    6155             :                                           scale10_round_decimal_double (arg,
    6156             :                                                                         (int)(precision - 1) - exponent + 1);
    6157             :                                         if (digits2 == NULL)
    6158             :                                           {
    6159             :                                             free (digits);
    6160             :                                             goto out_of_memory;
    6161             :                                           }
    6162             :                                         if (strlen (digits2) == precision)
    6163             :                                           {
    6164             :                                             free (digits);
    6165             :                                             digits = digits2;
    6166             :                                             exponent -= 1;
    6167             :                                           }
    6168             :                                         else
    6169             :                                           free (digits2);
    6170             :                                       }
    6171             :                                     /* Here ndigits = precision.  */
    6172             : 
    6173             :                                     /* Determine the number of trailing zeroes
    6174             :                                        that have to be dropped.  */
    6175             :                                     nzeroes = 0;
    6176             :                                     if ((flags & FLAG_ALT) == 0)
    6177             :                                       while (nzeroes < ndigits
    6178             :                                              && digits[nzeroes] == '0')
    6179             :                                         nzeroes++;
    6180             : 
    6181             :                                     /* The exponent is now determined.  */
    6182             :                                     if (exponent >= -4
    6183             :                                         && exponent < (long)precision)
    6184             :                                       {
    6185             :                                         /* Fixed-point notation:
    6186             :                                            max(exponent,0)+1 digits, then the
    6187             :                                            decimal point, then the remaining
    6188             :                                            digits without trailing zeroes.  */
    6189             :                                         if (exponent >= 0)
    6190             :                                           {
    6191             :                                             /* Number of digits before the decimal point.  */
    6192             :                                             size_t intpart_digits = exponent + 1;
    6193             :                                             /* Note: intpart_digits <= precision = ndigits.  */
    6194             : 
    6195             :                                             const DCHAR_T *thousep = NULL;
    6196             :                                             DCHAR_T thousep_buf[10];
    6197             : #   if !WIDE_CHAR_VERSION
    6198             :                                             size_t thousep_len = 0;
    6199             : #   endif
    6200             :                                             const signed char *grouping;
    6201             :                                             size_t insert = 0;
    6202             : 
    6203             :                                             if ((flags & FLAG_GROUP) && (intpart_digits > 1))
    6204             :                                               {
    6205             :                                                 /* Determine the thousands separator and
    6206             :                                                    the grouping rule of the current locale.  */
    6207             : #   if WIDE_CHAR_VERSION
    6208             :                                                 /* DCHAR_T is wchar_t.  */
    6209             :                                                 thousep = thousands_separator_wchar (thousep_buf);
    6210             : #                                               define thousep_len 1
    6211             : #   elif defined DCHAR_CONV_FROM_ENCODING
    6212             :                                                 /* DCHAR_T is uintN_t.  */
    6213             :                                                 thousep = thousands_separator_DCHAR (thousep_buf);
    6214             :                                                 thousep_len = DCHAR_STRLEN (thousep);
    6215             : #   else
    6216             :                                                 /* DCHAR_T is char.  */
    6217             :                                                 thousep = thousands_separator_char (thousep_buf);
    6218             :                                                 thousep_len = strlen (thousep);
    6219             : #   endif
    6220             :                                                 if (*thousep == 0)
    6221             :                                                   thousep = NULL;
    6222             :                                                 if (thousep != NULL)
    6223             :                                                   {
    6224             :                                                     grouping = grouping_rule ();
    6225             :                                                     insert =
    6226             :                                                       num_thousands_separators (grouping, intpart_digits);
    6227             :                                                   }
    6228             :                                               }
    6229             : 
    6230             :                                             const char *digitp = digits + ndigits - intpart_digits;
    6231             :                                             DCHAR_T *p_before_intpart = p;
    6232             :                                             p += intpart_digits + insert * thousep_len;
    6233             :                                             DCHAR_T *p_after_intpart = p;
    6234             :                                             if (insert > 0) /* implies (flag & FLAG_GROUP) && (thousep != NULL) */
    6235             :                                               {
    6236             :                                                 const signed char *g = grouping;
    6237             :                                                 for (;;)
    6238             :                                                   {
    6239             :                                                     int h = *g;
    6240             :                                                     if (h <= 0)
    6241             :                                                       abort ();
    6242             :                                                     int i = h;
    6243             :                                                     do
    6244             :                                                       *--p = *digitp++;
    6245             :                                                     while (--i > 0);
    6246             : #   if WIDE_CHAR_VERSION
    6247             :                                                     *--p = thousep[0];
    6248             : #   else
    6249             :                                                     p -= thousep_len;
    6250             :                                                     DCHAR_CPY (p, thousep, thousep_len);
    6251             : #   endif
    6252             :                                                     insert--;
    6253             :                                                     if (insert == 0)
    6254             :                                                       break;
    6255             :                                                     if (g[1] != 0)
    6256             :                                                       g++;
    6257             :                                                   }
    6258             :                                               }
    6259             :                                             for (;;)
    6260             :                                               {
    6261             :                                                 *--p = *digitp++;
    6262             :                                                 if (p == p_before_intpart)
    6263             :                                                   break;
    6264             :                                               }
    6265             :                                             p = p_after_intpart;
    6266             :                                             ndigits -= intpart_digits;
    6267             : #   undef thousep_len
    6268             : 
    6269             :                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
    6270             :                                               {
    6271             :                                                 *p++ = decimal_point_char ();
    6272             :                                                 while (ndigits > nzeroes)
    6273             :                                                   {
    6274             :                                                     --ndigits;
    6275             :                                                     *p++ = digits[ndigits];
    6276             :                                                   }
    6277             :                                               }
    6278             :                                           }
    6279             :                                         else
    6280             :                                           {
    6281             :                                             size_t ecount = -exponent - 1;
    6282             :                                             *p++ = '0';
    6283             :                                             *p++ = decimal_point_char ();
    6284             :                                             for (; ecount > 0; ecount--)
    6285             :                                               *p++ = '0';
    6286             :                                             while (ndigits > nzeroes)
    6287             :                                               {
    6288             :                                                 --ndigits;
    6289             :                                                 *p++ = digits[ndigits];
    6290             :                                               }
    6291             :                                           }
    6292             :                                       }
    6293             :                                     else
    6294             :                                       {
    6295             :                                         /* Exponential notation.  */
    6296             :                                         *p++ = digits[--ndigits];
    6297             :                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
    6298             :                                           {
    6299             :                                             *p++ = decimal_point_char ();
    6300             :                                             while (ndigits > nzeroes)
    6301             :                                               {
    6302             :                                                 --ndigits;
    6303             :                                                 *p++ = digits[ndigits];
    6304             :                                               }
    6305             :                                           }
    6306             :                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
    6307             : #   if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
    6308             :                                         {
    6309             :                                           static const wchar_t decimal_format[] =
    6310             :                                             /* Produce the same number of exponent digits
    6311             :                                                as the native printf implementation.  */
    6312             : #    if defined _WIN32 && ! defined __CYGWIN__
    6313             :                                             { '%', '+', '.', '3', 'd', '\0' };
    6314             : #    else
    6315             :                                             { '%', '+', '.', '2', 'd', '\0' };
    6316             : #    endif
    6317             :                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
    6318             :                                         }
    6319             :                                         while (*p != '\0')
    6320             :                                           p++;
    6321             : #   else
    6322             :                                         {
    6323             :                                           static const char decimal_format[] =
    6324             :                                             /* Produce the same number of exponent digits
    6325             :                                                as the native printf implementation.  */
    6326             : #    if defined _WIN32 && ! defined __CYGWIN__
    6327             :                                             "%+.3d";
    6328             : #    else
    6329             :                                             "%+.2d";
    6330             : #    endif
    6331             :                                           if (sizeof (DCHAR_T) == 1)
    6332             :                                             {
    6333             :                                               sprintf ((char *) p, decimal_format, exponent);
    6334             :                                               while (*p != '\0')
    6335             :                                                 p++;
    6336             :                                             }
    6337             :                                           else
    6338             :                                             {
    6339             :                                               char expbuf[6 + 1];
    6340             :                                               const char *ep;
    6341             :                                               sprintf (expbuf, decimal_format, exponent);
    6342             :                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    6343             :                                                 p++;
    6344             :                                             }
    6345             :                                         }
    6346             : #   endif
    6347             :                                       }
    6348             : 
    6349             :                                     free (digits);
    6350             :                                   }
    6351             :                               }
    6352             :                             else
    6353             :                               abort ();
    6354             : #  else
    6355             :                             /* arg is finite.  */
    6356             :                             if (!(arg == 0.0))
    6357             :                               abort ();
    6358             : 
    6359             :                             pad_ptr = p;
    6360             : 
    6361             :                             if (dp->conversion == 'f' || dp->conversion == 'F')
    6362             :                               {
    6363             :                                 *p++ = '0';
    6364             :                                 if ((flags & FLAG_ALT) || precision > 0)
    6365             :                                   {
    6366             :                                     *p++ = decimal_point_char ();
    6367             :                                     for (; precision > 0; precision--)
    6368             :                                       *p++ = '0';
    6369             :                                   }
    6370             :                               }
    6371             :                             else if (dp->conversion == 'e' || dp->conversion == 'E')
    6372             :                               {
    6373             :                                 *p++ = '0';
    6374             :                                 if ((flags & FLAG_ALT) || precision > 0)
    6375             :                                   {
    6376             :                                     *p++ = decimal_point_char ();
    6377             :                                     for (; precision > 0; precision--)
    6378             :                                       *p++ = '0';
    6379             :                                   }
    6380             :                                 *p++ = dp->conversion; /* 'e' or 'E' */
    6381             :                                 *p++ = '+';
    6382             :                                 /* Produce the same number of exponent digits as
    6383             :                                    the native printf implementation.  */
    6384             : #   if defined _WIN32 && ! defined __CYGWIN__
    6385             :                                 *p++ = '0';
    6386             : #   endif
    6387             :                                 *p++ = '0';
    6388             :                                 *p++ = '0';
    6389             :                               }
    6390             :                             else if (dp->conversion == 'g' || dp->conversion == 'G')
    6391             :                               {
    6392             :                                 *p++ = '0';
    6393             :                                 if (flags & FLAG_ALT)
    6394             :                                   {
    6395             :                                     size_t ndigits =
    6396             :                                       (precision > 0 ? precision - 1 : 0);
    6397             :                                     *p++ = decimal_point_char ();
    6398             :                                     for (; ndigits > 0; --ndigits)
    6399             :                                       *p++ = '0';
    6400             :                                   }
    6401             :                               }
    6402             :                             else
    6403             :                               abort ();
    6404             : #  endif
    6405             :                           }
    6406             :                       }
    6407             :                   }
    6408             : # endif
    6409             : 
    6410             :                 /* The generated string now extends from tmp to p, with the
    6411             :                    zero padding insertion point being at pad_ptr.  */
    6412             :                 count = p - tmp;
    6413             : 
    6414             :                 if (count < width)
    6415             :                   {
    6416             :                     size_t pad = width - count;
    6417             :                     DCHAR_T *end = p + pad;
    6418             : 
    6419             :                     if (flags & FLAG_LEFT)
    6420             :                       {
    6421             :                         /* Pad with spaces on the right.  */
    6422             :                         for (; pad > 0; pad--)
    6423             :                           *p++ = ' ';
    6424             :                       }
    6425             :                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
    6426             :                       {
    6427             :                         /* Pad with zeroes.  */
    6428             :                         DCHAR_T *q = end;
    6429             : 
    6430             :                         while (p > pad_ptr)
    6431             :                           *--q = *--p;
    6432             :                         for (; pad > 0; pad--)
    6433             :                           *p++ = '0';
    6434             :                       }
    6435             :                     else
    6436             :                       {
    6437             :                         /* Pad with spaces on the left.  */
    6438             :                         DCHAR_T *q = end;
    6439             : 
    6440             :                         while (p > tmp)
    6441             :                           *--q = *--p;
    6442             :                         for (; pad > 0; pad--)
    6443             :                           *p++ = ' ';
    6444             :                       }
    6445             : 
    6446             :                     p = end;
    6447             :                   }
    6448             : 
    6449             :                 count = p - tmp;
    6450             : 
    6451             :                 if (count >= tmp_length)
    6452             :                   /* tmp_length was incorrectly calculated - fix the
    6453             :                      code above!  */
    6454             :                   abort ();
    6455             : 
    6456             :                 /* Make room for the result.  */
    6457             :                 if (count >= allocated - length)
    6458             :                   {
    6459             :                     size_t n = xsum (length, count);
    6460             : 
    6461             :                     ENSURE_ALLOCATION_ELSE (n,
    6462             :                       { if (tmp != tmpbuf) free (tmp); goto out_of_memory; });
    6463             :                   }
    6464             : 
    6465             :                 /* Append the result.  */
    6466             :                 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
    6467             :                 if (tmp != tmpbuf)
    6468             :                   free (tmp);
    6469             :                 length += count;
    6470             :               }
    6471             : #endif
    6472             :             else
    6473             :               {
    6474       14534 :                 arg_type type = a.arg[dp->arg_index].type;
    6475       14534 :                 int flags = dp->flags;
    6476             : #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6477             :                 int has_width;
    6478             : #endif
    6479             : #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6480             :                 size_t width;
    6481             : #endif
    6482             : #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6483             :                 int has_precision;
    6484             :                 size_t precision;
    6485             : #endif
    6486             : #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    6487             :                 int prec_ourselves;
    6488             : #else
    6489             : #               define prec_ourselves 0
    6490             : #endif
    6491             : #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6492             :                 int group_ourselves;
    6493             : #else
    6494             : #               define group_ourselves 0
    6495             : #endif
    6496             : #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST
    6497             : #               define pad_ourselves 1
    6498             : #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6499             :                 int pad_ourselves;
    6500             : #else
    6501             : #               define pad_ourselves 0
    6502             : #endif
    6503             :                 TCHAR_T *fbp;
    6504             :                 unsigned int prefix_count;
    6505             :                 int prefixes[2] IF_LINT (= { 0 });
    6506             :                 int orig_errno;
    6507             : #if !USE_SNPRINTF
    6508             :                 size_t tmp_length;
    6509             :                 TCHAR_T tmpbuf[700];
    6510             :                 TCHAR_T *tmp;
    6511             : #endif
    6512             : 
    6513             : #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6514             :                 has_width = 0;
    6515             : #endif
    6516             : #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6517             :                 width = 0;
    6518             :                 if (dp->width_start != dp->width_end)
    6519             :                   {
    6520             :                     if (dp->width_arg_index != ARG_NONE)
    6521             :                       {
    6522             :                         int arg;
    6523             : 
    6524             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    6525             :                           abort ();
    6526             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    6527             :                         width = arg;
    6528             :                         if (arg < 0)
    6529             :                           {
    6530             :                             /* "A negative field width is taken as a '-' flag
    6531             :                                 followed by a positive field width."  */
    6532             :                             flags |= FLAG_LEFT;
    6533             :                             width = -width;
    6534             :                           }
    6535             :                       }
    6536             :                     else
    6537             :                       {
    6538             :                         const FCHAR_T *digitp = dp->width_start;
    6539             : 
    6540             :                         do
    6541             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    6542             :                         while (digitp != dp->width_end);
    6543             :                       }
    6544             :                     if (width > (size_t) INT_MAX)
    6545             :                       goto overflow;
    6546             : # define WIDTH_IS_CHECKED 1
    6547             : # if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6548             :                     has_width = 1;
    6549             : # endif
    6550             :                   }
    6551             : #endif
    6552             : 
    6553             : #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6554             :                 has_precision = 0;
    6555             :                 precision = 6;
    6556             :                 if (dp->precision_start != dp->precision_end)
    6557             :                   {
    6558             :                     if (dp->precision_arg_index != ARG_NONE)
    6559             :                       {
    6560             :                         int arg;
    6561             : 
    6562             :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    6563             :                           abort ();
    6564             :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    6565             :                         /* "A negative precision is taken as if the precision
    6566             :                             were omitted."  */
    6567             :                         if (arg >= 0)
    6568             :                           {
    6569             :                             precision = arg;
    6570             :                             has_precision = 1;
    6571             :                           }
    6572             :                       }
    6573             :                     else
    6574             :                       {
    6575             :                         const FCHAR_T *digitp = dp->precision_start + 1;
    6576             : 
    6577             :                         precision = 0;
    6578             :                         while (digitp != dp->precision_end)
    6579             :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    6580             :                         has_precision = 1;
    6581             :                       }
    6582             :                   }
    6583             : #endif
    6584             : 
    6585             :                 /* Decide whether to handle the precision ourselves.  */
    6586             : #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    6587             :                 switch (dp->conversion)
    6588             :                   {
    6589             : # if NEED_PRINTF_UNBOUNDED_PRECISION
    6590             :                   case 'd': case 'i': case 'u':
    6591             :                   case 'b':
    6592             :                   #if SUPPORT_GNU_PRINTF_DIRECTIVES \
    6593             :                       || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
    6594             :                   case 'B':
    6595             :                   #endif
    6596             :                   case 'o':
    6597             :                     prec_ourselves = has_precision && (precision > 0);
    6598             :                     break;
    6599             : # endif
    6600             :                   case 'x': case 'X': case 'p':
    6601             :                     prec_ourselves =
    6602             :                       has_precision
    6603             :                       && (0
    6604             : # if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO
    6605             :                           || (precision == 0)
    6606             : # endif
    6607             : # if NEED_PRINTF_UNBOUNDED_PRECISION
    6608             :                           || (precision > 0)
    6609             : # endif
    6610             :                          );
    6611             :                     break;
    6612             :                   default:
    6613             :                     prec_ourselves = 0;
    6614             :                     break;
    6615             :                   }
    6616             : #endif
    6617             : 
    6618             :                 /* Decide whether to add the thousands separators ourselves.  */
    6619             : #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6620             :                 if (flags & FLAG_GROUP)
    6621             :                   {
    6622             :                     switch (dp->conversion)
    6623             :                       {
    6624             :                       case 'd': case 'i': case 'u':
    6625             : # if NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    6626             :                         group_ourselves = 1;
    6627             : # else
    6628             :                         group_ourselves = prec_ourselves;
    6629             : # endif
    6630             :                         break;
    6631             :                       case 'f': case 'F': case 'g': case 'G':
    6632             : # if NEED_PRINTF_FLAG_GROUPING
    6633             :                         group_ourselves = 1;
    6634             : # else
    6635             :                         group_ourselves = prec_ourselves;
    6636             : # endif
    6637             :                         break;
    6638             :                       default:
    6639             :                         group_ourselves = 0;
    6640             :                         break;
    6641             :                       }
    6642             :                   }
    6643             :                 else
    6644             :                   group_ourselves = 0;
    6645             : #endif
    6646             : 
    6647             :                 /* Decide whether to perform the padding ourselves.  */
    6648             : #if !((WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST) && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT)
    6649             :                 switch (dp->conversion)
    6650             :                   {
    6651             : # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
    6652             :                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
    6653             :                      to perform the padding after this conversion.  Functions
    6654             :                      with unistdio extensions perform the padding based on
    6655             :                      character count rather than element count.  */
    6656             :                   case 'c': case 's':
    6657             : # endif
    6658             : # if NEED_PRINTF_FLAG_ZERO
    6659             :                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
    6660             :                   case 'a': case 'A':
    6661             : # endif
    6662             :                     pad_ourselves = 1;
    6663             :                     break;
    6664             :                   default:
    6665             :                     pad_ourselves = prec_ourselves | group_ourselves;
    6666             :                     break;
    6667             :                   }
    6668             : #endif
    6669             : 
    6670             : #if !USE_SNPRINTF
    6671             :                 /* Allocate a temporary buffer of sufficient size for calling
    6672             :                    sprintf.  */
    6673             :                 tmp_length =
    6674             :                   MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
    6675             :                                    flags, width, has_precision, precision,
    6676             :                                    pad_ourselves);
    6677             : 
    6678             :                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
    6679             :                   tmp = tmpbuf;
    6680             :                 else
    6681             :                   {
    6682             :                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
    6683             : 
    6684             :                     if (size_overflow_p (tmp_memsize))
    6685             :                       /* Overflow, would lead to out of memory.  */
    6686             :                       goto out_of_memory;
    6687             :                     tmp = (TCHAR_T *) malloc (tmp_memsize);
    6688             :                     if (tmp == NULL)
    6689             :                       /* Out of memory.  */
    6690             :                       goto out_of_memory;
    6691             :                   }
    6692             : #endif
    6693             : 
    6694             :                 /* Construct the format string for calling snprintf or
    6695             :                    sprintf.  */
    6696       14534 :                 fbp = buf;
    6697       14534 :                 *fbp++ = '%';
    6698       14534 :                 if ((flags & FLAG_GROUP) && !group_ourselves)
    6699           0 :                   *fbp++ = '\'';
    6700       14534 :                 if (flags & FLAG_LEFT)
    6701           0 :                   *fbp++ = '-';
    6702       14534 :                 if (flags & FLAG_SHOWSIGN)
    6703           0 :                   *fbp++ = '+';
    6704       14534 :                 if (flags & FLAG_SPACE)
    6705           0 :                   *fbp++ = ' ';
    6706       14534 :                 if (flags & FLAG_ALT)
    6707           0 :                   *fbp++ = '#';
    6708             : #if __GLIBC__ >= 2 && !defined __UCLIBC__
    6709       14534 :                 if (flags & FLAG_LOCALIZED)
    6710           0 :                   *fbp++ = 'I';
    6711             : #endif
    6712             :                 if (!pad_ourselves)
    6713             :                   {
    6714       14534 :                     if (flags & FLAG_ZERO)
    6715       13625 :                       *fbp++ = '0';
    6716       14534 :                     if (dp->width_start != dp->width_end)
    6717             :                       {
    6718       13625 :                         size_t n = dp->width_end - dp->width_start;
    6719             : #if !WIDTH_IS_CHECKED
    6720             :                         size_t width;
    6721             :                         /* Reject an out-of-range width.
    6722             :                            The underlying SNPRINTF already does this on some
    6723             :                            platforms (glibc, musl, macOS, FreeBSD, NetBSD,
    6724             :                            OpenBSD, Cygwin, Solaris, MSVC).  However, on others
    6725             :                            (AIX, mingw), it doesn't; thus this vasnprintf
    6726             :                            invocation would succeed and produce a wrong result.
    6727             :                            So, this is redundant on some platforms, but it's a
    6728             :                            quick check anyway.  */
    6729       13625 :                         if (dp->width_arg_index != ARG_NONE)
    6730             :                           {
    6731             :                             int arg;
    6732             : 
    6733           0 :                             if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    6734           0 :                               abort ();
    6735           0 :                             arg = a.arg[dp->width_arg_index].a.a_int;
    6736           0 :                             width = arg;
    6737           0 :                             if (arg < 0)
    6738             :                               {
    6739             :                                 /* "A negative field width is taken as a '-' flag
    6740             :                                     followed by a positive field width."  */
    6741           0 :                                 width = -width;
    6742             :                               }
    6743             :                           }
    6744             :                         else
    6745             :                           {
    6746       13625 :                             const FCHAR_T *digitp = dp->width_start;
    6747             : 
    6748       13625 :                             width = 0;
    6749             :                             do
    6750       13625 :                               width = xsum (xtimes (width, 10), *digitp++ - '0');
    6751       13625 :                             while (digitp != dp->width_end);
    6752             :                           }
    6753       13625 :                         if (width > (size_t) INT_MAX)
    6754           0 :                           goto overflow;
    6755             : #endif
    6756             :                         /* The width specification is known to consist only
    6757             :                            of standard ASCII characters.  */
    6758             :                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
    6759             :                           {
    6760       13625 :                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
    6761       13625 :                             fbp += n;
    6762             :                           }
    6763             :                         else
    6764             :                           {
    6765             :                             const FCHAR_T *mp = dp->width_start;
    6766             :                             do
    6767             :                               *fbp++ = *mp++;
    6768             :                             while (--n > 0);
    6769             :                           }
    6770             :                       }
    6771             :                   }
    6772             :                 if (!prec_ourselves)
    6773             :                   {
    6774       14534 :                     if (dp->precision_start != dp->precision_end)
    6775             :                       {
    6776          10 :                         size_t n = dp->precision_end - dp->precision_start;
    6777             :                         /* The precision specification is known to consist only
    6778             :                            of standard ASCII characters.  */
    6779             :                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
    6780             :                           {
    6781          10 :                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
    6782          10 :                             fbp += n;
    6783             :                           }
    6784             :                         else
    6785             :                           {
    6786             :                             const FCHAR_T *mp = dp->precision_start;
    6787             :                             do
    6788             :                               *fbp++ = *mp++;
    6789             :                             while (--n > 0);
    6790             :                           }
    6791             :                       }
    6792             :                   }
    6793             : 
    6794       14534 :                 switch (+type)
    6795             :                   {
    6796           0 :                   case TYPE_LONGLONGINT:
    6797             :                   case TYPE_ULONGLONGINT:
    6798             :                   #if INT8_WIDTH > LONG_WIDTH
    6799             :                   case TYPE_INT8_T:
    6800             :                   #endif
    6801             :                   #if UINT8_WIDTH > LONG_WIDTH
    6802             :                   case TYPE_UINT8_T:
    6803             :                   #endif
    6804             :                   #if INT16_WIDTH > LONG_WIDTH
    6805             :                   case TYPE_INT16_T:
    6806             :                   #endif
    6807             :                   #if UINT16_WIDTH > LONG_WIDTH
    6808             :                   case TYPE_UINT16_T:
    6809             :                   #endif
    6810             :                   #if INT32_WIDTH > LONG_WIDTH
    6811             :                   case TYPE_INT32_T:
    6812             :                   #endif
    6813             :                   #if UINT32_WIDTH > LONG_WIDTH
    6814             :                   case TYPE_UINT32_T:
    6815             :                   #endif
    6816             :                   #if INT64_WIDTH > LONG_WIDTH
    6817             :                   case TYPE_INT64_T:
    6818             :                   #endif
    6819             :                   #if UINT64_WIDTH > LONG_WIDTH
    6820             :                   case TYPE_UINT64_T:
    6821             :                   #endif
    6822             :                   #if INT_FAST8_WIDTH > LONG_WIDTH
    6823             :                   case TYPE_INT_FAST8_T:
    6824             :                   #endif
    6825             :                   #if UINT_FAST8_WIDTH > LONG_WIDTH
    6826             :                   case TYPE_UINT_FAST8_T:
    6827             :                   #endif
    6828             :                   #if INT_FAST16_WIDTH > LONG_WIDTH
    6829             :                   case TYPE_INT_FAST16_T:
    6830             :                   #endif
    6831             :                   #if UINT_FAST16_WIDTH > LONG_WIDTH
    6832             :                   case TYPE_UINT_FAST16_T:
    6833             :                   #endif
    6834             :                   #if INT_FAST32_WIDTH > LONG_WIDTH
    6835             :                   case TYPE_INT3_FAST2_T:
    6836             :                   #endif
    6837             :                   #if UINT_FAST32_WIDTH > LONG_WIDTH
    6838             :                   case TYPE_UINT_FAST32_T:
    6839             :                   #endif
    6840             :                   #if INT_FAST64_WIDTH > LONG_WIDTH
    6841             :                   case TYPE_INT_FAST64_T:
    6842             :                   #endif
    6843             :                   #if UINT_FAST64_WIDTH > LONG_WIDTH
    6844             :                   case TYPE_UINT_FAST64_T:
    6845             :                   #endif
    6846             : #if defined _WIN32 && ! defined __CYGWIN__
    6847             :                     *fbp++ = 'I';
    6848             :                     *fbp++ = '6';
    6849             :                     *fbp++ = '4';
    6850             :                     break;
    6851             : #else
    6852           0 :                     *fbp++ = 'l';
    6853             : #endif
    6854             :                     FALLTHROUGH;
    6855           0 :                   case TYPE_LONGINT:
    6856             :                   case TYPE_ULONGINT:
    6857             :                   #if INT8_WIDTH > INT_WIDTH && INT8_WIDTH <= LONG_WIDTH
    6858             :                   case TYPE_INT8_T:
    6859             :                   #endif
    6860             :                   #if UINT8_WIDTH > INT_WIDTH && UINT8_WIDTH <= LONG_WIDTH
    6861             :                   case TYPE_UINT8_T:
    6862             :                   #endif
    6863             :                   #if INT16_WIDTH > INT_WIDTH && INT16_WIDTH <= LONG_WIDTH
    6864             :                   case TYPE_INT16_T:
    6865             :                   #endif
    6866             :                   #if UINT16_WIDTH > INT_WIDTH && UINT16_WIDTH <= LONG_WIDTH
    6867             :                   case TYPE_UINT16_T:
    6868             :                   #endif
    6869             :                   #if INT32_WIDTH > INT_WIDTH && INT32_WIDTH <= LONG_WIDTH
    6870             :                   case TYPE_INT32_T:
    6871             :                   #endif
    6872             :                   #if UINT32_WIDTH > INT_WIDTH && UINT32_WIDTH <= LONG_WIDTH
    6873             :                   case TYPE_UINT32_T:
    6874             :                   #endif
    6875             :                   #if INT64_WIDTH > INT_WIDTH && INT64_WIDTH <= LONG_WIDTH
    6876             :                   case TYPE_INT64_T:
    6877             :                   #endif
    6878             :                   #if UINT64_WIDTH > INT_WIDTH && UINT64_WIDTH <= LONG_WIDTH
    6879             :                   case TYPE_UINT64_T:
    6880             :                   #endif
    6881             :                   #if INT_FAST8_WIDTH > INT_WIDTH && INT_FAST8_WIDTH <= LONG_WIDTH
    6882             :                   case TYPE_INT_FAST8_T:
    6883             :                   #endif
    6884             :                   #if UINT_FAST8_WIDTH > INT_WIDTH && UINT_FAST8_WIDTH <= LONG_WIDTH
    6885             :                   case TYPE_UINT_FAST8_T:
    6886             :                   #endif
    6887             :                   #if INT_FAST16_WIDTH > INT_WIDTH && INT_FAST16_WIDTH <= LONG_WIDTH
    6888             :                   case TYPE_INT_FAST16_T:
    6889             :                   #endif
    6890             :                   #if UINT_FAST16_WIDTH > INT_WIDTH && UINT_FAST16_WIDTH <= LONG_WIDTH
    6891             :                   case TYPE_UINT_FAST16_T:
    6892             :                   #endif
    6893             :                   #if INT_FAST32_WIDTH > INT_WIDTH && INT_FAST32_WIDTH <= LONG_WIDTH
    6894             :                   case TYPE_INT_FAST32_T:
    6895             :                   #endif
    6896             :                   #if UINT_FAST32_WIDTH > INT_WIDTH && UINT_FAST32_WIDTH <= LONG_WIDTH
    6897             :                   case TYPE_UINT_FAST32_T:
    6898             :                   #endif
    6899             :                   #if INT_FAST64_WIDTH > INT_WIDTH && INT_FAST64_WIDTH <= LONG_WIDTH
    6900             :                   case TYPE_INT_FAST64_T:
    6901             :                   #endif
    6902             :                   #if UINT_FAST64_WIDTH > INT_WIDTH && UINT_FAST64_WIDTH <= LONG_WIDTH
    6903             :                   case TYPE_UINT_FAST64_T:
    6904             :                   #endif
    6905             :                   #if HAVE_WINT_T
    6906             :                   case TYPE_WIDE_CHAR:
    6907             :                   #endif
    6908             :                   case TYPE_WIDE_STRING:
    6909           0 :                     *fbp++ = 'l';
    6910           0 :                     break;
    6911           0 :                   case TYPE_LONGDOUBLE:
    6912           0 :                     *fbp++ = 'L';
    6913           0 :                     break;
    6914       14534 :                   default:
    6915       14534 :                     break;
    6916             :                   }
    6917             : #if NEED_PRINTF_DIRECTIVE_F
    6918             :                 if (dp->conversion == 'F')
    6919             :                   *fbp = 'f';
    6920             :                 else
    6921             : #endif
    6922       14534 :                   *fbp = dp->conversion;
    6923             : #if USE_SNPRINTF
    6924             :                 /* Decide whether to pass %n in the format string
    6925             :                    to SNPRINTF.  */
    6926             : # if (((!WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR)                              \
    6927             :        && (HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99))       \
    6928             :       || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3))       \
    6929             :           && !defined __UCLIBC__)                                           \
    6930             :       || (defined __APPLE__ && defined __MACH__)                            \
    6931             :       || defined __OpenBSD__                                                \
    6932             :       || defined __ANDROID__                                                \
    6933             :       || (defined _WIN32 && ! defined __CYGWIN__))                          \
    6934             :       || (WIDE_CHAR_VERSION && MUSL_LIBC)
    6935             :                 /* We can avoid passing %n and instead rely on SNPRINTF's
    6936             :                    return value if
    6937             :                      - !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR, because otherwise,
    6938             :                        when WIDE_CHAR_VERSION && DCHAR_IS_TCHAR,
    6939             :                        snwprintf()/_snwprintf() (Windows) and swprintf() (Unix)
    6940             :                        don't return the needed buffer size,
    6941             :                      and
    6942             :                      - we're compiling for a system where we know
    6943             :                        - that snprintf's return value conforms to ISO C 99
    6944             :                          (HAVE_SNPRINTF_RETVAL_C99) and
    6945             :                        - that snprintf always produces NUL-terminated strings
    6946             :                          (HAVE_SNPRINTF_TRUNCATION_C99).
    6947             :                    And it is desirable to do so, because more and more platforms
    6948             :                    no longer support %n, for "security reasons".  */
    6949             :                 /* On specific platforms, listed below, we *must* avoid %n.
    6950             :                    In the case
    6951             :                      !WIDE_CHAR_VERSION && HAVE_SNPRINTF_RETVAL_C99 && !USE_MSVC__SNPRINTF
    6952             :                    we can rely on the return value of snprintf instead.  Whereas
    6953             :                    in the opposite case
    6954             :                      WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
    6955             :                    we need to make room based on an estimation, computed by
    6956             :                    MAX_ROOM_NEEDED.  */
    6957             :                 /* The following platforms forbid %n:
    6958             :                      - On glibc2 systems from 2004-10-18 or newer, the use of
    6959             :                        %n in format strings in writable memory may crash the
    6960             :                        program (if compiled with _FORTIFY_SOURCE=2).
    6961             :                      - On macOS 10.13 or newer, the use of %n in format
    6962             :                        strings in writable memory by default crashes the
    6963             :                        program.
    6964             :                      - On OpenBSD, since 2021-08-30, the use of %n in format
    6965             :                        strings produces an abort (see
    6966             :                        <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfprintf.c.diff?r1=1.79&r2=1.80&f=h>,
    6967             :                        <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfwprintf.c.diff?r1=1.20&r2=1.21&f=h>).
    6968             :                      - On Android, starting on 2018-03-07, the use of %n in
    6969             :                        format strings produces a fatal error (see
    6970             :                        <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>).
    6971             :                      - On native Windows systems (such as mingw) where the OS is
    6972             :                        Windows Vista, the use of %n in format strings by default
    6973             :                        crashes the program. See
    6974             :                          <https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
    6975             :                          <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output>
    6976             :                    On the first four of these platforms, if !WIDE_CHAR_VERSION,
    6977             :                    it is not a big deal to avoid %n, because on these platforms,
    6978             :                    HAVE_SNPRINTF_RETVAL_C99 and HAVE_SNPRINTF_TRUNCATION_C99 are
    6979             :                    1.
    6980             :                    On native Windows, if !WIDE_CHAR_VERSION, it's not a big deal
    6981             :                    either because:
    6982             :                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
    6983             :                        snprintf does not write more than the specified number
    6984             :                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
    6985             :                        '4', '5', '6' into buf, not '4', '5', '\0'.)
    6986             :                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
    6987             :                        allows us to recognize the case of an insufficient
    6988             :                        buffer size: it returns -1 in this case.  */
    6989             :                 /* Additionally, in the WIDE_CHAR_VERSION case, we cannot use %n
    6990             :                    on musl libc because we would run into an swprintf() bug.
    6991             :                    See <https://www.openwall.com/lists/musl/2023/03/19/1>.  */
    6992       14534 :                 fbp[1] = '\0';
    6993             : # else           /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */
    6994             :                 fbp[1] = '%';
    6995             :                 fbp[2] = 'n';
    6996             :                 fbp[3] = '\0';
    6997             : # endif
    6998             : #else
    6999             :                 fbp[1] = '\0';
    7000             : #endif
    7001             : 
    7002             :                 /* Construct the arguments for calling snprintf or sprintf.  */
    7003       14534 :                 prefix_count = 0;
    7004       14534 :                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
    7005             :                   {
    7006           0 :                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    7007           0 :                       abort ();
    7008           0 :                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
    7009             :                   }
    7010       14534 :                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
    7011             :                   {
    7012           0 :                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    7013           0 :                       abort ();
    7014           0 :                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
    7015             :                   }
    7016             : 
    7017             : #if USE_SNPRINTF
    7018             :                 /* The SNPRINTF result is appended after result[0..length].
    7019             :                    The latter is an array of DCHAR_T; SNPRINTF appends an
    7020             :                    array of TCHAR_T to it.  This is possible because
    7021             :                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
    7022             :                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
    7023             : # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
    7024             :                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
    7025             :                    where an snprintf() with maxlen==1 acts like sprintf().  */
    7026       14534 :                 ENSURE_ALLOCATION (xsum (length,
    7027             :                                          (2 + TCHARS_PER_DCHAR - 1)
    7028             :                                          / TCHARS_PER_DCHAR));
    7029             :                 /* Prepare checking whether snprintf returns the count
    7030             :                    via %n.  */
    7031       14534 :                 *(TCHAR_T *) (result + length) = '\0';
    7032             : #endif
    7033             : 
    7034       14534 :                 orig_errno = errno;
    7035             : 
    7036             :                 for (;;)
    7037           0 :                   {
    7038       14534 :                     int count = -1;
    7039             : 
    7040             : #if USE_SNPRINTF
    7041       14534 :                     int retcount = 0;
    7042       14534 :                     size_t maxlen = allocated - length;
    7043             :                     /* SNPRINTF can fail if its second argument is
    7044             :                        > INT_MAX.  */
    7045       14534 :                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
    7046           0 :                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
    7047       14534 :                     maxlen = maxlen * TCHARS_PER_DCHAR;
    7048             : # define SNPRINTF_BUF(arg) \
    7049             :                     switch (prefix_count)                                   \
    7050             :                       {                                                     \
    7051             :                       case 0:                                               \
    7052             :                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
    7053             :                                              maxlen, buf,                   \
    7054             :                                              arg, &count);                  \
    7055             :                         break;                                              \
    7056             :                       case 1:                                               \
    7057             :                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
    7058             :                                              maxlen, buf,                   \
    7059             :                                              prefixes[0], arg, &count);     \
    7060             :                         break;                                              \
    7061             :                       case 2:                                               \
    7062             :                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
    7063             :                                              maxlen, buf,                   \
    7064             :                                              prefixes[0], prefixes[1], arg, \
    7065             :                                              &count);                       \
    7066             :                         break;                                              \
    7067             :                       default:                                              \
    7068             :                         abort ();                                           \
    7069             :                       }
    7070             : #else
    7071             : # define SNPRINTF_BUF(arg) \
    7072             :                     switch (prefix_count)                                   \
    7073             :                       {                                                     \
    7074             :                       case 0:                                               \
    7075             :                         count = sprintf (tmp, buf, arg);                    \
    7076             :                         break;                                              \
    7077             :                       case 1:                                               \
    7078             :                         count = sprintf (tmp, buf, prefixes[0], arg);       \
    7079             :                         break;                                              \
    7080             :                       case 2:                                               \
    7081             :                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
    7082             :                                          arg);                              \
    7083             :                         break;                                              \
    7084             :                       default:                                              \
    7085             :                         abort ();                                           \
    7086             :                       }
    7087             : #endif
    7088             : 
    7089       14534 :                     errno = 0;
    7090       14534 :                     switch (+type)
    7091             :                       {
    7092           0 :                       case TYPE_SCHAR:
    7093             :                         {
    7094           0 :                           int arg = a.arg[dp->arg_index].a.a_schar;
    7095           0 :                           SNPRINTF_BUF (arg);
    7096             :                         }
    7097           0 :                         break;
    7098           0 :                       case TYPE_UCHAR:
    7099             :                         {
    7100           0 :                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
    7101           0 :                           SNPRINTF_BUF (arg);
    7102             :                         }
    7103           0 :                         break;
    7104           0 :                       case TYPE_SHORT:
    7105             :                         {
    7106           0 :                           int arg = a.arg[dp->arg_index].a.a_short;
    7107           0 :                           SNPRINTF_BUF (arg);
    7108             :                         }
    7109           0 :                         break;
    7110           0 :                       case TYPE_USHORT:
    7111             :                         {
    7112           0 :                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
    7113           0 :                           SNPRINTF_BUF (arg);
    7114             :                         }
    7115           0 :                         break;
    7116         755 :                       case TYPE_INT:
    7117             :                         {
    7118         755 :                           int arg = a.arg[dp->arg_index].a.a_int;
    7119         755 :                           SNPRINTF_BUF (arg);
    7120             :                         }
    7121         755 :                         break;
    7122       13705 :                       case TYPE_UINT:
    7123             :                         {
    7124       13705 :                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
    7125       13705 :                           SNPRINTF_BUF (arg);
    7126             :                         }
    7127       13705 :                         break;
    7128           0 :                       case TYPE_LONGINT:
    7129             :                         {
    7130           0 :                           long int arg = a.arg[dp->arg_index].a.a_longint;
    7131           0 :                           SNPRINTF_BUF (arg);
    7132             :                         }
    7133           0 :                         break;
    7134           0 :                       case TYPE_ULONGINT:
    7135             :                         {
    7136           0 :                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
    7137           0 :                           SNPRINTF_BUF (arg);
    7138             :                         }
    7139           0 :                         break;
    7140           0 :                       case TYPE_LONGLONGINT:
    7141             :                         {
    7142           0 :                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
    7143           0 :                           SNPRINTF_BUF (arg);
    7144             :                         }
    7145           0 :                         break;
    7146           0 :                       case TYPE_ULONGLONGINT:
    7147             :                         {
    7148           0 :                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
    7149           0 :                           SNPRINTF_BUF (arg);
    7150             :                         }
    7151           0 :                         break;
    7152           0 :                       case TYPE_INT8_T:
    7153             :                         {
    7154           0 :                           int8_t arg = a.arg[dp->arg_index].a.a_int8_t;
    7155           0 :                           SNPRINTF_BUF (arg);
    7156             :                         }
    7157           0 :                         break;
    7158           0 :                       case TYPE_UINT8_T:
    7159             :                         {
    7160           0 :                           uint8_t arg = a.arg[dp->arg_index].a.a_uint8_t;
    7161           0 :                           SNPRINTF_BUF (arg);
    7162             :                         }
    7163           0 :                         break;
    7164           0 :                       case TYPE_INT16_T:
    7165             :                         {
    7166           0 :                           int16_t arg = a.arg[dp->arg_index].a.a_int16_t;
    7167           0 :                           SNPRINTF_BUF (arg);
    7168             :                         }
    7169           0 :                         break;
    7170           0 :                       case TYPE_UINT16_T:
    7171             :                         {
    7172           0 :                           uint16_t arg = a.arg[dp->arg_index].a.a_uint16_t;
    7173           0 :                           SNPRINTF_BUF (arg);
    7174             :                         }
    7175           0 :                         break;
    7176           0 :                       case TYPE_INT32_T:
    7177             :                         {
    7178           0 :                           int32_t arg = a.arg[dp->arg_index].a.a_int32_t;
    7179           0 :                           SNPRINTF_BUF (arg);
    7180             :                         }
    7181           0 :                         break;
    7182           0 :                       case TYPE_UINT32_T:
    7183             :                         {
    7184           0 :                           uint32_t arg = a.arg[dp->arg_index].a.a_uint32_t;
    7185           0 :                           SNPRINTF_BUF (arg);
    7186             :                         }
    7187           0 :                         break;
    7188           0 :                       case TYPE_INT64_T:
    7189             :                         {
    7190           0 :                           int64_t arg = a.arg[dp->arg_index].a.a_int64_t;
    7191           0 :                           SNPRINTF_BUF (arg);
    7192             :                         }
    7193           0 :                         break;
    7194           0 :                       case TYPE_UINT64_T:
    7195             :                         {
    7196           0 :                           uint64_t arg = a.arg[dp->arg_index].a.a_uint64_t;
    7197           0 :                           SNPRINTF_BUF (arg);
    7198             :                         }
    7199           0 :                         break;
    7200           0 :                       case TYPE_INT_FAST8_T:
    7201             :                         {
    7202           0 :                           int_fast8_t arg = a.arg[dp->arg_index].a.a_int_fast8_t;
    7203           0 :                           SNPRINTF_BUF (arg);
    7204             :                         }
    7205           0 :                         break;
    7206           0 :                       case TYPE_UINT_FAST8_T:
    7207             :                         {
    7208           0 :                           uint_fast8_t arg = a.arg[dp->arg_index].a.a_uint_fast8_t;
    7209           0 :                           SNPRINTF_BUF (arg);
    7210             :                         }
    7211           0 :                         break;
    7212           0 :                       case TYPE_INT_FAST16_T:
    7213             :                         {
    7214           0 :                           int_fast16_t arg = a.arg[dp->arg_index].a.a_int_fast16_t;
    7215           0 :                           SNPRINTF_BUF (arg);
    7216             :                         }
    7217           0 :                         break;
    7218           0 :                       case TYPE_UINT_FAST16_T:
    7219             :                         {
    7220           0 :                           uint_fast16_t arg = a.arg[dp->arg_index].a.a_uint_fast16_t;
    7221           0 :                           SNPRINTF_BUF (arg);
    7222             :                         }
    7223           0 :                         break;
    7224           0 :                       case TYPE_INT_FAST32_T:
    7225             :                         {
    7226           0 :                           int_fast32_t arg = a.arg[dp->arg_index].a.a_int_fast32_t;
    7227           0 :                           SNPRINTF_BUF (arg);
    7228             :                         }
    7229           0 :                         break;
    7230           0 :                       case TYPE_UINT_FAST32_T:
    7231             :                         {
    7232           0 :                           uint_fast32_t arg = a.arg[dp->arg_index].a.a_uint_fast32_t;
    7233           0 :                           SNPRINTF_BUF (arg);
    7234             :                         }
    7235           0 :                         break;
    7236           0 :                       case TYPE_INT_FAST64_T:
    7237             :                         {
    7238           0 :                           int_fast64_t arg = a.arg[dp->arg_index].a.a_int_fast64_t;
    7239           0 :                           SNPRINTF_BUF (arg);
    7240             :                         }
    7241           0 :                         break;
    7242           0 :                       case TYPE_UINT_FAST64_T:
    7243             :                         {
    7244           0 :                           uint_fast64_t arg = a.arg[dp->arg_index].a.a_uint_fast64_t;
    7245           0 :                           SNPRINTF_BUF (arg);
    7246             :                         }
    7247           0 :                         break;
    7248          43 :                       case TYPE_DOUBLE:
    7249             :                         {
    7250          43 :                           double arg = a.arg[dp->arg_index].a.a_double;
    7251          43 :                           SNPRINTF_BUF (arg);
    7252             :                         }
    7253          43 :                         break;
    7254           0 :                       case TYPE_LONGDOUBLE:
    7255             :                         {
    7256           0 :                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
    7257           0 :                           SNPRINTF_BUF (arg);
    7258             :                         }
    7259           0 :                         break;
    7260          31 :                       case TYPE_CHAR:
    7261             :                         {
    7262          31 :                           int arg = a.arg[dp->arg_index].a.a_char;
    7263          31 :                           SNPRINTF_BUF (arg);
    7264             :                         }
    7265          31 :                         break;
    7266             : #if HAVE_WINT_T
    7267           0 :                       case TYPE_WIDE_CHAR:
    7268             :                         {
    7269           0 :                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
    7270           0 :                           SNPRINTF_BUF (arg);
    7271             :                         }
    7272           0 :                         break;
    7273             : #endif
    7274           0 :                       case TYPE_STRING:
    7275             :                         {
    7276           0 :                           const char *arg = a.arg[dp->arg_index].a.a_string;
    7277           0 :                           SNPRINTF_BUF (arg);
    7278             :                         }
    7279           0 :                         break;
    7280           0 :                       case TYPE_WIDE_STRING:
    7281             :                         {
    7282           0 :                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
    7283           0 :                           SNPRINTF_BUF (arg);
    7284             :                         }
    7285           0 :                         break;
    7286           0 :                       case TYPE_POINTER:
    7287             :                         {
    7288           0 :                           void *arg = a.arg[dp->arg_index].a.a_pointer;
    7289           0 :                           SNPRINTF_BUF (arg);
    7290             :                         }
    7291           0 :                         break;
    7292           0 :                       default:
    7293           0 :                         abort ();
    7294             :                       }
    7295             : 
    7296             : #if USE_SNPRINTF
    7297             :                     /* Portability: Not all implementations of snprintf()
    7298             :                        are ISO C 99 compliant.  Determine the number of
    7299             :                        bytes that snprintf() has produced or would have
    7300             :                        produced.  */
    7301       14534 :                     if (count >= 0)
    7302             :                       {
    7303             :                         /* Verify that snprintf() has NUL-terminated its
    7304             :                            result.  */
    7305           0 :                         if ((unsigned int) count < maxlen
    7306           0 :                             && ((TCHAR_T *) (result + length)) [count] != '\0')
    7307           0 :                           abort ();
    7308             :                         /* Portability hack.  */
    7309           0 :                         if (retcount > count)
    7310           0 :                           count = retcount;
    7311             :                       }
    7312             :                     else
    7313             :                       {
    7314             :                         /* snprintf() doesn't understand the '%n'
    7315             :                            directive.  */
    7316       14534 :                         if (fbp[1] != '\0')
    7317             :                           {
    7318             :                             /* Don't use the '%n' directive; instead, look
    7319             :                                at the snprintf() return value.  */
    7320           0 :                             fbp[1] = '\0';
    7321           0 :                             continue;
    7322             :                           }
    7323             :                         else
    7324             :                           {
    7325             :                             /* Look at the snprintf() return value.  */
    7326       14534 :                             if (retcount < 0)
    7327             :                               {
    7328             : # if (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
    7329             :                                 /* HP-UX 10.20 snprintf() is doubly deficient:
    7330             :                                    It doesn't understand the '%n' directive,
    7331             :                                    *and* it returns -1 (rather than the length
    7332             :                                    that would have been required) when the
    7333             :                                    buffer is too small.
    7334             :                                    Likewise, in case of
    7335             :                                    WIDE_CHAR_VERSION && DCHAR_IS_TCHAR, the
    7336             :                                    functions snwprintf()/_snwprintf() (Windows)
    7337             :                                    or swprintf() (Unix).
    7338             :                                    But a failure at this point can also come
    7339             :                                    from other reasons than a too small buffer,
    7340             :                                    such as an invalid wide string argument to
    7341             :                                    the %ls directive, or possibly an invalid
    7342             :                                    floating-point argument.  */
    7343             :                                 size_t tmp_length =
    7344             :                                   MAX_ROOM_NEEDED (&a, dp->arg_index,
    7345             :                                                    dp->conversion, type, flags,
    7346             :                                                    width,
    7347             :                                                    has_precision,
    7348             :                                                    precision, pad_ourselves);
    7349             : 
    7350             :                                 if (maxlen < tmp_length)
    7351             :                                   {
    7352             :                                     /* Make more room.  But try to do through
    7353             :                                        this reallocation only once.  */
    7354             :                                     size_t bigger_need =
    7355             :                                       xsum (length,
    7356             :                                             xsum (tmp_length,
    7357             :                                                   TCHARS_PER_DCHAR - 1)
    7358             :                                             / TCHARS_PER_DCHAR);
    7359             :                                     /* And always grow proportionally.
    7360             :                                        (There may be several arguments, each
    7361             :                                        needing a little more room than the
    7362             :                                        previous one.)  */
    7363             :                                     size_t bigger_need2 =
    7364             :                                       xsum (xtimes (allocated, 2), 12);
    7365             :                                     if (bigger_need < bigger_need2)
    7366             :                                       bigger_need = bigger_need2;
    7367             :                                     ENSURE_ALLOCATION (bigger_need);
    7368             :                                     continue;
    7369             :                                   }
    7370             : # endif
    7371             :                               }
    7372             :                             else
    7373             :                               {
    7374       14534 :                                 count = retcount;
    7375             : # if WIDE_CHAR_VERSION && defined __MINGW32__
    7376             :                                 if (count == 0 && dp->conversion == 'c')
    7377             :                                   /* snwprintf returned 0 instead of 1.  But it
    7378             :                                      wrote a null wide character.  */
    7379             :                                   count = 1;
    7380             : # endif
    7381             :                               }
    7382             :                           }
    7383             :                       }
    7384             : #endif
    7385             : 
    7386             :                     /* Attempt to handle failure.  */
    7387       14534 :                     if (count < 0)
    7388             :                       {
    7389             :                         /* SNPRINTF or sprintf failed.  Use the errno that it
    7390             :                            has set, if any.  */
    7391           0 :                         if (errno == 0)
    7392             :                           {
    7393           0 :                             if (dp->conversion == 'c' || dp->conversion == 's')
    7394           0 :                               errno = EILSEQ;
    7395             :                             else
    7396           0 :                               errno = EINVAL;
    7397             :                           }
    7398             : 
    7399           0 :                         goto fail_with_errno;
    7400             :                       }
    7401             : 
    7402             : #if USE_SNPRINTF
    7403             :                     /* Handle overflow of the allocated buffer.
    7404             :                        If such an overflow occurs, a C99 compliant snprintf()
    7405             :                        returns a count >= maxlen.  However, a non-compliant
    7406             :                        snprintf() function returns only count = maxlen - 1.  To
    7407             :                        cover both cases, test whether count >= maxlen - 1.  */
    7408       14534 :                     if ((unsigned int) count + 1 >= maxlen)
    7409             :                       {
    7410             :                         /* If maxlen already has attained its allowed maximum,
    7411             :                            allocating more memory will not increase maxlen.
    7412             :                            Instead of looping, bail out.  */
    7413           0 :                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
    7414           0 :                           goto overflow;
    7415             :                         else
    7416             :                           {
    7417             :                             /* Need at least (count + 1) * sizeof (TCHAR_T)
    7418             :                                bytes.  (The +1 is for the trailing NUL.)
    7419             :                                But ask for (count + 2) * sizeof (TCHAR_T)
    7420             :                                bytes, so that in the next round, we likely get
    7421             :                                  maxlen > (unsigned int) count + 1
    7422             :                                and so we don't get here again.
    7423             :                                And allocate proportionally, to avoid looping
    7424             :                                eternally if snprintf() reports a too small
    7425             :                                count.  */
    7426             :                             size_t n =
    7427           0 :                               xmax (xsum (length,
    7428           0 :                                           ((unsigned int) count + 2
    7429             :                                            + TCHARS_PER_DCHAR - 1)
    7430             :                                           / TCHARS_PER_DCHAR),
    7431           0 :                                     xtimes (allocated, 2));
    7432             : 
    7433           0 :                             ENSURE_ALLOCATION (n);
    7434           0 :                             continue;
    7435             :                           }
    7436             :                       }
    7437             : #endif
    7438             : 
    7439             : #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    7440             :                     if (prec_ourselves)
    7441             :                       {
    7442             :                         /* Handle the precision.  */
    7443             :                         TCHAR_T *prec_ptr =
    7444             : # if USE_SNPRINTF
    7445             :                           (TCHAR_T *) (result + length);
    7446             : # else
    7447             :                           tmp;
    7448             : # endif
    7449             :                         size_t prefix_count;
    7450             :                         size_t move;
    7451             : 
    7452             :                         prefix_count = 0;
    7453             :                         /* Put the additional zeroes after the sign.  */
    7454             :                         if (count >= 1
    7455             :                             && (*prec_ptr == '-' || *prec_ptr == '+'
    7456             :                                 || *prec_ptr == ' '))
    7457             :                           prefix_count = 1;
    7458             :                         /* Put the additional zeroes after the 0x prefix if
    7459             :                            (flags & FLAG_ALT) || (dp->conversion == 'p'), or
    7460             :                            after the 0b prefix if (flags & FLAG_ALT).  */
    7461             :                         else if (count >= 2
    7462             :                                  && prec_ptr[0] == '0'
    7463             :                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'
    7464             :                                      || prec_ptr[1] == 'b'
    7465             :                                      || prec_ptr[1] == 'B'))
    7466             :                           prefix_count = 2;
    7467             : 
    7468             :                         move = count - prefix_count;
    7469             :                         if (precision > move)
    7470             :                           {
    7471             :                             /* Insert zeroes.  */
    7472             :                             size_t insert = precision - move;
    7473             :                             TCHAR_T *prec_end;
    7474             : 
    7475             : # if USE_SNPRINTF
    7476             :                             size_t n =
    7477             :                               xsum (length,
    7478             :                                     (count + insert + TCHARS_PER_DCHAR - 1)
    7479             :                                     / TCHARS_PER_DCHAR);
    7480             :                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
    7481             :                             ENSURE_ALLOCATION (n);
    7482             :                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
    7483             :                             prec_ptr = (TCHAR_T *) (result + length);
    7484             : # endif
    7485             : 
    7486             :                             prec_end = prec_ptr + count;
    7487             :                             prec_ptr += prefix_count;
    7488             : 
    7489             :                             while (prec_end > prec_ptr)
    7490             :                               {
    7491             :                                 prec_end--;
    7492             :                                 prec_end[insert] = prec_end[0];
    7493             :                               }
    7494             : 
    7495             :                             prec_end += insert;
    7496             :                             do
    7497             :                               *--prec_end = '0';
    7498             :                             while (prec_end > prec_ptr);
    7499             : 
    7500             :                             count += insert;
    7501             :                           }
    7502             : # if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO
    7503             :                         else if (precision == 0
    7504             :                                  && move == 1
    7505             :                                  && prec_ptr[prefix_count] == '0')
    7506             :                           {
    7507             :                             /* Replace the "0" result with an empty string.  */
    7508             :                             count = prefix_count;
    7509             :                           }
    7510             : # endif
    7511             :                       }
    7512             : #endif
    7513             : 
    7514             : #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    7515             :                     if (group_ourselves) /* implies (flags & FLAG_GROUP) */
    7516             :                       /* Handle the grouping.  */
    7517             :                       switch (dp->conversion)
    7518             :                         {
    7519             :                         /* These are the only conversion to which grouping
    7520             :                            applies.  */
    7521             :                         case 'd': case 'i': case 'u':
    7522             :                         case 'f': case 'F': case 'g': case 'G':
    7523             :                           {
    7524             :                             /* Determine the thousands separator of the current
    7525             :                                locale.  */
    7526             :                             const TCHAR_T *thousep;
    7527             :                             TCHAR_T thousep_buf[10];
    7528             : 
    7529             : # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
    7530             :                             /* TCHAR_T is wchar_t.  */
    7531             :                             thousep = thousands_separator_wchar (thousep_buf);
    7532             : # else
    7533             :                             /* TCHAR_T is char.  */
    7534             :                             thousep = thousands_separator_char (thousep_buf);
    7535             : # endif
    7536             : 
    7537             :                             /* Nothing to do in locales where thousep is the empty
    7538             :                                string.  */
    7539             :                             if (*thousep != 0)
    7540             :                               {
    7541             :                                 /* Since FLAG_LOCALIZED is only supported on glibc
    7542             :                                    systems, here we can assume that all digits are
    7543             :                                    the ASCII digits '0'..'9'.  */
    7544             :                                 TCHAR_T *number_ptr =
    7545             : # if USE_SNPRINTF
    7546             :                                   (TCHAR_T *) (result + length);
    7547             : # else
    7548             :                                   tmp;
    7549             : # endif
    7550             :                                 TCHAR_T *end_ptr = number_ptr + count;
    7551             : 
    7552             :                                 /* Find where the leading digits start.  */
    7553             :                                 TCHAR_T *digits_ptr = number_ptr;
    7554             :                                 if (count >= 1
    7555             :                                     && (*digits_ptr == '-' || *digits_ptr == '+'
    7556             :                                         || *digits_ptr == ' '))
    7557             :                                   digits_ptr++;
    7558             : 
    7559             :                                 /* Find where the leading digits end.  */
    7560             :                                 TCHAR_T *digits_end_ptr;
    7561             :                                 switch (dp->conversion)
    7562             :                                   {
    7563             :                                   case 'd': case 'i': case 'u':
    7564             :                                     digits_end_ptr = end_ptr;
    7565             :                                     break;
    7566             :                                   case 'f': case 'F': case 'g': case 'G':
    7567             :                                     {
    7568             :                                       TCHAR_T decimal_point = decimal_point_char ();
    7569             :                                       for (digits_end_ptr = digits_ptr;
    7570             :                                            digits_end_ptr < end_ptr;
    7571             :                                            digits_end_ptr++)
    7572             :                                         if (*digits_end_ptr == decimal_point
    7573             :                                             || *digits_end_ptr == 'e')
    7574             :                                           break;
    7575             :                                     }
    7576             :                                     break;
    7577             :                                   }
    7578             : 
    7579             :                                 /* Determine the number of thousands separators
    7580             :                                    to insert.  */
    7581             :                                 const signed char *grouping = grouping_rule ();
    7582             :                                 size_t insert =
    7583             :                                   num_thousands_separators (grouping, digits_end_ptr - digits_ptr);
    7584             :                                 if (insert > 0)
    7585             :                                   {
    7586             : # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
    7587             : #                                   define thousep_len 1
    7588             : # else
    7589             :                                     size_t thousep_len = strlen (thousep);
    7590             : # endif
    7591             : # if USE_SNPRINTF
    7592             :                                     size_t digits_offset = digits_ptr - number_ptr;
    7593             :                                     size_t digits_end_offset = digits_end_ptr - number_ptr;
    7594             :                                     size_t n =
    7595             :                                       xsum (length,
    7596             :                                             (count + insert * thousep_len + TCHARS_PER_DCHAR - 1)
    7597             :                                             / TCHARS_PER_DCHAR);
    7598             :                                     length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
    7599             :                                     ENSURE_ALLOCATION (n);
    7600             :                                     length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
    7601             :                                     number_ptr = (TCHAR_T *) (result + length);
    7602             :                                     end_ptr = number_ptr + count;
    7603             :                                     digits_ptr = number_ptr + digits_offset;
    7604             :                                     digits_end_ptr = number_ptr + digits_end_offset;
    7605             : # endif
    7606             : 
    7607             :                                     count += insert * thousep_len;
    7608             : 
    7609             :                                     const TCHAR_T *p = end_ptr;
    7610             :                                     TCHAR_T *q = end_ptr + insert * thousep_len;
    7611             :                                     while (p > digits_end_ptr)
    7612             :                                       *--q = *--p;
    7613             :                                     const signed char *g = grouping;
    7614             :                                     for (;;)
    7615             :                                       {
    7616             :                                         int h = *g;
    7617             :                                         if (h <= 0)
    7618             :                                           abort ();
    7619             :                                         int i = h;
    7620             :                                         do
    7621             :                                           *--q = *--p;
    7622             :                                         while (--i > 0);
    7623             : # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
    7624             :                                         *--q = *thousep;
    7625             : # else
    7626             :                                         q -= thousep_len;
    7627             :                                         memcpy (q, thousep, thousep_len);
    7628             : # endif
    7629             :                                         insert--;
    7630             :                                         if (insert == 0)
    7631             :                                           break;
    7632             :                                         if (g[1] != 0)
    7633             :                                           g++;
    7634             :                                       }
    7635             :                                     /* Here q == p.  Done with the insertions.  */
    7636             :                                   }
    7637             :                               }
    7638             :                           }
    7639             :                           break;
    7640             :                         }
    7641             : #endif
    7642             : 
    7643             : #if !USE_SNPRINTF
    7644             :                     if (count >= tmp_length)
    7645             :                       /* tmp_length was incorrectly calculated - fix the
    7646             :                          code above!  */
    7647             :                       abort ();
    7648             : #endif
    7649             : 
    7650             : #if !DCHAR_IS_TCHAR
    7651             :                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
    7652             :                     if (dp->conversion == 'c' || dp->conversion == 's'
    7653             :                         || (flags & FLAG_GROUP)
    7654             : # if __GLIBC__ >= 2 && !defined __UCLIBC__
    7655             :                         || (flags & FLAG_LOCALIZED)
    7656             : # endif
    7657             :                        )
    7658             :                       {
    7659             :                         /* The result string is not guaranteed to be ASCII.  */
    7660             :                         const TCHAR_T *tmpsrc;
    7661             :                         DCHAR_T *tmpdst;
    7662             :                         size_t tmpdst_len;
    7663             :                         /* This code assumes that TCHAR_T is 'char'.  */
    7664             :                         static_assert (sizeof (TCHAR_T) == 1);
    7665             : # if USE_SNPRINTF
    7666             :                         tmpsrc = (TCHAR_T *) (result + length);
    7667             : # else
    7668             :                         tmpsrc = tmp;
    7669             : # endif
    7670             : # if WIDE_CHAR_VERSION
    7671             :                         /* Convert tmpsrc[0..count-1] to a freshly allocated
    7672             :                            wide character array.  */
    7673             :                         mbstate_t state;
    7674             : 
    7675             :                         mbszero (&state);
    7676             :                         tmpdst_len = 0;
    7677             :                         {
    7678             :                           const TCHAR_T *src = tmpsrc;
    7679             :                           size_t srclen = count;
    7680             : 
    7681             :                           for (; srclen > 0; tmpdst_len++)
    7682             :                             {
    7683             :                               /* Parse the next multibyte character.  */
    7684             :                               size_t ret = mbrtowc (NULL, src, srclen, &state);
    7685             :                               if (ret == (size_t)(-2) || ret == (size_t)(-1))
    7686             :                                 goto fail_with_EILSEQ;
    7687             :                               if (ret == 0)
    7688             :                                 ret = 1;
    7689             :                               src += ret;
    7690             :                               srclen -= ret;
    7691             :                             }
    7692             :                         }
    7693             : 
    7694             :                         tmpdst =
    7695             :                           (wchar_t *) malloc ((tmpdst_len + 1) * sizeof (wchar_t));
    7696             :                         if (tmpdst == NULL)
    7697             :                           goto out_of_memory;
    7698             : 
    7699             :                         mbszero (&state);
    7700             :                         {
    7701             :                           DCHAR_T *destptr = tmpdst;
    7702             :                           const TCHAR_T *src = tmpsrc;
    7703             :                           size_t srclen = count;
    7704             : 
    7705             :                           for (; srclen > 0; destptr++)
    7706             :                             {
    7707             :                               /* Parse the next multibyte character.  */
    7708             :                               size_t ret = mbrtowc (destptr, src, srclen, &state);
    7709             :                               if (ret == (size_t)(-2) || ret == (size_t)(-1))
    7710             :                                 /* Should already have been caught in the first
    7711             :                                    loop, above.  */
    7712             :                                 abort ();
    7713             :                               if (ret == 0)
    7714             :                                 ret = 1;
    7715             :                               src += ret;
    7716             :                               srclen -= ret;
    7717             :                             }
    7718             :                         }
    7719             : # else
    7720             :                         tmpdst =
    7721             :                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
    7722             :                                                     iconveh_question_mark,
    7723             :                                                     tmpsrc, count,
    7724             :                                                     NULL,
    7725             :                                                     NULL, &tmpdst_len);
    7726             :                         if (tmpdst == NULL)
    7727             :                           goto fail_with_errno;
    7728             : # endif
    7729             :                         ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
    7730             :                           { free (tmpdst); goto out_of_memory; });
    7731             :                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
    7732             :                         free (tmpdst);
    7733             :                         count = tmpdst_len;
    7734             :                       }
    7735             :                     else
    7736             :                       {
    7737             :                         /* The result string is ASCII.
    7738             :                            Simple 1:1 conversion.  */
    7739             : # if USE_SNPRINTF
    7740             :                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
    7741             :                            no-op conversion, in-place on the array starting
    7742             :                            at (result + length).  */
    7743             :                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
    7744             : # endif
    7745             :                           {
    7746             :                             const TCHAR_T *tmpsrc;
    7747             :                             DCHAR_T *tmpdst;
    7748             :                             size_t n;
    7749             : 
    7750             : # if USE_SNPRINTF
    7751             :                             if (result == resultbuf)
    7752             :                               {
    7753             :                                 tmpsrc = (TCHAR_T *) (result + length);
    7754             :                                 /* ENSURE_ALLOCATION will not move tmpsrc
    7755             :                                    (because it's part of resultbuf).  */
    7756             :                                 ENSURE_ALLOCATION (xsum (length, count));
    7757             :                               }
    7758             :                             else
    7759             :                               {
    7760             :                                 /* ENSURE_ALLOCATION will move the array
    7761             :                                    (because it uses realloc().  */
    7762             :                                 ENSURE_ALLOCATION (xsum (length, count));
    7763             :                                 tmpsrc = (TCHAR_T *) (result + length);
    7764             :                               }
    7765             : # else
    7766             :                             tmpsrc = tmp;
    7767             :                             ENSURE_ALLOCATION (xsum (length, count));
    7768             : # endif
    7769             :                             tmpdst = result + length;
    7770             :                             /* Copy backwards, because of overlapping.  */
    7771             :                             tmpsrc += count;
    7772             :                             tmpdst += count;
    7773             :                             for (n = count; n > 0; n--)
    7774             :                               *--tmpdst = *--tmpsrc;
    7775             :                           }
    7776             :                       }
    7777             : #endif
    7778             : 
    7779             : #if DCHAR_IS_TCHAR && !USE_SNPRINTF
    7780             :                     /* Make room for the result.  */
    7781             :                     if (count > allocated - length)
    7782             :                       {
    7783             :                         /* Need at least count elements.  But allocate
    7784             :                            proportionally.  */
    7785             :                         size_t n =
    7786             :                           xmax (xsum (length, count), xtimes (allocated, 2));
    7787             : 
    7788             :                         ENSURE_ALLOCATION (n);
    7789             :                       }
    7790             : #endif
    7791             : 
    7792             :                     /* Here count <= allocated - length.  */
    7793             : 
    7794             :                     /* Perform padding.  */
    7795             : #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION || NEED_PRINTF_FLAG_GROUPING || NEED_PRINTF_FLAG_GROUPING_INT
    7796             :                     if (pad_ourselves && has_width)
    7797             :                       {
    7798             :                         size_t w;
    7799             : # if ENABLE_UNISTDIO
    7800             :                         /* Outside POSIX, it's preferable to compare the width
    7801             :                            against the number of _characters_ of the converted
    7802             :                            value.  */
    7803             :                         w = DCHAR_MBSNLEN (result + length, count);
    7804             : # elif __GLIBC__ >= 2
    7805             :                         /* glibc prefers to compare the width against the number
    7806             :                            of characters as well, but only for numeric conversion
    7807             :                            specifiers.  See
    7808             :                            <https://sourceware.org/bugzilla/show_bug.cgi?id=28943>
    7809             :                            <https://sourceware.org/bugzilla/show_bug.cgi?id=30883>
    7810             :                            <https://sourceware.org/bugzilla/show_bug.cgi?id=31542>  */
    7811             :                         switch (dp->conversion)
    7812             :                           {
    7813             :                           case 'd': case 'i': case 'u':
    7814             :                           case 'f': case 'F': case 'g': case 'G':
    7815             :                             w = DCHAR_MBSNLEN (result + length, count);
    7816             :                             break;
    7817             :                           default:
    7818             :                             w = count;
    7819             :                             break;
    7820             :                           }
    7821             : # else
    7822             :                         /* The width is compared against the number of _bytes_
    7823             :                            of the converted value, says POSIX.  */
    7824             :                         w = count;
    7825             : # endif
    7826             :                         if (w < width)
    7827             :                           {
    7828             :                             size_t pad = width - w;
    7829             : 
    7830             :                             /* Make room for the result.  */
    7831             :                             if (xsum (count, pad) > allocated - length)
    7832             :                               {
    7833             :                                 /* Need at least count + pad elements.  But
    7834             :                                    allocate proportionally.  */
    7835             :                                 size_t n =
    7836             :                                   xmax (xsum3 (length, count, pad),
    7837             :                                         xtimes (allocated, 2));
    7838             : 
    7839             : # if USE_SNPRINTF
    7840             :                                 length += count;
    7841             :                                 ENSURE_ALLOCATION (n);
    7842             :                                 length -= count;
    7843             : # else
    7844             :                                 ENSURE_ALLOCATION (n);
    7845             : # endif
    7846             :                               }
    7847             :                             /* Here count + pad <= allocated - length.  */
    7848             : 
    7849             :                             {
    7850             : # if !DCHAR_IS_TCHAR || USE_SNPRINTF
    7851             :                               DCHAR_T * const rp = result + length;
    7852             : # else
    7853             :                               DCHAR_T * const rp = tmp;
    7854             : # endif
    7855             :                               DCHAR_T *p = rp + count;
    7856             :                               DCHAR_T *end = p + pad;
    7857             :                               DCHAR_T *pad_ptr;
    7858             : # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
    7859             :                               if (dp->conversion == 'c'
    7860             :                                   || dp->conversion == 's')
    7861             :                                 /* No zero-padding for string directives.  */
    7862             :                                 pad_ptr = NULL;
    7863             :                               else
    7864             : # endif
    7865             :                                 {
    7866             :                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
    7867             :                                   /* No zero-padding of "inf" and "nan".  */
    7868             :                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
    7869             :                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
    7870             :                                     pad_ptr = NULL;
    7871             :                                   else
    7872             :                                     /* Do the zero-padding after the "0x" or
    7873             :                                        "0b" prefix, not before.  */
    7874             :                                     if (p - rp >= 2
    7875             :                                         && *rp == '0'
    7876             :                                         && (((dp->conversion == 'a'
    7877             :                                               || dp->conversion == 'x')
    7878             :                                              && rp[1] == 'x')
    7879             :                                             || ((dp->conversion == 'A'
    7880             :                                                  || dp->conversion == 'X')
    7881             :                                                 && rp[1] == 'X')
    7882             :                                             || (dp->conversion == 'b'
    7883             :                                                 && rp[1] == 'b')
    7884             :                                             || (dp->conversion == 'B'
    7885             :                                                 && rp[1] == 'B')))
    7886             :                                       pad_ptr += 2;
    7887             :                                 }
    7888             :                               /* The generated string now extends from rp to p,
    7889             :                                  with the zero padding insertion point being at
    7890             :                                  pad_ptr.  */
    7891             : 
    7892             :                               count = count + pad; /* = end - rp */
    7893             : 
    7894             :                               if (flags & FLAG_LEFT)
    7895             :                                 {
    7896             :                                   /* Pad with spaces on the right.  */
    7897             :                                   for (; pad > 0; pad--)
    7898             :                                     *p++ = ' ';
    7899             :                                 }
    7900             :                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL
    7901             :                                        /* ISO C says: "For d, i, o, u, x, and X
    7902             :                                           conversions, if a precision is
    7903             :                                           specified, the 0 flag is ignored.  */
    7904             :                                        && !(has_precision
    7905             :                                             && (dp->conversion == 'd'
    7906             :                                                 || dp->conversion == 'i'
    7907             :                                                 || dp->conversion == 'o'
    7908             :                                                 || dp->conversion == 'u'
    7909             :                                                 || dp->conversion == 'x'
    7910             :                                                 || dp->conversion == 'X'
    7911             :                                                 /* Although ISO C does not
    7912             :                                                    require it, treat 'b' and 'B'
    7913             :                                                    like 'x' and 'X'.  */
    7914             :                                                 || dp->conversion == 'b'
    7915             :                                                 || dp->conversion == 'B')))
    7916             :                                 {
    7917             :                                   /* Pad with zeroes.  */
    7918             :                                   DCHAR_T *q = end;
    7919             : 
    7920             :                                   while (p > pad_ptr)
    7921             :                                     *--q = *--p;
    7922             :                                   for (; pad > 0; pad--)
    7923             :                                     *p++ = '0';
    7924             :                                 }
    7925             :                               else
    7926             :                                 {
    7927             :                                   /* Pad with spaces on the left.  */
    7928             :                                   DCHAR_T *q = end;
    7929             : 
    7930             :                                   while (p > rp)
    7931             :                                     *--q = *--p;
    7932             :                                   for (; pad > 0; pad--)
    7933             :                                     *p++ = ' ';
    7934             :                                 }
    7935             :                             }
    7936             :                           }
    7937             :                       }
    7938             : #endif
    7939             : 
    7940             :                     /* Here still count <= allocated - length.  */
    7941             : 
    7942             : #if !DCHAR_IS_TCHAR || USE_SNPRINTF
    7943             :                     /* The snprintf() result did fit.  */
    7944             : #else
    7945             :                     /* Append the sprintf() result.  */
    7946             :                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
    7947             : #endif
    7948             : #if !USE_SNPRINTF
    7949             :                     if (tmp != tmpbuf)
    7950             :                       free (tmp);
    7951             : #endif
    7952             : 
    7953             : #if NEED_PRINTF_DIRECTIVE_F
    7954             :                     if (dp->conversion == 'F')
    7955             :                       {
    7956             :                         /* Convert the %f result to upper case for %F.  */
    7957             :                         DCHAR_T *rp = result + length;
    7958             :                         size_t rc;
    7959             :                         for (rc = count; rc > 0; rc--, rp++)
    7960             :                           if (*rp >= 'a' && *rp <= 'z')
    7961             :                             *rp = *rp - 'a' + 'A';
    7962             :                       }
    7963             : #endif
    7964             : 
    7965       14534 :                     length += count;
    7966       14534 :                     break;
    7967             :                   }
    7968       14534 :                 errno = orig_errno;
    7969             : #undef pad_ourselves
    7970             : #undef prec_ourselves
    7971             :               }
    7972             :           }
    7973             :       }
    7974             : 
    7975             :     /* Add the final NUL.  */
    7976       14391 :     ENSURE_ALLOCATION (xsum (length, 1));
    7977       14391 :     result[length] = '\0';
    7978             : 
    7979       14391 :     if (result != resultbuf && length + 1 < allocated)
    7980             :       {
    7981             :         /* Shrink the allocated memory if possible.  */
    7982             :         DCHAR_T *memory;
    7983             : 
    7984           0 :         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
    7985           0 :         if (memory != NULL)
    7986           0 :           result = memory;
    7987             :       }
    7988             : 
    7989       14391 :     if (buf_malloced != NULL)
    7990           0 :       free (buf_malloced);
    7991       14391 :     CLEANUP ();
    7992       14391 :     *lengthp = length;
    7993             :     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
    7994             :        says that snprintf() fails with errno = EOVERFLOW in this case, but
    7995             :        that's only because snprintf() returns an 'int'.  This function does
    7996             :        not have this limitation.  */
    7997       14391 :     return result;
    7998             : 
    7999           0 :   overflow:
    8000           0 :     errno = EOVERFLOW;
    8001           0 :     goto fail_with_errno;
    8002             : 
    8003           0 :   out_of_memory:
    8004           0 :     errno = ENOMEM;
    8005           0 :     goto fail_with_errno;
    8006             : 
    8007             : #if ENABLE_UNISTDIO || (WIDE_CHAR_VERSION || !USE_SNPRINTF || (PTRDIFF_MAX > INT_MAX) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION) || (NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION)
    8008           0 :   fail_with_EILSEQ:
    8009           0 :     errno = EILSEQ;
    8010           0 :     goto fail_with_errno;
    8011             : #endif
    8012             : 
    8013           0 :   fail_with_errno:
    8014           0 :     if (result != resultbuf)
    8015           0 :       free (result);
    8016           0 :     if (buf_malloced != NULL)
    8017           0 :       free (buf_malloced);
    8018           0 :     CLEANUP ();
    8019           0 :     return NULL;
    8020             :   }
    8021             : 
    8022           0 :  out_of_memory_1:
    8023           0 :   errno = ENOMEM;
    8024           0 :   goto fail_1_with_errno;
    8025             : 
    8026           0 :  fail_1_with_EINVAL:
    8027           0 :   errno = EINVAL;
    8028           0 :   goto fail_1_with_errno;
    8029             : 
    8030           0 :  fail_1_with_errno:
    8031           0 :   CLEANUP ();
    8032           0 :   return NULL;
    8033             : }
    8034             : 
    8035             : #undef MAX_ROOM_NEEDED
    8036             : #undef TCHARS_PER_DCHAR
    8037             : #undef SNPRINTF
    8038             : #undef USE_SNPRINTF
    8039             : #undef DCHAR_SET
    8040             : #undef DCHAR_CPY
    8041             : #undef PRINTF_PARSE
    8042             : #undef DIRECTIVES
    8043             : #undef DIRECTIVE
    8044             : #undef DCHAR_IS_TCHAR
    8045             : #undef TCHAR_T
    8046             : #undef DCHAR_T
    8047             : #undef FCHAR_T
    8048             : #undef VASNPRINTF

Generated by: LCOV version 1.14