LCOV - code coverage report
Current view: top level - lib - vasnprintf.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 226 0.0 %
Date: 2017-08-04 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /* vsprintf with automatic memory allocation.
       2             :    Copyright (C) 1999, 2002-2016 Free Software Foundation, Inc.
       3             : 
       4             :    This program is free software; you can redistribute it and/or modify
       5             :    it under the terms of the GNU General Public License as published by
       6             :    the Free Software Foundation; either version 3, or (at your option)
       7             :    any later version.
       8             : 
       9             :    This program 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 General Public License for more details.
      13             : 
      14             :    You should have received a copy of the GNU General Public License along
      15             :    with this program; if not, see <http://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_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
      33             :      SNPRINTF           The system's snprintf (or similar) function.
      34             :                         This may be either snprintf or swprintf.
      35             :      TCHAR_T            The element type of the argument and result string
      36             :                         of the said SNPRINTF function.  This may be either
      37             :                         char or wchar_t.  The code exploits that
      38             :                         sizeof (TCHAR_T) | sizeof (DCHAR_T) and
      39             :                         alignof (TCHAR_T) <= alignof (DCHAR_T).
      40             :      DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
      41             :      DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
      42             :      DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
      43             :      DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
      44             :      DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.  */
      45             : 
      46             : /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
      47             :    This must come before <config.h> because <config.h> may include
      48             :    <features.h>, and once <features.h> has been included, it's too late.  */
      49             : #ifndef _GNU_SOURCE
      50             : # define _GNU_SOURCE    1
      51             : #endif
      52             : 
      53             : #ifndef VASNPRINTF
      54             : # include <config.h>
      55             : #endif
      56             : #ifndef IN_LIBINTL
      57             : # include <alloca.h>
      58             : #endif
      59             : 
      60             : /* Specification.  */
      61             : #ifndef VASNPRINTF
      62             : # if WIDE_CHAR_VERSION
      63             : #  include "vasnwprintf.h"
      64             : # else
      65             : #  include "vasnprintf.h"
      66             : # endif
      67             : #endif
      68             : 
      69             : #include <locale.h>     /* localeconv() */
      70             : #include <stdio.h>      /* snprintf(), sprintf() */
      71             : #include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
      72             : #include <string.h>     /* memcpy(), strlen() */
      73             : #include <errno.h>      /* errno */
      74             : #include <limits.h>     /* CHAR_BIT */
      75             : #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP */
      76             : #if HAVE_NL_LANGINFO
      77             : # include <langinfo.h>
      78             : #endif
      79             : #ifndef VASNPRINTF
      80             : # if WIDE_CHAR_VERSION
      81             : #  include "wprintf-parse.h"
      82             : # else
      83             : #  include "printf-parse.h"
      84             : # endif
      85             : #endif
      86             : 
      87             : /* Checked size_t computations.  */
      88             : #include "xsize.h"
      89             : 
      90             : #include "verify.h"
      91             : 
      92             : #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
      93             : # include <math.h>
      94             : # include "float+.h"
      95             : #endif
      96             : 
      97             : #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
      98             : # include <math.h>
      99             : # include "isnand-nolibm.h"
     100             : #endif
     101             : 
     102             : #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
     103             : # include <math.h>
     104             : # include "isnanl-nolibm.h"
     105             : # include "fpucw.h"
     106             : #endif
     107             : 
     108             : #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
     109             : # include <math.h>
     110             : # include "isnand-nolibm.h"
     111             : # include "printf-frexp.h"
     112             : #endif
     113             : 
     114             : #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
     115             : # include <math.h>
     116             : # include "isnanl-nolibm.h"
     117             : # include "printf-frexpl.h"
     118             : # include "fpucw.h"
     119             : #endif
     120             : 
     121             : /* Default parameters.  */
     122             : #ifndef VASNPRINTF
     123             : # if WIDE_CHAR_VERSION
     124             : #  define VASNPRINTF vasnwprintf
     125             : #  define FCHAR_T wchar_t
     126             : #  define DCHAR_T wchar_t
     127             : #  define TCHAR_T wchar_t
     128             : #  define DCHAR_IS_TCHAR 1
     129             : #  define DIRECTIVE wchar_t_directive
     130             : #  define DIRECTIVES wchar_t_directives
     131             : #  define PRINTF_PARSE wprintf_parse
     132             : #  define DCHAR_CPY wmemcpy
     133             : #  define DCHAR_SET wmemset
     134             : # else
     135             : #  define VASNPRINTF vasnprintf
     136             : #  define FCHAR_T char
     137             : #  define DCHAR_T char
     138             : #  define TCHAR_T char
     139             : #  define DCHAR_IS_TCHAR 1
     140             : #  define DIRECTIVE char_directive
     141             : #  define DIRECTIVES char_directives
     142             : #  define PRINTF_PARSE printf_parse
     143             : #  define DCHAR_CPY memcpy
     144             : #  define DCHAR_SET memset
     145             : # endif
     146             : #endif
     147             : #if WIDE_CHAR_VERSION
     148             :   /* TCHAR_T is wchar_t.  */
     149             : # define USE_SNPRINTF 1
     150             : # if HAVE_DECL__SNWPRINTF
     151             :    /* On Windows, the function swprintf() has a different signature than
     152             :       on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
     153             :       instead.  The mingw function snwprintf() has fewer bugs than the
     154             :       MSVCRT function _snwprintf(), so prefer that.  */
     155             : #  if defined __MINGW32__
     156             : #   define SNPRINTF snwprintf
     157             : #  else
     158             : #   define SNPRINTF _snwprintf
     159             : #  endif
     160             : # else
     161             :    /* Unix.  */
     162             : #  define SNPRINTF swprintf
     163             : # endif
     164             : #else
     165             :   /* TCHAR_T is char.  */
     166             :   /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
     167             :      But don't use it on BeOS, since BeOS snprintf produces no output if the
     168             :      size argument is >= 0x3000000.
     169             :      Also don't use it on Linux libc5, since there snprintf with size = 1
     170             :      writes any output without bounds, like sprintf.  */
     171             : # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
     172             : #  define USE_SNPRINTF 1
     173             : # else
     174             : #  define USE_SNPRINTF 0
     175             : # endif
     176             : # if HAVE_DECL__SNPRINTF
     177             :    /* Windows.  The mingw function snprintf() has fewer bugs than the MSVCRT
     178             :       function _snprintf(), so prefer that.  */
     179             : #  if defined __MINGW32__
     180             : #   define SNPRINTF snprintf
     181             :     /* Here we need to call the native snprintf, not rpl_snprintf.  */
     182             : #   undef snprintf
     183             : #  else
     184             : #   define SNPRINTF _snprintf
     185             : #  endif
     186             : # else
     187             :    /* Unix.  */
     188             : #  define SNPRINTF snprintf
     189             :    /* Here we need to call the native snprintf, not rpl_snprintf.  */
     190             : #  undef snprintf
     191             : # endif
     192             : #endif
     193             : /* Here we need to call the native sprintf, not rpl_sprintf.  */
     194             : #undef sprintf
     195             : 
     196             : /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
     197             :    warnings in this file.  Use -Dlint to suppress them.  */
     198             : #if defined GCC_LINT || defined lint
     199             : # define IF_LINT(Code) Code
     200             : #else
     201             : # define IF_LINT(Code) /* empty */
     202             : #endif
     203             : 
     204             : /* Avoid some warnings from "gcc -Wshadow".
     205             :    This file doesn't use the exp() and remainder() functions.  */
     206             : #undef exp
     207             : #define exp expo
     208             : #undef remainder
     209             : #define remainder rem
     210             : 
     211             : #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
     212             : # if (HAVE_STRNLEN && !defined _AIX)
     213             : #  define local_strnlen strnlen
     214             : # else
     215             : #  ifndef local_strnlen_defined
     216             : #   define local_strnlen_defined 1
     217             : static size_t
     218             : local_strnlen (const char *string, size_t maxlen)
     219             : {
     220             :   const char *end = memchr (string, '\0', maxlen);
     221             :   return end ? (size_t) (end - string) : maxlen;
     222             : }
     223             : #  endif
     224             : # endif
     225             : #endif
     226             : 
     227             : #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
     228             : # if HAVE_WCSLEN
     229             : #  define local_wcslen wcslen
     230             : # else
     231             :    /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
     232             :       a dependency towards this library, here is a local substitute.
     233             :       Define this substitute only once, even if this file is included
     234             :       twice in the same compilation unit.  */
     235             : #  ifndef local_wcslen_defined
     236             : #   define local_wcslen_defined 1
     237             : static size_t
     238             : local_wcslen (const wchar_t *s)
     239             : {
     240             :   const wchar_t *ptr;
     241             : 
     242             :   for (ptr = s; *ptr != (wchar_t) 0; ptr++)
     243             :     ;
     244             :   return ptr - s;
     245             : }
     246             : #  endif
     247             : # endif
     248             : #endif
     249             : 
     250             : #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
     251             : # if HAVE_WCSNLEN
     252             : #  define local_wcsnlen wcsnlen
     253             : # else
     254             : #  ifndef local_wcsnlen_defined
     255             : #   define local_wcsnlen_defined 1
     256             : static size_t
     257             : local_wcsnlen (const wchar_t *s, size_t maxlen)
     258             : {
     259             :   const wchar_t *ptr;
     260             : 
     261             :   for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
     262             :     ;
     263             :   return ptr - s;
     264             : }
     265             : #  endif
     266             : # endif
     267             : #endif
     268             : 
     269             : #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
     270             : /* Determine the decimal-point character according to the current locale.  */
     271             : # ifndef decimal_point_char_defined
     272             : #  define decimal_point_char_defined 1
     273             : static char
     274             : decimal_point_char (void)
     275             : {
     276             :   const char *point;
     277             :   /* Determine it in a multithread-safe way.  We know nl_langinfo is
     278             :      multithread-safe on glibc systems and Mac OS X systems, but is not required
     279             :      to be multithread-safe by POSIX.  sprintf(), however, is multithread-safe.
     280             :      localeconv() is rarely multithread-safe.  */
     281             : #  if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
     282             :   point = nl_langinfo (RADIXCHAR);
     283             : #  elif 1
     284             :   char pointbuf[5];
     285             :   sprintf (pointbuf, "%#.0f", 1.0);
     286             :   point = &pointbuf[1];
     287             : #  else
     288             :   point = localeconv () -> decimal_point;
     289             : #  endif
     290             :   /* The decimal point is always a single byte: either '.' or ','.  */
     291             :   return (point[0] != '\0' ? point[0] : '.');
     292             : }
     293             : # endif
     294             : #endif
     295             : 
     296             : #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
     297             : 
     298             : /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
     299             : static int
     300             : is_infinite_or_zero (double x)
     301             : {
     302             :   return isnand (x) || x + x == x;
     303             : }
     304             : 
     305             : #endif
     306             : 
     307             : #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
     308             : 
     309             : /* Equivalent to !isfinite(x) || x == 0, but does not require libm.  */
     310             : static int
     311             : is_infinite_or_zerol (long double x)
     312             : {
     313             :   return isnanl (x) || x + x == x;
     314             : }
     315             : 
     316             : #endif
     317             : 
     318             : #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
     319             : 
     320             : /* Converting 'long double' to decimal without rare rounding bugs requires
     321             :    real bignums.  We use the naming conventions of GNU gmp, but vastly simpler
     322             :    (and slower) algorithms.  */
     323             : 
     324             : typedef unsigned int mp_limb_t;
     325             : # define GMP_LIMB_BITS 32
     326             : verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
     327             : 
     328             : typedef unsigned long long mp_twolimb_t;
     329             : # define GMP_TWOLIMB_BITS 64
     330             : verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
     331             : 
     332             : /* Representation of a bignum >= 0.  */
     333             : typedef struct
     334             : {
     335             :   size_t nlimbs;
     336             :   mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc().  */
     337             : } mpn_t;
     338             : 
     339             : /* Compute the product of two bignums >= 0.
     340             :    Return the allocated memory in case of success, NULL in case of memory
     341             :    allocation failure.  */
     342             : static void *
     343             : multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
     344             : {
     345             :   const mp_limb_t *p1;
     346             :   const mp_limb_t *p2;
     347             :   size_t len1;
     348             :   size_t len2;
     349             : 
     350             :   if (src1.nlimbs <= src2.nlimbs)
     351             :     {
     352             :       len1 = src1.nlimbs;
     353             :       p1 = src1.limbs;
     354             :       len2 = src2.nlimbs;
     355             :       p2 = src2.limbs;
     356             :     }
     357             :   else
     358             :     {
     359             :       len1 = src2.nlimbs;
     360             :       p1 = src2.limbs;
     361             :       len2 = src1.nlimbs;
     362             :       p2 = src1.limbs;
     363             :     }
     364             :   /* Now 0 <= len1 <= len2.  */
     365             :   if (len1 == 0)
     366             :     {
     367             :       /* src1 or src2 is zero.  */
     368             :       dest->nlimbs = 0;
     369             :       dest->limbs = (mp_limb_t *) malloc (1);
     370             :     }
     371             :   else
     372             :     {
     373             :       /* Here 1 <= len1 <= len2.  */
     374             :       size_t dlen;
     375             :       mp_limb_t *dp;
     376             :       size_t k, i, j;
     377             : 
     378             :       dlen = len1 + len2;
     379             :       dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
     380             :       if (dp == NULL)
     381             :         return NULL;
     382             :       for (k = len2; k > 0; )
     383             :         dp[--k] = 0;
     384             :       for (i = 0; i < len1; i++)
     385             :         {
     386             :           mp_limb_t digit1 = p1[i];
     387             :           mp_twolimb_t carry = 0;
     388             :           for (j = 0; j < len2; j++)
     389             :             {
     390             :               mp_limb_t digit2 = p2[j];
     391             :               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
     392             :               carry += dp[i + j];
     393             :               dp[i + j] = (mp_limb_t) carry;
     394             :               carry = carry >> GMP_LIMB_BITS;
     395             :             }
     396             :           dp[i + len2] = (mp_limb_t) carry;
     397             :         }
     398             :       /* Normalise.  */
     399             :       while (dlen > 0 && dp[dlen - 1] == 0)
     400             :         dlen--;
     401             :       dest->nlimbs = dlen;
     402             :       dest->limbs = dp;
     403             :     }
     404             :   return dest->limbs;
     405             : }
     406             : 
     407             : /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
     408             :    a is written as  a = q * b + r  with 0 <= r < b.  q is the quotient, r
     409             :    the remainder.
     410             :    Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
     411             :    q is incremented.
     412             :    Return the allocated memory in case of success, NULL in case of memory
     413             :    allocation failure.  */
     414             : static void *
     415             : divide (mpn_t a, mpn_t b, mpn_t *q)
     416             : {
     417             :   /* Algorithm:
     418             :      First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
     419             :      with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
     420             :      If m<n, then q:=0 and r:=a.
     421             :      If m>=n=1, perform a single-precision division:
     422             :        r:=0, j:=m,
     423             :        while j>0 do
     424             :          {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
     425             :                = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
     426             :          j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
     427             :        Normalise [q[m-1],...,q[0]], yields q.
     428             :      If m>=n>1, perform a multiple-precision division:
     429             :        We have a/b < beta^(m-n+1).
     430             :        s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
     431             :        Shift a and b left by s bits, copying them. r:=a.
     432             :        r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
     433             :        For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
     434             :          Compute q* :
     435             :            q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
     436             :            In case of overflow (q* >= beta) set q* := beta-1.
     437             :            Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
     438             :            and c3 := b[n-2] * q*.
     439             :            {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
     440             :             occurred.  Furthermore 0 <= c3 < beta^2.
     441             :             If there was overflow and
     442             :             r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
     443             :             the next test can be skipped.}
     444             :            While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
     445             :              Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
     446             :            If q* > 0:
     447             :              Put r := r - b * q* * beta^j. In detail:
     448             :                [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
     449             :                hence: u:=0, for i:=0 to n-1 do
     450             :                               u := u + q* * b[i],
     451             :                               r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
     452             :                               u:=u div beta (+ 1, if carry in subtraction)
     453             :                       r[n+j]:=r[n+j]-u.
     454             :                {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
     455             :                                < q* + 1 <= beta,
     456             :                 the carry u does not overflow.}
     457             :              If a negative carry occurs, put q* := q* - 1
     458             :                and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
     459             :          Set q[j] := q*.
     460             :        Normalise [q[m-n],..,q[0]]; this yields the quotient q.
     461             :        Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
     462             :        rest r.
     463             :        The room for q[j] can be allocated at the memory location of r[n+j].
     464             :      Finally, round-to-even:
     465             :        Shift r left by 1 bit.
     466             :        If r > b or if r = b and q[0] is odd, q := q+1.
     467             :    */
     468             :   const mp_limb_t *a_ptr = a.limbs;
     469             :   size_t a_len = a.nlimbs;
     470             :   const mp_limb_t *b_ptr = b.limbs;
     471             :   size_t b_len = b.nlimbs;
     472             :   mp_limb_t *roomptr;
     473             :   mp_limb_t *tmp_roomptr = NULL;
     474             :   mp_limb_t *q_ptr;
     475             :   size_t q_len;
     476             :   mp_limb_t *r_ptr;
     477             :   size_t r_len;
     478             : 
     479             :   /* Allocate room for a_len+2 digits.
     480             :      (Need a_len+1 digits for the real division and 1 more digit for the
     481             :      final rounding of q.)  */
     482             :   roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
     483             :   if (roomptr == NULL)
     484             :     return NULL;
     485             : 
     486             :   /* Normalise a.  */
     487             :   while (a_len > 0 && a_ptr[a_len - 1] == 0)
     488             :     a_len--;
     489             : 
     490             :   /* Normalise b.  */
     491             :   for (;;)
     492             :     {
     493             :       if (b_len == 0)
     494             :         /* Division by zero.  */
     495             :         abort ();
     496             :       if (b_ptr[b_len - 1] == 0)
     497             :         b_len--;
     498             :       else
     499             :         break;
     500             :     }
     501             : 
     502             :   /* Here m = a_len >= 0 and n = b_len > 0.  */
     503             : 
     504             :   if (a_len < b_len)
     505             :     {
     506             :       /* m<n: trivial case.  q=0, r := copy of a.  */
     507             :       r_ptr = roomptr;
     508             :       r_len = a_len;
     509             :       memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
     510             :       q_ptr = roomptr + a_len;
     511             :       q_len = 0;
     512             :     }
     513             :   else if (b_len == 1)
     514             :     {
     515             :       /* n=1: single precision division.
     516             :          beta^(m-1) <= a < beta^m  ==>  beta^(m-2) <= a/b < beta^m  */
     517             :       r_ptr = roomptr;
     518             :       q_ptr = roomptr + 1;
     519             :       {
     520             :         mp_limb_t den = b_ptr[0];
     521             :         mp_limb_t remainder = 0;
     522             :         const mp_limb_t *sourceptr = a_ptr + a_len;
     523             :         mp_limb_t *destptr = q_ptr + a_len;
     524             :         size_t count;
     525             :         for (count = a_len; count > 0; count--)
     526             :           {
     527             :             mp_twolimb_t num =
     528             :               ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
     529             :             *--destptr = num / den;
     530             :             remainder = num % den;
     531             :           }
     532             :         /* Normalise and store r.  */
     533             :         if (remainder > 0)
     534             :           {
     535             :             r_ptr[0] = remainder;
     536             :             r_len = 1;
     537             :           }
     538             :         else
     539             :           r_len = 0;
     540             :         /* Normalise q.  */
     541             :         q_len = a_len;
     542             :         if (q_ptr[q_len - 1] == 0)
     543             :           q_len--;
     544             :       }
     545             :     }
     546             :   else
     547             :     {
     548             :       /* n>1: multiple precision division.
     549             :          beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n  ==>
     550             :          beta^(m-n-1) <= a/b < beta^(m-n+1).  */
     551             :       /* Determine s.  */
     552             :       size_t s;
     553             :       {
     554             :         mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
     555             :         /* Determine s = GMP_LIMB_BITS - integer_length (msd).
     556             :            Code copied from gnulib's integer_length.c.  */
     557             : # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
     558             :         s = __builtin_clz (msd);
     559             : # else
     560             : #  if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
     561             :         if (GMP_LIMB_BITS <= DBL_MANT_BIT)
     562             :           {
     563             :             /* Use 'double' operations.
     564             :                Assumes an IEEE 754 'double' implementation.  */
     565             : #   define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
     566             : #   define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
     567             : #   define NWORDS \
     568             :      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
     569             :             union { double value; unsigned int word[NWORDS]; } m;
     570             : 
     571             :             /* Use a single integer to floating-point conversion.  */
     572             :             m.value = msd;
     573             : 
     574             :             s = GMP_LIMB_BITS
     575             :                 - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
     576             :                    - DBL_EXP_BIAS);
     577             :           }
     578             :         else
     579             : #   undef NWORDS
     580             : #  endif
     581             :           {
     582             :             s = 31;
     583             :             if (msd >= 0x10000)
     584             :               {
     585             :                 msd = msd >> 16;
     586             :                 s -= 16;
     587             :               }
     588             :             if (msd >= 0x100)
     589             :               {
     590             :                 msd = msd >> 8;
     591             :                 s -= 8;
     592             :               }
     593             :             if (msd >= 0x10)
     594             :               {
     595             :                 msd = msd >> 4;
     596             :                 s -= 4;
     597             :               }
     598             :             if (msd >= 0x4)
     599             :               {
     600             :                 msd = msd >> 2;
     601             :                 s -= 2;
     602             :               }
     603             :             if (msd >= 0x2)
     604             :               {
     605             :                 msd = msd >> 1;
     606             :                 s -= 1;
     607             :               }
     608             :           }
     609             : # endif
     610             :       }
     611             :       /* 0 <= s < GMP_LIMB_BITS.
     612             :          Copy b, shifting it left by s bits.  */
     613             :       if (s > 0)
     614             :         {
     615             :           tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
     616             :           if (tmp_roomptr == NULL)
     617             :             {
     618             :               free (roomptr);
     619             :               return NULL;
     620             :             }
     621             :           {
     622             :             const mp_limb_t *sourceptr = b_ptr;
     623             :             mp_limb_t *destptr = tmp_roomptr;
     624             :             mp_twolimb_t accu = 0;
     625             :             size_t count;
     626             :             for (count = b_len; count > 0; count--)
     627             :               {
     628             :                 accu += (mp_twolimb_t) *sourceptr++ << s;
     629             :                 *destptr++ = (mp_limb_t) accu;
     630             :                 accu = accu >> GMP_LIMB_BITS;
     631             :               }
     632             :             /* accu must be zero, since that was how s was determined.  */
     633             :             if (accu != 0)
     634             :               abort ();
     635             :           }
     636             :           b_ptr = tmp_roomptr;
     637             :         }
     638             :       /* Copy a, shifting it left by s bits, yields r.
     639             :          Memory layout:
     640             :          At the beginning: r = roomptr[0..a_len],
     641             :          at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len]  */
     642             :       r_ptr = roomptr;
     643             :       if (s == 0)
     644             :         {
     645             :           memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
     646             :           r_ptr[a_len] = 0;
     647             :         }
     648             :       else
     649             :         {
     650             :           const mp_limb_t *sourceptr = a_ptr;
     651             :           mp_limb_t *destptr = r_ptr;
     652             :           mp_twolimb_t accu = 0;
     653             :           size_t count;
     654             :           for (count = a_len; count > 0; count--)
     655             :             {
     656             :               accu += (mp_twolimb_t) *sourceptr++ << s;
     657             :               *destptr++ = (mp_limb_t) accu;
     658             :               accu = accu >> GMP_LIMB_BITS;
     659             :             }
     660             :           *destptr++ = (mp_limb_t) accu;
     661             :         }
     662             :       q_ptr = roomptr + b_len;
     663             :       q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
     664             :       {
     665             :         size_t j = a_len - b_len; /* m-n */
     666             :         mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
     667             :         mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
     668             :         mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
     669             :           ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
     670             :         /* Division loop, traversed m-n+1 times.
     671             :            j counts down, b is unchanged, beta/2 <= b[n-1] < beta.  */
     672             :         for (;;)
     673             :           {
     674             :             mp_limb_t q_star;
     675             :             mp_limb_t c1;
     676             :             if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
     677             :               {
     678             :                 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow.  */
     679             :                 mp_twolimb_t num =
     680             :                   ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
     681             :                   | r_ptr[j + b_len - 1];
     682             :                 q_star = num / b_msd;
     683             :                 c1 = num % b_msd;
     684             :               }
     685             :             else
     686             :               {
     687             :                 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1].  */
     688             :                 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
     689             :                 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
     690             :                    <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
     691             :                    <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
     692             :                         {<= beta !}.
     693             :                    If yes, jump directly to the subtraction loop.
     694             :                    (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
     695             :                     <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
     696             :                 if (r_ptr[j + b_len] > b_msd
     697             :                     || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
     698             :                   /* r[j+n] >= b[n-1]+1 or
     699             :                      r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
     700             :                      carry.  */
     701             :                   goto subtract;
     702             :               }
     703             :             /* q_star = q*,
     704             :                c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta).  */
     705             :             {
     706             :               mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
     707             :                 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
     708             :               mp_twolimb_t c3 = /* b[n-2] * q* */
     709             :                 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
     710             :               /* While c2 < c3, increase c2 and decrease c3.
     711             :                  Consider c3-c2.  While it is > 0, decrease it by
     712             :                  b[n-1]*beta+b[n-2].  Because of b[n-1]*beta+b[n-2] >= beta^2/2
     713             :                  this can happen only twice.  */
     714             :               if (c3 > c2)
     715             :                 {
     716             :                   q_star = q_star - 1; /* q* := q* - 1 */
     717             :                   if (c3 - c2 > b_msdd)
     718             :                     q_star = q_star - 1; /* q* := q* - 1 */
     719             :                 }
     720             :             }
     721             :             if (q_star > 0)
     722             :               subtract:
     723             :               {
     724             :                 /* Subtract r := r - b * q* * beta^j.  */
     725             :                 mp_limb_t cr;
     726             :                 {
     727             :                   const mp_limb_t *sourceptr = b_ptr;
     728             :                   mp_limb_t *destptr = r_ptr + j;
     729             :                   mp_twolimb_t carry = 0;
     730             :                   size_t count;
     731             :                   for (count = b_len; count > 0; count--)
     732             :                     {
     733             :                       /* Here 0 <= carry <= q*.  */
     734             :                       carry =
     735             :                         carry
     736             :                         + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
     737             :                         + (mp_limb_t) ~(*destptr);
     738             :                       /* Here 0 <= carry <= beta*q* + beta-1.  */
     739             :                       *destptr++ = ~(mp_limb_t) carry;
     740             :                       carry = carry >> GMP_LIMB_BITS; /* <= q* */
     741             :                     }
     742             :                   cr = (mp_limb_t) carry;
     743             :                 }
     744             :                 /* Subtract cr from r_ptr[j + b_len], then forget about
     745             :                    r_ptr[j + b_len].  */
     746             :                 if (cr > r_ptr[j + b_len])
     747             :                   {
     748             :                     /* Subtraction gave a carry.  */
     749             :                     q_star = q_star - 1; /* q* := q* - 1 */
     750             :                     /* Add b back.  */
     751             :                     {
     752             :                       const mp_limb_t *sourceptr = b_ptr;
     753             :                       mp_limb_t *destptr = r_ptr + j;
     754             :                       mp_limb_t carry = 0;
     755             :                       size_t count;
     756             :                       for (count = b_len; count > 0; count--)
     757             :                         {
     758             :                           mp_limb_t source1 = *sourceptr++;
     759             :                           mp_limb_t source2 = *destptr;
     760             :                           *destptr++ = source1 + source2 + carry;
     761             :                           carry =
     762             :                             (carry
     763             :                              ? source1 >= (mp_limb_t) ~source2
     764             :                              : source1 > (mp_limb_t) ~source2);
     765             :                         }
     766             :                     }
     767             :                     /* Forget about the carry and about r[j+n].  */
     768             :                   }
     769             :               }
     770             :             /* q* is determined.  Store it as q[j].  */
     771             :             q_ptr[j] = q_star;
     772             :             if (j == 0)
     773             :               break;
     774             :             j--;
     775             :           }
     776             :       }
     777             :       r_len = b_len;
     778             :       /* Normalise q.  */
     779             :       if (q_ptr[q_len - 1] == 0)
     780             :         q_len--;
     781             : # if 0 /* Not needed here, since we need r only to compare it with b/2, and
     782             :           b is shifted left by s bits.  */
     783             :       /* Shift r right by s bits.  */
     784             :       if (s > 0)
     785             :         {
     786             :           mp_limb_t ptr = r_ptr + r_len;
     787             :           mp_twolimb_t accu = 0;
     788             :           size_t count;
     789             :           for (count = r_len; count > 0; count--)
     790             :             {
     791             :               accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
     792             :               accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
     793             :               *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
     794             :             }
     795             :         }
     796             : # endif
     797             :       /* Normalise r.  */
     798             :       while (r_len > 0 && r_ptr[r_len - 1] == 0)
     799             :         r_len--;
     800             :     }
     801             :   /* Compare r << 1 with b.  */
     802             :   if (r_len > b_len)
     803             :     goto increment_q;
     804             :   {
     805             :     size_t i;
     806             :     for (i = b_len;;)
     807             :       {
     808             :         mp_limb_t r_i =
     809             :           (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
     810             :           | (i < r_len ? r_ptr[i] << 1 : 0);
     811             :         mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
     812             :         if (r_i > b_i)
     813             :           goto increment_q;
     814             :         if (r_i < b_i)
     815             :           goto keep_q;
     816             :         if (i == 0)
     817             :           break;
     818             :         i--;
     819             :       }
     820             :   }
     821             :   if (q_len > 0 && ((q_ptr[0] & 1) != 0))
     822             :     /* q is odd.  */
     823             :     increment_q:
     824             :     {
     825             :       size_t i;
     826             :       for (i = 0; i < q_len; i++)
     827             :         if (++(q_ptr[i]) != 0)
     828             :           goto keep_q;
     829             :       q_ptr[q_len++] = 1;
     830             :     }
     831             :   keep_q:
     832             :   if (tmp_roomptr != NULL)
     833             :     free (tmp_roomptr);
     834             :   q->limbs = q_ptr;
     835             :   q->nlimbs = q_len;
     836             :   return roomptr;
     837             : }
     838             : 
     839             : /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
     840             :    representation.
     841             :    Destroys the contents of a.
     842             :    Return the allocated memory - containing the decimal digits in low-to-high
     843             :    order, terminated with a NUL character - in case of success, NULL in case
     844             :    of memory allocation failure.  */
     845             : static char *
     846             : convert_to_decimal (mpn_t a, size_t extra_zeroes)
     847             : {
     848             :   mp_limb_t *a_ptr = a.limbs;
     849             :   size_t a_len = a.nlimbs;
     850             :   /* 0.03345 is slightly larger than log(2)/(9*log(10)).  */
     851             :   size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
     852             :   char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
     853             :   if (c_ptr != NULL)
     854             :     {
     855             :       char *d_ptr = c_ptr;
     856             :       for (; extra_zeroes > 0; extra_zeroes--)
     857             :         *d_ptr++ = '0';
     858             :       while (a_len > 0)
     859             :         {
     860             :           /* Divide a by 10^9, in-place.  */
     861             :           mp_limb_t remainder = 0;
     862             :           mp_limb_t *ptr = a_ptr + a_len;
     863             :           size_t count;
     864             :           for (count = a_len; count > 0; count--)
     865             :             {
     866             :               mp_twolimb_t num =
     867             :                 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
     868             :               *ptr = num / 1000000000;
     869             :               remainder = num % 1000000000;
     870             :             }
     871             :           /* Store the remainder as 9 decimal digits.  */
     872             :           for (count = 9; count > 0; count--)
     873             :             {
     874             :               *d_ptr++ = '0' + (remainder % 10);
     875             :               remainder = remainder / 10;
     876             :             }
     877             :           /* Normalize a.  */
     878             :           if (a_ptr[a_len - 1] == 0)
     879             :             a_len--;
     880             :         }
     881             :       /* Remove leading zeroes.  */
     882             :       while (d_ptr > c_ptr && d_ptr[-1] == '0')
     883             :         d_ptr--;
     884             :       /* But keep at least one zero.  */
     885             :       if (d_ptr == c_ptr)
     886             :         *d_ptr++ = '0';
     887             :       /* Terminate the string.  */
     888             :       *d_ptr = '\0';
     889             :     }
     890             :   return c_ptr;
     891             : }
     892             : 
     893             : # if NEED_PRINTF_LONG_DOUBLE
     894             : 
     895             : /* Assuming x is finite and >= 0:
     896             :    write x as x = 2^e * m, where m is a bignum.
     897             :    Return the allocated memory in case of success, NULL in case of memory
     898             :    allocation failure.  */
     899             : static void *
     900             : decode_long_double (long double x, int *ep, mpn_t *mp)
     901             : {
     902             :   mpn_t m;
     903             :   int exp;
     904             :   long double y;
     905             :   size_t i;
     906             : 
     907             :   /* Allocate memory for result.  */
     908             :   m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
     909             :   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
     910             :   if (m.limbs == NULL)
     911             :     return NULL;
     912             :   /* Split into exponential part and mantissa.  */
     913             :   y = frexpl (x, &exp);
     914             :   if (!(y >= 0.0L && y < 1.0L))
     915             :     abort ();
     916             :   /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
     917             :      latter is an integer.  */
     918             :   /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
     919             :      I'm not sure whether it's safe to cast a 'long double' value between
     920             :      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
     921             :      'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
     922             :      doesn't matter).  */
     923             : #  if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
     924             : #   if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
     925             :     {
     926             :       mp_limb_t hi, lo;
     927             :       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
     928             :       hi = (int) y;
     929             :       y -= hi;
     930             :       if (!(y >= 0.0L && y < 1.0L))
     931             :         abort ();
     932             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
     933             :       lo = (int) y;
     934             :       y -= lo;
     935             :       if (!(y >= 0.0L && y < 1.0L))
     936             :         abort ();
     937             :       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
     938             :     }
     939             : #   else
     940             :     {
     941             :       mp_limb_t d;
     942             :       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
     943             :       d = (int) y;
     944             :       y -= d;
     945             :       if (!(y >= 0.0L && y < 1.0L))
     946             :         abort ();
     947             :       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
     948             :     }
     949             : #   endif
     950             : #  endif
     951             :   for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
     952             :     {
     953             :       mp_limb_t hi, lo;
     954             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
     955             :       hi = (int) y;
     956             :       y -= hi;
     957             :       if (!(y >= 0.0L && y < 1.0L))
     958             :         abort ();
     959             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
     960             :       lo = (int) y;
     961             :       y -= lo;
     962             :       if (!(y >= 0.0L && y < 1.0L))
     963             :         abort ();
     964             :       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
     965             :     }
     966             : #  if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
     967             :            precision.  */
     968             :   if (!(y == 0.0L))
     969             :     abort ();
     970             : #  endif
     971             :   /* Normalise.  */
     972             :   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
     973             :     m.nlimbs--;
     974             :   *mp = m;
     975             :   *ep = exp - LDBL_MANT_BIT;
     976             :   return m.limbs;
     977             : }
     978             : 
     979             : # endif
     980             : 
     981             : # if NEED_PRINTF_DOUBLE
     982             : 
     983             : /* Assuming x is finite and >= 0:
     984             :    write x as x = 2^e * m, where m is a bignum.
     985             :    Return the allocated memory in case of success, NULL in case of memory
     986             :    allocation failure.  */
     987             : static void *
     988             : decode_double (double x, int *ep, mpn_t *mp)
     989             : {
     990             :   mpn_t m;
     991             :   int exp;
     992             :   double y;
     993             :   size_t i;
     994             : 
     995             :   /* Allocate memory for result.  */
     996             :   m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
     997             :   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
     998             :   if (m.limbs == NULL)
     999             :     return NULL;
    1000             :   /* Split into exponential part and mantissa.  */
    1001             :   y = frexp (x, &exp);
    1002             :   if (!(y >= 0.0 && y < 1.0))
    1003             :     abort ();
    1004             :   /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
    1005             :      latter is an integer.  */
    1006             :   /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
    1007             :      I'm not sure whether it's safe to cast a 'double' value between
    1008             :      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
    1009             :      'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
    1010             :      doesn't matter).  */
    1011             : #  if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
    1012             : #   if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
    1013             :     {
    1014             :       mp_limb_t hi, lo;
    1015             :       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
    1016             :       hi = (int) y;
    1017             :       y -= hi;
    1018             :       if (!(y >= 0.0 && y < 1.0))
    1019             :         abort ();
    1020             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
    1021             :       lo = (int) y;
    1022             :       y -= lo;
    1023             :       if (!(y >= 0.0 && y < 1.0))
    1024             :         abort ();
    1025             :       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
    1026             :     }
    1027             : #   else
    1028             :     {
    1029             :       mp_limb_t d;
    1030             :       y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
    1031             :       d = (int) y;
    1032             :       y -= d;
    1033             :       if (!(y >= 0.0 && y < 1.0))
    1034             :         abort ();
    1035             :       m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
    1036             :     }
    1037             : #   endif
    1038             : #  endif
    1039             :   for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
    1040             :     {
    1041             :       mp_limb_t hi, lo;
    1042             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
    1043             :       hi = (int) y;
    1044             :       y -= hi;
    1045             :       if (!(y >= 0.0 && y < 1.0))
    1046             :         abort ();
    1047             :       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
    1048             :       lo = (int) y;
    1049             :       y -= lo;
    1050             :       if (!(y >= 0.0 && y < 1.0))
    1051             :         abort ();
    1052             :       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
    1053             :     }
    1054             :   if (!(y == 0.0))
    1055             :     abort ();
    1056             :   /* Normalise.  */
    1057             :   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
    1058             :     m.nlimbs--;
    1059             :   *mp = m;
    1060             :   *ep = exp - DBL_MANT_BIT;
    1061             :   return m.limbs;
    1062             : }
    1063             : 
    1064             : # endif
    1065             : 
    1066             : /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
    1067             :    Returns the decimal representation of round (x * 10^n).
    1068             :    Return the allocated memory - containing the decimal digits in low-to-high
    1069             :    order, terminated with a NUL character - in case of success, NULL in case
    1070             :    of memory allocation failure.  */
    1071             : static char *
    1072             : scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
    1073             : {
    1074             :   int s;
    1075             :   size_t extra_zeroes;
    1076             :   unsigned int abs_n;
    1077             :   unsigned int abs_s;
    1078             :   mp_limb_t *pow5_ptr;
    1079             :   size_t pow5_len;
    1080             :   unsigned int s_limbs;
    1081             :   unsigned int s_bits;
    1082             :   mpn_t pow5;
    1083             :   mpn_t z;
    1084             :   void *z_memory;
    1085             :   char *digits;
    1086             : 
    1087             :   if (memory == NULL)
    1088             :     return NULL;
    1089             :   /* x = 2^e * m, hence
    1090             :      y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
    1091             :        = round (2^s * 5^n * m).  */
    1092             :   s = e + n;
    1093             :   extra_zeroes = 0;
    1094             :   /* Factor out a common power of 10 if possible.  */
    1095             :   if (s > 0 && n > 0)
    1096             :     {
    1097             :       extra_zeroes = (s < n ? s : n);
    1098             :       s -= extra_zeroes;
    1099             :       n -= extra_zeroes;
    1100             :     }
    1101             :   /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
    1102             :      Before converting to decimal, we need to compute
    1103             :      z = round (2^s * 5^n * m).  */
    1104             :   /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
    1105             :      sign.  2.322 is slightly larger than log(5)/log(2).  */
    1106             :   abs_n = (n >= 0 ? n : -n);
    1107             :   abs_s = (s >= 0 ? s : -s);
    1108             :   pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
    1109             :                                     + abs_s / GMP_LIMB_BITS + 1)
    1110             :                                    * sizeof (mp_limb_t));
    1111             :   if (pow5_ptr == NULL)
    1112             :     {
    1113             :       free (memory);
    1114             :       return NULL;
    1115             :     }
    1116             :   /* Initialize with 1.  */
    1117             :   pow5_ptr[0] = 1;
    1118             :   pow5_len = 1;
    1119             :   /* Multiply with 5^|n|.  */
    1120             :   if (abs_n > 0)
    1121             :     {
    1122             :       static mp_limb_t const small_pow5[13 + 1] =
    1123             :         {
    1124             :           1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
    1125             :           48828125, 244140625, 1220703125
    1126             :         };
    1127             :       unsigned int n13;
    1128             :       for (n13 = 0; n13 <= abs_n; n13 += 13)
    1129             :         {
    1130             :           mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
    1131             :           size_t j;
    1132             :           mp_twolimb_t carry = 0;
    1133             :           for (j = 0; j < pow5_len; j++)
    1134             :             {
    1135             :               mp_limb_t digit2 = pow5_ptr[j];
    1136             :               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
    1137             :               pow5_ptr[j] = (mp_limb_t) carry;
    1138             :               carry = carry >> GMP_LIMB_BITS;
    1139             :             }
    1140             :           if (carry > 0)
    1141             :             pow5_ptr[pow5_len++] = (mp_limb_t) carry;
    1142             :         }
    1143             :     }
    1144             :   s_limbs = abs_s / GMP_LIMB_BITS;
    1145             :   s_bits = abs_s % GMP_LIMB_BITS;
    1146             :   if (n >= 0 ? s >= 0 : s <= 0)
    1147             :     {
    1148             :       /* Multiply with 2^|s|.  */
    1149             :       if (s_bits > 0)
    1150             :         {
    1151             :           mp_limb_t *ptr = pow5_ptr;
    1152             :           mp_twolimb_t accu = 0;
    1153             :           size_t count;
    1154             :           for (count = pow5_len; count > 0; count--)
    1155             :             {
    1156             :               accu += (mp_twolimb_t) *ptr << s_bits;
    1157             :               *ptr++ = (mp_limb_t) accu;
    1158             :               accu = accu >> GMP_LIMB_BITS;
    1159             :             }
    1160             :           if (accu > 0)
    1161             :             {
    1162             :               *ptr = (mp_limb_t) accu;
    1163             :               pow5_len++;
    1164             :             }
    1165             :         }
    1166             :       if (s_limbs > 0)
    1167             :         {
    1168             :           size_t count;
    1169             :           for (count = pow5_len; count > 0;)
    1170             :             {
    1171             :               count--;
    1172             :               pow5_ptr[s_limbs + count] = pow5_ptr[count];
    1173             :             }
    1174             :           for (count = s_limbs; count > 0;)
    1175             :             {
    1176             :               count--;
    1177             :               pow5_ptr[count] = 0;
    1178             :             }
    1179             :           pow5_len += s_limbs;
    1180             :         }
    1181             :       pow5.limbs = pow5_ptr;
    1182             :       pow5.nlimbs = pow5_len;
    1183             :       if (n >= 0)
    1184             :         {
    1185             :           /* Multiply m with pow5.  No division needed.  */
    1186             :           z_memory = multiply (m, pow5, &z);
    1187             :         }
    1188             :       else
    1189             :         {
    1190             :           /* Divide m by pow5 and round.  */
    1191             :           z_memory = divide (m, pow5, &z);
    1192             :         }
    1193             :     }
    1194             :   else
    1195             :     {
    1196             :       pow5.limbs = pow5_ptr;
    1197             :       pow5.nlimbs = pow5_len;
    1198             :       if (n >= 0)
    1199             :         {
    1200             :           /* n >= 0, s < 0.
    1201             :              Multiply m with pow5, then divide by 2^|s|.  */
    1202             :           mpn_t numerator;
    1203             :           mpn_t denominator;
    1204             :           void *tmp_memory;
    1205             :           tmp_memory = multiply (m, pow5, &numerator);
    1206             :           if (tmp_memory == NULL)
    1207             :             {
    1208             :               free (pow5_ptr);
    1209             :               free (memory);
    1210             :               return NULL;
    1211             :             }
    1212             :           /* Construct 2^|s|.  */
    1213             :           {
    1214             :             mp_limb_t *ptr = pow5_ptr + pow5_len;
    1215             :             size_t i;
    1216             :             for (i = 0; i < s_limbs; i++)
    1217             :               ptr[i] = 0;
    1218             :             ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
    1219             :             denominator.limbs = ptr;
    1220             :             denominator.nlimbs = s_limbs + 1;
    1221             :           }
    1222             :           z_memory = divide (numerator, denominator, &z);
    1223             :           free (tmp_memory);
    1224             :         }
    1225             :       else
    1226             :         {
    1227             :           /* n < 0, s > 0.
    1228             :              Multiply m with 2^s, then divide by pow5.  */
    1229             :           mpn_t numerator;
    1230             :           mp_limb_t *num_ptr;
    1231             :           num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
    1232             :                                           * sizeof (mp_limb_t));
    1233             :           if (num_ptr == NULL)
    1234             :             {
    1235             :               free (pow5_ptr);
    1236             :               free (memory);
    1237             :               return NULL;
    1238             :             }
    1239             :           {
    1240             :             mp_limb_t *destptr = num_ptr;
    1241             :             {
    1242             :               size_t i;
    1243             :               for (i = 0; i < s_limbs; i++)
    1244             :                 *destptr++ = 0;
    1245             :             }
    1246             :             if (s_bits > 0)
    1247             :               {
    1248             :                 const mp_limb_t *sourceptr = m.limbs;
    1249             :                 mp_twolimb_t accu = 0;
    1250             :                 size_t count;
    1251             :                 for (count = m.nlimbs; count > 0; count--)
    1252             :                   {
    1253             :                     accu += (mp_twolimb_t) *sourceptr++ << s_bits;
    1254             :                     *destptr++ = (mp_limb_t) accu;
    1255             :                     accu = accu >> GMP_LIMB_BITS;
    1256             :                   }
    1257             :                 if (accu > 0)
    1258             :                   *destptr++ = (mp_limb_t) accu;
    1259             :               }
    1260             :             else
    1261             :               {
    1262             :                 const mp_limb_t *sourceptr = m.limbs;
    1263             :                 size_t count;
    1264             :                 for (count = m.nlimbs; count > 0; count--)
    1265             :                   *destptr++ = *sourceptr++;
    1266             :               }
    1267             :             numerator.limbs = num_ptr;
    1268             :             numerator.nlimbs = destptr - num_ptr;
    1269             :           }
    1270             :           z_memory = divide (numerator, pow5, &z);
    1271             :           free (num_ptr);
    1272             :         }
    1273             :     }
    1274             :   free (pow5_ptr);
    1275             :   free (memory);
    1276             : 
    1277             :   /* Here y = round (x * 10^n) = z * 10^extra_zeroes.  */
    1278             : 
    1279             :   if (z_memory == NULL)
    1280             :     return NULL;
    1281             :   digits = convert_to_decimal (z, extra_zeroes);
    1282             :   free (z_memory);
    1283             :   return digits;
    1284             : }
    1285             : 
    1286             : # if NEED_PRINTF_LONG_DOUBLE
    1287             : 
    1288             : /* Assuming x is finite and >= 0, and n is an integer:
    1289             :    Returns the decimal representation of round (x * 10^n).
    1290             :    Return the allocated memory - containing the decimal digits in low-to-high
    1291             :    order, terminated with a NUL character - in case of success, NULL in case
    1292             :    of memory allocation failure.  */
    1293             : static char *
    1294             : scale10_round_decimal_long_double (long double x, int n)
    1295             : {
    1296             :   int e IF_LINT(= 0);
    1297             :   mpn_t m;
    1298             :   void *memory = decode_long_double (x, &e, &m);
    1299             :   return scale10_round_decimal_decoded (e, m, memory, n);
    1300             : }
    1301             : 
    1302             : # endif
    1303             : 
    1304             : # if NEED_PRINTF_DOUBLE
    1305             : 
    1306             : /* Assuming x is finite and >= 0, and n is an integer:
    1307             :    Returns the decimal representation of round (x * 10^n).
    1308             :    Return the allocated memory - containing the decimal digits in low-to-high
    1309             :    order, terminated with a NUL character - in case of success, NULL in case
    1310             :    of memory allocation failure.  */
    1311             : static char *
    1312             : scale10_round_decimal_double (double x, int n)
    1313             : {
    1314             :   int e IF_LINT(= 0);
    1315             :   mpn_t m;
    1316             :   void *memory = decode_double (x, &e, &m);
    1317             :   return scale10_round_decimal_decoded (e, m, memory, n);
    1318             : }
    1319             : 
    1320             : # endif
    1321             : 
    1322             : # if NEED_PRINTF_LONG_DOUBLE
    1323             : 
    1324             : /* Assuming x is finite and > 0:
    1325             :    Return an approximation for n with 10^n <= x < 10^(n+1).
    1326             :    The approximation is usually the right n, but may be off by 1 sometimes.  */
    1327             : static int
    1328             : floorlog10l (long double x)
    1329             : {
    1330             :   int exp;
    1331             :   long double y;
    1332             :   double z;
    1333             :   double l;
    1334             : 
    1335             :   /* Split into exponential part and mantissa.  */
    1336             :   y = frexpl (x, &exp);
    1337             :   if (!(y >= 0.0L && y < 1.0L))
    1338             :     abort ();
    1339             :   if (y == 0.0L)
    1340             :     return INT_MIN;
    1341             :   if (y < 0.5L)
    1342             :     {
    1343             :       while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
    1344             :         {
    1345             :           y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
    1346             :           exp -= GMP_LIMB_BITS;
    1347             :         }
    1348             :       if (y < (1.0L / (1 << 16)))
    1349             :         {
    1350             :           y *= 1.0L * (1 << 16);
    1351             :           exp -= 16;
    1352             :         }
    1353             :       if (y < (1.0L / (1 << 8)))
    1354             :         {
    1355             :           y *= 1.0L * (1 << 8);
    1356             :           exp -= 8;
    1357             :         }
    1358             :       if (y < (1.0L / (1 << 4)))
    1359             :         {
    1360             :           y *= 1.0L * (1 << 4);
    1361             :           exp -= 4;
    1362             :         }
    1363             :       if (y < (1.0L / (1 << 2)))
    1364             :         {
    1365             :           y *= 1.0L * (1 << 2);
    1366             :           exp -= 2;
    1367             :         }
    1368             :       if (y < (1.0L / (1 << 1)))
    1369             :         {
    1370             :           y *= 1.0L * (1 << 1);
    1371             :           exp -= 1;
    1372             :         }
    1373             :     }
    1374             :   if (!(y >= 0.5L && y < 1.0L))
    1375             :     abort ();
    1376             :   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
    1377             :   l = exp;
    1378             :   z = y;
    1379             :   if (z < 0.70710678118654752444)
    1380             :     {
    1381             :       z *= 1.4142135623730950488;
    1382             :       l -= 0.5;
    1383             :     }
    1384             :   if (z < 0.8408964152537145431)
    1385             :     {
    1386             :       z *= 1.1892071150027210667;
    1387             :       l -= 0.25;
    1388             :     }
    1389             :   if (z < 0.91700404320467123175)
    1390             :     {
    1391             :       z *= 1.0905077326652576592;
    1392             :       l -= 0.125;
    1393             :     }
    1394             :   if (z < 0.9576032806985736469)
    1395             :     {
    1396             :       z *= 1.0442737824274138403;
    1397             :       l -= 0.0625;
    1398             :     }
    1399             :   /* Now 0.95 <= z <= 1.01.  */
    1400             :   z = 1 - z;
    1401             :   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
    1402             :      Four terms are enough to get an approximation with error < 10^-7.  */
    1403             :   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
    1404             :   /* Finally multiply with log(2)/log(10), yields an approximation for
    1405             :      log10(x).  */
    1406             :   l *= 0.30102999566398119523;
    1407             :   /* Round down to the next integer.  */
    1408             :   return (int) l + (l < 0 ? -1 : 0);
    1409             : }
    1410             : 
    1411             : # endif
    1412             : 
    1413             : # if NEED_PRINTF_DOUBLE
    1414             : 
    1415             : /* Assuming x is finite and > 0:
    1416             :    Return an approximation for n with 10^n <= x < 10^(n+1).
    1417             :    The approximation is usually the right n, but may be off by 1 sometimes.  */
    1418             : static int
    1419             : floorlog10 (double x)
    1420             : {
    1421             :   int exp;
    1422             :   double y;
    1423             :   double z;
    1424             :   double l;
    1425             : 
    1426             :   /* Split into exponential part and mantissa.  */
    1427             :   y = frexp (x, &exp);
    1428             :   if (!(y >= 0.0 && y < 1.0))
    1429             :     abort ();
    1430             :   if (y == 0.0)
    1431             :     return INT_MIN;
    1432             :   if (y < 0.5)
    1433             :     {
    1434             :       while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
    1435             :         {
    1436             :           y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
    1437             :           exp -= GMP_LIMB_BITS;
    1438             :         }
    1439             :       if (y < (1.0 / (1 << 16)))
    1440             :         {
    1441             :           y *= 1.0 * (1 << 16);
    1442             :           exp -= 16;
    1443             :         }
    1444             :       if (y < (1.0 / (1 << 8)))
    1445             :         {
    1446             :           y *= 1.0 * (1 << 8);
    1447             :           exp -= 8;
    1448             :         }
    1449             :       if (y < (1.0 / (1 << 4)))
    1450             :         {
    1451             :           y *= 1.0 * (1 << 4);
    1452             :           exp -= 4;
    1453             :         }
    1454             :       if (y < (1.0 / (1 << 2)))
    1455             :         {
    1456             :           y *= 1.0 * (1 << 2);
    1457             :           exp -= 2;
    1458             :         }
    1459             :       if (y < (1.0 / (1 << 1)))
    1460             :         {
    1461             :           y *= 1.0 * (1 << 1);
    1462             :           exp -= 1;
    1463             :         }
    1464             :     }
    1465             :   if (!(y >= 0.5 && y < 1.0))
    1466             :     abort ();
    1467             :   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
    1468             :   l = exp;
    1469             :   z = y;
    1470             :   if (z < 0.70710678118654752444)
    1471             :     {
    1472             :       z *= 1.4142135623730950488;
    1473             :       l -= 0.5;
    1474             :     }
    1475             :   if (z < 0.8408964152537145431)
    1476             :     {
    1477             :       z *= 1.1892071150027210667;
    1478             :       l -= 0.25;
    1479             :     }
    1480             :   if (z < 0.91700404320467123175)
    1481             :     {
    1482             :       z *= 1.0905077326652576592;
    1483             :       l -= 0.125;
    1484             :     }
    1485             :   if (z < 0.9576032806985736469)
    1486             :     {
    1487             :       z *= 1.0442737824274138403;
    1488             :       l -= 0.0625;
    1489             :     }
    1490             :   /* Now 0.95 <= z <= 1.01.  */
    1491             :   z = 1 - z;
    1492             :   /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
    1493             :      Four terms are enough to get an approximation with error < 10^-7.  */
    1494             :   l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
    1495             :   /* Finally multiply with log(2)/log(10), yields an approximation for
    1496             :      log10(x).  */
    1497             :   l *= 0.30102999566398119523;
    1498             :   /* Round down to the next integer.  */
    1499             :   return (int) l + (l < 0 ? -1 : 0);
    1500             : }
    1501             : 
    1502             : # endif
    1503             : 
    1504             : /* Tests whether a string of digits consists of exactly PRECISION zeroes and
    1505             :    a single '1' digit.  */
    1506             : static int
    1507             : is_borderline (const char *digits, size_t precision)
    1508             : {
    1509             :   for (; precision > 0; precision--, digits++)
    1510             :     if (*digits != '0')
    1511             :       return 0;
    1512             :   if (*digits != '1')
    1513             :     return 0;
    1514             :   digits++;
    1515             :   return *digits == '\0';
    1516             : }
    1517             : 
    1518             : #endif
    1519             : 
    1520             : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
    1521             : 
    1522             : /* Use a different function name, to make it possible that the 'wchar_t'
    1523             :    parametrization and the 'char' parametrization get compiled in the same
    1524             :    translation unit.  */
    1525             : # if WIDE_CHAR_VERSION
    1526             : #  define MAX_ROOM_NEEDED wmax_room_needed
    1527             : # else
    1528             : #  define MAX_ROOM_NEEDED max_room_needed
    1529             : # endif
    1530             : 
    1531             : /* Returns the number of TCHAR_T units needed as temporary space for the result
    1532             :    of sprintf or SNPRINTF of a single conversion directive.  */
    1533             : static size_t
    1534             : MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
    1535             :                  arg_type type, int flags, size_t width, int has_precision,
    1536             :                  size_t precision, int pad_ourselves)
    1537             : {
    1538             :   size_t tmp_length;
    1539             : 
    1540             :   switch (conversion)
    1541             :     {
    1542             :     case 'd': case 'i': case 'u':
    1543             : # if HAVE_LONG_LONG_INT
    1544             :       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
    1545             :         tmp_length =
    1546             :           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
    1547             :                           * 0.30103 /* binary -> decimal */
    1548             :                          )
    1549             :           + 1; /* turn floor into ceil */
    1550             :       else
    1551             : # endif
    1552             :       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
    1553             :         tmp_length =
    1554             :           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
    1555             :                           * 0.30103 /* binary -> decimal */
    1556             :                          )
    1557             :           + 1; /* turn floor into ceil */
    1558             :       else
    1559             :         tmp_length =
    1560             :           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
    1561             :                           * 0.30103 /* binary -> decimal */
    1562             :                          )
    1563             :           + 1; /* turn floor into ceil */
    1564             :       if (tmp_length < precision)
    1565             :         tmp_length = precision;
    1566             :       /* Multiply by 2, as an estimate for FLAG_GROUP.  */
    1567             :       tmp_length = xsum (tmp_length, tmp_length);
    1568             :       /* Add 1, to account for a leading sign.  */
    1569             :       tmp_length = xsum (tmp_length, 1);
    1570             :       break;
    1571             : 
    1572             :     case 'o':
    1573             : # if HAVE_LONG_LONG_INT
    1574             :       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
    1575             :         tmp_length =
    1576             :           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
    1577             :                           * 0.333334 /* binary -> octal */
    1578             :                          )
    1579             :           + 1; /* turn floor into ceil */
    1580             :       else
    1581             : # endif
    1582             :       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
    1583             :         tmp_length =
    1584             :           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
    1585             :                           * 0.333334 /* binary -> octal */
    1586             :                          )
    1587             :           + 1; /* turn floor into ceil */
    1588             :       else
    1589             :         tmp_length =
    1590             :           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
    1591             :                           * 0.333334 /* binary -> octal */
    1592             :                          )
    1593             :           + 1; /* turn floor into ceil */
    1594             :       if (tmp_length < precision)
    1595             :         tmp_length = precision;
    1596             :       /* Add 1, to account for a leading sign.  */
    1597             :       tmp_length = xsum (tmp_length, 1);
    1598             :       break;
    1599             : 
    1600             :     case 'x': case 'X':
    1601             : # if HAVE_LONG_LONG_INT
    1602             :       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
    1603             :         tmp_length =
    1604             :           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
    1605             :                           * 0.25 /* binary -> hexadecimal */
    1606             :                          )
    1607             :           + 1; /* turn floor into ceil */
    1608             :       else
    1609             : # endif
    1610             :       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
    1611             :         tmp_length =
    1612             :           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
    1613             :                           * 0.25 /* binary -> hexadecimal */
    1614             :                          )
    1615             :           + 1; /* turn floor into ceil */
    1616             :       else
    1617             :         tmp_length =
    1618             :           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
    1619             :                           * 0.25 /* binary -> hexadecimal */
    1620             :                          )
    1621             :           + 1; /* turn floor into ceil */
    1622             :       if (tmp_length < precision)
    1623             :         tmp_length = precision;
    1624             :       /* Add 2, to account for a leading sign or alternate form.  */
    1625             :       tmp_length = xsum (tmp_length, 2);
    1626             :       break;
    1627             : 
    1628             :     case 'f': case 'F':
    1629             :       if (type == TYPE_LONGDOUBLE)
    1630             :         tmp_length =
    1631             :           (unsigned int) (LDBL_MAX_EXP
    1632             :                           * 0.30103 /* binary -> decimal */
    1633             :                           * 2 /* estimate for FLAG_GROUP */
    1634             :                          )
    1635             :           + 1 /* turn floor into ceil */
    1636             :           + 10; /* sign, decimal point etc. */
    1637             :       else
    1638             :         tmp_length =
    1639             :           (unsigned int) (DBL_MAX_EXP
    1640             :                           * 0.30103 /* binary -> decimal */
    1641             :                           * 2 /* estimate for FLAG_GROUP */
    1642             :                          )
    1643             :           + 1 /* turn floor into ceil */
    1644             :           + 10; /* sign, decimal point etc. */
    1645             :       tmp_length = xsum (tmp_length, precision);
    1646             :       break;
    1647             : 
    1648             :     case 'e': case 'E': case 'g': case 'G':
    1649             :       tmp_length =
    1650             :         12; /* sign, decimal point, exponent etc. */
    1651             :       tmp_length = xsum (tmp_length, precision);
    1652             :       break;
    1653             : 
    1654             :     case 'a': case 'A':
    1655             :       if (type == TYPE_LONGDOUBLE)
    1656             :         tmp_length =
    1657             :           (unsigned int) (LDBL_DIG
    1658             :                           * 0.831 /* decimal -> hexadecimal */
    1659             :                          )
    1660             :           + 1; /* turn floor into ceil */
    1661             :       else
    1662             :         tmp_length =
    1663             :           (unsigned int) (DBL_DIG
    1664             :                           * 0.831 /* decimal -> hexadecimal */
    1665             :                          )
    1666             :           + 1; /* turn floor into ceil */
    1667             :       if (tmp_length < precision)
    1668             :         tmp_length = precision;
    1669             :       /* Account for sign, decimal point etc. */
    1670             :       tmp_length = xsum (tmp_length, 12);
    1671             :       break;
    1672             : 
    1673             :     case 'c':
    1674             : # if HAVE_WINT_T && !WIDE_CHAR_VERSION
    1675             :       if (type == TYPE_WIDE_CHAR)
    1676             :         tmp_length = MB_CUR_MAX;
    1677             :       else
    1678             : # endif
    1679             :         tmp_length = 1;
    1680             :       break;
    1681             : 
    1682             :     case 's':
    1683             : # if HAVE_WCHAR_T
    1684             :       if (type == TYPE_WIDE_STRING)
    1685             :         {
    1686             : #  if WIDE_CHAR_VERSION
    1687             :           /* ISO C says about %ls in fwprintf:
    1688             :                "If the precision is not specified or is greater than the size
    1689             :                 of the array, the array shall contain a null wide character."
    1690             :              So if there is a precision, we must not use wcslen.  */
    1691             :           const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
    1692             : 
    1693             :           if (has_precision)
    1694             :             tmp_length = local_wcsnlen (arg, precision);
    1695             :           else
    1696             :             tmp_length = local_wcslen (arg);
    1697             : #  else
    1698             :           /* ISO C says about %ls in fprintf:
    1699             :                "If a precision is specified, no more than that many bytes are
    1700             :                 written (including shift sequences, if any), and the array
    1701             :                 shall contain a null wide character if, to equal the multibyte
    1702             :                 character sequence length given by the precision, the function
    1703             :                 would need to access a wide character one past the end of the
    1704             :                 array."
    1705             :              So if there is a precision, we must not use wcslen.  */
    1706             :           /* This case has already been handled separately in VASNPRINTF.  */
    1707             :           abort ();
    1708             : #  endif
    1709             :         }
    1710             :       else
    1711             : # endif
    1712             :         {
    1713             : # if WIDE_CHAR_VERSION
    1714             :           /* ISO C says about %s in fwprintf:
    1715             :                "If the precision is not specified or is greater than the size
    1716             :                 of the converted array, the converted array shall contain a
    1717             :                 null wide character."
    1718             :              So if there is a precision, we must not use strlen.  */
    1719             :           /* This case has already been handled separately in VASNPRINTF.  */
    1720             :           abort ();
    1721             : # else
    1722             :           /* ISO C says about %s in fprintf:
    1723             :                "If the precision is not specified or greater than the size of
    1724             :                 the array, the array shall contain a null character."
    1725             :              So if there is a precision, we must not use strlen.  */
    1726             :           const char *arg = ap->arg[arg_index].a.a_string;
    1727             : 
    1728             :           if (has_precision)
    1729             :             tmp_length = local_strnlen (arg, precision);
    1730             :           else
    1731             :             tmp_length = strlen (arg);
    1732             : # endif
    1733             :         }
    1734             :       break;
    1735             : 
    1736             :     case 'p':
    1737             :       tmp_length =
    1738             :         (unsigned int) (sizeof (void *) * CHAR_BIT
    1739             :                         * 0.25 /* binary -> hexadecimal */
    1740             :                        )
    1741             :           + 1 /* turn floor into ceil */
    1742             :           + 2; /* account for leading 0x */
    1743             :       break;
    1744             : 
    1745             :     default:
    1746             :       abort ();
    1747             :     }
    1748             : 
    1749             :   if (!pad_ourselves)
    1750             :     {
    1751             : # if ENABLE_UNISTDIO
    1752             :       /* Padding considers the number of characters, therefore the number of
    1753             :          elements after padding may be
    1754             :            > max (tmp_length, width)
    1755             :          but is certainly
    1756             :            <= tmp_length + width.  */
    1757             :       tmp_length = xsum (tmp_length, width);
    1758             : # else
    1759             :       /* Padding considers the number of elements, says POSIX.  */
    1760             :       if (tmp_length < width)
    1761             :         tmp_length = width;
    1762             : # endif
    1763             :     }
    1764             : 
    1765             :   tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
    1766             : 
    1767             :   return tmp_length;
    1768             : }
    1769             : 
    1770             : #endif
    1771             : 
    1772             : DCHAR_T *
    1773           0 : VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
    1774             :             const FCHAR_T *format, va_list args)
    1775             : {
    1776             :   DIRECTIVES d;
    1777             :   arguments a;
    1778             : 
    1779           0 :   if (PRINTF_PARSE (format, &d, &a) < 0)
    1780             :     /* errno is already set.  */
    1781           0 :     return NULL;
    1782             : 
    1783             : #define CLEANUP() \
    1784             :   if (d.dir != d.direct_alloc_dir)                                      \
    1785             :     free (d.dir);                                                       \
    1786             :   if (a.arg != a.direct_alloc_arg)                                      \
    1787             :     free (a.arg);
    1788             : 
    1789           0 :   if (PRINTF_FETCHARGS (args, &a) < 0)
    1790             :     {
    1791           0 :       CLEANUP ();
    1792           0 :       errno = EINVAL;
    1793           0 :       return NULL;
    1794             :     }
    1795             : 
    1796             :   {
    1797             :     size_t buf_neededlength;
    1798             :     TCHAR_T *buf;
    1799             :     TCHAR_T *buf_malloced;
    1800             :     const FCHAR_T *cp;
    1801             :     size_t i;
    1802             :     DIRECTIVE *dp;
    1803             :     /* Output string accumulator.  */
    1804             :     DCHAR_T *result;
    1805             :     size_t allocated;
    1806             :     size_t length;
    1807             : 
    1808             :     /* Allocate a small buffer that will hold a directive passed to
    1809             :        sprintf or snprintf.  */
    1810           0 :     buf_neededlength =
    1811           0 :       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
    1812             : #if HAVE_ALLOCA
    1813           0 :     if (buf_neededlength < 4000 / sizeof (TCHAR_T))
    1814             :       {
    1815           0 :         buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
    1816           0 :         buf_malloced = NULL;
    1817             :       }
    1818             :     else
    1819             : #endif
    1820             :       {
    1821           0 :         size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
    1822           0 :         if (size_overflow_p (buf_memsize))
    1823           0 :           goto out_of_memory_1;
    1824           0 :         buf = (TCHAR_T *) malloc (buf_memsize);
    1825           0 :         if (buf == NULL)
    1826           0 :           goto out_of_memory_1;
    1827           0 :         buf_malloced = buf;
    1828             :       }
    1829             : 
    1830           0 :     if (resultbuf != NULL)
    1831             :       {
    1832           0 :         result = resultbuf;
    1833           0 :         allocated = *lengthp;
    1834             :       }
    1835             :     else
    1836             :       {
    1837           0 :         result = NULL;
    1838           0 :         allocated = 0;
    1839             :       }
    1840           0 :     length = 0;
    1841             :     /* Invariants:
    1842             :        result is either == resultbuf or == NULL or malloc-allocated.
    1843             :        If length > 0, then result != NULL.  */
    1844             : 
    1845             :     /* Ensures that allocated >= needed.  Aborts through a jump to
    1846             :        out_of_memory if needed is SIZE_MAX or otherwise too big.  */
    1847             : #define ENSURE_ALLOCATION(needed) \
    1848             :     if ((needed) > allocated)                                                \
    1849             :       {                                                                      \
    1850             :         size_t memory_size;                                                  \
    1851             :         DCHAR_T *memory;                                                     \
    1852             :                                                                              \
    1853             :         allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
    1854             :         if ((needed) > allocated)                                            \
    1855             :           allocated = (needed);                                              \
    1856             :         memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
    1857             :         if (size_overflow_p (memory_size))                                   \
    1858             :           goto out_of_memory;                                                \
    1859             :         if (result == resultbuf || result == NULL)                           \
    1860             :           memory = (DCHAR_T *) malloc (memory_size);                         \
    1861             :         else                                                                 \
    1862             :           memory = (DCHAR_T *) realloc (result, memory_size);                \
    1863             :         if (memory == NULL)                                                  \
    1864             :           goto out_of_memory;                                                \
    1865             :         if (result == resultbuf && length > 0)                               \
    1866             :           DCHAR_CPY (memory, result, length);                                \
    1867             :         result = memory;                                                     \
    1868             :       }
    1869             : 
    1870           0 :     for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
    1871             :       {
    1872           0 :         if (cp != dp->dir_start)
    1873             :           {
    1874           0 :             size_t n = dp->dir_start - cp;
    1875           0 :             size_t augmented_length = xsum (length, n);
    1876             : 
    1877           0 :             ENSURE_ALLOCATION (augmented_length);
    1878             :             /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
    1879             :                need that the format string contains only ASCII characters
    1880             :                if FCHAR_T and DCHAR_T are not the same type.  */
    1881             :             if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
    1882             :               {
    1883           0 :                 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
    1884           0 :                 length = augmented_length;
    1885             :               }
    1886             :             else
    1887             :               {
    1888             :                 do
    1889             :                   result[length++] = *cp++;
    1890             :                 while (--n > 0);
    1891             :               }
    1892             :           }
    1893           0 :         if (i == d.count)
    1894           0 :           break;
    1895             : 
    1896             :         /* Execute a single directive.  */
    1897           0 :         if (dp->conversion == '%')
    1898             :           {
    1899             :             size_t augmented_length;
    1900             : 
    1901           0 :             if (!(dp->arg_index == ARG_NONE))
    1902           0 :               abort ();
    1903           0 :             augmented_length = xsum (length, 1);
    1904           0 :             ENSURE_ALLOCATION (augmented_length);
    1905           0 :             result[length] = '%';
    1906           0 :             length = augmented_length;
    1907             :           }
    1908             :         else
    1909             :           {
    1910           0 :             if (!(dp->arg_index != ARG_NONE))
    1911           0 :               abort ();
    1912             : 
    1913           0 :             if (dp->conversion == 'n')
    1914             :               {
    1915           0 :                 switch (a.arg[dp->arg_index].type)
    1916             :                   {
    1917             :                   case TYPE_COUNT_SCHAR_POINTER:
    1918           0 :                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
    1919           0 :                     break;
    1920             :                   case TYPE_COUNT_SHORT_POINTER:
    1921           0 :                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
    1922           0 :                     break;
    1923             :                   case TYPE_COUNT_INT_POINTER:
    1924           0 :                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
    1925           0 :                     break;
    1926             :                   case TYPE_COUNT_LONGINT_POINTER:
    1927           0 :                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
    1928           0 :                     break;
    1929             : #if HAVE_LONG_LONG_INT
    1930             :                   case TYPE_COUNT_LONGLONGINT_POINTER:
    1931           0 :                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
    1932           0 :                     break;
    1933             : #endif
    1934             :                   default:
    1935           0 :                     abort ();
    1936             :                   }
    1937             :               }
    1938             : #if ENABLE_UNISTDIO
    1939             :             /* The unistdio extensions.  */
    1940             :             else if (dp->conversion == 'U')
    1941             :               {
    1942             :                 arg_type type = a.arg[dp->arg_index].type;
    1943             :                 int flags = dp->flags;
    1944             :                 int has_width;
    1945             :                 size_t width;
    1946             :                 int has_precision;
    1947             :                 size_t precision;
    1948             : 
    1949             :                 has_width = 0;
    1950             :                 width = 0;
    1951             :                 if (dp->width_start != dp->width_end)
    1952             :                   {
    1953             :                     if (dp->width_arg_index != ARG_NONE)
    1954             :                       {
    1955             :                         int arg;
    1956             : 
    1957             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    1958             :                           abort ();
    1959             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    1960             :                         width = arg;
    1961             :                         if (arg < 0)
    1962             :                           {
    1963             :                             /* "A negative field width is taken as a '-' flag
    1964             :                                 followed by a positive field width."  */
    1965             :                             flags |= FLAG_LEFT;
    1966             :                             width = -width;
    1967             :                           }
    1968             :                       }
    1969             :                     else
    1970             :                       {
    1971             :                         const FCHAR_T *digitp = dp->width_start;
    1972             : 
    1973             :                         do
    1974             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    1975             :                         while (digitp != dp->width_end);
    1976             :                       }
    1977             :                     has_width = 1;
    1978             :                   }
    1979             : 
    1980             :                 has_precision = 0;
    1981             :                 precision = 0;
    1982             :                 if (dp->precision_start != dp->precision_end)
    1983             :                   {
    1984             :                     if (dp->precision_arg_index != ARG_NONE)
    1985             :                       {
    1986             :                         int arg;
    1987             : 
    1988             :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    1989             :                           abort ();
    1990             :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    1991             :                         /* "A negative precision is taken as if the precision
    1992             :                             were omitted."  */
    1993             :                         if (arg >= 0)
    1994             :                           {
    1995             :                             precision = arg;
    1996             :                             has_precision = 1;
    1997             :                           }
    1998             :                       }
    1999             :                     else
    2000             :                       {
    2001             :                         const FCHAR_T *digitp = dp->precision_start + 1;
    2002             : 
    2003             :                         precision = 0;
    2004             :                         while (digitp != dp->precision_end)
    2005             :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    2006             :                         has_precision = 1;
    2007             :                       }
    2008             :                   }
    2009             : 
    2010             :                 switch (type)
    2011             :                   {
    2012             :                   case TYPE_U8_STRING:
    2013             :                     {
    2014             :                       const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
    2015             :                       const uint8_t *arg_end;
    2016             :                       size_t characters;
    2017             : 
    2018             :                       if (has_precision)
    2019             :                         {
    2020             :                           /* Use only PRECISION characters, from the left.  */
    2021             :                           arg_end = arg;
    2022             :                           characters = 0;
    2023             :                           for (; precision > 0; precision--)
    2024             :                             {
    2025             :                               int count = u8_strmblen (arg_end);
    2026             :                               if (count == 0)
    2027             :                                 break;
    2028             :                               if (count < 0)
    2029             :                                 {
    2030             :                                   if (!(result == resultbuf || result == NULL))
    2031             :                                     free (result);
    2032             :                                   if (buf_malloced != NULL)
    2033             :                                     free (buf_malloced);
    2034             :                                   CLEANUP ();
    2035             :                                   errno = EILSEQ;
    2036             :                                   return NULL;
    2037             :                                 }
    2038             :                               arg_end += count;
    2039             :                               characters++;
    2040             :                             }
    2041             :                         }
    2042             :                       else if (has_width)
    2043             :                         {
    2044             :                           /* Use the entire string, and count the number of
    2045             :                              characters.  */
    2046             :                           arg_end = arg;
    2047             :                           characters = 0;
    2048             :                           for (;;)
    2049             :                             {
    2050             :                               int count = u8_strmblen (arg_end);
    2051             :                               if (count == 0)
    2052             :                                 break;
    2053             :                               if (count < 0)
    2054             :                                 {
    2055             :                                   if (!(result == resultbuf || result == NULL))
    2056             :                                     free (result);
    2057             :                                   if (buf_malloced != NULL)
    2058             :                                     free (buf_malloced);
    2059             :                                   CLEANUP ();
    2060             :                                   errno = EILSEQ;
    2061             :                                   return NULL;
    2062             :                                 }
    2063             :                               arg_end += count;
    2064             :                               characters++;
    2065             :                             }
    2066             :                         }
    2067             :                       else
    2068             :                         {
    2069             :                           /* Use the entire string.  */
    2070             :                           arg_end = arg + u8_strlen (arg);
    2071             :                           /* The number of characters doesn't matter.  */
    2072             :                           characters = 0;
    2073             :                         }
    2074             : 
    2075             :                       if (characters < width && !(dp->flags & FLAG_LEFT))
    2076             :                         {
    2077             :                           size_t n = width - characters;
    2078             :                           ENSURE_ALLOCATION (xsum (length, n));
    2079             :                           DCHAR_SET (result + length, ' ', n);
    2080             :                           length += n;
    2081             :                         }
    2082             : 
    2083             : # if DCHAR_IS_UINT8_T
    2084             :                       {
    2085             :                         size_t n = arg_end - arg;
    2086             :                         ENSURE_ALLOCATION (xsum (length, n));
    2087             :                         DCHAR_CPY (result + length, arg, n);
    2088             :                         length += n;
    2089             :                       }
    2090             : # else
    2091             :                       { /* Convert.  */
    2092             :                         DCHAR_T *converted = result + length;
    2093             :                         size_t converted_len = allocated - length;
    2094             : #  if DCHAR_IS_TCHAR
    2095             :                         /* Convert from UTF-8 to locale encoding.  */
    2096             :                         converted =
    2097             :                           u8_conv_to_encoding (locale_charset (),
    2098             :                                                iconveh_question_mark,
    2099             :                                                arg, arg_end - arg, NULL,
    2100             :                                                converted, &converted_len);
    2101             : #  else
    2102             :                         /* Convert from UTF-8 to UTF-16/UTF-32.  */
    2103             :                         converted =
    2104             :                           U8_TO_DCHAR (arg, arg_end - arg,
    2105             :                                        converted, &converted_len);
    2106             : #  endif
    2107             :                         if (converted == NULL)
    2108             :                           {
    2109             :                             int saved_errno = errno;
    2110             :                             if (!(result == resultbuf || result == NULL))
    2111             :                               free (result);
    2112             :                             if (buf_malloced != NULL)
    2113             :                               free (buf_malloced);
    2114             :                             CLEANUP ();
    2115             :                             errno = saved_errno;
    2116             :                             return NULL;
    2117             :                           }
    2118             :                         if (converted != result + length)
    2119             :                           {
    2120             :                             ENSURE_ALLOCATION (xsum (length, converted_len));
    2121             :                             DCHAR_CPY (result + length, converted, converted_len);
    2122             :                             free (converted);
    2123             :                           }
    2124             :                         length += converted_len;
    2125             :                       }
    2126             : # endif
    2127             : 
    2128             :                       if (characters < width && (dp->flags & FLAG_LEFT))
    2129             :                         {
    2130             :                           size_t n = width - characters;
    2131             :                           ENSURE_ALLOCATION (xsum (length, n));
    2132             :                           DCHAR_SET (result + length, ' ', n);
    2133             :                           length += n;
    2134             :                         }
    2135             :                     }
    2136             :                     break;
    2137             : 
    2138             :                   case TYPE_U16_STRING:
    2139             :                     {
    2140             :                       const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
    2141             :                       const uint16_t *arg_end;
    2142             :                       size_t characters;
    2143             : 
    2144             :                       if (has_precision)
    2145             :                         {
    2146             :                           /* Use only PRECISION characters, from the left.  */
    2147             :                           arg_end = arg;
    2148             :                           characters = 0;
    2149             :                           for (; precision > 0; precision--)
    2150             :                             {
    2151             :                               int count = u16_strmblen (arg_end);
    2152             :                               if (count == 0)
    2153             :                                 break;
    2154             :                               if (count < 0)
    2155             :                                 {
    2156             :                                   if (!(result == resultbuf || result == NULL))
    2157             :                                     free (result);
    2158             :                                   if (buf_malloced != NULL)
    2159             :                                     free (buf_malloced);
    2160             :                                   CLEANUP ();
    2161             :                                   errno = EILSEQ;
    2162             :                                   return NULL;
    2163             :                                 }
    2164             :                               arg_end += count;
    2165             :                               characters++;
    2166             :                             }
    2167             :                         }
    2168             :                       else if (has_width)
    2169             :                         {
    2170             :                           /* Use the entire string, and count the number of
    2171             :                              characters.  */
    2172             :                           arg_end = arg;
    2173             :                           characters = 0;
    2174             :                           for (;;)
    2175             :                             {
    2176             :                               int count = u16_strmblen (arg_end);
    2177             :                               if (count == 0)
    2178             :                                 break;
    2179             :                               if (count < 0)
    2180             :                                 {
    2181             :                                   if (!(result == resultbuf || result == NULL))
    2182             :                                     free (result);
    2183             :                                   if (buf_malloced != NULL)
    2184             :                                     free (buf_malloced);
    2185             :                                   CLEANUP ();
    2186             :                                   errno = EILSEQ;
    2187             :                                   return NULL;
    2188             :                                 }
    2189             :                               arg_end += count;
    2190             :                               characters++;
    2191             :                             }
    2192             :                         }
    2193             :                       else
    2194             :                         {
    2195             :                           /* Use the entire string.  */
    2196             :                           arg_end = arg + u16_strlen (arg);
    2197             :                           /* The number of characters doesn't matter.  */
    2198             :                           characters = 0;
    2199             :                         }
    2200             : 
    2201             :                       if (characters < width && !(dp->flags & FLAG_LEFT))
    2202             :                         {
    2203             :                           size_t n = width - characters;
    2204             :                           ENSURE_ALLOCATION (xsum (length, n));
    2205             :                           DCHAR_SET (result + length, ' ', n);
    2206             :                           length += n;
    2207             :                         }
    2208             : 
    2209             : # if DCHAR_IS_UINT16_T
    2210             :                       {
    2211             :                         size_t n = arg_end - arg;
    2212             :                         ENSURE_ALLOCATION (xsum (length, n));
    2213             :                         DCHAR_CPY (result + length, arg, n);
    2214             :                         length += n;
    2215             :                       }
    2216             : # else
    2217             :                       { /* Convert.  */
    2218             :                         DCHAR_T *converted = result + length;
    2219             :                         size_t converted_len = allocated - length;
    2220             : #  if DCHAR_IS_TCHAR
    2221             :                         /* Convert from UTF-16 to locale encoding.  */
    2222             :                         converted =
    2223             :                           u16_conv_to_encoding (locale_charset (),
    2224             :                                                 iconveh_question_mark,
    2225             :                                                 arg, arg_end - arg, NULL,
    2226             :                                                 converted, &converted_len);
    2227             : #  else
    2228             :                         /* Convert from UTF-16 to UTF-8/UTF-32.  */
    2229             :                         converted =
    2230             :                           U16_TO_DCHAR (arg, arg_end - arg,
    2231             :                                         converted, &converted_len);
    2232             : #  endif
    2233             :                         if (converted == NULL)
    2234             :                           {
    2235             :                             int saved_errno = errno;
    2236             :                             if (!(result == resultbuf || result == NULL))
    2237             :                               free (result);
    2238             :                             if (buf_malloced != NULL)
    2239             :                               free (buf_malloced);
    2240             :                             CLEANUP ();
    2241             :                             errno = saved_errno;
    2242             :                             return NULL;
    2243             :                           }
    2244             :                         if (converted != result + length)
    2245             :                           {
    2246             :                             ENSURE_ALLOCATION (xsum (length, converted_len));
    2247             :                             DCHAR_CPY (result + length, converted, converted_len);
    2248             :                             free (converted);
    2249             :                           }
    2250             :                         length += converted_len;
    2251             :                       }
    2252             : # endif
    2253             : 
    2254             :                       if (characters < width && (dp->flags & FLAG_LEFT))
    2255             :                         {
    2256             :                           size_t n = width - characters;
    2257             :                           ENSURE_ALLOCATION (xsum (length, n));
    2258             :                           DCHAR_SET (result + length, ' ', n);
    2259             :                           length += n;
    2260             :                         }
    2261             :                     }
    2262             :                     break;
    2263             : 
    2264             :                   case TYPE_U32_STRING:
    2265             :                     {
    2266             :                       const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
    2267             :                       const uint32_t *arg_end;
    2268             :                       size_t characters;
    2269             : 
    2270             :                       if (has_precision)
    2271             :                         {
    2272             :                           /* Use only PRECISION characters, from the left.  */
    2273             :                           arg_end = arg;
    2274             :                           characters = 0;
    2275             :                           for (; precision > 0; precision--)
    2276             :                             {
    2277             :                               int count = u32_strmblen (arg_end);
    2278             :                               if (count == 0)
    2279             :                                 break;
    2280             :                               if (count < 0)
    2281             :                                 {
    2282             :                                   if (!(result == resultbuf || result == NULL))
    2283             :                                     free (result);
    2284             :                                   if (buf_malloced != NULL)
    2285             :                                     free (buf_malloced);
    2286             :                                   CLEANUP ();
    2287             :                                   errno = EILSEQ;
    2288             :                                   return NULL;
    2289             :                                 }
    2290             :                               arg_end += count;
    2291             :                               characters++;
    2292             :                             }
    2293             :                         }
    2294             :                       else if (has_width)
    2295             :                         {
    2296             :                           /* Use the entire string, and count the number of
    2297             :                              characters.  */
    2298             :                           arg_end = arg;
    2299             :                           characters = 0;
    2300             :                           for (;;)
    2301             :                             {
    2302             :                               int count = u32_strmblen (arg_end);
    2303             :                               if (count == 0)
    2304             :                                 break;
    2305             :                               if (count < 0)
    2306             :                                 {
    2307             :                                   if (!(result == resultbuf || result == NULL))
    2308             :                                     free (result);
    2309             :                                   if (buf_malloced != NULL)
    2310             :                                     free (buf_malloced);
    2311             :                                   CLEANUP ();
    2312             :                                   errno = EILSEQ;
    2313             :                                   return NULL;
    2314             :                                 }
    2315             :                               arg_end += count;
    2316             :                               characters++;
    2317             :                             }
    2318             :                         }
    2319             :                       else
    2320             :                         {
    2321             :                           /* Use the entire string.  */
    2322             :                           arg_end = arg + u32_strlen (arg);
    2323             :                           /* The number of characters doesn't matter.  */
    2324             :                           characters = 0;
    2325             :                         }
    2326             : 
    2327             :                       if (characters < width && !(dp->flags & FLAG_LEFT))
    2328             :                         {
    2329             :                           size_t n = width - characters;
    2330             :                           ENSURE_ALLOCATION (xsum (length, n));
    2331             :                           DCHAR_SET (result + length, ' ', n);
    2332             :                           length += n;
    2333             :                         }
    2334             : 
    2335             : # if DCHAR_IS_UINT32_T
    2336             :                       {
    2337             :                         size_t n = arg_end - arg;
    2338             :                         ENSURE_ALLOCATION (xsum (length, n));
    2339             :                         DCHAR_CPY (result + length, arg, n);
    2340             :                         length += n;
    2341             :                       }
    2342             : # else
    2343             :                       { /* Convert.  */
    2344             :                         DCHAR_T *converted = result + length;
    2345             :                         size_t converted_len = allocated - length;
    2346             : #  if DCHAR_IS_TCHAR
    2347             :                         /* Convert from UTF-32 to locale encoding.  */
    2348             :                         converted =
    2349             :                           u32_conv_to_encoding (locale_charset (),
    2350             :                                                 iconveh_question_mark,
    2351             :                                                 arg, arg_end - arg, NULL,
    2352             :                                                 converted, &converted_len);
    2353             : #  else
    2354             :                         /* Convert from UTF-32 to UTF-8/UTF-16.  */
    2355             :                         converted =
    2356             :                           U32_TO_DCHAR (arg, arg_end - arg,
    2357             :                                         converted, &converted_len);
    2358             : #  endif
    2359             :                         if (converted == NULL)
    2360             :                           {
    2361             :                             int saved_errno = errno;
    2362             :                             if (!(result == resultbuf || result == NULL))
    2363             :                               free (result);
    2364             :                             if (buf_malloced != NULL)
    2365             :                               free (buf_malloced);
    2366             :                             CLEANUP ();
    2367             :                             errno = saved_errno;
    2368             :                             return NULL;
    2369             :                           }
    2370             :                         if (converted != result + length)
    2371             :                           {
    2372             :                             ENSURE_ALLOCATION (xsum (length, converted_len));
    2373             :                             DCHAR_CPY (result + length, converted, converted_len);
    2374             :                             free (converted);
    2375             :                           }
    2376             :                         length += converted_len;
    2377             :                       }
    2378             : # endif
    2379             : 
    2380             :                       if (characters < width && (dp->flags & FLAG_LEFT))
    2381             :                         {
    2382             :                           size_t n = width - characters;
    2383             :                           ENSURE_ALLOCATION (xsum (length, n));
    2384             :                           DCHAR_SET (result + length, ' ', n);
    2385             :                           length += n;
    2386             :                         }
    2387             :                     }
    2388             :                     break;
    2389             : 
    2390             :                   default:
    2391             :                     abort ();
    2392             :                   }
    2393             :               }
    2394             : #endif
    2395             : #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
    2396             :             else if (dp->conversion == 's'
    2397             : # if WIDE_CHAR_VERSION
    2398             :                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
    2399             : # else
    2400             :                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
    2401             : # endif
    2402             :                     )
    2403             :               {
    2404             :                 /* The normal handling of the 's' directive below requires
    2405             :                    allocating a temporary buffer.  The determination of its
    2406             :                    length (tmp_length), in the case when a precision is
    2407             :                    specified, below requires a conversion between a char[]
    2408             :                    string and a wchar_t[] wide string.  It could be done, but
    2409             :                    we have no guarantee that the implementation of sprintf will
    2410             :                    use the exactly same algorithm.  Without this guarantee, it
    2411             :                    is possible to have buffer overrun bugs.  In order to avoid
    2412             :                    such bugs, we implement the entire processing of the 's'
    2413             :                    directive ourselves.  */
    2414             :                 int flags = dp->flags;
    2415             :                 int has_width;
    2416             :                 size_t width;
    2417             :                 int has_precision;
    2418             :                 size_t precision;
    2419             : 
    2420             :                 has_width = 0;
    2421             :                 width = 0;
    2422             :                 if (dp->width_start != dp->width_end)
    2423             :                   {
    2424             :                     if (dp->width_arg_index != ARG_NONE)
    2425             :                       {
    2426             :                         int arg;
    2427             : 
    2428             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    2429             :                           abort ();
    2430             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    2431             :                         width = arg;
    2432             :                         if (arg < 0)
    2433             :                           {
    2434             :                             /* "A negative field width is taken as a '-' flag
    2435             :                                 followed by a positive field width."  */
    2436             :                             flags |= FLAG_LEFT;
    2437             :                             width = -width;
    2438             :                           }
    2439             :                       }
    2440             :                     else
    2441             :                       {
    2442             :                         const FCHAR_T *digitp = dp->width_start;
    2443             : 
    2444             :                         do
    2445             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    2446             :                         while (digitp != dp->width_end);
    2447             :                       }
    2448             :                     has_width = 1;
    2449             :                   }
    2450             : 
    2451             :                 has_precision = 0;
    2452             :                 precision = 6;
    2453             :                 if (dp->precision_start != dp->precision_end)
    2454             :                   {
    2455             :                     if (dp->precision_arg_index != ARG_NONE)
    2456             :                       {
    2457             :                         int arg;
    2458             : 
    2459             :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    2460             :                           abort ();
    2461             :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    2462             :                         /* "A negative precision is taken as if the precision
    2463             :                             were omitted."  */
    2464             :                         if (arg >= 0)
    2465             :                           {
    2466             :                             precision = arg;
    2467             :                             has_precision = 1;
    2468             :                           }
    2469             :                       }
    2470             :                     else
    2471             :                       {
    2472             :                         const FCHAR_T *digitp = dp->precision_start + 1;
    2473             : 
    2474             :                         precision = 0;
    2475             :                         while (digitp != dp->precision_end)
    2476             :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    2477             :                         has_precision = 1;
    2478             :                       }
    2479             :                   }
    2480             : 
    2481             : # if WIDE_CHAR_VERSION
    2482             :                 /* %s in vasnwprintf.  See the specification of fwprintf.  */
    2483             :                 {
    2484             :                   const char *arg = a.arg[dp->arg_index].a.a_string;
    2485             :                   const char *arg_end;
    2486             :                   size_t characters;
    2487             : 
    2488             :                   if (has_precision)
    2489             :                     {
    2490             :                       /* Use only as many bytes as needed to produce PRECISION
    2491             :                          wide characters, from the left.  */
    2492             : #  if HAVE_MBRTOWC
    2493             :                       mbstate_t state;
    2494             :                       memset (&state, '\0', sizeof (mbstate_t));
    2495             : #  endif
    2496             :                       arg_end = arg;
    2497             :                       characters = 0;
    2498             :                       for (; precision > 0; precision--)
    2499             :                         {
    2500             :                           int count;
    2501             : #  if HAVE_MBRTOWC
    2502             :                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
    2503             : #  else
    2504             :                           count = mblen (arg_end, MB_CUR_MAX);
    2505             : #  endif
    2506             :                           if (count == 0)
    2507             :                             /* Found the terminating NUL.  */
    2508             :                             break;
    2509             :                           if (count < 0)
    2510             :                             {
    2511             :                               /* Invalid or incomplete multibyte character.  */
    2512             :                               if (!(result == resultbuf || result == NULL))
    2513             :                                 free (result);
    2514             :                               if (buf_malloced != NULL)
    2515             :                                 free (buf_malloced);
    2516             :                               CLEANUP ();
    2517             :                               errno = EILSEQ;
    2518             :                               return NULL;
    2519             :                             }
    2520             :                           arg_end += count;
    2521             :                           characters++;
    2522             :                         }
    2523             :                     }
    2524             :                   else if (has_width)
    2525             :                     {
    2526             :                       /* Use the entire string, and count the number of wide
    2527             :                          characters.  */
    2528             : #  if HAVE_MBRTOWC
    2529             :                       mbstate_t state;
    2530             :                       memset (&state, '\0', sizeof (mbstate_t));
    2531             : #  endif
    2532             :                       arg_end = arg;
    2533             :                       characters = 0;
    2534             :                       for (;;)
    2535             :                         {
    2536             :                           int count;
    2537             : #  if HAVE_MBRTOWC
    2538             :                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
    2539             : #  else
    2540             :                           count = mblen (arg_end, MB_CUR_MAX);
    2541             : #  endif
    2542             :                           if (count == 0)
    2543             :                             /* Found the terminating NUL.  */
    2544             :                             break;
    2545             :                           if (count < 0)
    2546             :                             {
    2547             :                               /* Invalid or incomplete multibyte character.  */
    2548             :                               if (!(result == resultbuf || result == NULL))
    2549             :                                 free (result);
    2550             :                               if (buf_malloced != NULL)
    2551             :                                 free (buf_malloced);
    2552             :                               CLEANUP ();
    2553             :                               errno = EILSEQ;
    2554             :                               return NULL;
    2555             :                             }
    2556             :                           arg_end += count;
    2557             :                           characters++;
    2558             :                         }
    2559             :                     }
    2560             :                   else
    2561             :                     {
    2562             :                       /* Use the entire string.  */
    2563             :                       arg_end = arg + strlen (arg);
    2564             :                       /* The number of characters doesn't matter.  */
    2565             :                       characters = 0;
    2566             :                     }
    2567             : 
    2568             :                   if (characters < width && !(dp->flags & FLAG_LEFT))
    2569             :                     {
    2570             :                       size_t n = width - characters;
    2571             :                       ENSURE_ALLOCATION (xsum (length, n));
    2572             :                       DCHAR_SET (result + length, ' ', n);
    2573             :                       length += n;
    2574             :                     }
    2575             : 
    2576             :                   if (has_precision || has_width)
    2577             :                     {
    2578             :                       /* We know the number of wide characters in advance.  */
    2579             :                       size_t remaining;
    2580             : #  if HAVE_MBRTOWC
    2581             :                       mbstate_t state;
    2582             :                       memset (&state, '\0', sizeof (mbstate_t));
    2583             : #  endif
    2584             :                       ENSURE_ALLOCATION (xsum (length, characters));
    2585             :                       for (remaining = characters; remaining > 0; remaining--)
    2586             :                         {
    2587             :                           wchar_t wc;
    2588             :                           int count;
    2589             : #  if HAVE_MBRTOWC
    2590             :                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
    2591             : #  else
    2592             :                           count = mbtowc (&wc, arg, arg_end - arg);
    2593             : #  endif
    2594             :                           if (count <= 0)
    2595             :                             /* mbrtowc not consistent with mbrlen, or mbtowc
    2596             :                                not consistent with mblen.  */
    2597             :                             abort ();
    2598             :                           result[length++] = wc;
    2599             :                           arg += count;
    2600             :                         }
    2601             :                       if (!(arg == arg_end))
    2602             :                         abort ();
    2603             :                     }
    2604             :                   else
    2605             :                     {
    2606             : #  if HAVE_MBRTOWC
    2607             :                       mbstate_t state;
    2608             :                       memset (&state, '\0', sizeof (mbstate_t));
    2609             : #  endif
    2610             :                       while (arg < arg_end)
    2611             :                         {
    2612             :                           wchar_t wc;
    2613             :                           int count;
    2614             : #  if HAVE_MBRTOWC
    2615             :                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
    2616             : #  else
    2617             :                           count = mbtowc (&wc, arg, arg_end - arg);
    2618             : #  endif
    2619             :                           if (count <= 0)
    2620             :                             /* mbrtowc not consistent with mbrlen, or mbtowc
    2621             :                                not consistent with mblen.  */
    2622             :                             abort ();
    2623             :                           ENSURE_ALLOCATION (xsum (length, 1));
    2624             :                           result[length++] = wc;
    2625             :                           arg += count;
    2626             :                         }
    2627             :                     }
    2628             : 
    2629             :                   if (characters < width && (dp->flags & FLAG_LEFT))
    2630             :                     {
    2631             :                       size_t n = width - characters;
    2632             :                       ENSURE_ALLOCATION (xsum (length, n));
    2633             :                       DCHAR_SET (result + length, ' ', n);
    2634             :                       length += n;
    2635             :                     }
    2636             :                 }
    2637             : # else
    2638             :                 /* %ls in vasnprintf.  See the specification of fprintf.  */
    2639             :                 {
    2640             :                   const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
    2641             :                   const wchar_t *arg_end;
    2642             :                   size_t characters;
    2643             : #  if !DCHAR_IS_TCHAR
    2644             :                   /* This code assumes that TCHAR_T is 'char'.  */
    2645             :                   verify (sizeof (TCHAR_T) == 1);
    2646             :                   TCHAR_T *tmpsrc;
    2647             :                   DCHAR_T *tmpdst;
    2648             :                   size_t tmpdst_len;
    2649             : #  endif
    2650             :                   size_t w;
    2651             : 
    2652             :                   if (has_precision)
    2653             :                     {
    2654             :                       /* Use only as many wide characters as needed to produce
    2655             :                          at most PRECISION bytes, from the left.  */
    2656             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2657             :                       mbstate_t state;
    2658             :                       memset (&state, '\0', sizeof (mbstate_t));
    2659             : #  endif
    2660             :                       arg_end = arg;
    2661             :                       characters = 0;
    2662             :                       while (precision > 0)
    2663             :                         {
    2664             :                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    2665             :                           int count;
    2666             : 
    2667             :                           if (*arg_end == 0)
    2668             :                             /* Found the terminating null wide character.  */
    2669             :                             break;
    2670             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2671             :                           count = wcrtomb (cbuf, *arg_end, &state);
    2672             : #  else
    2673             :                           count = wctomb (cbuf, *arg_end);
    2674             : #  endif
    2675             :                           if (count < 0)
    2676             :                             {
    2677             :                               /* Cannot convert.  */
    2678             :                               if (!(result == resultbuf || result == NULL))
    2679             :                                 free (result);
    2680             :                               if (buf_malloced != NULL)
    2681             :                                 free (buf_malloced);
    2682             :                               CLEANUP ();
    2683             :                               errno = EILSEQ;
    2684             :                               return NULL;
    2685             :                             }
    2686             :                           if (precision < count)
    2687             :                             break;
    2688             :                           arg_end++;
    2689             :                           characters += count;
    2690             :                           precision -= count;
    2691             :                         }
    2692             :                     }
    2693             : #  if DCHAR_IS_TCHAR
    2694             :                   else if (has_width)
    2695             : #  else
    2696             :                   else
    2697             : #  endif
    2698             :                     {
    2699             :                       /* Use the entire string, and count the number of
    2700             :                          bytes.  */
    2701             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2702             :                       mbstate_t state;
    2703             :                       memset (&state, '\0', sizeof (mbstate_t));
    2704             : #  endif
    2705             :                       arg_end = arg;
    2706             :                       characters = 0;
    2707             :                       for (;;)
    2708             :                         {
    2709             :                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    2710             :                           int count;
    2711             : 
    2712             :                           if (*arg_end == 0)
    2713             :                             /* Found the terminating null wide character.  */
    2714             :                             break;
    2715             : #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2716             :                           count = wcrtomb (cbuf, *arg_end, &state);
    2717             : #  else
    2718             :                           count = wctomb (cbuf, *arg_end);
    2719             : #  endif
    2720             :                           if (count < 0)
    2721             :                             {
    2722             :                               /* Cannot convert.  */
    2723             :                               if (!(result == resultbuf || result == NULL))
    2724             :                                 free (result);
    2725             :                               if (buf_malloced != NULL)
    2726             :                                 free (buf_malloced);
    2727             :                               CLEANUP ();
    2728             :                               errno = EILSEQ;
    2729             :                               return NULL;
    2730             :                             }
    2731             :                           arg_end++;
    2732             :                           characters += count;
    2733             :                         }
    2734             :                     }
    2735             : #  if DCHAR_IS_TCHAR
    2736             :                   else
    2737             :                     {
    2738             :                       /* Use the entire string.  */
    2739             :                       arg_end = arg + local_wcslen (arg);
    2740             :                       /* The number of bytes doesn't matter.  */
    2741             :                       characters = 0;
    2742             :                     }
    2743             : #  endif
    2744             : 
    2745             : #  if !DCHAR_IS_TCHAR
    2746             :                   /* Convert the string into a piece of temporary memory.  */
    2747             :                   tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
    2748             :                   if (tmpsrc == NULL)
    2749             :                     goto out_of_memory;
    2750             :                   {
    2751             :                     TCHAR_T *tmpptr = tmpsrc;
    2752             :                     size_t remaining;
    2753             : #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2754             :                     mbstate_t state;
    2755             :                     memset (&state, '\0', sizeof (mbstate_t));
    2756             : #   endif
    2757             :                     for (remaining = characters; remaining > 0; )
    2758             :                       {
    2759             :                         char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    2760             :                         int count;
    2761             : 
    2762             :                         if (*arg == 0)
    2763             :                           abort ();
    2764             : #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2765             :                         count = wcrtomb (cbuf, *arg, &state);
    2766             : #   else
    2767             :                         count = wctomb (cbuf, *arg);
    2768             : #   endif
    2769             :                         if (count <= 0)
    2770             :                           /* Inconsistency.  */
    2771             :                           abort ();
    2772             :                         memcpy (tmpptr, cbuf, count);
    2773             :                         tmpptr += count;
    2774             :                         arg++;
    2775             :                         remaining -= count;
    2776             :                       }
    2777             :                     if (!(arg == arg_end))
    2778             :                       abort ();
    2779             :                   }
    2780             : 
    2781             :                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
    2782             :                   tmpdst =
    2783             :                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
    2784             :                                               iconveh_question_mark,
    2785             :                                               tmpsrc, characters,
    2786             :                                               NULL,
    2787             :                                               NULL, &tmpdst_len);
    2788             :                   if (tmpdst == NULL)
    2789             :                     {
    2790             :                       int saved_errno = errno;
    2791             :                       free (tmpsrc);
    2792             :                       if (!(result == resultbuf || result == NULL))
    2793             :                         free (result);
    2794             :                       if (buf_malloced != NULL)
    2795             :                         free (buf_malloced);
    2796             :                       CLEANUP ();
    2797             :                       errno = saved_errno;
    2798             :                       return NULL;
    2799             :                     }
    2800             :                   free (tmpsrc);
    2801             : #  endif
    2802             : 
    2803             :                   if (has_width)
    2804             :                     {
    2805             : #  if ENABLE_UNISTDIO
    2806             :                       /* Outside POSIX, it's preferable to compare the width
    2807             :                          against the number of _characters_ of the converted
    2808             :                          value.  */
    2809             :                       w = DCHAR_MBSNLEN (result + length, characters);
    2810             : #  else
    2811             :                       /* The width is compared against the number of _bytes_
    2812             :                          of the converted value, says POSIX.  */
    2813             :                       w = characters;
    2814             : #  endif
    2815             :                     }
    2816             :                   else
    2817             :                     /* w doesn't matter.  */
    2818             :                     w = 0;
    2819             : 
    2820             :                   if (w < width && !(dp->flags & FLAG_LEFT))
    2821             :                     {
    2822             :                       size_t n = width - w;
    2823             :                       ENSURE_ALLOCATION (xsum (length, n));
    2824             :                       DCHAR_SET (result + length, ' ', n);
    2825             :                       length += n;
    2826             :                     }
    2827             : 
    2828             : #  if DCHAR_IS_TCHAR
    2829             :                   if (has_precision || has_width)
    2830             :                     {
    2831             :                       /* We know the number of bytes in advance.  */
    2832             :                       size_t remaining;
    2833             : #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2834             :                       mbstate_t state;
    2835             :                       memset (&state, '\0', sizeof (mbstate_t));
    2836             : #   endif
    2837             :                       ENSURE_ALLOCATION (xsum (length, characters));
    2838             :                       for (remaining = characters; remaining > 0; )
    2839             :                         {
    2840             :                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    2841             :                           int count;
    2842             : 
    2843             :                           if (*arg == 0)
    2844             :                             abort ();
    2845             : #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2846             :                           count = wcrtomb (cbuf, *arg, &state);
    2847             : #   else
    2848             :                           count = wctomb (cbuf, *arg);
    2849             : #   endif
    2850             :                           if (count <= 0)
    2851             :                             /* Inconsistency.  */
    2852             :                             abort ();
    2853             :                           memcpy (result + length, cbuf, count);
    2854             :                           length += count;
    2855             :                           arg++;
    2856             :                           remaining -= count;
    2857             :                         }
    2858             :                       if (!(arg == arg_end))
    2859             :                         abort ();
    2860             :                     }
    2861             :                   else
    2862             :                     {
    2863             : #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2864             :                       mbstate_t state;
    2865             :                       memset (&state, '\0', sizeof (mbstate_t));
    2866             : #   endif
    2867             :                       while (arg < arg_end)
    2868             :                         {
    2869             :                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
    2870             :                           int count;
    2871             : 
    2872             :                           if (*arg == 0)
    2873             :                             abort ();
    2874             : #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
    2875             :                           count = wcrtomb (cbuf, *arg, &state);
    2876             : #   else
    2877             :                           count = wctomb (cbuf, *arg);
    2878             : #   endif
    2879             :                           if (count <= 0)
    2880             :                             {
    2881             :                               /* Cannot convert.  */
    2882             :                               if (!(result == resultbuf || result == NULL))
    2883             :                                 free (result);
    2884             :                               if (buf_malloced != NULL)
    2885             :                                 free (buf_malloced);
    2886             :                               CLEANUP ();
    2887             :                               errno = EILSEQ;
    2888             :                               return NULL;
    2889             :                             }
    2890             :                           ENSURE_ALLOCATION (xsum (length, count));
    2891             :                           memcpy (result + length, cbuf, count);
    2892             :                           length += count;
    2893             :                           arg++;
    2894             :                         }
    2895             :                     }
    2896             : #  else
    2897             :                   ENSURE_ALLOCATION (xsum (length, tmpdst_len));
    2898             :                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
    2899             :                   free (tmpdst);
    2900             :                   length += tmpdst_len;
    2901             : #  endif
    2902             : 
    2903             :                   if (w < width && (dp->flags & FLAG_LEFT))
    2904             :                     {
    2905             :                       size_t n = width - w;
    2906             :                       ENSURE_ALLOCATION (xsum (length, n));
    2907             :                       DCHAR_SET (result + length, ' ', n);
    2908             :                       length += n;
    2909             :                     }
    2910             :                 }
    2911             : # endif
    2912             :               }
    2913             : #endif
    2914             : #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
    2915             :             else if ((dp->conversion == 'a' || dp->conversion == 'A')
    2916             : # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
    2917             :                      && (0
    2918             : #  if NEED_PRINTF_DOUBLE
    2919             :                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
    2920             : #  endif
    2921             : #  if NEED_PRINTF_LONG_DOUBLE
    2922             :                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
    2923             : #  endif
    2924             :                         )
    2925             : # endif
    2926             :                     )
    2927             :               {
    2928             :                 arg_type type = a.arg[dp->arg_index].type;
    2929             :                 int flags = dp->flags;
    2930             :                 size_t width;
    2931             :                 int has_precision;
    2932             :                 size_t precision;
    2933             :                 size_t tmp_length;
    2934             :                 size_t count;
    2935             :                 DCHAR_T tmpbuf[700];
    2936             :                 DCHAR_T *tmp;
    2937             :                 DCHAR_T *pad_ptr;
    2938             :                 DCHAR_T *p;
    2939             : 
    2940             :                 width = 0;
    2941             :                 if (dp->width_start != dp->width_end)
    2942             :                   {
    2943             :                     if (dp->width_arg_index != ARG_NONE)
    2944             :                       {
    2945             :                         int arg;
    2946             : 
    2947             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    2948             :                           abort ();
    2949             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    2950             :                         width = arg;
    2951             :                         if (arg < 0)
    2952             :                           {
    2953             :                             /* "A negative field width is taken as a '-' flag
    2954             :                                 followed by a positive field width."  */
    2955             :                             flags |= FLAG_LEFT;
    2956             :                             width = -width;
    2957             :                           }
    2958             :                       }
    2959             :                     else
    2960             :                       {
    2961             :                         const FCHAR_T *digitp = dp->width_start;
    2962             : 
    2963             :                         do
    2964             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    2965             :                         while (digitp != dp->width_end);
    2966             :                       }
    2967             :                   }
    2968             : 
    2969             :                 has_precision = 0;
    2970             :                 precision = 0;
    2971             :                 if (dp->precision_start != dp->precision_end)
    2972             :                   {
    2973             :                     if (dp->precision_arg_index != ARG_NONE)
    2974             :                       {
    2975             :                         int arg;
    2976             : 
    2977             :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    2978             :                           abort ();
    2979             :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    2980             :                         /* "A negative precision is taken as if the precision
    2981             :                             were omitted."  */
    2982             :                         if (arg >= 0)
    2983             :                           {
    2984             :                             precision = arg;
    2985             :                             has_precision = 1;
    2986             :                           }
    2987             :                       }
    2988             :                     else
    2989             :                       {
    2990             :                         const FCHAR_T *digitp = dp->precision_start + 1;
    2991             : 
    2992             :                         precision = 0;
    2993             :                         while (digitp != dp->precision_end)
    2994             :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    2995             :                         has_precision = 1;
    2996             :                       }
    2997             :                   }
    2998             : 
    2999             :                 /* Allocate a temporary buffer of sufficient size.  */
    3000             :                 if (type == TYPE_LONGDOUBLE)
    3001             :                   tmp_length =
    3002             :                     (unsigned int) ((LDBL_DIG + 1)
    3003             :                                     * 0.831 /* decimal -> hexadecimal */
    3004             :                                    )
    3005             :                     + 1; /* turn floor into ceil */
    3006             :                 else
    3007             :                   tmp_length =
    3008             :                     (unsigned int) ((DBL_DIG + 1)
    3009             :                                     * 0.831 /* decimal -> hexadecimal */
    3010             :                                    )
    3011             :                     + 1; /* turn floor into ceil */
    3012             :                 if (tmp_length < precision)
    3013             :                   tmp_length = precision;
    3014             :                 /* Account for sign, decimal point etc. */
    3015             :                 tmp_length = xsum (tmp_length, 12);
    3016             : 
    3017             :                 if (tmp_length < width)
    3018             :                   tmp_length = width;
    3019             : 
    3020             :                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
    3021             : 
    3022             :                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
    3023             :                   tmp = tmpbuf;
    3024             :                 else
    3025             :                   {
    3026             :                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
    3027             : 
    3028             :                     if (size_overflow_p (tmp_memsize))
    3029             :                       /* Overflow, would lead to out of memory.  */
    3030             :                       goto out_of_memory;
    3031             :                     tmp = (DCHAR_T *) malloc (tmp_memsize);
    3032             :                     if (tmp == NULL)
    3033             :                       /* Out of memory.  */
    3034             :                       goto out_of_memory;
    3035             :                   }
    3036             : 
    3037             :                 pad_ptr = NULL;
    3038             :                 p = tmp;
    3039             :                 if (type == TYPE_LONGDOUBLE)
    3040             :                   {
    3041             : # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
    3042             :                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
    3043             : 
    3044             :                     if (isnanl (arg))
    3045             :                       {
    3046             :                         if (dp->conversion == 'A')
    3047             :                           {
    3048             :                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
    3049             :                           }
    3050             :                         else
    3051             :                           {
    3052             :                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
    3053             :                           }
    3054             :                       }
    3055             :                     else
    3056             :                       {
    3057             :                         int sign = 0;
    3058             :                         DECL_LONG_DOUBLE_ROUNDING
    3059             : 
    3060             :                         BEGIN_LONG_DOUBLE_ROUNDING ();
    3061             : 
    3062             :                         if (signbit (arg)) /* arg < 0.0L or negative zero */
    3063             :                           {
    3064             :                             sign = -1;
    3065             :                             arg = -arg;
    3066             :                           }
    3067             : 
    3068             :                         if (sign < 0)
    3069             :                           *p++ = '-';
    3070             :                         else if (flags & FLAG_SHOWSIGN)
    3071             :                           *p++ = '+';
    3072             :                         else if (flags & FLAG_SPACE)
    3073             :                           *p++ = ' ';
    3074             : 
    3075             :                         if (arg > 0.0L && arg + arg == arg)
    3076             :                           {
    3077             :                             if (dp->conversion == 'A')
    3078             :                               {
    3079             :                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
    3080             :                               }
    3081             :                             else
    3082             :                               {
    3083             :                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
    3084             :                               }
    3085             :                           }
    3086             :                         else
    3087             :                           {
    3088             :                             int exponent;
    3089             :                             long double mantissa;
    3090             : 
    3091             :                             if (arg > 0.0L)
    3092             :                               mantissa = printf_frexpl (arg, &exponent);
    3093             :                             else
    3094             :                               {
    3095             :                                 exponent = 0;
    3096             :                                 mantissa = 0.0L;
    3097             :                               }
    3098             : 
    3099             :                             if (has_precision
    3100             :                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
    3101             :                               {
    3102             :                                 /* Round the mantissa.  */
    3103             :                                 long double tail = mantissa;
    3104             :                                 size_t q;
    3105             : 
    3106             :                                 for (q = precision; ; q--)
    3107             :                                   {
    3108             :                                     int digit = (int) tail;
    3109             :                                     tail -= digit;
    3110             :                                     if (q == 0)
    3111             :                                       {
    3112             :                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
    3113             :                                           tail = 1 - tail;
    3114             :                                         else
    3115             :                                           tail = - tail;
    3116             :                                         break;
    3117             :                                       }
    3118             :                                     tail *= 16.0L;
    3119             :                                   }
    3120             :                                 if (tail != 0.0L)
    3121             :                                   for (q = precision; q > 0; q--)
    3122             :                                     tail *= 0.0625L;
    3123             :                                 mantissa += tail;
    3124             :                               }
    3125             : 
    3126             :                             *p++ = '0';
    3127             :                             *p++ = dp->conversion - 'A' + 'X';
    3128             :                             pad_ptr = p;
    3129             :                             {
    3130             :                               int digit;
    3131             : 
    3132             :                               digit = (int) mantissa;
    3133             :                               mantissa -= digit;
    3134             :                               *p++ = '0' + digit;
    3135             :                               if ((flags & FLAG_ALT)
    3136             :                                   || mantissa > 0.0L || precision > 0)
    3137             :                                 {
    3138             :                                   *p++ = decimal_point_char ();
    3139             :                                   /* This loop terminates because we assume
    3140             :                                      that FLT_RADIX is a power of 2.  */
    3141             :                                   while (mantissa > 0.0L)
    3142             :                                     {
    3143             :                                       mantissa *= 16.0L;
    3144             :                                       digit = (int) mantissa;
    3145             :                                       mantissa -= digit;
    3146             :                                       *p++ = digit
    3147             :                                              + (digit < 10
    3148             :                                                 ? '0'
    3149             :                                                 : dp->conversion - 10);
    3150             :                                       if (precision > 0)
    3151             :                                         precision--;
    3152             :                                     }
    3153             :                                   while (precision > 0)
    3154             :                                     {
    3155             :                                       *p++ = '0';
    3156             :                                       precision--;
    3157             :                                     }
    3158             :                                 }
    3159             :                               }
    3160             :                               *p++ = dp->conversion - 'A' + 'P';
    3161             : #  if WIDE_CHAR_VERSION
    3162             :                               {
    3163             :                                 static const wchar_t decimal_format[] =
    3164             :                                   { '%', '+', 'd', '\0' };
    3165             :                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
    3166             :                               }
    3167             :                               while (*p != '\0')
    3168             :                                 p++;
    3169             : #  else
    3170             :                               if (sizeof (DCHAR_T) == 1)
    3171             :                                 {
    3172             :                                   sprintf ((char *) p, "%+d", exponent);
    3173             :                                   while (*p != '\0')
    3174             :                                     p++;
    3175             :                                 }
    3176             :                               else
    3177             :                                 {
    3178             :                                   char expbuf[6 + 1];
    3179             :                                   const char *ep;
    3180             :                                   sprintf (expbuf, "%+d", exponent);
    3181             :                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    3182             :                                     p++;
    3183             :                                 }
    3184             : #  endif
    3185             :                           }
    3186             : 
    3187             :                         END_LONG_DOUBLE_ROUNDING ();
    3188             :                       }
    3189             : # else
    3190             :                     abort ();
    3191             : # endif
    3192             :                   }
    3193             :                 else
    3194             :                   {
    3195             : # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
    3196             :                     double arg = a.arg[dp->arg_index].a.a_double;
    3197             : 
    3198             :                     if (isnand (arg))
    3199             :                       {
    3200             :                         if (dp->conversion == 'A')
    3201             :                           {
    3202             :                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
    3203             :                           }
    3204             :                         else
    3205             :                           {
    3206             :                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
    3207             :                           }
    3208             :                       }
    3209             :                     else
    3210             :                       {
    3211             :                         int sign = 0;
    3212             : 
    3213             :                         if (signbit (arg)) /* arg < 0.0 or negative zero */
    3214             :                           {
    3215             :                             sign = -1;
    3216             :                             arg = -arg;
    3217             :                           }
    3218             : 
    3219             :                         if (sign < 0)
    3220             :                           *p++ = '-';
    3221             :                         else if (flags & FLAG_SHOWSIGN)
    3222             :                           *p++ = '+';
    3223             :                         else if (flags & FLAG_SPACE)
    3224             :                           *p++ = ' ';
    3225             : 
    3226             :                         if (arg > 0.0 && arg + arg == arg)
    3227             :                           {
    3228             :                             if (dp->conversion == 'A')
    3229             :                               {
    3230             :                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
    3231             :                               }
    3232             :                             else
    3233             :                               {
    3234             :                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
    3235             :                               }
    3236             :                           }
    3237             :                         else
    3238             :                           {
    3239             :                             int exponent;
    3240             :                             double mantissa;
    3241             : 
    3242             :                             if (arg > 0.0)
    3243             :                               mantissa = printf_frexp (arg, &exponent);
    3244             :                             else
    3245             :                               {
    3246             :                                 exponent = 0;
    3247             :                                 mantissa = 0.0;
    3248             :                               }
    3249             : 
    3250             :                             if (has_precision
    3251             :                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
    3252             :                               {
    3253             :                                 /* Round the mantissa.  */
    3254             :                                 double tail = mantissa;
    3255             :                                 size_t q;
    3256             : 
    3257             :                                 for (q = precision; ; q--)
    3258             :                                   {
    3259             :                                     int digit = (int) tail;
    3260             :                                     tail -= digit;
    3261             :                                     if (q == 0)
    3262             :                                       {
    3263             :                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
    3264             :                                           tail = 1 - tail;
    3265             :                                         else
    3266             :                                           tail = - tail;
    3267             :                                         break;
    3268             :                                       }
    3269             :                                     tail *= 16.0;
    3270             :                                   }
    3271             :                                 if (tail != 0.0)
    3272             :                                   for (q = precision; q > 0; q--)
    3273             :                                     tail *= 0.0625;
    3274             :                                 mantissa += tail;
    3275             :                               }
    3276             : 
    3277             :                             *p++ = '0';
    3278             :                             *p++ = dp->conversion - 'A' + 'X';
    3279             :                             pad_ptr = p;
    3280             :                             {
    3281             :                               int digit;
    3282             : 
    3283             :                               digit = (int) mantissa;
    3284             :                               mantissa -= digit;
    3285             :                               *p++ = '0' + digit;
    3286             :                               if ((flags & FLAG_ALT)
    3287             :                                   || mantissa > 0.0 || precision > 0)
    3288             :                                 {
    3289             :                                   *p++ = decimal_point_char ();
    3290             :                                   /* This loop terminates because we assume
    3291             :                                      that FLT_RADIX is a power of 2.  */
    3292             :                                   while (mantissa > 0.0)
    3293             :                                     {
    3294             :                                       mantissa *= 16.0;
    3295             :                                       digit = (int) mantissa;
    3296             :                                       mantissa -= digit;
    3297             :                                       *p++ = digit
    3298             :                                              + (digit < 10
    3299             :                                                 ? '0'
    3300             :                                                 : dp->conversion - 10);
    3301             :                                       if (precision > 0)
    3302             :                                         precision--;
    3303             :                                     }
    3304             :                                   while (precision > 0)
    3305             :                                     {
    3306             :                                       *p++ = '0';
    3307             :                                       precision--;
    3308             :                                     }
    3309             :                                 }
    3310             :                               }
    3311             :                               *p++ = dp->conversion - 'A' + 'P';
    3312             : #  if WIDE_CHAR_VERSION
    3313             :                               {
    3314             :                                 static const wchar_t decimal_format[] =
    3315             :                                   { '%', '+', 'd', '\0' };
    3316             :                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
    3317             :                               }
    3318             :                               while (*p != '\0')
    3319             :                                 p++;
    3320             : #  else
    3321             :                               if (sizeof (DCHAR_T) == 1)
    3322             :                                 {
    3323             :                                   sprintf ((char *) p, "%+d", exponent);
    3324             :                                   while (*p != '\0')
    3325             :                                     p++;
    3326             :                                 }
    3327             :                               else
    3328             :                                 {
    3329             :                                   char expbuf[6 + 1];
    3330             :                                   const char *ep;
    3331             :                                   sprintf (expbuf, "%+d", exponent);
    3332             :                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    3333             :                                     p++;
    3334             :                                 }
    3335             : #  endif
    3336             :                           }
    3337             :                       }
    3338             : # else
    3339             :                     abort ();
    3340             : # endif
    3341             :                   }
    3342             : 
    3343             :                 /* The generated string now extends from tmp to p, with the
    3344             :                    zero padding insertion point being at pad_ptr.  */
    3345             :                 count = p - tmp;
    3346             : 
    3347             :                 if (count < width)
    3348             :                   {
    3349             :                     size_t pad = width - count;
    3350             :                     DCHAR_T *end = p + pad;
    3351             : 
    3352             :                     if (flags & FLAG_LEFT)
    3353             :                       {
    3354             :                         /* Pad with spaces on the right.  */
    3355             :                         for (; pad > 0; pad--)
    3356             :                           *p++ = ' ';
    3357             :                       }
    3358             :                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
    3359             :                       {
    3360             :                         /* Pad with zeroes.  */
    3361             :                         DCHAR_T *q = end;
    3362             : 
    3363             :                         while (p > pad_ptr)
    3364             :                           *--q = *--p;
    3365             :                         for (; pad > 0; pad--)
    3366             :                           *p++ = '0';
    3367             :                       }
    3368             :                     else
    3369             :                       {
    3370             :                         /* Pad with spaces on the left.  */
    3371             :                         DCHAR_T *q = end;
    3372             : 
    3373             :                         while (p > tmp)
    3374             :                           *--q = *--p;
    3375             :                         for (; pad > 0; pad--)
    3376             :                           *p++ = ' ';
    3377             :                       }
    3378             : 
    3379             :                     p = end;
    3380             :                   }
    3381             : 
    3382             :                 count = p - tmp;
    3383             : 
    3384             :                 if (count >= tmp_length)
    3385             :                   /* tmp_length was incorrectly calculated - fix the
    3386             :                      code above!  */
    3387             :                   abort ();
    3388             : 
    3389             :                 /* Make room for the result.  */
    3390             :                 if (count >= allocated - length)
    3391             :                   {
    3392             :                     size_t n = xsum (length, count);
    3393             : 
    3394             :                     ENSURE_ALLOCATION (n);
    3395             :                   }
    3396             : 
    3397             :                 /* Append the result.  */
    3398             :                 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
    3399             :                 if (tmp != tmpbuf)
    3400             :                   free (tmp);
    3401             :                 length += count;
    3402             :               }
    3403             : #endif
    3404             : #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
    3405             :             else if ((dp->conversion == 'f' || dp->conversion == 'F'
    3406             :                       || dp->conversion == 'e' || dp->conversion == 'E'
    3407             :                       || dp->conversion == 'g' || dp->conversion == 'G'
    3408             :                       || dp->conversion == 'a' || dp->conversion == 'A')
    3409             :                      && (0
    3410             : # if NEED_PRINTF_DOUBLE
    3411             :                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
    3412             : # elif NEED_PRINTF_INFINITE_DOUBLE
    3413             :                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
    3414             :                              /* The systems (mingw) which produce wrong output
    3415             :                                 for Inf, -Inf, and NaN also do so for -0.0.
    3416             :                                 Therefore we treat this case here as well.  */
    3417             :                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
    3418             : # endif
    3419             : # if NEED_PRINTF_LONG_DOUBLE
    3420             :                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
    3421             : # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
    3422             :                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
    3423             :                              /* Some systems produce wrong output for Inf,
    3424             :                                 -Inf, and NaN.  Some systems in this category
    3425             :                                 (IRIX 5.3) also do so for -0.0.  Therefore we
    3426             :                                 treat this case here as well.  */
    3427             :                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
    3428             : # endif
    3429             :                         ))
    3430             :               {
    3431             : # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
    3432             :                 arg_type type = a.arg[dp->arg_index].type;
    3433             : # endif
    3434             :                 int flags = dp->flags;
    3435             :                 size_t width;
    3436             :                 size_t count;
    3437             :                 int has_precision;
    3438             :                 size_t precision;
    3439             :                 size_t tmp_length;
    3440             :                 DCHAR_T tmpbuf[700];
    3441             :                 DCHAR_T *tmp;
    3442             :                 DCHAR_T *pad_ptr;
    3443             :                 DCHAR_T *p;
    3444             : 
    3445             :                 width = 0;
    3446             :                 if (dp->width_start != dp->width_end)
    3447             :                   {
    3448             :                     if (dp->width_arg_index != ARG_NONE)
    3449             :                       {
    3450             :                         int arg;
    3451             : 
    3452             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    3453             :                           abort ();
    3454             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    3455             :                         width = arg;
    3456             :                         if (arg < 0)
    3457             :                           {
    3458             :                             /* "A negative field width is taken as a '-' flag
    3459             :                                 followed by a positive field width."  */
    3460             :                             flags |= FLAG_LEFT;
    3461             :                             width = -width;
    3462             :                           }
    3463             :                       }
    3464             :                     else
    3465             :                       {
    3466             :                         const FCHAR_T *digitp = dp->width_start;
    3467             : 
    3468             :                         do
    3469             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    3470             :                         while (digitp != dp->width_end);
    3471             :                       }
    3472             :                   }
    3473             : 
    3474             :                 has_precision = 0;
    3475             :                 precision = 0;
    3476             :                 if (dp->precision_start != dp->precision_end)
    3477             :                   {
    3478             :                     if (dp->precision_arg_index != ARG_NONE)
    3479             :                       {
    3480             :                         int arg;
    3481             : 
    3482             :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    3483             :                           abort ();
    3484             :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    3485             :                         /* "A negative precision is taken as if the precision
    3486             :                             were omitted."  */
    3487             :                         if (arg >= 0)
    3488             :                           {
    3489             :                             precision = arg;
    3490             :                             has_precision = 1;
    3491             :                           }
    3492             :                       }
    3493             :                     else
    3494             :                       {
    3495             :                         const FCHAR_T *digitp = dp->precision_start + 1;
    3496             : 
    3497             :                         precision = 0;
    3498             :                         while (digitp != dp->precision_end)
    3499             :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    3500             :                         has_precision = 1;
    3501             :                       }
    3502             :                   }
    3503             : 
    3504             :                 /* POSIX specifies the default precision to be 6 for %f, %F,
    3505             :                    %e, %E, but not for %g, %G.  Implementations appear to use
    3506             :                    the same default precision also for %g, %G.  But for %a, %A,
    3507             :                    the default precision is 0.  */
    3508             :                 if (!has_precision)
    3509             :                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
    3510             :                     precision = 6;
    3511             : 
    3512             :                 /* Allocate a temporary buffer of sufficient size.  */
    3513             : # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
    3514             :                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
    3515             : # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
    3516             :                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
    3517             : # elif NEED_PRINTF_LONG_DOUBLE
    3518             :                 tmp_length = LDBL_DIG + 1;
    3519             : # elif NEED_PRINTF_DOUBLE
    3520             :                 tmp_length = DBL_DIG + 1;
    3521             : # else
    3522             :                 tmp_length = 0;
    3523             : # endif
    3524             :                 if (tmp_length < precision)
    3525             :                   tmp_length = precision;
    3526             : # if NEED_PRINTF_LONG_DOUBLE
    3527             : #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
    3528             :                 if (type == TYPE_LONGDOUBLE)
    3529             : #  endif
    3530             :                   if (dp->conversion == 'f' || dp->conversion == 'F')
    3531             :                     {
    3532             :                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
    3533             :                       if (!(isnanl (arg) || arg + arg == arg))
    3534             :                         {
    3535             :                           /* arg is finite and nonzero.  */
    3536             :                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
    3537             :                           if (exponent >= 0 && tmp_length < exponent + precision)
    3538             :                             tmp_length = exponent + precision;
    3539             :                         }
    3540             :                     }
    3541             : # endif
    3542             : # if NEED_PRINTF_DOUBLE
    3543             : #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
    3544             :                 if (type == TYPE_DOUBLE)
    3545             : #  endif
    3546             :                   if (dp->conversion == 'f' || dp->conversion == 'F')
    3547             :                     {
    3548             :                       double arg = a.arg[dp->arg_index].a.a_double;
    3549             :                       if (!(isnand (arg) || arg + arg == arg))
    3550             :                         {
    3551             :                           /* arg is finite and nonzero.  */
    3552             :                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
    3553             :                           if (exponent >= 0 && tmp_length < exponent + precision)
    3554             :                             tmp_length = exponent + precision;
    3555             :                         }
    3556             :                     }
    3557             : # endif
    3558             :                 /* Account for sign, decimal point etc. */
    3559             :                 tmp_length = xsum (tmp_length, 12);
    3560             : 
    3561             :                 if (tmp_length < width)
    3562             :                   tmp_length = width;
    3563             : 
    3564             :                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
    3565             : 
    3566             :                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
    3567             :                   tmp = tmpbuf;
    3568             :                 else
    3569             :                   {
    3570             :                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
    3571             : 
    3572             :                     if (size_overflow_p (tmp_memsize))
    3573             :                       /* Overflow, would lead to out of memory.  */
    3574             :                       goto out_of_memory;
    3575             :                     tmp = (DCHAR_T *) malloc (tmp_memsize);
    3576             :                     if (tmp == NULL)
    3577             :                       /* Out of memory.  */
    3578             :                       goto out_of_memory;
    3579             :                   }
    3580             : 
    3581             :                 pad_ptr = NULL;
    3582             :                 p = tmp;
    3583             : 
    3584             : # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
    3585             : #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
    3586             :                 if (type == TYPE_LONGDOUBLE)
    3587             : #  endif
    3588             :                   {
    3589             :                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
    3590             : 
    3591             :                     if (isnanl (arg))
    3592             :                       {
    3593             :                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
    3594             :                           {
    3595             :                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
    3596             :                           }
    3597             :                         else
    3598             :                           {
    3599             :                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
    3600             :                           }
    3601             :                       }
    3602             :                     else
    3603             :                       {
    3604             :                         int sign = 0;
    3605             :                         DECL_LONG_DOUBLE_ROUNDING
    3606             : 
    3607             :                         BEGIN_LONG_DOUBLE_ROUNDING ();
    3608             : 
    3609             :                         if (signbit (arg)) /* arg < 0.0L or negative zero */
    3610             :                           {
    3611             :                             sign = -1;
    3612             :                             arg = -arg;
    3613             :                           }
    3614             : 
    3615             :                         if (sign < 0)
    3616             :                           *p++ = '-';
    3617             :                         else if (flags & FLAG_SHOWSIGN)
    3618             :                           *p++ = '+';
    3619             :                         else if (flags & FLAG_SPACE)
    3620             :                           *p++ = ' ';
    3621             : 
    3622             :                         if (arg > 0.0L && arg + arg == arg)
    3623             :                           {
    3624             :                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
    3625             :                               {
    3626             :                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
    3627             :                               }
    3628             :                             else
    3629             :                               {
    3630             :                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
    3631             :                               }
    3632             :                           }
    3633             :                         else
    3634             :                           {
    3635             : #  if NEED_PRINTF_LONG_DOUBLE
    3636             :                             pad_ptr = p;
    3637             : 
    3638             :                             if (dp->conversion == 'f' || dp->conversion == 'F')
    3639             :                               {
    3640             :                                 char *digits;
    3641             :                                 size_t ndigits;
    3642             : 
    3643             :                                 digits =
    3644             :                                   scale10_round_decimal_long_double (arg, precision);
    3645             :                                 if (digits == NULL)
    3646             :                                   {
    3647             :                                     END_LONG_DOUBLE_ROUNDING ();
    3648             :                                     goto out_of_memory;
    3649             :                                   }
    3650             :                                 ndigits = strlen (digits);
    3651             : 
    3652             :                                 if (ndigits > precision)
    3653             :                                   do
    3654             :                                     {
    3655             :                                       --ndigits;
    3656             :                                       *p++ = digits[ndigits];
    3657             :                                     }
    3658             :                                   while (ndigits > precision);
    3659             :                                 else
    3660             :                                   *p++ = '0';
    3661             :                                 /* Here ndigits <= precision.  */
    3662             :                                 if ((flags & FLAG_ALT) || precision > 0)
    3663             :                                   {
    3664             :                                     *p++ = decimal_point_char ();
    3665             :                                     for (; precision > ndigits; precision--)
    3666             :                                       *p++ = '0';
    3667             :                                     while (ndigits > 0)
    3668             :                                       {
    3669             :                                         --ndigits;
    3670             :                                         *p++ = digits[ndigits];
    3671             :                                       }
    3672             :                                   }
    3673             : 
    3674             :                                 free (digits);
    3675             :                               }
    3676             :                             else if (dp->conversion == 'e' || dp->conversion == 'E')
    3677             :                               {
    3678             :                                 int exponent;
    3679             : 
    3680             :                                 if (arg == 0.0L)
    3681             :                                   {
    3682             :                                     exponent = 0;
    3683             :                                     *p++ = '0';
    3684             :                                     if ((flags & FLAG_ALT) || precision > 0)
    3685             :                                       {
    3686             :                                         *p++ = decimal_point_char ();
    3687             :                                         for (; precision > 0; precision--)
    3688             :                                           *p++ = '0';
    3689             :                                       }
    3690             :                                   }
    3691             :                                 else
    3692             :                                   {
    3693             :                                     /* arg > 0.0L.  */
    3694             :                                     int adjusted;
    3695             :                                     char *digits;
    3696             :                                     size_t ndigits;
    3697             : 
    3698             :                                     exponent = floorlog10l (arg);
    3699             :                                     adjusted = 0;
    3700             :                                     for (;;)
    3701             :                                       {
    3702             :                                         digits =
    3703             :                                           scale10_round_decimal_long_double (arg,
    3704             :                                                                              (int)precision - exponent);
    3705             :                                         if (digits == NULL)
    3706             :                                           {
    3707             :                                             END_LONG_DOUBLE_ROUNDING ();
    3708             :                                             goto out_of_memory;
    3709             :                                           }
    3710             :                                         ndigits = strlen (digits);
    3711             : 
    3712             :                                         if (ndigits == precision + 1)
    3713             :                                           break;
    3714             :                                         if (ndigits < precision
    3715             :                                             || ndigits > precision + 2)
    3716             :                                           /* The exponent was not guessed
    3717             :                                              precisely enough.  */
    3718             :                                           abort ();
    3719             :                                         if (adjusted)
    3720             :                                           /* None of two values of exponent is
    3721             :                                              the right one.  Prevent an endless
    3722             :                                              loop.  */
    3723             :                                           abort ();
    3724             :                                         free (digits);
    3725             :                                         if (ndigits == precision)
    3726             :                                           exponent -= 1;
    3727             :                                         else
    3728             :                                           exponent += 1;
    3729             :                                         adjusted = 1;
    3730             :                                       }
    3731             :                                     /* Here ndigits = precision+1.  */
    3732             :                                     if (is_borderline (digits, precision))
    3733             :                                       {
    3734             :                                         /* Maybe the exponent guess was too high
    3735             :                                            and a smaller exponent can be reached
    3736             :                                            by turning a 10...0 into 9...9x.  */
    3737             :                                         char *digits2 =
    3738             :                                           scale10_round_decimal_long_double (arg,
    3739             :                                                                              (int)precision - exponent + 1);
    3740             :                                         if (digits2 == NULL)
    3741             :                                           {
    3742             :                                             free (digits);
    3743             :                                             END_LONG_DOUBLE_ROUNDING ();
    3744             :                                             goto out_of_memory;
    3745             :                                           }
    3746             :                                         if (strlen (digits2) == precision + 1)
    3747             :                                           {
    3748             :                                             free (digits);
    3749             :                                             digits = digits2;
    3750             :                                             exponent -= 1;
    3751             :                                           }
    3752             :                                         else
    3753             :                                           free (digits2);
    3754             :                                       }
    3755             :                                     /* Here ndigits = precision+1.  */
    3756             : 
    3757             :                                     *p++ = digits[--ndigits];
    3758             :                                     if ((flags & FLAG_ALT) || precision > 0)
    3759             :                                       {
    3760             :                                         *p++ = decimal_point_char ();
    3761             :                                         while (ndigits > 0)
    3762             :                                           {
    3763             :                                             --ndigits;
    3764             :                                             *p++ = digits[ndigits];
    3765             :                                           }
    3766             :                                       }
    3767             : 
    3768             :                                     free (digits);
    3769             :                                   }
    3770             : 
    3771             :                                 *p++ = dp->conversion; /* 'e' or 'E' */
    3772             : #   if WIDE_CHAR_VERSION
    3773             :                                 {
    3774             :                                   static const wchar_t decimal_format[] =
    3775             :                                     { '%', '+', '.', '2', 'd', '\0' };
    3776             :                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
    3777             :                                 }
    3778             :                                 while (*p != '\0')
    3779             :                                   p++;
    3780             : #   else
    3781             :                                 if (sizeof (DCHAR_T) == 1)
    3782             :                                   {
    3783             :                                     sprintf ((char *) p, "%+.2d", exponent);
    3784             :                                     while (*p != '\0')
    3785             :                                       p++;
    3786             :                                   }
    3787             :                                 else
    3788             :                                   {
    3789             :                                     char expbuf[6 + 1];
    3790             :                                     const char *ep;
    3791             :                                     sprintf (expbuf, "%+.2d", exponent);
    3792             :                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    3793             :                                       p++;
    3794             :                                   }
    3795             : #   endif
    3796             :                               }
    3797             :                             else if (dp->conversion == 'g' || dp->conversion == 'G')
    3798             :                               {
    3799             :                                 if (precision == 0)
    3800             :                                   precision = 1;
    3801             :                                 /* precision >= 1.  */
    3802             : 
    3803             :                                 if (arg == 0.0L)
    3804             :                                   /* The exponent is 0, >= -4, < precision.
    3805             :                                      Use fixed-point notation.  */
    3806             :                                   {
    3807             :                                     size_t ndigits = precision;
    3808             :                                     /* Number of trailing zeroes that have to be
    3809             :                                        dropped.  */
    3810             :                                     size_t nzeroes =
    3811             :                                       (flags & FLAG_ALT ? 0 : precision - 1);
    3812             : 
    3813             :                                     --ndigits;
    3814             :                                     *p++ = '0';
    3815             :                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
    3816             :                                       {
    3817             :                                         *p++ = decimal_point_char ();
    3818             :                                         while (ndigits > nzeroes)
    3819             :                                           {
    3820             :                                             --ndigits;
    3821             :                                             *p++ = '0';
    3822             :                                           }
    3823             :                                       }
    3824             :                                   }
    3825             :                                 else
    3826             :                                   {
    3827             :                                     /* arg > 0.0L.  */
    3828             :                                     int exponent;
    3829             :                                     int adjusted;
    3830             :                                     char *digits;
    3831             :                                     size_t ndigits;
    3832             :                                     size_t nzeroes;
    3833             : 
    3834             :                                     exponent = floorlog10l (arg);
    3835             :                                     adjusted = 0;
    3836             :                                     for (;;)
    3837             :                                       {
    3838             :                                         digits =
    3839             :                                           scale10_round_decimal_long_double (arg,
    3840             :                                                                              (int)(precision - 1) - exponent);
    3841             :                                         if (digits == NULL)
    3842             :                                           {
    3843             :                                             END_LONG_DOUBLE_ROUNDING ();
    3844             :                                             goto out_of_memory;
    3845             :                                           }
    3846             :                                         ndigits = strlen (digits);
    3847             : 
    3848             :                                         if (ndigits == precision)
    3849             :                                           break;
    3850             :                                         if (ndigits < precision - 1
    3851             :                                             || ndigits > precision + 1)
    3852             :                                           /* The exponent was not guessed
    3853             :                                              precisely enough.  */
    3854             :                                           abort ();
    3855             :                                         if (adjusted)
    3856             :                                           /* None of two values of exponent is
    3857             :                                              the right one.  Prevent an endless
    3858             :                                              loop.  */
    3859             :                                           abort ();
    3860             :                                         free (digits);
    3861             :                                         if (ndigits < precision)
    3862             :                                           exponent -= 1;
    3863             :                                         else
    3864             :                                           exponent += 1;
    3865             :                                         adjusted = 1;
    3866             :                                       }
    3867             :                                     /* Here ndigits = precision.  */
    3868             :                                     if (is_borderline (digits, precision - 1))
    3869             :                                       {
    3870             :                                         /* Maybe the exponent guess was too high
    3871             :                                            and a smaller exponent can be reached
    3872             :                                            by turning a 10...0 into 9...9x.  */
    3873             :                                         char *digits2 =
    3874             :                                           scale10_round_decimal_long_double (arg,
    3875             :                                                                              (int)(precision - 1) - exponent + 1);
    3876             :                                         if (digits2 == NULL)
    3877             :                                           {
    3878             :                                             free (digits);
    3879             :                                             END_LONG_DOUBLE_ROUNDING ();
    3880             :                                             goto out_of_memory;
    3881             :                                           }
    3882             :                                         if (strlen (digits2) == precision)
    3883             :                                           {
    3884             :                                             free (digits);
    3885             :                                             digits = digits2;
    3886             :                                             exponent -= 1;
    3887             :                                           }
    3888             :                                         else
    3889             :                                           free (digits2);
    3890             :                                       }
    3891             :                                     /* Here ndigits = precision.  */
    3892             : 
    3893             :                                     /* Determine the number of trailing zeroes
    3894             :                                        that have to be dropped.  */
    3895             :                                     nzeroes = 0;
    3896             :                                     if ((flags & FLAG_ALT) == 0)
    3897             :                                       while (nzeroes < ndigits
    3898             :                                              && digits[nzeroes] == '0')
    3899             :                                         nzeroes++;
    3900             : 
    3901             :                                     /* The exponent is now determined.  */
    3902             :                                     if (exponent >= -4
    3903             :                                         && exponent < (long)precision)
    3904             :                                       {
    3905             :                                         /* Fixed-point notation:
    3906             :                                            max(exponent,0)+1 digits, then the
    3907             :                                            decimal point, then the remaining
    3908             :                                            digits without trailing zeroes.  */
    3909             :                                         if (exponent >= 0)
    3910             :                                           {
    3911             :                                             size_t ecount = exponent + 1;
    3912             :                                             /* Note: count <= precision = ndigits.  */
    3913             :                                             for (; ecount > 0; ecount--)
    3914             :                                               *p++ = digits[--ndigits];
    3915             :                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
    3916             :                                               {
    3917             :                                                 *p++ = decimal_point_char ();
    3918             :                                                 while (ndigits > nzeroes)
    3919             :                                                   {
    3920             :                                                     --ndigits;
    3921             :                                                     *p++ = digits[ndigits];
    3922             :                                                   }
    3923             :                                               }
    3924             :                                           }
    3925             :                                         else
    3926             :                                           {
    3927             :                                             size_t ecount = -exponent - 1;
    3928             :                                             *p++ = '0';
    3929             :                                             *p++ = decimal_point_char ();
    3930             :                                             for (; ecount > 0; ecount--)
    3931             :                                               *p++ = '0';
    3932             :                                             while (ndigits > nzeroes)
    3933             :                                               {
    3934             :                                                 --ndigits;
    3935             :                                                 *p++ = digits[ndigits];
    3936             :                                               }
    3937             :                                           }
    3938             :                                       }
    3939             :                                     else
    3940             :                                       {
    3941             :                                         /* Exponential notation.  */
    3942             :                                         *p++ = digits[--ndigits];
    3943             :                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
    3944             :                                           {
    3945             :                                             *p++ = decimal_point_char ();
    3946             :                                             while (ndigits > nzeroes)
    3947             :                                               {
    3948             :                                                 --ndigits;
    3949             :                                                 *p++ = digits[ndigits];
    3950             :                                               }
    3951             :                                           }
    3952             :                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
    3953             : #   if WIDE_CHAR_VERSION
    3954             :                                         {
    3955             :                                           static const wchar_t decimal_format[] =
    3956             :                                             { '%', '+', '.', '2', 'd', '\0' };
    3957             :                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
    3958             :                                         }
    3959             :                                         while (*p != '\0')
    3960             :                                           p++;
    3961             : #   else
    3962             :                                         if (sizeof (DCHAR_T) == 1)
    3963             :                                           {
    3964             :                                             sprintf ((char *) p, "%+.2d", exponent);
    3965             :                                             while (*p != '\0')
    3966             :                                               p++;
    3967             :                                           }
    3968             :                                         else
    3969             :                                           {
    3970             :                                             char expbuf[6 + 1];
    3971             :                                             const char *ep;
    3972             :                                             sprintf (expbuf, "%+.2d", exponent);
    3973             :                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    3974             :                                               p++;
    3975             :                                           }
    3976             : #   endif
    3977             :                                       }
    3978             : 
    3979             :                                     free (digits);
    3980             :                                   }
    3981             :                               }
    3982             :                             else
    3983             :                               abort ();
    3984             : #  else
    3985             :                             /* arg is finite.  */
    3986             :                             if (!(arg == 0.0L))
    3987             :                               abort ();
    3988             : 
    3989             :                             pad_ptr = p;
    3990             : 
    3991             :                             if (dp->conversion == 'f' || dp->conversion == 'F')
    3992             :                               {
    3993             :                                 *p++ = '0';
    3994             :                                 if ((flags & FLAG_ALT) || precision > 0)
    3995             :                                   {
    3996             :                                     *p++ = decimal_point_char ();
    3997             :                                     for (; precision > 0; precision--)
    3998             :                                       *p++ = '0';
    3999             :                                   }
    4000             :                               }
    4001             :                             else if (dp->conversion == 'e' || dp->conversion == 'E')
    4002             :                               {
    4003             :                                 *p++ = '0';
    4004             :                                 if ((flags & FLAG_ALT) || precision > 0)
    4005             :                                   {
    4006             :                                     *p++ = decimal_point_char ();
    4007             :                                     for (; precision > 0; precision--)
    4008             :                                       *p++ = '0';
    4009             :                                   }
    4010             :                                 *p++ = dp->conversion; /* 'e' or 'E' */
    4011             :                                 *p++ = '+';
    4012             :                                 *p++ = '0';
    4013             :                                 *p++ = '0';
    4014             :                               }
    4015             :                             else if (dp->conversion == 'g' || dp->conversion == 'G')
    4016             :                               {
    4017             :                                 *p++ = '0';
    4018             :                                 if (flags & FLAG_ALT)
    4019             :                                   {
    4020             :                                     size_t ndigits =
    4021             :                                       (precision > 0 ? precision - 1 : 0);
    4022             :                                     *p++ = decimal_point_char ();
    4023             :                                     for (; ndigits > 0; --ndigits)
    4024             :                                       *p++ = '0';
    4025             :                                   }
    4026             :                               }
    4027             :                             else if (dp->conversion == 'a' || dp->conversion == 'A')
    4028             :                               {
    4029             :                                 *p++ = '0';
    4030             :                                 *p++ = dp->conversion - 'A' + 'X';
    4031             :                                 pad_ptr = p;
    4032             :                                 *p++ = '0';
    4033             :                                 if ((flags & FLAG_ALT) || precision > 0)
    4034             :                                   {
    4035             :                                     *p++ = decimal_point_char ();
    4036             :                                     for (; precision > 0; precision--)
    4037             :                                       *p++ = '0';
    4038             :                                   }
    4039             :                                 *p++ = dp->conversion - 'A' + 'P';
    4040             :                                 *p++ = '+';
    4041             :                                 *p++ = '0';
    4042             :                               }
    4043             :                             else
    4044             :                               abort ();
    4045             : #  endif
    4046             :                           }
    4047             : 
    4048             :                         END_LONG_DOUBLE_ROUNDING ();
    4049             :                       }
    4050             :                   }
    4051             : #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
    4052             :                 else
    4053             : #  endif
    4054             : # endif
    4055             : # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
    4056             :                   {
    4057             :                     double arg = a.arg[dp->arg_index].a.a_double;
    4058             : 
    4059             :                     if (isnand (arg))
    4060             :                       {
    4061             :                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
    4062             :                           {
    4063             :                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
    4064             :                           }
    4065             :                         else
    4066             :                           {
    4067             :                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
    4068             :                           }
    4069             :                       }
    4070             :                     else
    4071             :                       {
    4072             :                         int sign = 0;
    4073             : 
    4074             :                         if (signbit (arg)) /* arg < 0.0 or negative zero */
    4075             :                           {
    4076             :                             sign = -1;
    4077             :                             arg = -arg;
    4078             :                           }
    4079             : 
    4080             :                         if (sign < 0)
    4081             :                           *p++ = '-';
    4082             :                         else if (flags & FLAG_SHOWSIGN)
    4083             :                           *p++ = '+';
    4084             :                         else if (flags & FLAG_SPACE)
    4085             :                           *p++ = ' ';
    4086             : 
    4087             :                         if (arg > 0.0 && arg + arg == arg)
    4088             :                           {
    4089             :                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
    4090             :                               {
    4091             :                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
    4092             :                               }
    4093             :                             else
    4094             :                               {
    4095             :                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
    4096             :                               }
    4097             :                           }
    4098             :                         else
    4099             :                           {
    4100             : #  if NEED_PRINTF_DOUBLE
    4101             :                             pad_ptr = p;
    4102             : 
    4103             :                             if (dp->conversion == 'f' || dp->conversion == 'F')
    4104             :                               {
    4105             :                                 char *digits;
    4106             :                                 size_t ndigits;
    4107             : 
    4108             :                                 digits =
    4109             :                                   scale10_round_decimal_double (arg, precision);
    4110             :                                 if (digits == NULL)
    4111             :                                   goto out_of_memory;
    4112             :                                 ndigits = strlen (digits);
    4113             : 
    4114             :                                 if (ndigits > precision)
    4115             :                                   do
    4116             :                                     {
    4117             :                                       --ndigits;
    4118             :                                       *p++ = digits[ndigits];
    4119             :                                     }
    4120             :                                   while (ndigits > precision);
    4121             :                                 else
    4122             :                                   *p++ = '0';
    4123             :                                 /* Here ndigits <= precision.  */
    4124             :                                 if ((flags & FLAG_ALT) || precision > 0)
    4125             :                                   {
    4126             :                                     *p++ = decimal_point_char ();
    4127             :                                     for (; precision > ndigits; precision--)
    4128             :                                       *p++ = '0';
    4129             :                                     while (ndigits > 0)
    4130             :                                       {
    4131             :                                         --ndigits;
    4132             :                                         *p++ = digits[ndigits];
    4133             :                                       }
    4134             :                                   }
    4135             : 
    4136             :                                 free (digits);
    4137             :                               }
    4138             :                             else if (dp->conversion == 'e' || dp->conversion == 'E')
    4139             :                               {
    4140             :                                 int exponent;
    4141             : 
    4142             :                                 if (arg == 0.0)
    4143             :                                   {
    4144             :                                     exponent = 0;
    4145             :                                     *p++ = '0';
    4146             :                                     if ((flags & FLAG_ALT) || precision > 0)
    4147             :                                       {
    4148             :                                         *p++ = decimal_point_char ();
    4149             :                                         for (; precision > 0; precision--)
    4150             :                                           *p++ = '0';
    4151             :                                       }
    4152             :                                   }
    4153             :                                 else
    4154             :                                   {
    4155             :                                     /* arg > 0.0.  */
    4156             :                                     int adjusted;
    4157             :                                     char *digits;
    4158             :                                     size_t ndigits;
    4159             : 
    4160             :                                     exponent = floorlog10 (arg);
    4161             :                                     adjusted = 0;
    4162             :                                     for (;;)
    4163             :                                       {
    4164             :                                         digits =
    4165             :                                           scale10_round_decimal_double (arg,
    4166             :                                                                         (int)precision - exponent);
    4167             :                                         if (digits == NULL)
    4168             :                                           goto out_of_memory;
    4169             :                                         ndigits = strlen (digits);
    4170             : 
    4171             :                                         if (ndigits == precision + 1)
    4172             :                                           break;
    4173             :                                         if (ndigits < precision
    4174             :                                             || ndigits > precision + 2)
    4175             :                                           /* The exponent was not guessed
    4176             :                                              precisely enough.  */
    4177             :                                           abort ();
    4178             :                                         if (adjusted)
    4179             :                                           /* None of two values of exponent is
    4180             :                                              the right one.  Prevent an endless
    4181             :                                              loop.  */
    4182             :                                           abort ();
    4183             :                                         free (digits);
    4184             :                                         if (ndigits == precision)
    4185             :                                           exponent -= 1;
    4186             :                                         else
    4187             :                                           exponent += 1;
    4188             :                                         adjusted = 1;
    4189             :                                       }
    4190             :                                     /* Here ndigits = precision+1.  */
    4191             :                                     if (is_borderline (digits, precision))
    4192             :                                       {
    4193             :                                         /* Maybe the exponent guess was too high
    4194             :                                            and a smaller exponent can be reached
    4195             :                                            by turning a 10...0 into 9...9x.  */
    4196             :                                         char *digits2 =
    4197             :                                           scale10_round_decimal_double (arg,
    4198             :                                                                         (int)precision - exponent + 1);
    4199             :                                         if (digits2 == NULL)
    4200             :                                           {
    4201             :                                             free (digits);
    4202             :                                             goto out_of_memory;
    4203             :                                           }
    4204             :                                         if (strlen (digits2) == precision + 1)
    4205             :                                           {
    4206             :                                             free (digits);
    4207             :                                             digits = digits2;
    4208             :                                             exponent -= 1;
    4209             :                                           }
    4210             :                                         else
    4211             :                                           free (digits2);
    4212             :                                       }
    4213             :                                     /* Here ndigits = precision+1.  */
    4214             : 
    4215             :                                     *p++ = digits[--ndigits];
    4216             :                                     if ((flags & FLAG_ALT) || precision > 0)
    4217             :                                       {
    4218             :                                         *p++ = decimal_point_char ();
    4219             :                                         while (ndigits > 0)
    4220             :                                           {
    4221             :                                             --ndigits;
    4222             :                                             *p++ = digits[ndigits];
    4223             :                                           }
    4224             :                                       }
    4225             : 
    4226             :                                     free (digits);
    4227             :                                   }
    4228             : 
    4229             :                                 *p++ = dp->conversion; /* 'e' or 'E' */
    4230             : #   if WIDE_CHAR_VERSION
    4231             :                                 {
    4232             :                                   static const wchar_t decimal_format[] =
    4233             :                                     /* Produce the same number of exponent digits
    4234             :                                        as the native printf implementation.  */
    4235             : #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
    4236             :                                     { '%', '+', '.', '3', 'd', '\0' };
    4237             : #    else
    4238             :                                     { '%', '+', '.', '2', 'd', '\0' };
    4239             : #    endif
    4240             :                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
    4241             :                                 }
    4242             :                                 while (*p != '\0')
    4243             :                                   p++;
    4244             : #   else
    4245             :                                 {
    4246             :                                   static const char decimal_format[] =
    4247             :                                     /* Produce the same number of exponent digits
    4248             :                                        as the native printf implementation.  */
    4249             : #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
    4250             :                                     "%+.3d";
    4251             : #    else
    4252             :                                     "%+.2d";
    4253             : #    endif
    4254             :                                   if (sizeof (DCHAR_T) == 1)
    4255             :                                     {
    4256             :                                       sprintf ((char *) p, decimal_format, exponent);
    4257             :                                       while (*p != '\0')
    4258             :                                         p++;
    4259             :                                     }
    4260             :                                   else
    4261             :                                     {
    4262             :                                       char expbuf[6 + 1];
    4263             :                                       const char *ep;
    4264             :                                       sprintf (expbuf, decimal_format, exponent);
    4265             :                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    4266             :                                         p++;
    4267             :                                     }
    4268             :                                 }
    4269             : #   endif
    4270             :                               }
    4271             :                             else if (dp->conversion == 'g' || dp->conversion == 'G')
    4272             :                               {
    4273             :                                 if (precision == 0)
    4274             :                                   precision = 1;
    4275             :                                 /* precision >= 1.  */
    4276             : 
    4277             :                                 if (arg == 0.0)
    4278             :                                   /* The exponent is 0, >= -4, < precision.
    4279             :                                      Use fixed-point notation.  */
    4280             :                                   {
    4281             :                                     size_t ndigits = precision;
    4282             :                                     /* Number of trailing zeroes that have to be
    4283             :                                        dropped.  */
    4284             :                                     size_t nzeroes =
    4285             :                                       (flags & FLAG_ALT ? 0 : precision - 1);
    4286             : 
    4287             :                                     --ndigits;
    4288             :                                     *p++ = '0';
    4289             :                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
    4290             :                                       {
    4291             :                                         *p++ = decimal_point_char ();
    4292             :                                         while (ndigits > nzeroes)
    4293             :                                           {
    4294             :                                             --ndigits;
    4295             :                                             *p++ = '0';
    4296             :                                           }
    4297             :                                       }
    4298             :                                   }
    4299             :                                 else
    4300             :                                   {
    4301             :                                     /* arg > 0.0.  */
    4302             :                                     int exponent;
    4303             :                                     int adjusted;
    4304             :                                     char *digits;
    4305             :                                     size_t ndigits;
    4306             :                                     size_t nzeroes;
    4307             : 
    4308             :                                     exponent = floorlog10 (arg);
    4309             :                                     adjusted = 0;
    4310             :                                     for (;;)
    4311             :                                       {
    4312             :                                         digits =
    4313             :                                           scale10_round_decimal_double (arg,
    4314             :                                                                         (int)(precision - 1) - exponent);
    4315             :                                         if (digits == NULL)
    4316             :                                           goto out_of_memory;
    4317             :                                         ndigits = strlen (digits);
    4318             : 
    4319             :                                         if (ndigits == precision)
    4320             :                                           break;
    4321             :                                         if (ndigits < precision - 1
    4322             :                                             || ndigits > precision + 1)
    4323             :                                           /* The exponent was not guessed
    4324             :                                              precisely enough.  */
    4325             :                                           abort ();
    4326             :                                         if (adjusted)
    4327             :                                           /* None of two values of exponent is
    4328             :                                              the right one.  Prevent an endless
    4329             :                                              loop.  */
    4330             :                                           abort ();
    4331             :                                         free (digits);
    4332             :                                         if (ndigits < precision)
    4333             :                                           exponent -= 1;
    4334             :                                         else
    4335             :                                           exponent += 1;
    4336             :                                         adjusted = 1;
    4337             :                                       }
    4338             :                                     /* Here ndigits = precision.  */
    4339             :                                     if (is_borderline (digits, precision - 1))
    4340             :                                       {
    4341             :                                         /* Maybe the exponent guess was too high
    4342             :                                            and a smaller exponent can be reached
    4343             :                                            by turning a 10...0 into 9...9x.  */
    4344             :                                         char *digits2 =
    4345             :                                           scale10_round_decimal_double (arg,
    4346             :                                                                         (int)(precision - 1) - exponent + 1);
    4347             :                                         if (digits2 == NULL)
    4348             :                                           {
    4349             :                                             free (digits);
    4350             :                                             goto out_of_memory;
    4351             :                                           }
    4352             :                                         if (strlen (digits2) == precision)
    4353             :                                           {
    4354             :                                             free (digits);
    4355             :                                             digits = digits2;
    4356             :                                             exponent -= 1;
    4357             :                                           }
    4358             :                                         else
    4359             :                                           free (digits2);
    4360             :                                       }
    4361             :                                     /* Here ndigits = precision.  */
    4362             : 
    4363             :                                     /* Determine the number of trailing zeroes
    4364             :                                        that have to be dropped.  */
    4365             :                                     nzeroes = 0;
    4366             :                                     if ((flags & FLAG_ALT) == 0)
    4367             :                                       while (nzeroes < ndigits
    4368             :                                              && digits[nzeroes] == '0')
    4369             :                                         nzeroes++;
    4370             : 
    4371             :                                     /* The exponent is now determined.  */
    4372             :                                     if (exponent >= -4
    4373             :                                         && exponent < (long)precision)
    4374             :                                       {
    4375             :                                         /* Fixed-point notation:
    4376             :                                            max(exponent,0)+1 digits, then the
    4377             :                                            decimal point, then the remaining
    4378             :                                            digits without trailing zeroes.  */
    4379             :                                         if (exponent >= 0)
    4380             :                                           {
    4381             :                                             size_t ecount = exponent + 1;
    4382             :                                             /* Note: ecount <= precision = ndigits.  */
    4383             :                                             for (; ecount > 0; ecount--)
    4384             :                                               *p++ = digits[--ndigits];
    4385             :                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
    4386             :                                               {
    4387             :                                                 *p++ = decimal_point_char ();
    4388             :                                                 while (ndigits > nzeroes)
    4389             :                                                   {
    4390             :                                                     --ndigits;
    4391             :                                                     *p++ = digits[ndigits];
    4392             :                                                   }
    4393             :                                               }
    4394             :                                           }
    4395             :                                         else
    4396             :                                           {
    4397             :                                             size_t ecount = -exponent - 1;
    4398             :                                             *p++ = '0';
    4399             :                                             *p++ = decimal_point_char ();
    4400             :                                             for (; ecount > 0; ecount--)
    4401             :                                               *p++ = '0';
    4402             :                                             while (ndigits > nzeroes)
    4403             :                                               {
    4404             :                                                 --ndigits;
    4405             :                                                 *p++ = digits[ndigits];
    4406             :                                               }
    4407             :                                           }
    4408             :                                       }
    4409             :                                     else
    4410             :                                       {
    4411             :                                         /* Exponential notation.  */
    4412             :                                         *p++ = digits[--ndigits];
    4413             :                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
    4414             :                                           {
    4415             :                                             *p++ = decimal_point_char ();
    4416             :                                             while (ndigits > nzeroes)
    4417             :                                               {
    4418             :                                                 --ndigits;
    4419             :                                                 *p++ = digits[ndigits];
    4420             :                                               }
    4421             :                                           }
    4422             :                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
    4423             : #   if WIDE_CHAR_VERSION
    4424             :                                         {
    4425             :                                           static const wchar_t decimal_format[] =
    4426             :                                             /* Produce the same number of exponent digits
    4427             :                                                as the native printf implementation.  */
    4428             : #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
    4429             :                                             { '%', '+', '.', '3', 'd', '\0' };
    4430             : #    else
    4431             :                                             { '%', '+', '.', '2', 'd', '\0' };
    4432             : #    endif
    4433             :                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
    4434             :                                         }
    4435             :                                         while (*p != '\0')
    4436             :                                           p++;
    4437             : #   else
    4438             :                                         {
    4439             :                                           static const char decimal_format[] =
    4440             :                                             /* Produce the same number of exponent digits
    4441             :                                                as the native printf implementation.  */
    4442             : #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
    4443             :                                             "%+.3d";
    4444             : #    else
    4445             :                                             "%+.2d";
    4446             : #    endif
    4447             :                                           if (sizeof (DCHAR_T) == 1)
    4448             :                                             {
    4449             :                                               sprintf ((char *) p, decimal_format, exponent);
    4450             :                                               while (*p != '\0')
    4451             :                                                 p++;
    4452             :                                             }
    4453             :                                           else
    4454             :                                             {
    4455             :                                               char expbuf[6 + 1];
    4456             :                                               const char *ep;
    4457             :                                               sprintf (expbuf, decimal_format, exponent);
    4458             :                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
    4459             :                                                 p++;
    4460             :                                             }
    4461             :                                         }
    4462             : #   endif
    4463             :                                       }
    4464             : 
    4465             :                                     free (digits);
    4466             :                                   }
    4467             :                               }
    4468             :                             else
    4469             :                               abort ();
    4470             : #  else
    4471             :                             /* arg is finite.  */
    4472             :                             if (!(arg == 0.0))
    4473             :                               abort ();
    4474             : 
    4475             :                             pad_ptr = p;
    4476             : 
    4477             :                             if (dp->conversion == 'f' || dp->conversion == 'F')
    4478             :                               {
    4479             :                                 *p++ = '0';
    4480             :                                 if ((flags & FLAG_ALT) || precision > 0)
    4481             :                                   {
    4482             :                                     *p++ = decimal_point_char ();
    4483             :                                     for (; precision > 0; precision--)
    4484             :                                       *p++ = '0';
    4485             :                                   }
    4486             :                               }
    4487             :                             else if (dp->conversion == 'e' || dp->conversion == 'E')
    4488             :                               {
    4489             :                                 *p++ = '0';
    4490             :                                 if ((flags & FLAG_ALT) || precision > 0)
    4491             :                                   {
    4492             :                                     *p++ = decimal_point_char ();
    4493             :                                     for (; precision > 0; precision--)
    4494             :                                       *p++ = '0';
    4495             :                                   }
    4496             :                                 *p++ = dp->conversion; /* 'e' or 'E' */
    4497             :                                 *p++ = '+';
    4498             :                                 /* Produce the same number of exponent digits as
    4499             :                                    the native printf implementation.  */
    4500             : #   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
    4501             :                                 *p++ = '0';
    4502             : #   endif
    4503             :                                 *p++ = '0';
    4504             :                                 *p++ = '0';
    4505             :                               }
    4506             :                             else if (dp->conversion == 'g' || dp->conversion == 'G')
    4507             :                               {
    4508             :                                 *p++ = '0';
    4509             :                                 if (flags & FLAG_ALT)
    4510             :                                   {
    4511             :                                     size_t ndigits =
    4512             :                                       (precision > 0 ? precision - 1 : 0);
    4513             :                                     *p++ = decimal_point_char ();
    4514             :                                     for (; ndigits > 0; --ndigits)
    4515             :                                       *p++ = '0';
    4516             :                                   }
    4517             :                               }
    4518             :                             else
    4519             :                               abort ();
    4520             : #  endif
    4521             :                           }
    4522             :                       }
    4523             :                   }
    4524             : # endif
    4525             : 
    4526             :                 /* The generated string now extends from tmp to p, with the
    4527             :                    zero padding insertion point being at pad_ptr.  */
    4528             :                 count = p - tmp;
    4529             : 
    4530             :                 if (count < width)
    4531             :                   {
    4532             :                     size_t pad = width - count;
    4533             :                     DCHAR_T *end = p + pad;
    4534             : 
    4535             :                     if (flags & FLAG_LEFT)
    4536             :                       {
    4537             :                         /* Pad with spaces on the right.  */
    4538             :                         for (; pad > 0; pad--)
    4539             :                           *p++ = ' ';
    4540             :                       }
    4541             :                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
    4542             :                       {
    4543             :                         /* Pad with zeroes.  */
    4544             :                         DCHAR_T *q = end;
    4545             : 
    4546             :                         while (p > pad_ptr)
    4547             :                           *--q = *--p;
    4548             :                         for (; pad > 0; pad--)
    4549             :                           *p++ = '0';
    4550             :                       }
    4551             :                     else
    4552             :                       {
    4553             :                         /* Pad with spaces on the left.  */
    4554             :                         DCHAR_T *q = end;
    4555             : 
    4556             :                         while (p > tmp)
    4557             :                           *--q = *--p;
    4558             :                         for (; pad > 0; pad--)
    4559             :                           *p++ = ' ';
    4560             :                       }
    4561             : 
    4562             :                     p = end;
    4563             :                   }
    4564             : 
    4565             :                 count = p - tmp;
    4566             : 
    4567             :                 if (count >= tmp_length)
    4568             :                   /* tmp_length was incorrectly calculated - fix the
    4569             :                      code above!  */
    4570             :                   abort ();
    4571             : 
    4572             :                 /* Make room for the result.  */
    4573             :                 if (count >= allocated - length)
    4574             :                   {
    4575             :                     size_t n = xsum (length, count);
    4576             : 
    4577             :                     ENSURE_ALLOCATION (n);
    4578             :                   }
    4579             : 
    4580             :                 /* Append the result.  */
    4581             :                 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
    4582             :                 if (tmp != tmpbuf)
    4583             :                   free (tmp);
    4584             :                 length += count;
    4585             :               }
    4586             : #endif
    4587             :             else
    4588             :               {
    4589           0 :                 arg_type type = a.arg[dp->arg_index].type;
    4590           0 :                 int flags = dp->flags;
    4591             : #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    4592             :                 int has_width;
    4593             : #endif
    4594             : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    4595             :                 size_t width;
    4596             : #endif
    4597             : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
    4598             :                 int has_precision;
    4599             :                 size_t precision;
    4600             : #endif
    4601             : #if NEED_PRINTF_UNBOUNDED_PRECISION
    4602             :                 int prec_ourselves;
    4603             : #else
    4604             : #               define prec_ourselves 0
    4605             : #endif
    4606             : #if NEED_PRINTF_FLAG_LEFTADJUST
    4607             : #               define pad_ourselves 1
    4608             : #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    4609             :                 int pad_ourselves;
    4610             : #else
    4611             : #               define pad_ourselves 0
    4612             : #endif
    4613             :                 TCHAR_T *fbp;
    4614             :                 unsigned int prefix_count;
    4615             :                 int prefixes[2] IF_LINT (= { 0 });
    4616             :                 int orig_errno;
    4617             : #if !USE_SNPRINTF
    4618             :                 size_t tmp_length;
    4619             :                 TCHAR_T tmpbuf[700];
    4620             :                 TCHAR_T *tmp;
    4621             : #endif
    4622             : 
    4623             : #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    4624             :                 has_width = 0;
    4625             : #endif
    4626             : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    4627             :                 width = 0;
    4628             :                 if (dp->width_start != dp->width_end)
    4629             :                   {
    4630             :                     if (dp->width_arg_index != ARG_NONE)
    4631             :                       {
    4632             :                         int arg;
    4633             : 
    4634             :                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    4635             :                           abort ();
    4636             :                         arg = a.arg[dp->width_arg_index].a.a_int;
    4637             :                         width = arg;
    4638             :                         if (arg < 0)
    4639             :                           {
    4640             :                             /* "A negative field width is taken as a '-' flag
    4641             :                                 followed by a positive field width."  */
    4642             :                             flags |= FLAG_LEFT;
    4643             :                             width = -width;
    4644             :                           }
    4645             :                       }
    4646             :                     else
    4647             :                       {
    4648             :                         const FCHAR_T *digitp = dp->width_start;
    4649             : 
    4650             :                         do
    4651             :                           width = xsum (xtimes (width, 10), *digitp++ - '0');
    4652             :                         while (digitp != dp->width_end);
    4653             :                       }
    4654             : #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    4655             :                     has_width = 1;
    4656             : #endif
    4657             :                   }
    4658             : #endif
    4659             : 
    4660             : #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
    4661             :                 has_precision = 0;
    4662             :                 precision = 6;
    4663             :                 if (dp->precision_start != dp->precision_end)
    4664             :                   {
    4665             :                     if (dp->precision_arg_index != ARG_NONE)
    4666             :                       {
    4667             :                         int arg;
    4668             : 
    4669             :                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    4670             :                           abort ();
    4671             :                         arg = a.arg[dp->precision_arg_index].a.a_int;
    4672             :                         /* "A negative precision is taken as if the precision
    4673             :                             were omitted."  */
    4674             :                         if (arg >= 0)
    4675             :                           {
    4676             :                             precision = arg;
    4677             :                             has_precision = 1;
    4678             :                           }
    4679             :                       }
    4680             :                     else
    4681             :                       {
    4682             :                         const FCHAR_T *digitp = dp->precision_start + 1;
    4683             : 
    4684             :                         precision = 0;
    4685             :                         while (digitp != dp->precision_end)
    4686             :                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
    4687             :                         has_precision = 1;
    4688             :                       }
    4689             :                   }
    4690             : #endif
    4691             : 
    4692             :                 /* Decide whether to handle the precision ourselves.  */
    4693             : #if NEED_PRINTF_UNBOUNDED_PRECISION
    4694             :                 switch (dp->conversion)
    4695             :                   {
    4696             :                   case 'd': case 'i': case 'u':
    4697             :                   case 'o':
    4698             :                   case 'x': case 'X': case 'p':
    4699             :                     prec_ourselves = has_precision && (precision > 0);
    4700             :                     break;
    4701             :                   default:
    4702             :                     prec_ourselves = 0;
    4703             :                     break;
    4704             :                   }
    4705             : #endif
    4706             : 
    4707             :                 /* Decide whether to perform the padding ourselves.  */
    4708             : #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
    4709             :                 switch (dp->conversion)
    4710             :                   {
    4711             : # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
    4712             :                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
    4713             :                      to perform the padding after this conversion.  Functions
    4714             :                      with unistdio extensions perform the padding based on
    4715             :                      character count rather than element count.  */
    4716             :                   case 'c': case 's':
    4717             : # endif
    4718             : # if NEED_PRINTF_FLAG_ZERO
    4719             :                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
    4720             :                   case 'a': case 'A':
    4721             : # endif
    4722             :                     pad_ourselves = 1;
    4723             :                     break;
    4724             :                   default:
    4725             :                     pad_ourselves = prec_ourselves;
    4726             :                     break;
    4727             :                   }
    4728             : #endif
    4729             : 
    4730             : #if !USE_SNPRINTF
    4731             :                 /* Allocate a temporary buffer of sufficient size for calling
    4732             :                    sprintf.  */
    4733             :                 tmp_length =
    4734             :                   MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
    4735             :                                    flags, width, has_precision, precision,
    4736             :                                    pad_ourselves);
    4737             : 
    4738             :                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
    4739             :                   tmp = tmpbuf;
    4740             :                 else
    4741             :                   {
    4742             :                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
    4743             : 
    4744             :                     if (size_overflow_p (tmp_memsize))
    4745             :                       /* Overflow, would lead to out of memory.  */
    4746             :                       goto out_of_memory;
    4747             :                     tmp = (TCHAR_T *) malloc (tmp_memsize);
    4748             :                     if (tmp == NULL)
    4749             :                       /* Out of memory.  */
    4750             :                       goto out_of_memory;
    4751             :                   }
    4752             : #endif
    4753             : 
    4754             :                 /* Construct the format string for calling snprintf or
    4755             :                    sprintf.  */
    4756           0 :                 fbp = buf;
    4757           0 :                 *fbp++ = '%';
    4758             : #if NEED_PRINTF_FLAG_GROUPING
    4759             :                 /* The underlying implementation doesn't support the ' flag.
    4760             :                    Produce no grouping characters in this case; this is
    4761             :                    acceptable because the grouping is locale dependent.  */
    4762             : #else
    4763           0 :                 if (flags & FLAG_GROUP)
    4764           0 :                   *fbp++ = '\'';
    4765             : #endif
    4766           0 :                 if (flags & FLAG_LEFT)
    4767           0 :                   *fbp++ = '-';
    4768           0 :                 if (flags & FLAG_SHOWSIGN)
    4769           0 :                   *fbp++ = '+';
    4770           0 :                 if (flags & FLAG_SPACE)
    4771           0 :                   *fbp++ = ' ';
    4772           0 :                 if (flags & FLAG_ALT)
    4773           0 :                   *fbp++ = '#';
    4774             : #if __GLIBC__ >= 2 && !defined __UCLIBC__
    4775           0 :                 if (flags & FLAG_LOCALIZED)
    4776           0 :                   *fbp++ = 'I';
    4777             : #endif
    4778             :                 if (!pad_ourselves)
    4779             :                   {
    4780           0 :                     if (flags & FLAG_ZERO)
    4781           0 :                       *fbp++ = '0';
    4782           0 :                     if (dp->width_start != dp->width_end)
    4783             :                       {
    4784           0 :                         size_t n = dp->width_end - dp->width_start;
    4785             :                         /* The width specification is known to consist only
    4786             :                            of standard ASCII characters.  */
    4787             :                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
    4788             :                           {
    4789           0 :                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
    4790           0 :                             fbp += n;
    4791             :                           }
    4792             :                         else
    4793             :                           {
    4794             :                             const FCHAR_T *mp = dp->width_start;
    4795             :                             do
    4796             :                               *fbp++ = *mp++;
    4797             :                             while (--n > 0);
    4798             :                           }
    4799             :                       }
    4800             :                   }
    4801             :                 if (!prec_ourselves)
    4802             :                   {
    4803           0 :                     if (dp->precision_start != dp->precision_end)
    4804             :                       {
    4805           0 :                         size_t n = dp->precision_end - dp->precision_start;
    4806             :                         /* The precision specification is known to consist only
    4807             :                            of standard ASCII characters.  */
    4808             :                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
    4809             :                           {
    4810           0 :                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
    4811           0 :                             fbp += n;
    4812             :                           }
    4813             :                         else
    4814             :                           {
    4815             :                             const FCHAR_T *mp = dp->precision_start;
    4816             :                             do
    4817             :                               *fbp++ = *mp++;
    4818             :                             while (--n > 0);
    4819             :                           }
    4820             :                       }
    4821             :                   }
    4822             : 
    4823           0 :                 switch (type)
    4824             :                   {
    4825             : #if HAVE_LONG_LONG_INT
    4826             :                   case TYPE_LONGLONGINT:
    4827             :                   case TYPE_ULONGLONGINT:
    4828             : # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
    4829             :                     *fbp++ = 'I';
    4830             :                     *fbp++ = '6';
    4831             :                     *fbp++ = '4';
    4832             :                     break;
    4833             : # else
    4834           0 :                     *fbp++ = 'l';
    4835             :                     /*FALLTHROUGH*/
    4836             : # endif
    4837             : #endif
    4838             :                   case TYPE_LONGINT:
    4839             :                   case TYPE_ULONGINT:
    4840             : #if HAVE_WINT_T
    4841             :                   case TYPE_WIDE_CHAR:
    4842             : #endif
    4843             : #if HAVE_WCHAR_T
    4844             :                   case TYPE_WIDE_STRING:
    4845             : #endif
    4846           0 :                     *fbp++ = 'l';
    4847           0 :                     break;
    4848             :                   case TYPE_LONGDOUBLE:
    4849           0 :                     *fbp++ = 'L';
    4850           0 :                     break;
    4851             :                   default:
    4852           0 :                     break;
    4853             :                   }
    4854             : #if NEED_PRINTF_DIRECTIVE_F
    4855             :                 if (dp->conversion == 'F')
    4856             :                   *fbp = 'f';
    4857             :                 else
    4858             : #endif
    4859           0 :                   *fbp = dp->conversion;
    4860             : #if USE_SNPRINTF
    4861             : # if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
    4862             :                 fbp[1] = '%';
    4863             :                 fbp[2] = 'n';
    4864             :                 fbp[3] = '\0';
    4865             : # else
    4866             :                 /* On glibc2 systems from glibc >= 2.3 - probably also older
    4867             :                    ones - we know that snprintf's return value conforms to
    4868             :                    ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
    4869             :                    gl_SNPRINTF_TRUNCATION_C99 pass.
    4870             :                    Therefore we can avoid using %n in this situation.
    4871             :                    On glibc2 systems from 2004-10-18 or newer, the use of %n
    4872             :                    in format strings in writable memory may crash the program
    4873             :                    (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
    4874             :                    in this situation.  */
    4875             :                 /* On native Windows systems (such as mingw), we can avoid using
    4876             :                    %n because:
    4877             :                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
    4878             :                        snprintf does not write more than the specified number
    4879             :                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
    4880             :                        '4', '5', '6' into buf, not '4', '5', '\0'.)
    4881             :                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
    4882             :                        allows us to recognize the case of an insufficient
    4883             :                        buffer size: it returns -1 in this case.
    4884             :                    On native Windows systems (such as mingw) where the OS is
    4885             :                    Windows Vista, the use of %n in format strings by default
    4886             :                    crashes the program. See
    4887             :                      <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
    4888             :                      <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
    4889             :                    So we should avoid %n in this situation.  */
    4890           0 :                 fbp[1] = '\0';
    4891             : # endif
    4892             : #else
    4893             :                 fbp[1] = '\0';
    4894             : #endif
    4895             : 
    4896             :                 /* Construct the arguments for calling snprintf or sprintf.  */
    4897           0 :                 prefix_count = 0;
    4898           0 :                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
    4899             :                   {
    4900           0 :                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
    4901           0 :                       abort ();
    4902           0 :                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
    4903             :                   }
    4904           0 :                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
    4905             :                   {
    4906           0 :                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
    4907           0 :                       abort ();
    4908           0 :                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
    4909             :                   }
    4910             : 
    4911             : #if USE_SNPRINTF
    4912             :                 /* The SNPRINTF result is appended after result[0..length].
    4913             :                    The latter is an array of DCHAR_T; SNPRINTF appends an
    4914             :                    array of TCHAR_T to it.  This is possible because
    4915             :                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
    4916             :                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
    4917             : # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
    4918             :                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
    4919             :                    where an snprintf() with maxlen==1 acts like sprintf().  */
    4920           0 :                 ENSURE_ALLOCATION (xsum (length,
    4921             :                                          (2 + TCHARS_PER_DCHAR - 1)
    4922             :                                          / TCHARS_PER_DCHAR));
    4923             :                 /* Prepare checking whether snprintf returns the count
    4924             :                    via %n.  */
    4925           0 :                 *(TCHAR_T *) (result + length) = '\0';
    4926             : #endif
    4927             : 
    4928           0 :                 orig_errno = errno;
    4929             : 
    4930             :                 for (;;)
    4931             :                   {
    4932           0 :                     int count = -1;
    4933             : 
    4934             : #if USE_SNPRINTF
    4935           0 :                     int retcount = 0;
    4936           0 :                     size_t maxlen = allocated - length;
    4937             :                     /* SNPRINTF can fail if its second argument is
    4938             :                        > INT_MAX.  */
    4939           0 :                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
    4940           0 :                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
    4941           0 :                     maxlen = maxlen * TCHARS_PER_DCHAR;
    4942             : # define SNPRINTF_BUF(arg) \
    4943             :                     switch (prefix_count)                                   \
    4944             :                       {                                                     \
    4945             :                       case 0:                                               \
    4946             :                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
    4947             :                                              maxlen, buf,                   \
    4948             :                                              arg, &count);                  \
    4949             :                         break;                                              \
    4950             :                       case 1:                                               \
    4951             :                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
    4952             :                                              maxlen, buf,                   \
    4953             :                                              prefixes[0], arg, &count);     \
    4954             :                         break;                                              \
    4955             :                       case 2:                                               \
    4956             :                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
    4957             :                                              maxlen, buf,                   \
    4958             :                                              prefixes[0], prefixes[1], arg, \
    4959             :                                              &count);                       \
    4960             :                         break;                                              \
    4961             :                       default:                                              \
    4962             :                         abort ();                                           \
    4963             :                       }
    4964             : #else
    4965             : # define SNPRINTF_BUF(arg) \
    4966             :                     switch (prefix_count)                                   \
    4967             :                       {                                                     \
    4968             :                       case 0:                                               \
    4969             :                         count = sprintf (tmp, buf, arg);                    \
    4970             :                         break;                                              \
    4971             :                       case 1:                                               \
    4972             :                         count = sprintf (tmp, buf, prefixes[0], arg);       \
    4973             :                         break;                                              \
    4974             :                       case 2:                                               \
    4975             :                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
    4976             :                                          arg);                              \
    4977             :                         break;                                              \
    4978             :                       default:                                              \
    4979             :                         abort ();                                           \
    4980             :                       }
    4981             : #endif
    4982             : 
    4983           0 :                     errno = 0;
    4984           0 :                     switch (type)
    4985             :                       {
    4986             :                       case TYPE_SCHAR:
    4987             :                         {
    4988           0 :                           int arg = a.arg[dp->arg_index].a.a_schar;
    4989           0 :                           SNPRINTF_BUF (arg);
    4990             :                         }
    4991           0 :                         break;
    4992             :                       case TYPE_UCHAR:
    4993             :                         {
    4994           0 :                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
    4995           0 :                           SNPRINTF_BUF (arg);
    4996             :                         }
    4997           0 :                         break;
    4998             :                       case TYPE_SHORT:
    4999             :                         {
    5000           0 :                           int arg = a.arg[dp->arg_index].a.a_short;
    5001           0 :                           SNPRINTF_BUF (arg);
    5002             :                         }
    5003           0 :                         break;
    5004             :                       case TYPE_USHORT:
    5005             :                         {
    5006           0 :                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
    5007           0 :                           SNPRINTF_BUF (arg);
    5008             :                         }
    5009           0 :                         break;
    5010             :                       case TYPE_INT:
    5011             :                         {
    5012           0 :                           int arg = a.arg[dp->arg_index].a.a_int;
    5013           0 :                           SNPRINTF_BUF (arg);
    5014             :                         }
    5015           0 :                         break;
    5016             :                       case TYPE_UINT:
    5017             :                         {
    5018           0 :                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
    5019           0 :                           SNPRINTF_BUF (arg);
    5020             :                         }
    5021           0 :                         break;
    5022             :                       case TYPE_LONGINT:
    5023             :                         {
    5024           0 :                           long int arg = a.arg[dp->arg_index].a.a_longint;
    5025           0 :                           SNPRINTF_BUF (arg);
    5026             :                         }
    5027           0 :                         break;
    5028             :                       case TYPE_ULONGINT:
    5029             :                         {
    5030           0 :                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
    5031           0 :                           SNPRINTF_BUF (arg);
    5032             :                         }
    5033           0 :                         break;
    5034             : #if HAVE_LONG_LONG_INT
    5035             :                       case TYPE_LONGLONGINT:
    5036             :                         {
    5037           0 :                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
    5038           0 :                           SNPRINTF_BUF (arg);
    5039             :                         }
    5040           0 :                         break;
    5041             :                       case TYPE_ULONGLONGINT:
    5042             :                         {
    5043           0 :                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
    5044           0 :                           SNPRINTF_BUF (arg);
    5045             :                         }
    5046           0 :                         break;
    5047             : #endif
    5048             :                       case TYPE_DOUBLE:
    5049             :                         {
    5050           0 :                           double arg = a.arg[dp->arg_index].a.a_double;
    5051           0 :                           SNPRINTF_BUF (arg);
    5052             :                         }
    5053           0 :                         break;
    5054             :                       case TYPE_LONGDOUBLE:
    5055             :                         {
    5056           0 :                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
    5057           0 :                           SNPRINTF_BUF (arg);
    5058             :                         }
    5059           0 :                         break;
    5060             :                       case TYPE_CHAR:
    5061             :                         {
    5062           0 :                           int arg = a.arg[dp->arg_index].a.a_char;
    5063           0 :                           SNPRINTF_BUF (arg);
    5064             :                         }
    5065           0 :                         break;
    5066             : #if HAVE_WINT_T
    5067             :                       case TYPE_WIDE_CHAR:
    5068             :                         {
    5069           0 :                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
    5070           0 :                           SNPRINTF_BUF (arg);
    5071             :                         }
    5072           0 :                         break;
    5073             : #endif
    5074             :                       case TYPE_STRING:
    5075             :                         {
    5076           0 :                           const char *arg = a.arg[dp->arg_index].a.a_string;
    5077           0 :                           SNPRINTF_BUF (arg);
    5078             :                         }
    5079           0 :                         break;
    5080             : #if HAVE_WCHAR_T
    5081             :                       case TYPE_WIDE_STRING:
    5082             :                         {
    5083           0 :                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
    5084           0 :                           SNPRINTF_BUF (arg);
    5085             :                         }
    5086           0 :                         break;
    5087             : #endif
    5088             :                       case TYPE_POINTER:
    5089             :                         {
    5090           0 :                           void *arg = a.arg[dp->arg_index].a.a_pointer;
    5091           0 :                           SNPRINTF_BUF (arg);
    5092             :                         }
    5093           0 :                         break;
    5094             :                       default:
    5095           0 :                         abort ();
    5096             :                       }
    5097             : 
    5098             : #if USE_SNPRINTF
    5099             :                     /* Portability: Not all implementations of snprintf()
    5100             :                        are ISO C 99 compliant.  Determine the number of
    5101             :                        bytes that snprintf() has produced or would have
    5102             :                        produced.  */
    5103           0 :                     if (count >= 0)
    5104             :                       {
    5105             :                         /* Verify that snprintf() has NUL-terminated its
    5106             :                            result.  */
    5107           0 :                         if (count < maxlen
    5108           0 :                             && ((TCHAR_T *) (result + length)) [count] != '\0')
    5109           0 :                           abort ();
    5110             :                         /* Portability hack.  */
    5111           0 :                         if (retcount > count)
    5112           0 :                           count = retcount;
    5113             :                       }
    5114             :                     else
    5115             :                       {
    5116             :                         /* snprintf() doesn't understand the '%n'
    5117             :                            directive.  */
    5118           0 :                         if (fbp[1] != '\0')
    5119             :                           {
    5120             :                             /* Don't use the '%n' directive; instead, look
    5121             :                                at the snprintf() return value.  */
    5122           0 :                             fbp[1] = '\0';
    5123           0 :                             continue;
    5124             :                           }
    5125             :                         else
    5126             :                           {
    5127             :                             /* Look at the snprintf() return value.  */
    5128           0 :                             if (retcount < 0)
    5129             :                               {
    5130             : # if !HAVE_SNPRINTF_RETVAL_C99
    5131             :                                 /* HP-UX 10.20 snprintf() is doubly deficient:
    5132             :                                    It doesn't understand the '%n' directive,
    5133             :                                    *and* it returns -1 (rather than the length
    5134             :                                    that would have been required) when the
    5135             :                                    buffer is too small.
    5136             :                                    But a failure at this point can also come
    5137             :                                    from other reasons than a too small buffer,
    5138             :                                    such as an invalid wide string argument to
    5139             :                                    the %ls directive, or possibly an invalid
    5140             :                                    floating-point argument.  */
    5141             :                                 size_t tmp_length =
    5142             :                                   MAX_ROOM_NEEDED (&a, dp->arg_index,
    5143             :                                                    dp->conversion, type, flags,
    5144             :                                                    width,
    5145             :                                                    has_precision,
    5146             :                                                    precision, pad_ourselves);
    5147             : 
    5148             :                                 if (maxlen < tmp_length)
    5149             :                                   {
    5150             :                                     /* Make more room.  But try to do through
    5151             :                                        this reallocation only once.  */
    5152             :                                     size_t bigger_need =
    5153             :                                       xsum (length,
    5154             :                                             xsum (tmp_length,
    5155             :                                                   TCHARS_PER_DCHAR - 1)
    5156             :                                             / TCHARS_PER_DCHAR);
    5157             :                                     /* And always grow proportionally.
    5158             :                                        (There may be several arguments, each
    5159             :                                        needing a little more room than the
    5160             :                                        previous one.)  */
    5161             :                                     size_t bigger_need2 =
    5162             :                                       xsum (xtimes (allocated, 2), 12);
    5163             :                                     if (bigger_need < bigger_need2)
    5164             :                                       bigger_need = bigger_need2;
    5165             :                                     ENSURE_ALLOCATION (bigger_need);
    5166             :                                     continue;
    5167             :                                   }
    5168             : # endif
    5169             :                               }
    5170             :                             else
    5171           0 :                               count = retcount;
    5172             :                           }
    5173             :                       }
    5174             : #endif
    5175             : 
    5176             :                     /* Attempt to handle failure.  */
    5177           0 :                     if (count < 0)
    5178             :                       {
    5179             :                         /* SNPRINTF or sprintf failed.  Save and use the errno
    5180             :                            that it has set, if any.  */
    5181           0 :                         int saved_errno = errno;
    5182           0 :                         if (saved_errno == 0)
    5183             :                           {
    5184           0 :                             if (dp->conversion == 'c' || dp->conversion == 's')
    5185           0 :                               saved_errno = EILSEQ;
    5186             :                             else
    5187           0 :                               saved_errno = EINVAL;
    5188             :                           }
    5189             : 
    5190           0 :                         if (!(result == resultbuf || result == NULL))
    5191           0 :                           free (result);
    5192           0 :                         if (buf_malloced != NULL)
    5193           0 :                           free (buf_malloced);
    5194           0 :                         CLEANUP ();
    5195             : 
    5196           0 :                         errno = saved_errno;
    5197           0 :                         return NULL;
    5198             :                       }
    5199             : 
    5200             : #if USE_SNPRINTF
    5201             :                     /* Handle overflow of the allocated buffer.
    5202             :                        If such an overflow occurs, a C99 compliant snprintf()
    5203             :                        returns a count >= maxlen.  However, a non-compliant
    5204             :                        snprintf() function returns only count = maxlen - 1.  To
    5205             :                        cover both cases, test whether count >= maxlen - 1.  */
    5206           0 :                     if ((unsigned int) count + 1 >= maxlen)
    5207             :                       {
    5208             :                         /* If maxlen already has attained its allowed maximum,
    5209             :                            allocating more memory will not increase maxlen.
    5210             :                            Instead of looping, bail out.  */
    5211           0 :                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
    5212           0 :                           goto overflow;
    5213             :                         else
    5214             :                           {
    5215             :                             /* Need at least (count + 1) * sizeof (TCHAR_T)
    5216             :                                bytes.  (The +1 is for the trailing NUL.)
    5217             :                                But ask for (count + 2) * sizeof (TCHAR_T)
    5218             :                                bytes, so that in the next round, we likely get
    5219             :                                  maxlen > (unsigned int) count + 1
    5220             :                                and so we don't get here again.
    5221             :                                And allocate proportionally, to avoid looping
    5222             :                                eternally if snprintf() reports a too small
    5223             :                                count.  */
    5224           0 :                             size_t n =
    5225           0 :                               xmax (xsum (length,
    5226           0 :                                           ((unsigned int) count + 2
    5227             :                                            + TCHARS_PER_DCHAR - 1)
    5228             :                                           / TCHARS_PER_DCHAR),
    5229           0 :                                     xtimes (allocated, 2));
    5230             : 
    5231           0 :                             ENSURE_ALLOCATION (n);
    5232           0 :                             continue;
    5233             :                           }
    5234             :                       }
    5235             : #endif
    5236             : 
    5237             : #if NEED_PRINTF_UNBOUNDED_PRECISION
    5238             :                     if (prec_ourselves)
    5239             :                       {
    5240             :                         /* Handle the precision.  */
    5241             :                         TCHAR_T *prec_ptr =
    5242             : # if USE_SNPRINTF
    5243             :                           (TCHAR_T *) (result + length);
    5244             : # else
    5245             :                           tmp;
    5246             : # endif
    5247             :                         size_t prefix_count;
    5248             :                         size_t move;
    5249             : 
    5250             :                         prefix_count = 0;
    5251             :                         /* Put the additional zeroes after the sign.  */
    5252             :                         if (count >= 1
    5253             :                             && (*prec_ptr == '-' || *prec_ptr == '+'
    5254             :                                 || *prec_ptr == ' '))
    5255             :                           prefix_count = 1;
    5256             :                         /* Put the additional zeroes after the 0x prefix if
    5257             :                            (flags & FLAG_ALT) || (dp->conversion == 'p').  */
    5258             :                         else if (count >= 2
    5259             :                                  && prec_ptr[0] == '0'
    5260             :                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
    5261             :                           prefix_count = 2;
    5262             : 
    5263             :                         move = count - prefix_count;
    5264             :                         if (precision > move)
    5265             :                           {
    5266             :                             /* Insert zeroes.  */
    5267             :                             size_t insert = precision - move;
    5268             :                             TCHAR_T *prec_end;
    5269             : 
    5270             : # if USE_SNPRINTF
    5271             :                             size_t n =
    5272             :                               xsum (length,
    5273             :                                     (count + insert + TCHARS_PER_DCHAR - 1)
    5274             :                                     / TCHARS_PER_DCHAR);
    5275             :                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
    5276             :                             ENSURE_ALLOCATION (n);
    5277             :                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
    5278             :                             prec_ptr = (TCHAR_T *) (result + length);
    5279             : # endif
    5280             : 
    5281             :                             prec_end = prec_ptr + count;
    5282             :                             prec_ptr += prefix_count;
    5283             : 
    5284             :                             while (prec_end > prec_ptr)
    5285             :                               {
    5286             :                                 prec_end--;
    5287             :                                 prec_end[insert] = prec_end[0];
    5288             :                               }
    5289             : 
    5290             :                             prec_end += insert;
    5291             :                             do
    5292             :                               *--prec_end = '0';
    5293             :                             while (prec_end > prec_ptr);
    5294             : 
    5295             :                             count += insert;
    5296             :                           }
    5297             :                       }
    5298             : #endif
    5299             : 
    5300             : #if !USE_SNPRINTF
    5301             :                     if (count >= tmp_length)
    5302             :                       /* tmp_length was incorrectly calculated - fix the
    5303             :                          code above!  */
    5304             :                       abort ();
    5305             : #endif
    5306             : 
    5307             : #if !DCHAR_IS_TCHAR
    5308             :                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
    5309             :                     if (dp->conversion == 'c' || dp->conversion == 's')
    5310             :                       {
    5311             :                         /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
    5312             :                            TYPE_WIDE_STRING.
    5313             :                            The result string is not certainly ASCII.  */
    5314             :                         const TCHAR_T *tmpsrc;
    5315             :                         DCHAR_T *tmpdst;
    5316             :                         size_t tmpdst_len;
    5317             :                         /* This code assumes that TCHAR_T is 'char'.  */
    5318             :                         verify (sizeof (TCHAR_T) == 1);
    5319             : # if USE_SNPRINTF
    5320             :                         tmpsrc = (TCHAR_T *) (result + length);
    5321             : # else
    5322             :                         tmpsrc = tmp;
    5323             : # endif
    5324             :                         tmpdst =
    5325             :                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
    5326             :                                                     iconveh_question_mark,
    5327             :                                                     tmpsrc, count,
    5328             :                                                     NULL,
    5329             :                                                     NULL, &tmpdst_len);
    5330             :                         if (tmpdst == NULL)
    5331             :                           {
    5332             :                             int saved_errno = errno;
    5333             :                             if (!(result == resultbuf || result == NULL))
    5334             :                               free (result);
    5335             :                             if (buf_malloced != NULL)
    5336             :                               free (buf_malloced);
    5337             :                             CLEANUP ();
    5338             :                             errno = saved_errno;
    5339             :                             return NULL;
    5340             :                           }
    5341             :                         ENSURE_ALLOCATION (xsum (length, tmpdst_len));
    5342             :                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
    5343             :                         free (tmpdst);
    5344             :                         count = tmpdst_len;
    5345             :                       }
    5346             :                     else
    5347             :                       {
    5348             :                         /* The result string is ASCII.
    5349             :                            Simple 1:1 conversion.  */
    5350             : # if USE_SNPRINTF
    5351             :                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
    5352             :                            no-op conversion, in-place on the array starting
    5353             :                            at (result + length).  */
    5354             :                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
    5355             : # endif
    5356             :                           {
    5357             :                             const TCHAR_T *tmpsrc;
    5358             :                             DCHAR_T *tmpdst;
    5359             :                             size_t n;
    5360             : 
    5361             : # if USE_SNPRINTF
    5362             :                             if (result == resultbuf)
    5363             :                               {
    5364             :                                 tmpsrc = (TCHAR_T *) (result + length);
    5365             :                                 /* ENSURE_ALLOCATION will not move tmpsrc
    5366             :                                    (because it's part of resultbuf).  */
    5367             :                                 ENSURE_ALLOCATION (xsum (length, count));
    5368             :                               }
    5369             :                             else
    5370             :                               {
    5371             :                                 /* ENSURE_ALLOCATION will move the array
    5372             :                                    (because it uses realloc().  */
    5373             :                                 ENSURE_ALLOCATION (xsum (length, count));
    5374             :                                 tmpsrc = (TCHAR_T *) (result + length);
    5375             :                               }
    5376             : # else
    5377             :                             tmpsrc = tmp;
    5378             :                             ENSURE_ALLOCATION (xsum (length, count));
    5379             : # endif
    5380             :                             tmpdst = result + length;
    5381             :                             /* Copy backwards, because of overlapping.  */
    5382             :                             tmpsrc += count;
    5383             :                             tmpdst += count;
    5384             :                             for (n = count; n > 0; n--)
    5385             :                               *--tmpdst = *--tmpsrc;
    5386             :                           }
    5387             :                       }
    5388             : #endif
    5389             : 
    5390             : #if DCHAR_IS_TCHAR && !USE_SNPRINTF
    5391             :                     /* Make room for the result.  */
    5392             :                     if (count > allocated - length)
    5393             :                       {
    5394             :                         /* Need at least count elements.  But allocate
    5395             :                            proportionally.  */
    5396             :                         size_t n =
    5397             :                           xmax (xsum (length, count), xtimes (allocated, 2));
    5398             : 
    5399             :                         ENSURE_ALLOCATION (n);
    5400             :                       }
    5401             : #endif
    5402             : 
    5403             :                     /* Here count <= allocated - length.  */
    5404             : 
    5405             :                     /* Perform padding.  */
    5406             : #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
    5407             :                     if (pad_ourselves && has_width)
    5408             :                       {
    5409             :                         size_t w;
    5410             : # if ENABLE_UNISTDIO
    5411             :                         /* Outside POSIX, it's preferable to compare the width
    5412             :                            against the number of _characters_ of the converted
    5413             :                            value.  */
    5414             :                         w = DCHAR_MBSNLEN (result + length, count);
    5415             : # else
    5416             :                         /* The width is compared against the number of _bytes_
    5417             :                            of the converted value, says POSIX.  */
    5418             :                         w = count;
    5419             : # endif
    5420             :                         if (w < width)
    5421             :                           {
    5422             :                             size_t pad = width - w;
    5423             : 
    5424             :                             /* Make room for the result.  */
    5425             :                             if (xsum (count, pad) > allocated - length)
    5426             :                               {
    5427             :                                 /* Need at least count + pad elements.  But
    5428             :                                    allocate proportionally.  */
    5429             :                                 size_t n =
    5430             :                                   xmax (xsum3 (length, count, pad),
    5431             :                                         xtimes (allocated, 2));
    5432             : 
    5433             : # if USE_SNPRINTF
    5434             :                                 length += count;
    5435             :                                 ENSURE_ALLOCATION (n);
    5436             :                                 length -= count;
    5437             : # else
    5438             :                                 ENSURE_ALLOCATION (n);
    5439             : # endif
    5440             :                               }
    5441             :                             /* Here count + pad <= allocated - length.  */
    5442             : 
    5443             :                             {
    5444             : # if !DCHAR_IS_TCHAR || USE_SNPRINTF
    5445             :                               DCHAR_T * const rp = result + length;
    5446             : # else
    5447             :                               DCHAR_T * const rp = tmp;
    5448             : # endif
    5449             :                               DCHAR_T *p = rp + count;
    5450             :                               DCHAR_T *end = p + pad;
    5451             :                               DCHAR_T *pad_ptr;
    5452             : # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
    5453             :                               if (dp->conversion == 'c'
    5454             :                                   || dp->conversion == 's')
    5455             :                                 /* No zero-padding for string directives.  */
    5456             :                                 pad_ptr = NULL;
    5457             :                               else
    5458             : # endif
    5459             :                                 {
    5460             :                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
    5461             :                                   /* No zero-padding of "inf" and "nan".  */
    5462             :                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
    5463             :                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
    5464             :                                     pad_ptr = NULL;
    5465             :                                 }
    5466             :                               /* The generated string now extends from rp to p,
    5467             :                                  with the zero padding insertion point being at
    5468             :                                  pad_ptr.  */
    5469             : 
    5470             :                               count = count + pad; /* = end - rp */
    5471             : 
    5472             :                               if (flags & FLAG_LEFT)
    5473             :                                 {
    5474             :                                   /* Pad with spaces on the right.  */
    5475             :                                   for (; pad > 0; pad--)
    5476             :                                     *p++ = ' ';
    5477             :                                 }
    5478             :                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
    5479             :                                 {
    5480             :                                   /* Pad with zeroes.  */
    5481             :                                   DCHAR_T *q = end;
    5482             : 
    5483             :                                   while (p > pad_ptr)
    5484             :                                     *--q = *--p;
    5485             :                                   for (; pad > 0; pad--)
    5486             :                                     *p++ = '0';
    5487             :                                 }
    5488             :                               else
    5489             :                                 {
    5490             :                                   /* Pad with spaces on the left.  */
    5491             :                                   DCHAR_T *q = end;
    5492             : 
    5493             :                                   while (p > rp)
    5494             :                                     *--q = *--p;
    5495             :                                   for (; pad > 0; pad--)
    5496             :                                     *p++ = ' ';
    5497             :                                 }
    5498             :                             }
    5499             :                           }
    5500             :                       }
    5501             : #endif
    5502             : 
    5503             :                     /* Here still count <= allocated - length.  */
    5504             : 
    5505             : #if !DCHAR_IS_TCHAR || USE_SNPRINTF
    5506             :                     /* The snprintf() result did fit.  */
    5507             : #else
    5508             :                     /* Append the sprintf() result.  */
    5509             :                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
    5510             : #endif
    5511             : #if !USE_SNPRINTF
    5512             :                     if (tmp != tmpbuf)
    5513             :                       free (tmp);
    5514             : #endif
    5515             : 
    5516             : #if NEED_PRINTF_DIRECTIVE_F
    5517             :                     if (dp->conversion == 'F')
    5518             :                       {
    5519             :                         /* Convert the %f result to upper case for %F.  */
    5520             :                         DCHAR_T *rp = result + length;
    5521             :                         size_t rc;
    5522             :                         for (rc = count; rc > 0; rc--, rp++)
    5523             :                           if (*rp >= 'a' && *rp <= 'z')
    5524             :                             *rp = *rp - 'a' + 'A';
    5525             :                       }
    5526             : #endif
    5527             : 
    5528           0 :                     length += count;
    5529           0 :                     break;
    5530           0 :                   }
    5531           0 :                 errno = orig_errno;
    5532             : #undef pad_ourselves
    5533             : #undef prec_ourselves
    5534             :               }
    5535             :           }
    5536           0 :       }
    5537             : 
    5538             :     /* Add the final NUL.  */
    5539           0 :     ENSURE_ALLOCATION (xsum (length, 1));
    5540           0 :     result[length] = '\0';
    5541             : 
    5542           0 :     if (result != resultbuf && length + 1 < allocated)
    5543             :       {
    5544             :         /* Shrink the allocated memory if possible.  */
    5545             :         DCHAR_T *memory;
    5546             : 
    5547           0 :         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
    5548           0 :         if (memory != NULL)
    5549           0 :           result = memory;
    5550             :       }
    5551             : 
    5552           0 :     if (buf_malloced != NULL)
    5553           0 :       free (buf_malloced);
    5554           0 :     CLEANUP ();
    5555           0 :     *lengthp = length;
    5556             :     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
    5557             :        says that snprintf() fails with errno = EOVERFLOW in this case, but
    5558             :        that's only because snprintf() returns an 'int'.  This function does
    5559             :        not have this limitation.  */
    5560           0 :     return result;
    5561             : 
    5562             : #if USE_SNPRINTF
    5563             :   overflow:
    5564           0 :     if (!(result == resultbuf || result == NULL))
    5565           0 :       free (result);
    5566           0 :     if (buf_malloced != NULL)
    5567           0 :       free (buf_malloced);
    5568           0 :     CLEANUP ();
    5569           0 :     errno = EOVERFLOW;
    5570           0 :     return NULL;
    5571             : #endif
    5572             : 
    5573             :   out_of_memory:
    5574           0 :     if (!(result == resultbuf || result == NULL))
    5575           0 :       free (result);
    5576           0 :     if (buf_malloced != NULL)
    5577           0 :       free (buf_malloced);
    5578             :   out_of_memory_1:
    5579           0 :     CLEANUP ();
    5580           0 :     errno = ENOMEM;
    5581           0 :     return NULL;
    5582             :   }
    5583             : }
    5584             : 
    5585             : #undef MAX_ROOM_NEEDED
    5586             : #undef TCHARS_PER_DCHAR
    5587             : #undef SNPRINTF
    5588             : #undef USE_SNPRINTF
    5589             : #undef DCHAR_SET
    5590             : #undef DCHAR_CPY
    5591             : #undef PRINTF_PARSE
    5592             : #undef DIRECTIVES
    5593             : #undef DIRECTIVE
    5594             : #undef DCHAR_IS_TCHAR
    5595             : #undef TCHAR_T
    5596             : #undef DCHAR_T
    5597             : #undef FCHAR_T
    5598             : #undef VASNPRINTF

Generated by: LCOV version 1.10