Home | History | Annotate | Download | only in lib
      1 /* vsprintf with automatic memory allocation.
      2    Copyright (C) 1999, 2002-2012 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 #ifdef 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 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
   1774             const FCHAR_T *format, va_list args)
   1775 {
   1776   DIRECTIVES d;
   1777   arguments a;
   1778 
   1779   if (PRINTF_PARSE (format, &d, &a) < 0)
   1780     /* errno is already set.  */
   1781     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   if (PRINTF_FETCHARGS (args, &a) < 0)
   1790     {
   1791       CLEANUP ();
   1792       errno = EINVAL;
   1793       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     buf_neededlength =
   1811       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
   1812 #if HAVE_ALLOCA
   1813     if (buf_neededlength < 4000 / sizeof (TCHAR_T))
   1814       {
   1815         buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
   1816         buf_malloced = NULL;
   1817       }
   1818     else
   1819 #endif
   1820       {
   1821         size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
   1822         if (size_overflow_p (buf_memsize))
   1823           goto out_of_memory_1;
   1824         buf = (TCHAR_T *) malloc (buf_memsize);
   1825         if (buf == NULL)
   1826           goto out_of_memory_1;
   1827         buf_malloced = buf;
   1828       }
   1829 
   1830     if (resultbuf != NULL)
   1831       {
   1832         result = resultbuf;
   1833         allocated = *lengthp;
   1834       }
   1835     else
   1836       {
   1837         result = NULL;
   1838         allocated = 0;
   1839       }
   1840     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     for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
   1871       {
   1872         if (cp != dp->dir_start)
   1873           {
   1874             size_t n = dp->dir_start - cp;
   1875             size_t augmented_length = xsum (length, n);
   1876 
   1877             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                 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
   1884                 length = augmented_length;
   1885               }
   1886             else
   1887               {
   1888                 do
   1889                   result[length++] = (unsigned char) *cp++;
   1890                 while (--n > 0);
   1891               }
   1892           }
   1893         if (i == d.count)
   1894           break;
   1895 
   1896         /* Execute a single directive.  */
   1897         if (dp->conversion == '%')
   1898           {
   1899             size_t augmented_length;
   1900 
   1901             if (!(dp->arg_index == ARG_NONE))
   1902               abort ();
   1903             augmented_length = xsum (length, 1);
   1904             ENSURE_ALLOCATION (augmented_length);
   1905             result[length] = '%';
   1906             length = augmented_length;
   1907           }
   1908         else
   1909           {
   1910             if (!(dp->arg_index != ARG_NONE))
   1911               abort ();
   1912 
   1913             if (dp->conversion == 'n')
   1914               {
   1915                 switch (a.arg[dp->arg_index].type)
   1916                   {
   1917                   case TYPE_COUNT_SCHAR_POINTER:
   1918                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
   1919                     break;
   1920                   case TYPE_COUNT_SHORT_POINTER:
   1921                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
   1922                     break;
   1923                   case TYPE_COUNT_INT_POINTER:
   1924                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
   1925                     break;
   1926                   case TYPE_COUNT_LONGINT_POINTER:
   1927                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
   1928                     break;
   1929 #if HAVE_LONG_LONG_INT
   1930                   case TYPE_COUNT_LONGLONGINT_POINTER:
   1931                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
   1932                     break;
   1933 #endif
   1934                   default:
   1935                     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                         if (arg < 0)
   1961                           {
   1962                             /* "A negative field width is taken as a '-' flag
   1963                                 followed by a positive field width."  */
   1964                             flags |= FLAG_LEFT;
   1965                             width = (unsigned int) (-arg);
   1966                           }
   1967                         else
   1968                           width = arg;
   1969                       }
   1970                     else
   1971                       {
   1972                         const FCHAR_T *digitp = dp->width_start;
   1973 
   1974                         do
   1975                           width = xsum (xtimes (width, 10), *digitp++ - '0');
   1976                         while (digitp != dp->width_end);
   1977                       }
   1978                     has_width = 1;
   1979                   }
   1980 
   1981                 has_precision = 0;
   1982                 precision = 0;
   1983                 if (dp->precision_start != dp->precision_end)
   1984                   {
   1985                     if (dp->precision_arg_index != ARG_NONE)
   1986                       {
   1987                         int arg;
   1988 
   1989                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
   1990                           abort ();
   1991                         arg = a.arg[dp->precision_arg_index].a.a_int;
   1992                         /* "A negative precision is taken as if the precision
   1993                             were omitted."  */
   1994                         if (arg >= 0)
   1995                           {
   1996                             precision = arg;
   1997                             has_precision = 1;
   1998                           }
   1999                       }
   2000                     else
   2001                       {
   2002                         const FCHAR_T *digitp = dp->precision_start + 1;
   2003 
   2004                         precision = 0;
   2005                         while (digitp != dp->precision_end)
   2006                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
   2007                         has_precision = 1;
   2008                       }
   2009                   }
   2010 
   2011                 switch (type)
   2012                   {
   2013                   case TYPE_U8_STRING:
   2014                     {
   2015                       const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
   2016                       const uint8_t *arg_end;
   2017                       size_t characters;
   2018 
   2019                       if (has_precision)
   2020                         {
   2021                           /* Use only PRECISION characters, from the left.  */
   2022                           arg_end = arg;
   2023                           characters = 0;
   2024                           for (; precision > 0; precision--)
   2025                             {
   2026                               int count = u8_strmblen (arg_end);
   2027                               if (count == 0)
   2028                                 break;
   2029                               if (count < 0)
   2030                                 {
   2031                                   if (!(result == resultbuf || result == NULL))
   2032                                     free (result);
   2033                                   if (buf_malloced != NULL)
   2034                                     free (buf_malloced);
   2035                                   CLEANUP ();
   2036                                   errno = EILSEQ;
   2037                                   return NULL;
   2038                                 }
   2039                               arg_end += count;
   2040                               characters++;
   2041                             }
   2042                         }
   2043                       else if (has_width)
   2044                         {
   2045                           /* Use the entire string, and count the number of
   2046                              characters.  */
   2047                           arg_end = arg;
   2048                           characters = 0;
   2049                           for (;;)
   2050                             {
   2051                               int count = u8_strmblen (arg_end);
   2052                               if (count == 0)
   2053                                 break;
   2054                               if (count < 0)
   2055                                 {
   2056                                   if (!(result == resultbuf || result == NULL))
   2057                                     free (result);
   2058                                   if (buf_malloced != NULL)
   2059                                     free (buf_malloced);
   2060                                   CLEANUP ();
   2061                                   errno = EILSEQ;
   2062                                   return NULL;
   2063                                 }
   2064                               arg_end += count;
   2065                               characters++;
   2066                             }
   2067                         }
   2068                       else
   2069                         {
   2070                           /* Use the entire string.  */
   2071                           arg_end = arg + u8_strlen (arg);
   2072                           /* The number of characters doesn't matter.  */
   2073                           characters = 0;
   2074                         }
   2075 
   2076                       if (has_width && width > characters
   2077                           && !(dp->flags & FLAG_LEFT))
   2078                         {
   2079                           size_t n = width - characters;
   2080                           ENSURE_ALLOCATION (xsum (length, n));
   2081                           DCHAR_SET (result + length, ' ', n);
   2082                           length += n;
   2083                         }
   2084 
   2085 # if DCHAR_IS_UINT8_T
   2086                       {
   2087                         size_t n = arg_end - arg;
   2088                         ENSURE_ALLOCATION (xsum (length, n));
   2089                         DCHAR_CPY (result + length, arg, n);
   2090                         length += n;
   2091                       }
   2092 # else
   2093                       { /* Convert.  */
   2094                         DCHAR_T *converted = result + length;
   2095                         size_t converted_len = allocated - length;
   2096 #  if DCHAR_IS_TCHAR
   2097                         /* Convert from UTF-8 to locale encoding.  */
   2098                         converted =
   2099                           u8_conv_to_encoding (locale_charset (),
   2100                                                iconveh_question_mark,
   2101                                                arg, arg_end - arg, NULL,
   2102                                                converted, &converted_len);
   2103 #  else
   2104                         /* Convert from UTF-8 to UTF-16/UTF-32.  */
   2105                         converted =
   2106                           U8_TO_DCHAR (arg, arg_end - arg,
   2107                                        converted, &converted_len);
   2108 #  endif
   2109                         if (converted == NULL)
   2110                           {
   2111                             int saved_errno = errno;
   2112                             if (!(result == resultbuf || result == NULL))
   2113                               free (result);
   2114                             if (buf_malloced != NULL)
   2115                               free (buf_malloced);
   2116                             CLEANUP ();
   2117                             errno = saved_errno;
   2118                             return NULL;
   2119                           }
   2120                         if (converted != result + length)
   2121                           {
   2122                             ENSURE_ALLOCATION (xsum (length, converted_len));
   2123                             DCHAR_CPY (result + length, converted, converted_len);
   2124                             free (converted);
   2125                           }
   2126                         length += converted_len;
   2127                       }
   2128 # endif
   2129 
   2130                       if (has_width && width > characters
   2131                           && (dp->flags & FLAG_LEFT))
   2132                         {
   2133                           size_t n = width - characters;
   2134                           ENSURE_ALLOCATION (xsum (length, n));
   2135                           DCHAR_SET (result + length, ' ', n);
   2136                           length += n;
   2137                         }
   2138                     }
   2139                     break;
   2140 
   2141                   case TYPE_U16_STRING:
   2142                     {
   2143                       const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
   2144                       const uint16_t *arg_end;
   2145                       size_t characters;
   2146 
   2147                       if (has_precision)
   2148                         {
   2149                           /* Use only PRECISION characters, from the left.  */
   2150                           arg_end = arg;
   2151                           characters = 0;
   2152                           for (; precision > 0; precision--)
   2153                             {
   2154                               int count = u16_strmblen (arg_end);
   2155                               if (count == 0)
   2156                                 break;
   2157                               if (count < 0)
   2158                                 {
   2159                                   if (!(result == resultbuf || result == NULL))
   2160                                     free (result);
   2161                                   if (buf_malloced != NULL)
   2162                                     free (buf_malloced);
   2163                                   CLEANUP ();
   2164                                   errno = EILSEQ;
   2165                                   return NULL;
   2166                                 }
   2167                               arg_end += count;
   2168                               characters++;
   2169                             }
   2170                         }
   2171                       else if (has_width)
   2172                         {
   2173                           /* Use the entire string, and count the number of
   2174                              characters.  */
   2175                           arg_end = arg;
   2176                           characters = 0;
   2177                           for (;;)
   2178                             {
   2179                               int count = u16_strmblen (arg_end);
   2180                               if (count == 0)
   2181                                 break;
   2182                               if (count < 0)
   2183                                 {
   2184                                   if (!(result == resultbuf || result == NULL))
   2185                                     free (result);
   2186                                   if (buf_malloced != NULL)
   2187                                     free (buf_malloced);
   2188                                   CLEANUP ();
   2189                                   errno = EILSEQ;
   2190                                   return NULL;
   2191                                 }
   2192                               arg_end += count;
   2193                               characters++;
   2194                             }
   2195                         }
   2196                       else
   2197                         {
   2198                           /* Use the entire string.  */
   2199                           arg_end = arg + u16_strlen (arg);
   2200                           /* The number of characters doesn't matter.  */
   2201                           characters = 0;
   2202                         }
   2203 
   2204                       if (has_width && width > characters
   2205                           && !(dp->flags & FLAG_LEFT))
   2206                         {
   2207                           size_t n = width - characters;
   2208                           ENSURE_ALLOCATION (xsum (length, n));
   2209                           DCHAR_SET (result + length, ' ', n);
   2210                           length += n;
   2211                         }
   2212 
   2213 # if DCHAR_IS_UINT16_T
   2214                       {
   2215                         size_t n = arg_end - arg;
   2216                         ENSURE_ALLOCATION (xsum (length, n));
   2217                         DCHAR_CPY (result + length, arg, n);
   2218                         length += n;
   2219                       }
   2220 # else
   2221                       { /* Convert.  */
   2222                         DCHAR_T *converted = result + length;
   2223                         size_t converted_len = allocated - length;
   2224 #  if DCHAR_IS_TCHAR
   2225                         /* Convert from UTF-16 to locale encoding.  */
   2226                         converted =
   2227                           u16_conv_to_encoding (locale_charset (),
   2228                                                 iconveh_question_mark,
   2229                                                 arg, arg_end - arg, NULL,
   2230                                                 converted, &converted_len);
   2231 #  else
   2232                         /* Convert from UTF-16 to UTF-8/UTF-32.  */
   2233                         converted =
   2234                           U16_TO_DCHAR (arg, arg_end - arg,
   2235                                         converted, &converted_len);
   2236 #  endif
   2237                         if (converted == NULL)
   2238                           {
   2239                             int saved_errno = errno;
   2240                             if (!(result == resultbuf || result == NULL))
   2241                               free (result);
   2242                             if (buf_malloced != NULL)
   2243                               free (buf_malloced);
   2244                             CLEANUP ();
   2245                             errno = saved_errno;
   2246                             return NULL;
   2247                           }
   2248                         if (converted != result + length)
   2249                           {
   2250                             ENSURE_ALLOCATION (xsum (length, converted_len));
   2251                             DCHAR_CPY (result + length, converted, converted_len);
   2252                             free (converted);
   2253                           }
   2254                         length += converted_len;
   2255                       }
   2256 # endif
   2257 
   2258                       if (has_width && width > characters
   2259                           && (dp->flags & FLAG_LEFT))
   2260                         {
   2261                           size_t n = width - characters;
   2262                           ENSURE_ALLOCATION (xsum (length, n));
   2263                           DCHAR_SET (result + length, ' ', n);
   2264                           length += n;
   2265                         }
   2266                     }
   2267                     break;
   2268 
   2269                   case TYPE_U32_STRING:
   2270                     {
   2271                       const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
   2272                       const uint32_t *arg_end;
   2273                       size_t characters;
   2274 
   2275                       if (has_precision)
   2276                         {
   2277                           /* Use only PRECISION characters, from the left.  */
   2278                           arg_end = arg;
   2279                           characters = 0;
   2280                           for (; precision > 0; precision--)
   2281                             {
   2282                               int count = u32_strmblen (arg_end);
   2283                               if (count == 0)
   2284                                 break;
   2285                               if (count < 0)
   2286                                 {
   2287                                   if (!(result == resultbuf || result == NULL))
   2288                                     free (result);
   2289                                   if (buf_malloced != NULL)
   2290                                     free (buf_malloced);
   2291                                   CLEANUP ();
   2292                                   errno = EILSEQ;
   2293                                   return NULL;
   2294                                 }
   2295                               arg_end += count;
   2296                               characters++;
   2297                             }
   2298                         }
   2299                       else if (has_width)
   2300                         {
   2301                           /* Use the entire string, and count the number of
   2302                              characters.  */
   2303                           arg_end = arg;
   2304                           characters = 0;
   2305                           for (;;)
   2306                             {
   2307                               int count = u32_strmblen (arg_end);
   2308                               if (count == 0)
   2309                                 break;
   2310                               if (count < 0)
   2311                                 {
   2312                                   if (!(result == resultbuf || result == NULL))
   2313                                     free (result);
   2314                                   if (buf_malloced != NULL)
   2315                                     free (buf_malloced);
   2316                                   CLEANUP ();
   2317                                   errno = EILSEQ;
   2318                                   return NULL;
   2319                                 }
   2320                               arg_end += count;
   2321                               characters++;
   2322                             }
   2323                         }
   2324                       else
   2325                         {
   2326                           /* Use the entire string.  */
   2327                           arg_end = arg + u32_strlen (arg);
   2328                           /* The number of characters doesn't matter.  */
   2329                           characters = 0;
   2330                         }
   2331 
   2332                       if (has_width && width > characters
   2333                           && !(dp->flags & FLAG_LEFT))
   2334                         {
   2335                           size_t n = width - characters;
   2336                           ENSURE_ALLOCATION (xsum (length, n));
   2337                           DCHAR_SET (result + length, ' ', n);
   2338                           length += n;
   2339                         }
   2340 
   2341 # if DCHAR_IS_UINT32_T
   2342                       {
   2343                         size_t n = arg_end - arg;
   2344                         ENSURE_ALLOCATION (xsum (length, n));
   2345                         DCHAR_CPY (result + length, arg, n);
   2346                         length += n;
   2347                       }
   2348 # else
   2349                       { /* Convert.  */
   2350                         DCHAR_T *converted = result + length;
   2351                         size_t converted_len = allocated - length;
   2352 #  if DCHAR_IS_TCHAR
   2353                         /* Convert from UTF-32 to locale encoding.  */
   2354                         converted =
   2355                           u32_conv_to_encoding (locale_charset (),
   2356                                                 iconveh_question_mark,
   2357                                                 arg, arg_end - arg, NULL,
   2358                                                 converted, &converted_len);
   2359 #  else
   2360                         /* Convert from UTF-32 to UTF-8/UTF-16.  */
   2361                         converted =
   2362                           U32_TO_DCHAR (arg, arg_end - arg,
   2363                                         converted, &converted_len);
   2364 #  endif
   2365                         if (converted == NULL)
   2366                           {
   2367                             int saved_errno = errno;
   2368                             if (!(result == resultbuf || result == NULL))
   2369                               free (result);
   2370                             if (buf_malloced != NULL)
   2371                               free (buf_malloced);
   2372                             CLEANUP ();
   2373                             errno = saved_errno;
   2374                             return NULL;
   2375                           }
   2376                         if (converted != result + length)
   2377                           {
   2378                             ENSURE_ALLOCATION (xsum (length, converted_len));
   2379                             DCHAR_CPY (result + length, converted, converted_len);
   2380                             free (converted);
   2381                           }
   2382                         length += converted_len;
   2383                       }
   2384 # endif
   2385 
   2386                       if (has_width && width > characters
   2387                           && (dp->flags & FLAG_LEFT))
   2388                         {
   2389                           size_t n = width - characters;
   2390                           ENSURE_ALLOCATION (xsum (length, n));
   2391                           DCHAR_SET (result + length, ' ', n);
   2392                           length += n;
   2393                         }
   2394                     }
   2395                     break;
   2396 
   2397                   default:
   2398                     abort ();
   2399                   }
   2400               }
   2401 #endif
   2402 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
   2403             else if (dp->conversion == 's'
   2404 # if WIDE_CHAR_VERSION
   2405                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
   2406 # else
   2407                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
   2408 # endif
   2409                     )
   2410               {
   2411                 /* The normal handling of the 's' directive below requires
   2412                    allocating a temporary buffer.  The determination of its
   2413                    length (tmp_length), in the case when a precision is
   2414                    specified, below requires a conversion between a char[]
   2415                    string and a wchar_t[] wide string.  It could be done, but
   2416                    we have no guarantee that the implementation of sprintf will
   2417                    use the exactly same algorithm.  Without this guarantee, it
   2418                    is possible to have buffer overrun bugs.  In order to avoid
   2419                    such bugs, we implement the entire processing of the 's'
   2420                    directive ourselves.  */
   2421                 int flags = dp->flags;
   2422                 int has_width;
   2423                 size_t width;
   2424                 int has_precision;
   2425                 size_t precision;
   2426 
   2427                 has_width = 0;
   2428                 width = 0;
   2429                 if (dp->width_start != dp->width_end)
   2430                   {
   2431                     if (dp->width_arg_index != ARG_NONE)
   2432                       {
   2433                         int arg;
   2434 
   2435                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
   2436                           abort ();
   2437                         arg = a.arg[dp->width_arg_index].a.a_int;
   2438                         if (arg < 0)
   2439                           {
   2440                             /* "A negative field width is taken as a '-' flag
   2441                                 followed by a positive field width."  */
   2442                             flags |= FLAG_LEFT;
   2443                             width = (unsigned int) (-arg);
   2444                           }
   2445                         else
   2446                           width = arg;
   2447                       }
   2448                     else
   2449                       {
   2450                         const FCHAR_T *digitp = dp->width_start;
   2451 
   2452                         do
   2453                           width = xsum (xtimes (width, 10), *digitp++ - '0');
   2454                         while (digitp != dp->width_end);
   2455                       }
   2456                     has_width = 1;
   2457                   }
   2458 
   2459                 has_precision = 0;
   2460                 precision = 6;
   2461                 if (dp->precision_start != dp->precision_end)
   2462                   {
   2463                     if (dp->precision_arg_index != ARG_NONE)
   2464                       {
   2465                         int arg;
   2466 
   2467                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
   2468                           abort ();
   2469                         arg = a.arg[dp->precision_arg_index].a.a_int;
   2470                         /* "A negative precision is taken as if the precision
   2471                             were omitted."  */
   2472                         if (arg >= 0)
   2473                           {
   2474                             precision = arg;
   2475                             has_precision = 1;
   2476                           }
   2477                       }
   2478                     else
   2479                       {
   2480                         const FCHAR_T *digitp = dp->precision_start + 1;
   2481 
   2482                         precision = 0;
   2483                         while (digitp != dp->precision_end)
   2484                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
   2485                         has_precision = 1;
   2486                       }
   2487                   }
   2488 
   2489 # if WIDE_CHAR_VERSION
   2490                 /* %s in vasnwprintf.  See the specification of fwprintf.  */
   2491                 {
   2492                   const char *arg = a.arg[dp->arg_index].a.a_string;
   2493                   const char *arg_end;
   2494                   size_t characters;
   2495 
   2496                   if (has_precision)
   2497                     {
   2498                       /* Use only as many bytes as needed to produce PRECISION
   2499                          wide characters, from the left.  */
   2500 #  if HAVE_MBRTOWC
   2501                       mbstate_t state;
   2502                       memset (&state, '\0', sizeof (mbstate_t));
   2503 #  endif
   2504                       arg_end = arg;
   2505                       characters = 0;
   2506                       for (; precision > 0; precision--)
   2507                         {
   2508                           int count;
   2509 #  if HAVE_MBRTOWC
   2510                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
   2511 #  else
   2512                           count = mblen (arg_end, MB_CUR_MAX);
   2513 #  endif
   2514                           if (count == 0)
   2515                             /* Found the terminating NUL.  */
   2516                             break;
   2517                           if (count < 0)
   2518                             {
   2519                               /* Invalid or incomplete multibyte character.  */
   2520                               if (!(result == resultbuf || result == NULL))
   2521                                 free (result);
   2522                               if (buf_malloced != NULL)
   2523                                 free (buf_malloced);
   2524                               CLEANUP ();
   2525                               errno = EILSEQ;
   2526                               return NULL;
   2527                             }
   2528                           arg_end += count;
   2529                           characters++;
   2530                         }
   2531                     }
   2532                   else if (has_width)
   2533                     {
   2534                       /* Use the entire string, and count the number of wide
   2535                          characters.  */
   2536 #  if HAVE_MBRTOWC
   2537                       mbstate_t state;
   2538                       memset (&state, '\0', sizeof (mbstate_t));
   2539 #  endif
   2540                       arg_end = arg;
   2541                       characters = 0;
   2542                       for (;;)
   2543                         {
   2544                           int count;
   2545 #  if HAVE_MBRTOWC
   2546                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
   2547 #  else
   2548                           count = mblen (arg_end, MB_CUR_MAX);
   2549 #  endif
   2550                           if (count == 0)
   2551                             /* Found the terminating NUL.  */
   2552                             break;
   2553                           if (count < 0)
   2554                             {
   2555                               /* Invalid or incomplete multibyte character.  */
   2556                               if (!(result == resultbuf || result == NULL))
   2557                                 free (result);
   2558                               if (buf_malloced != NULL)
   2559                                 free (buf_malloced);
   2560                               CLEANUP ();
   2561                               errno = EILSEQ;
   2562                               return NULL;
   2563                             }
   2564                           arg_end += count;
   2565                           characters++;
   2566                         }
   2567                     }
   2568                   else
   2569                     {
   2570                       /* Use the entire string.  */
   2571                       arg_end = arg + strlen (arg);
   2572                       /* The number of characters doesn't matter.  */
   2573                       characters = 0;
   2574                     }
   2575 
   2576                   if (has_width && width > characters
   2577                       && !(dp->flags & FLAG_LEFT))
   2578                     {
   2579                       size_t n = width - characters;
   2580                       ENSURE_ALLOCATION (xsum (length, n));
   2581                       DCHAR_SET (result + length, ' ', n);
   2582                       length += n;
   2583                     }
   2584 
   2585                   if (has_precision || has_width)
   2586                     {
   2587                       /* We know the number of wide characters in advance.  */
   2588                       size_t remaining;
   2589 #  if HAVE_MBRTOWC
   2590                       mbstate_t state;
   2591                       memset (&state, '\0', sizeof (mbstate_t));
   2592 #  endif
   2593                       ENSURE_ALLOCATION (xsum (length, characters));
   2594                       for (remaining = characters; remaining > 0; remaining--)
   2595                         {
   2596                           wchar_t wc;
   2597                           int count;
   2598 #  if HAVE_MBRTOWC
   2599                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
   2600 #  else
   2601                           count = mbtowc (&wc, arg, arg_end - arg);
   2602 #  endif
   2603                           if (count <= 0)
   2604                             /* mbrtowc not consistent with mbrlen, or mbtowc
   2605                                not consistent with mblen.  */
   2606                             abort ();
   2607                           result[length++] = wc;
   2608                           arg += count;
   2609                         }
   2610                       if (!(arg == arg_end))
   2611                         abort ();
   2612                     }
   2613                   else
   2614                     {
   2615 #  if HAVE_MBRTOWC
   2616                       mbstate_t state;
   2617                       memset (&state, '\0', sizeof (mbstate_t));
   2618 #  endif
   2619                       while (arg < arg_end)
   2620                         {
   2621                           wchar_t wc;
   2622                           int count;
   2623 #  if HAVE_MBRTOWC
   2624                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
   2625 #  else
   2626                           count = mbtowc (&wc, arg, arg_end - arg);
   2627 #  endif
   2628                           if (count <= 0)
   2629                             /* mbrtowc not consistent with mbrlen, or mbtowc
   2630                                not consistent with mblen.  */
   2631                             abort ();
   2632                           ENSURE_ALLOCATION (xsum (length, 1));
   2633                           result[length++] = wc;
   2634                           arg += count;
   2635                         }
   2636                     }
   2637 
   2638                   if (has_width && width > characters
   2639                       && (dp->flags & FLAG_LEFT))
   2640                     {
   2641                       size_t n = width - characters;
   2642                       ENSURE_ALLOCATION (xsum (length, n));
   2643                       DCHAR_SET (result + length, ' ', n);
   2644                       length += n;
   2645                     }
   2646                 }
   2647 # else
   2648                 /* %ls in vasnprintf.  See the specification of fprintf.  */
   2649                 {
   2650                   const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
   2651                   const wchar_t *arg_end;
   2652                   size_t characters;
   2653 #  if !DCHAR_IS_TCHAR
   2654                   /* This code assumes that TCHAR_T is 'char'.  */
   2655                   verify (sizeof (TCHAR_T) == 1);
   2656                   TCHAR_T *tmpsrc;
   2657                   DCHAR_T *tmpdst;
   2658                   size_t tmpdst_len;
   2659 #  endif
   2660                   size_t w;
   2661 
   2662                   if (has_precision)
   2663                     {
   2664                       /* Use only as many wide characters as needed to produce
   2665                          at most PRECISION bytes, from the left.  */
   2666 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2667                       mbstate_t state;
   2668                       memset (&state, '\0', sizeof (mbstate_t));
   2669 #  endif
   2670                       arg_end = arg;
   2671                       characters = 0;
   2672                       while (precision > 0)
   2673                         {
   2674                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
   2675                           int count;
   2676 
   2677                           if (*arg_end == 0)
   2678                             /* Found the terminating null wide character.  */
   2679                             break;
   2680 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2681                           count = wcrtomb (cbuf, *arg_end, &state);
   2682 #  else
   2683                           count = wctomb (cbuf, *arg_end);
   2684 #  endif
   2685                           if (count < 0)
   2686                             {
   2687                               /* Cannot convert.  */
   2688                               if (!(result == resultbuf || result == NULL))
   2689                                 free (result);
   2690                               if (buf_malloced != NULL)
   2691                                 free (buf_malloced);
   2692                               CLEANUP ();
   2693                               errno = EILSEQ;
   2694                               return NULL;
   2695                             }
   2696                           if (precision < count)
   2697                             break;
   2698                           arg_end++;
   2699                           characters += count;
   2700                           precision -= count;
   2701                         }
   2702                     }
   2703 #  if DCHAR_IS_TCHAR
   2704                   else if (has_width)
   2705 #  else
   2706                   else
   2707 #  endif
   2708                     {
   2709                       /* Use the entire string, and count the number of
   2710                          bytes.  */
   2711 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2712                       mbstate_t state;
   2713                       memset (&state, '\0', sizeof (mbstate_t));
   2714 #  endif
   2715                       arg_end = arg;
   2716                       characters = 0;
   2717                       for (;;)
   2718                         {
   2719                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
   2720                           int count;
   2721 
   2722                           if (*arg_end == 0)
   2723                             /* Found the terminating null wide character.  */
   2724                             break;
   2725 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2726                           count = wcrtomb (cbuf, *arg_end, &state);
   2727 #  else
   2728                           count = wctomb (cbuf, *arg_end);
   2729 #  endif
   2730                           if (count < 0)
   2731                             {
   2732                               /* Cannot convert.  */
   2733                               if (!(result == resultbuf || result == NULL))
   2734                                 free (result);
   2735                               if (buf_malloced != NULL)
   2736                                 free (buf_malloced);
   2737                               CLEANUP ();
   2738                               errno = EILSEQ;
   2739                               return NULL;
   2740                             }
   2741                           arg_end++;
   2742                           characters += count;
   2743                         }
   2744                     }
   2745 #  if DCHAR_IS_TCHAR
   2746                   else
   2747                     {
   2748                       /* Use the entire string.  */
   2749                       arg_end = arg + local_wcslen (arg);
   2750                       /* The number of bytes doesn't matter.  */
   2751                       characters = 0;
   2752                     }
   2753 #  endif
   2754 
   2755 #  if !DCHAR_IS_TCHAR
   2756                   /* Convert the string into a piece of temporary memory.  */
   2757                   tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
   2758                   if (tmpsrc == NULL)
   2759                     goto out_of_memory;
   2760                   {
   2761                     TCHAR_T *tmpptr = tmpsrc;
   2762                     size_t remaining;
   2763 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2764                     mbstate_t state;
   2765                     memset (&state, '\0', sizeof (mbstate_t));
   2766 #   endif
   2767                     for (remaining = characters; remaining > 0; )
   2768                       {
   2769                         char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
   2770                         int count;
   2771 
   2772                         if (*arg == 0)
   2773                           abort ();
   2774 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2775                         count = wcrtomb (cbuf, *arg, &state);
   2776 #   else
   2777                         count = wctomb (cbuf, *arg);
   2778 #   endif
   2779                         if (count <= 0)
   2780                           /* Inconsistency.  */
   2781                           abort ();
   2782                         memcpy (tmpptr, cbuf, count);
   2783                         tmpptr += count;
   2784                         arg++;
   2785                         remaining -= count;
   2786                       }
   2787                     if (!(arg == arg_end))
   2788                       abort ();
   2789                   }
   2790 
   2791                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
   2792                   tmpdst =
   2793                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
   2794                                               iconveh_question_mark,
   2795                                               tmpsrc, characters,
   2796                                               NULL,
   2797                                               NULL, &tmpdst_len);
   2798                   if (tmpdst == NULL)
   2799                     {
   2800                       int saved_errno = errno;
   2801                       free (tmpsrc);
   2802                       if (!(result == resultbuf || result == NULL))
   2803                         free (result);
   2804                       if (buf_malloced != NULL)
   2805                         free (buf_malloced);
   2806                       CLEANUP ();
   2807                       errno = saved_errno;
   2808                       return NULL;
   2809                     }
   2810                   free (tmpsrc);
   2811 #  endif
   2812 
   2813                   if (has_width)
   2814                     {
   2815 #  if ENABLE_UNISTDIO
   2816                       /* Outside POSIX, it's preferable to compare the width
   2817                          against the number of _characters_ of the converted
   2818                          value.  */
   2819                       w = DCHAR_MBSNLEN (result + length, characters);
   2820 #  else
   2821                       /* The width is compared against the number of _bytes_
   2822                          of the converted value, says POSIX.  */
   2823                       w = characters;
   2824 #  endif
   2825                     }
   2826                   else
   2827                     /* w doesn't matter.  */
   2828                     w = 0;
   2829 
   2830                   if (has_width && width > w
   2831                       && !(dp->flags & FLAG_LEFT))
   2832                     {
   2833                       size_t n = width - w;
   2834                       ENSURE_ALLOCATION (xsum (length, n));
   2835                       DCHAR_SET (result + length, ' ', n);
   2836                       length += n;
   2837                     }
   2838 
   2839 #  if DCHAR_IS_TCHAR
   2840                   if (has_precision || has_width)
   2841                     {
   2842                       /* We know the number of bytes in advance.  */
   2843                       size_t remaining;
   2844 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2845                       mbstate_t state;
   2846                       memset (&state, '\0', sizeof (mbstate_t));
   2847 #   endif
   2848                       ENSURE_ALLOCATION (xsum (length, characters));
   2849                       for (remaining = characters; remaining > 0; )
   2850                         {
   2851                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
   2852                           int count;
   2853 
   2854                           if (*arg == 0)
   2855                             abort ();
   2856 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2857                           count = wcrtomb (cbuf, *arg, &state);
   2858 #   else
   2859                           count = wctomb (cbuf, *arg);
   2860 #   endif
   2861                           if (count <= 0)
   2862                             /* Inconsistency.  */
   2863                             abort ();
   2864                           memcpy (result + length, cbuf, count);
   2865                           length += count;
   2866                           arg++;
   2867                           remaining -= count;
   2868                         }
   2869                       if (!(arg == arg_end))
   2870                         abort ();
   2871                     }
   2872                   else
   2873                     {
   2874 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2875                       mbstate_t state;
   2876                       memset (&state, '\0', sizeof (mbstate_t));
   2877 #   endif
   2878                       while (arg < arg_end)
   2879                         {
   2880                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
   2881                           int count;
   2882 
   2883                           if (*arg == 0)
   2884                             abort ();
   2885 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
   2886                           count = wcrtomb (cbuf, *arg, &state);
   2887 #   else
   2888                           count = wctomb (cbuf, *arg);
   2889 #   endif
   2890                           if (count <= 0)
   2891                             {
   2892                               /* Cannot convert.  */
   2893                               if (!(result == resultbuf || result == NULL))
   2894                                 free (result);
   2895                               if (buf_malloced != NULL)
   2896                                 free (buf_malloced);
   2897                               CLEANUP ();
   2898                               errno = EILSEQ;
   2899                               return NULL;
   2900                             }
   2901                           ENSURE_ALLOCATION (xsum (length, count));
   2902                           memcpy (result + length, cbuf, count);
   2903                           length += count;
   2904                           arg++;
   2905                         }
   2906                     }
   2907 #  else
   2908                   ENSURE_ALLOCATION (xsum (length, tmpdst_len));
   2909                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
   2910                   free (tmpdst);
   2911                   length += tmpdst_len;
   2912 #  endif
   2913 
   2914                   if (has_width && width > w
   2915                       && (dp->flags & FLAG_LEFT))
   2916                     {
   2917                       size_t n = width - w;
   2918                       ENSURE_ALLOCATION (xsum (length, n));
   2919                       DCHAR_SET (result + length, ' ', n);
   2920                       length += n;
   2921                     }
   2922                 }
   2923 # endif
   2924               }
   2925 #endif
   2926 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
   2927             else if ((dp->conversion == 'a' || dp->conversion == 'A')
   2928 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
   2929                      && (0
   2930 #  if NEED_PRINTF_DOUBLE
   2931                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
   2932 #  endif
   2933 #  if NEED_PRINTF_LONG_DOUBLE
   2934                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
   2935 #  endif
   2936                         )
   2937 # endif
   2938                     )
   2939               {
   2940                 arg_type type = a.arg[dp->arg_index].type;
   2941                 int flags = dp->flags;
   2942                 int has_width;
   2943                 size_t width;
   2944                 int has_precision;
   2945                 size_t precision;
   2946                 size_t tmp_length;
   2947                 DCHAR_T tmpbuf[700];
   2948                 DCHAR_T *tmp;
   2949                 DCHAR_T *pad_ptr;
   2950                 DCHAR_T *p;
   2951 
   2952                 has_width = 0;
   2953                 width = 0;
   2954                 if (dp->width_start != dp->width_end)
   2955                   {
   2956                     if (dp->width_arg_index != ARG_NONE)
   2957                       {
   2958                         int arg;
   2959 
   2960                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
   2961                           abort ();
   2962                         arg = a.arg[dp->width_arg_index].a.a_int;
   2963                         if (arg < 0)
   2964                           {
   2965                             /* "A negative field width is taken as a '-' flag
   2966                                 followed by a positive field width."  */
   2967                             flags |= FLAG_LEFT;
   2968                             width = (unsigned int) (-arg);
   2969                           }
   2970                         else
   2971                           width = arg;
   2972                       }
   2973                     else
   2974                       {
   2975                         const FCHAR_T *digitp = dp->width_start;
   2976 
   2977                         do
   2978                           width = xsum (xtimes (width, 10), *digitp++ - '0');
   2979                         while (digitp != dp->width_end);
   2980                       }
   2981                     has_width = 1;
   2982                   }
   2983 
   2984                 has_precision = 0;
   2985                 precision = 0;
   2986                 if (dp->precision_start != dp->precision_end)
   2987                   {
   2988                     if (dp->precision_arg_index != ARG_NONE)
   2989                       {
   2990                         int arg;
   2991 
   2992                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
   2993                           abort ();
   2994                         arg = a.arg[dp->precision_arg_index].a.a_int;
   2995                         /* "A negative precision is taken as if the precision
   2996                             were omitted."  */
   2997                         if (arg >= 0)
   2998                           {
   2999                             precision = arg;
   3000                             has_precision = 1;
   3001                           }
   3002                       }
   3003                     else
   3004                       {
   3005                         const FCHAR_T *digitp = dp->precision_start + 1;
   3006 
   3007                         precision = 0;
   3008                         while (digitp != dp->precision_end)
   3009                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
   3010                         has_precision = 1;
   3011                       }
   3012                   }
   3013 
   3014                 /* Allocate a temporary buffer of sufficient size.  */
   3015                 if (type == TYPE_LONGDOUBLE)
   3016                   tmp_length =
   3017                     (unsigned int) ((LDBL_DIG + 1)
   3018                                     * 0.831 /* decimal -> hexadecimal */
   3019                                    )
   3020                     + 1; /* turn floor into ceil */
   3021                 else
   3022                   tmp_length =
   3023                     (unsigned int) ((DBL_DIG + 1)
   3024                                     * 0.831 /* decimal -> hexadecimal */
   3025                                    )
   3026                     + 1; /* turn floor into ceil */
   3027                 if (tmp_length < precision)
   3028                   tmp_length = precision;
   3029                 /* Account for sign, decimal point etc. */
   3030                 tmp_length = xsum (tmp_length, 12);
   3031 
   3032                 if (tmp_length < width)
   3033                   tmp_length = width;
   3034 
   3035                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
   3036 
   3037                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
   3038                   tmp = tmpbuf;
   3039                 else
   3040                   {
   3041                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
   3042 
   3043                     if (size_overflow_p (tmp_memsize))
   3044                       /* Overflow, would lead to out of memory.  */
   3045                       goto out_of_memory;
   3046                     tmp = (DCHAR_T *) malloc (tmp_memsize);
   3047                     if (tmp == NULL)
   3048                       /* Out of memory.  */
   3049                       goto out_of_memory;
   3050                   }
   3051 
   3052                 pad_ptr = NULL;
   3053                 p = tmp;
   3054                 if (type == TYPE_LONGDOUBLE)
   3055                   {
   3056 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
   3057                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
   3058 
   3059                     if (isnanl (arg))
   3060                       {
   3061                         if (dp->conversion == 'A')
   3062                           {
   3063                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
   3064                           }
   3065                         else
   3066                           {
   3067                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
   3068                           }
   3069                       }
   3070                     else
   3071                       {
   3072                         int sign = 0;
   3073                         DECL_LONG_DOUBLE_ROUNDING
   3074 
   3075                         BEGIN_LONG_DOUBLE_ROUNDING ();
   3076 
   3077                         if (signbit (arg)) /* arg < 0.0L or negative zero */
   3078                           {
   3079                             sign = -1;
   3080                             arg = -arg;
   3081                           }
   3082 
   3083                         if (sign < 0)
   3084                           *p++ = '-';
   3085                         else if (flags & FLAG_SHOWSIGN)
   3086                           *p++ = '+';
   3087                         else if (flags & FLAG_SPACE)
   3088                           *p++ = ' ';
   3089 
   3090                         if (arg > 0.0L && arg + arg == arg)
   3091                           {
   3092                             if (dp->conversion == 'A')
   3093                               {
   3094                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
   3095                               }
   3096                             else
   3097                               {
   3098                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
   3099                               }
   3100                           }
   3101                         else
   3102                           {
   3103                             int exponent;
   3104                             long double mantissa;
   3105 
   3106                             if (arg > 0.0L)
   3107                               mantissa = printf_frexpl (arg, &exponent);
   3108                             else
   3109                               {
   3110                                 exponent = 0;
   3111                                 mantissa = 0.0L;
   3112                               }
   3113 
   3114                             if (has_precision
   3115                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
   3116                               {
   3117                                 /* Round the mantissa.  */
   3118                                 long double tail = mantissa;
   3119                                 size_t q;
   3120 
   3121                                 for (q = precision; ; q--)
   3122                                   {
   3123                                     int digit = (int) tail;
   3124                                     tail -= digit;
   3125                                     if (q == 0)
   3126                                       {
   3127                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
   3128                                           tail = 1 - tail;
   3129                                         else
   3130                                           tail = - tail;
   3131                                         break;
   3132                                       }
   3133                                     tail *= 16.0L;
   3134                                   }
   3135                                 if (tail != 0.0L)
   3136                                   for (q = precision; q > 0; q--)
   3137                                     tail *= 0.0625L;
   3138                                 mantissa += tail;
   3139                               }
   3140 
   3141                             *p++ = '0';
   3142                             *p++ = dp->conversion - 'A' + 'X';
   3143                             pad_ptr = p;
   3144                             {
   3145                               int digit;
   3146 
   3147                               digit = (int) mantissa;
   3148                               mantissa -= digit;
   3149                               *p++ = '0' + digit;
   3150                               if ((flags & FLAG_ALT)
   3151                                   || mantissa > 0.0L || precision > 0)
   3152                                 {
   3153                                   *p++ = decimal_point_char ();
   3154                                   /* This loop terminates because we assume
   3155                                      that FLT_RADIX is a power of 2.  */
   3156                                   while (mantissa > 0.0L)
   3157                                     {
   3158                                       mantissa *= 16.0L;
   3159                                       digit = (int) mantissa;
   3160                                       mantissa -= digit;
   3161                                       *p++ = digit
   3162                                              + (digit < 10
   3163                                                 ? '0'
   3164                                                 : dp->conversion - 10);
   3165                                       if (precision > 0)
   3166                                         precision--;
   3167                                     }
   3168                                   while (precision > 0)
   3169                                     {
   3170                                       *p++ = '0';
   3171                                       precision--;
   3172                                     }
   3173                                 }
   3174                               }
   3175                               *p++ = dp->conversion - 'A' + 'P';
   3176 #  if WIDE_CHAR_VERSION
   3177                               {
   3178                                 static const wchar_t decimal_format[] =
   3179                                   { '%', '+', 'd', '\0' };
   3180                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
   3181                               }
   3182                               while (*p != '\0')
   3183                                 p++;
   3184 #  else
   3185                               if (sizeof (DCHAR_T) == 1)
   3186                                 {
   3187                                   sprintf ((char *) p, "%+d", exponent);
   3188                                   while (*p != '\0')
   3189                                     p++;
   3190                                 }
   3191                               else
   3192                                 {
   3193                                   char expbuf[6 + 1];
   3194                                   const char *ep;
   3195                                   sprintf (expbuf, "%+d", exponent);
   3196                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
   3197                                     p++;
   3198                                 }
   3199 #  endif
   3200                           }
   3201 
   3202                         END_LONG_DOUBLE_ROUNDING ();
   3203                       }
   3204 # else
   3205                     abort ();
   3206 # endif
   3207                   }
   3208                 else
   3209                   {
   3210 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
   3211                     double arg = a.arg[dp->arg_index].a.a_double;
   3212 
   3213                     if (isnand (arg))
   3214                       {
   3215                         if (dp->conversion == 'A')
   3216                           {
   3217                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
   3218                           }
   3219                         else
   3220                           {
   3221                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
   3222                           }
   3223                       }
   3224                     else
   3225                       {
   3226                         int sign = 0;
   3227 
   3228                         if (signbit (arg)) /* arg < 0.0 or negative zero */
   3229                           {
   3230                             sign = -1;
   3231                             arg = -arg;
   3232                           }
   3233 
   3234                         if (sign < 0)
   3235                           *p++ = '-';
   3236                         else if (flags & FLAG_SHOWSIGN)
   3237                           *p++ = '+';
   3238                         else if (flags & FLAG_SPACE)
   3239                           *p++ = ' ';
   3240 
   3241                         if (arg > 0.0 && arg + arg == arg)
   3242                           {
   3243                             if (dp->conversion == 'A')
   3244                               {
   3245                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
   3246                               }
   3247                             else
   3248                               {
   3249                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
   3250                               }
   3251                           }
   3252                         else
   3253                           {
   3254                             int exponent;
   3255                             double mantissa;
   3256 
   3257                             if (arg > 0.0)
   3258                               mantissa = printf_frexp (arg, &exponent);
   3259                             else
   3260                               {
   3261                                 exponent = 0;
   3262                                 mantissa = 0.0;
   3263                               }
   3264 
   3265                             if (has_precision
   3266                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
   3267                               {
   3268                                 /* Round the mantissa.  */
   3269                                 double tail = mantissa;
   3270                                 size_t q;
   3271 
   3272                                 for (q = precision; ; q--)
   3273                                   {
   3274                                     int digit = (int) tail;
   3275                                     tail -= digit;
   3276                                     if (q == 0)
   3277                                       {
   3278                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
   3279                                           tail = 1 - tail;
   3280                                         else
   3281                                           tail = - tail;
   3282                                         break;
   3283                                       }
   3284                                     tail *= 16.0;
   3285                                   }
   3286                                 if (tail != 0.0)
   3287                                   for (q = precision; q > 0; q--)
   3288                                     tail *= 0.0625;
   3289                                 mantissa += tail;
   3290                               }
   3291 
   3292                             *p++ = '0';
   3293                             *p++ = dp->conversion - 'A' + 'X';
   3294                             pad_ptr = p;
   3295                             {
   3296                               int digit;
   3297 
   3298                               digit = (int) mantissa;
   3299                               mantissa -= digit;
   3300                               *p++ = '0' + digit;
   3301                               if ((flags & FLAG_ALT)
   3302                                   || mantissa > 0.0 || precision > 0)
   3303                                 {
   3304                                   *p++ = decimal_point_char ();
   3305                                   /* This loop terminates because we assume
   3306                                      that FLT_RADIX is a power of 2.  */
   3307                                   while (mantissa > 0.0)
   3308                                     {
   3309                                       mantissa *= 16.0;
   3310                                       digit = (int) mantissa;
   3311                                       mantissa -= digit;
   3312                                       *p++ = digit
   3313                                              + (digit < 10
   3314                                                 ? '0'
   3315                                                 : dp->conversion - 10);
   3316                                       if (precision > 0)
   3317                                         precision--;
   3318                                     }
   3319                                   while (precision > 0)
   3320                                     {
   3321                                       *p++ = '0';
   3322                                       precision--;
   3323                                     }
   3324                                 }
   3325                               }
   3326                               *p++ = dp->conversion - 'A' + 'P';
   3327 #  if WIDE_CHAR_VERSION
   3328                               {
   3329                                 static const wchar_t decimal_format[] =
   3330                                   { '%', '+', 'd', '\0' };
   3331                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
   3332                               }
   3333                               while (*p != '\0')
   3334                                 p++;
   3335 #  else
   3336                               if (sizeof (DCHAR_T) == 1)
   3337                                 {
   3338                                   sprintf ((char *) p, "%+d", exponent);
   3339                                   while (*p != '\0')
   3340                                     p++;
   3341                                 }
   3342                               else
   3343                                 {
   3344                                   char expbuf[6 + 1];
   3345                                   const char *ep;
   3346                                   sprintf (expbuf, "%+d", exponent);
   3347                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
   3348                                     p++;
   3349                                 }
   3350 #  endif
   3351                           }
   3352                       }
   3353 # else
   3354                     abort ();
   3355 # endif
   3356                   }
   3357                 /* The generated string now extends from tmp to p, with the
   3358                    zero padding insertion point being at pad_ptr.  */
   3359                 if (has_width && p - tmp < width)
   3360                   {
   3361                     size_t pad = width - (p - tmp);
   3362                     DCHAR_T *end = p + pad;
   3363 
   3364                     if (flags & FLAG_LEFT)
   3365                       {
   3366                         /* Pad with spaces on the right.  */
   3367                         for (; pad > 0; pad--)
   3368                           *p++ = ' ';
   3369                       }
   3370                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
   3371                       {
   3372                         /* Pad with zeroes.  */
   3373                         DCHAR_T *q = end;
   3374 
   3375                         while (p > pad_ptr)
   3376                           *--q = *--p;
   3377                         for (; pad > 0; pad--)
   3378                           *p++ = '0';
   3379                       }
   3380                     else
   3381                       {
   3382                         /* Pad with spaces on the left.  */
   3383                         DCHAR_T *q = end;
   3384 
   3385                         while (p > tmp)
   3386                           *--q = *--p;
   3387                         for (; pad > 0; pad--)
   3388                           *p++ = ' ';
   3389                       }
   3390 
   3391                     p = end;
   3392                   }
   3393 
   3394                 {
   3395                   size_t count = p - tmp;
   3396 
   3397                   if (count >= tmp_length)
   3398                     /* tmp_length was incorrectly calculated - fix the
   3399                        code above!  */
   3400                     abort ();
   3401 
   3402                   /* Make room for the result.  */
   3403                   if (count >= allocated - length)
   3404                     {
   3405                       size_t n = xsum (length, count);
   3406 
   3407                       ENSURE_ALLOCATION (n);
   3408                     }
   3409 
   3410                   /* Append the result.  */
   3411                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
   3412                   if (tmp != tmpbuf)
   3413                     free (tmp);
   3414                   length += count;
   3415                 }
   3416               }
   3417 #endif
   3418 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
   3419             else if ((dp->conversion == 'f' || dp->conversion == 'F'
   3420                       || dp->conversion == 'e' || dp->conversion == 'E'
   3421                       || dp->conversion == 'g' || dp->conversion == 'G'
   3422                       || dp->conversion == 'a' || dp->conversion == 'A')
   3423                      && (0
   3424 # if NEED_PRINTF_DOUBLE
   3425                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
   3426 # elif NEED_PRINTF_INFINITE_DOUBLE
   3427                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
   3428                              /* The systems (mingw) which produce wrong output
   3429                                 for Inf, -Inf, and NaN also do so for -0.0.
   3430                                 Therefore we treat this case here as well.  */
   3431                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
   3432 # endif
   3433 # if NEED_PRINTF_LONG_DOUBLE
   3434                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
   3435 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
   3436                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
   3437                              /* Some systems produce wrong output for Inf,
   3438                                 -Inf, and NaN.  Some systems in this category
   3439                                 (IRIX 5.3) also do so for -0.0.  Therefore we
   3440                                 treat this case here as well.  */
   3441                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
   3442 # endif
   3443                         ))
   3444               {
   3445 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
   3446                 arg_type type = a.arg[dp->arg_index].type;
   3447 # endif
   3448                 int flags = dp->flags;
   3449                 int has_width;
   3450                 size_t width;
   3451                 int has_precision;
   3452                 size_t precision;
   3453                 size_t tmp_length;
   3454                 DCHAR_T tmpbuf[700];
   3455                 DCHAR_T *tmp;
   3456                 DCHAR_T *pad_ptr;
   3457                 DCHAR_T *p;
   3458 
   3459                 has_width = 0;
   3460                 width = 0;
   3461                 if (dp->width_start != dp->width_end)
   3462                   {
   3463                     if (dp->width_arg_index != ARG_NONE)
   3464                       {
   3465                         int arg;
   3466 
   3467                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
   3468                           abort ();
   3469                         arg = a.arg[dp->width_arg_index].a.a_int;
   3470                         if (arg < 0)
   3471                           {
   3472                             /* "A negative field width is taken as a '-' flag
   3473                                 followed by a positive field width."  */
   3474                             flags |= FLAG_LEFT;
   3475                             width = (unsigned int) (-arg);
   3476                           }
   3477                         else
   3478                           width = arg;
   3479                       }
   3480                     else
   3481                       {
   3482                         const FCHAR_T *digitp = dp->width_start;
   3483 
   3484                         do
   3485                           width = xsum (xtimes (width, 10), *digitp++ - '0');
   3486                         while (digitp != dp->width_end);
   3487                       }
   3488                     has_width = 1;
   3489                   }
   3490 
   3491                 has_precision = 0;
   3492                 precision = 0;
   3493                 if (dp->precision_start != dp->precision_end)
   3494                   {
   3495                     if (dp->precision_arg_index != ARG_NONE)
   3496                       {
   3497                         int arg;
   3498 
   3499                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
   3500                           abort ();
   3501                         arg = a.arg[dp->precision_arg_index].a.a_int;
   3502                         /* "A negative precision is taken as if the precision
   3503                             were omitted."  */
   3504                         if (arg >= 0)
   3505                           {
   3506                             precision = arg;
   3507                             has_precision = 1;
   3508                           }
   3509                       }
   3510                     else
   3511                       {
   3512                         const FCHAR_T *digitp = dp->precision_start + 1;
   3513 
   3514                         precision = 0;
   3515                         while (digitp != dp->precision_end)
   3516                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
   3517                         has_precision = 1;
   3518                       }
   3519                   }
   3520 
   3521                 /* POSIX specifies the default precision to be 6 for %f, %F,
   3522                    %e, %E, but not for %g, %G.  Implementations appear to use
   3523                    the same default precision also for %g, %G.  But for %a, %A,
   3524                    the default precision is 0.  */
   3525                 if (!has_precision)
   3526                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
   3527                     precision = 6;
   3528 
   3529                 /* Allocate a temporary buffer of sufficient size.  */
   3530 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
   3531                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
   3532 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
   3533                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
   3534 # elif NEED_PRINTF_LONG_DOUBLE
   3535                 tmp_length = LDBL_DIG + 1;
   3536 # elif NEED_PRINTF_DOUBLE
   3537                 tmp_length = DBL_DIG + 1;
   3538 # else
   3539                 tmp_length = 0;
   3540 # endif
   3541                 if (tmp_length < precision)
   3542                   tmp_length = precision;
   3543 # if NEED_PRINTF_LONG_DOUBLE
   3544 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
   3545                 if (type == TYPE_LONGDOUBLE)
   3546 #  endif
   3547                   if (dp->conversion == 'f' || dp->conversion == 'F')
   3548                     {
   3549                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
   3550                       if (!(isnanl (arg) || arg + arg == arg))
   3551                         {
   3552                           /* arg is finite and nonzero.  */
   3553                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
   3554                           if (exponent >= 0 && tmp_length < exponent + precision)
   3555                             tmp_length = exponent + precision;
   3556                         }
   3557                     }
   3558 # endif
   3559 # if NEED_PRINTF_DOUBLE
   3560 #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
   3561                 if (type == TYPE_DOUBLE)
   3562 #  endif
   3563                   if (dp->conversion == 'f' || dp->conversion == 'F')
   3564                     {
   3565                       double arg = a.arg[dp->arg_index].a.a_double;
   3566                       if (!(isnand (arg) || arg + arg == arg))
   3567                         {
   3568                           /* arg is finite and nonzero.  */
   3569                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
   3570                           if (exponent >= 0 && tmp_length < exponent + precision)
   3571                             tmp_length = exponent + precision;
   3572                         }
   3573                     }
   3574 # endif
   3575                 /* Account for sign, decimal point etc. */
   3576                 tmp_length = xsum (tmp_length, 12);
   3577 
   3578                 if (tmp_length < width)
   3579                   tmp_length = width;
   3580 
   3581                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
   3582 
   3583                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
   3584                   tmp = tmpbuf;
   3585                 else
   3586                   {
   3587                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
   3588 
   3589                     if (size_overflow_p (tmp_memsize))
   3590                       /* Overflow, would lead to out of memory.  */
   3591                       goto out_of_memory;
   3592                     tmp = (DCHAR_T *) malloc (tmp_memsize);
   3593                     if (tmp == NULL)
   3594                       /* Out of memory.  */
   3595                       goto out_of_memory;
   3596                   }
   3597 
   3598                 pad_ptr = NULL;
   3599                 p = tmp;
   3600 
   3601 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
   3602 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
   3603                 if (type == TYPE_LONGDOUBLE)
   3604 #  endif
   3605                   {
   3606                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
   3607 
   3608                     if (isnanl (arg))
   3609                       {
   3610                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
   3611                           {
   3612                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
   3613                           }
   3614                         else
   3615                           {
   3616                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
   3617                           }
   3618                       }
   3619                     else
   3620                       {
   3621                         int sign = 0;
   3622                         DECL_LONG_DOUBLE_ROUNDING
   3623 
   3624                         BEGIN_LONG_DOUBLE_ROUNDING ();
   3625 
   3626                         if (signbit (arg)) /* arg < 0.0L or negative zero */
   3627                           {
   3628                             sign = -1;
   3629                             arg = -arg;
   3630                           }
   3631 
   3632                         if (sign < 0)
   3633                           *p++ = '-';
   3634                         else if (flags & FLAG_SHOWSIGN)
   3635                           *p++ = '+';
   3636                         else if (flags & FLAG_SPACE)
   3637                           *p++ = ' ';
   3638 
   3639                         if (arg > 0.0L && arg + arg == arg)
   3640                           {
   3641                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
   3642                               {
   3643                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
   3644                               }
   3645                             else
   3646                               {
   3647                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
   3648                               }
   3649                           }
   3650                         else
   3651                           {
   3652 #  if NEED_PRINTF_LONG_DOUBLE
   3653                             pad_ptr = p;
   3654 
   3655                             if (dp->conversion == 'f' || dp->conversion == 'F')
   3656                               {
   3657                                 char *digits;
   3658                                 size_t ndigits;
   3659 
   3660                                 digits =
   3661                                   scale10_round_decimal_long_double (arg, precision);
   3662                                 if (digits == NULL)
   3663                                   {
   3664                                     END_LONG_DOUBLE_ROUNDING ();
   3665                                     goto out_of_memory;
   3666                                   }
   3667                                 ndigits = strlen (digits);
   3668 
   3669                                 if (ndigits > precision)
   3670                                   do
   3671                                     {
   3672                                       --ndigits;
   3673                                       *p++ = digits[ndigits];
   3674                                     }
   3675                                   while (ndigits > precision);
   3676                                 else
   3677                                   *p++ = '0';
   3678                                 /* Here ndigits <= precision.  */
   3679                                 if ((flags & FLAG_ALT) || precision > 0)
   3680                                   {
   3681                                     *p++ = decimal_point_char ();
   3682                                     for (; precision > ndigits; precision--)
   3683                                       *p++ = '0';
   3684                                     while (ndigits > 0)
   3685                                       {
   3686                                         --ndigits;
   3687                                         *p++ = digits[ndigits];
   3688                                       }
   3689                                   }
   3690 
   3691                                 free (digits);
   3692                               }
   3693                             else if (dp->conversion == 'e' || dp->conversion == 'E')
   3694                               {
   3695                                 int exponent;
   3696 
   3697                                 if (arg == 0.0L)
   3698                                   {
   3699                                     exponent = 0;
   3700                                     *p++ = '0';
   3701                                     if ((flags & FLAG_ALT) || precision > 0)
   3702                                       {
   3703                                         *p++ = decimal_point_char ();
   3704                                         for (; precision > 0; precision--)
   3705                                           *p++ = '0';
   3706                                       }
   3707                                   }
   3708                                 else
   3709                                   {
   3710                                     /* arg > 0.0L.  */
   3711                                     int adjusted;
   3712                                     char *digits;
   3713                                     size_t ndigits;
   3714 
   3715                                     exponent = floorlog10l (arg);
   3716                                     adjusted = 0;
   3717                                     for (;;)
   3718                                       {
   3719                                         digits =
   3720                                           scale10_round_decimal_long_double (arg,
   3721                                                                              (int)precision - exponent);
   3722                                         if (digits == NULL)
   3723                                           {
   3724                                             END_LONG_DOUBLE_ROUNDING ();
   3725                                             goto out_of_memory;
   3726                                           }
   3727                                         ndigits = strlen (digits);
   3728 
   3729                                         if (ndigits == precision + 1)
   3730                                           break;
   3731                                         if (ndigits < precision
   3732                                             || ndigits > precision + 2)
   3733                                           /* The exponent was not guessed
   3734                                              precisely enough.  */
   3735                                           abort ();
   3736                                         if (adjusted)
   3737                                           /* None of two values of exponent is
   3738                                              the right one.  Prevent an endless
   3739                                              loop.  */
   3740                                           abort ();
   3741                                         free (digits);
   3742                                         if (ndigits == precision)
   3743                                           exponent -= 1;
   3744                                         else
   3745                                           exponent += 1;
   3746                                         adjusted = 1;
   3747                                       }
   3748                                     /* Here ndigits = precision+1.  */
   3749                                     if (is_borderline (digits, precision))
   3750                                       {
   3751                                         /* Maybe the exponent guess was too high
   3752                                            and a smaller exponent can be reached
   3753                                            by turning a 10...0 into 9...9x.  */
   3754                                         char *digits2 =
   3755                                           scale10_round_decimal_long_double (arg,
   3756                                                                              (int)precision - exponent + 1);
   3757                                         if (digits2 == NULL)
   3758                                           {
   3759                                             free (digits);
   3760                                             END_LONG_DOUBLE_ROUNDING ();
   3761                                             goto out_of_memory;
   3762                                           }
   3763                                         if (strlen (digits2) == precision + 1)
   3764                                           {
   3765                                             free (digits);
   3766                                             digits = digits2;
   3767                                             exponent -= 1;
   3768                                           }
   3769                                         else
   3770                                           free (digits2);
   3771                                       }
   3772                                     /* Here ndigits = precision+1.  */
   3773 
   3774                                     *p++ = digits[--ndigits];
   3775                                     if ((flags & FLAG_ALT) || precision > 0)
   3776                                       {
   3777                                         *p++ = decimal_point_char ();
   3778                                         while (ndigits > 0)
   3779                                           {
   3780                                             --ndigits;
   3781                                             *p++ = digits[ndigits];
   3782                                           }
   3783                                       }
   3784 
   3785                                     free (digits);
   3786                                   }
   3787 
   3788                                 *p++ = dp->conversion; /* 'e' or 'E' */
   3789 #   if WIDE_CHAR_VERSION
   3790                                 {
   3791                                   static const wchar_t decimal_format[] =
   3792                                     { '%', '+', '.', '2', 'd', '\0' };
   3793                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
   3794                                 }
   3795                                 while (*p != '\0')
   3796                                   p++;
   3797 #   else
   3798                                 if (sizeof (DCHAR_T) == 1)
   3799                                   {
   3800                                     sprintf ((char *) p, "%+.2d", exponent);
   3801                                     while (*p != '\0')
   3802                                       p++;
   3803                                   }
   3804                                 else
   3805                                   {
   3806                                     char expbuf[6 + 1];
   3807                                     const char *ep;
   3808                                     sprintf (expbuf, "%+.2d", exponent);
   3809                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
   3810                                       p++;
   3811                                   }
   3812 #   endif
   3813                               }
   3814                             else if (dp->conversion == 'g' || dp->conversion == 'G')
   3815                               {
   3816                                 if (precision == 0)
   3817                                   precision = 1;
   3818                                 /* precision >= 1.  */
   3819 
   3820                                 if (arg == 0.0L)
   3821                                   /* The exponent is 0, >= -4, < precision.
   3822                                      Use fixed-point notation.  */
   3823                                   {
   3824                                     size_t ndigits = precision;
   3825                                     /* Number of trailing zeroes that have to be
   3826                                        dropped.  */
   3827                                     size_t nzeroes =
   3828                                       (flags & FLAG_ALT ? 0 : precision - 1);
   3829 
   3830                                     --ndigits;
   3831                                     *p++ = '0';
   3832                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
   3833                                       {
   3834                                         *p++ = decimal_point_char ();
   3835                                         while (ndigits > nzeroes)
   3836                                           {
   3837                                             --ndigits;
   3838                                             *p++ = '0';
   3839                                           }
   3840                                       }
   3841                                   }
   3842                                 else
   3843                                   {
   3844                                     /* arg > 0.0L.  */
   3845                                     int exponent;
   3846                                     int adjusted;
   3847                                     char *digits;
   3848                                     size_t ndigits;
   3849                                     size_t nzeroes;
   3850 
   3851                                     exponent = floorlog10l (arg);
   3852                                     adjusted = 0;
   3853                                     for (;;)
   3854                                       {
   3855                                         digits =
   3856                                           scale10_round_decimal_long_double (arg,
   3857                                                                              (int)(precision - 1) - exponent);
   3858                                         if (digits == NULL)
   3859                                           {
   3860                                             END_LONG_DOUBLE_ROUNDING ();
   3861                                             goto out_of_memory;
   3862                                           }
   3863                                         ndigits = strlen (digits);
   3864 
   3865                                         if (ndigits == precision)
   3866                                           break;
   3867                                         if (ndigits < precision - 1
   3868                                             || ndigits > precision + 1)
   3869                                           /* The exponent was not guessed
   3870                                              precisely enough.  */
   3871                                           abort ();
   3872                                         if (adjusted)
   3873                                           /* None of two values of exponent is
   3874                                              the right one.  Prevent an endless
   3875                                              loop.  */
   3876                                           abort ();
   3877                                         free (digits);
   3878                                         if (ndigits < precision)
   3879                                           exponent -= 1;
   3880                                         else
   3881                                           exponent += 1;
   3882                                         adjusted = 1;
   3883                                       }
   3884                                     /* Here ndigits = precision.  */
   3885                                     if (is_borderline (digits, precision - 1))
   3886                                       {
   3887                                         /* Maybe the exponent guess was too high
   3888                                            and a smaller exponent can be reached
   3889                                            by turning a 10...0 into 9...9x.  */
   3890                                         char *digits2 =
   3891                                           scale10_round_decimal_long_double (arg,
   3892                                                                              (int)(precision - 1) - exponent + 1);
   3893                                         if (digits2 == NULL)
   3894                                           {
   3895                                             free (digits);
   3896                                             END_LONG_DOUBLE_ROUNDING ();
   3897                                             goto out_of_memory;
   3898                                           }
   3899                                         if (strlen (digits2) == precision)
   3900                                           {
   3901                                             free (digits);
   3902                                             digits = digits2;
   3903                                             exponent -= 1;
   3904                                           }
   3905                                         else
   3906                                           free (digits2);
   3907                                       }
   3908                                     /* Here ndigits = precision.  */
   3909 
   3910                                     /* Determine the number of trailing zeroes
   3911                                        that have to be dropped.  */
   3912                                     nzeroes = 0;
   3913                                     if ((flags & FLAG_ALT) == 0)
   3914                                       while (nzeroes < ndigits
   3915                                              && digits[nzeroes] == '0')
   3916                                         nzeroes++;
   3917 
   3918                                     /* The exponent is now determined.  */
   3919                                     if (exponent >= -4
   3920                                         && exponent < (long)precision)
   3921                                       {
   3922                                         /* Fixed-point notation:
   3923                                            max(exponent,0)+1 digits, then the
   3924                                            decimal point, then the remaining
   3925                                            digits without trailing zeroes.  */
   3926                                         if (exponent >= 0)
   3927                                           {
   3928                                             size_t count = exponent + 1;
   3929                                             /* Note: count <= precision = ndigits.  */
   3930                                             for (; count > 0; count--)
   3931                                               *p++ = digits[--ndigits];
   3932                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
   3933                                               {
   3934                                                 *p++ = decimal_point_char ();
   3935                                                 while (ndigits > nzeroes)
   3936                                                   {
   3937                                                     --ndigits;
   3938                                                     *p++ = digits[ndigits];
   3939                                                   }
   3940                                               }
   3941                                           }
   3942                                         else
   3943                                           {
   3944                                             size_t count = -exponent - 1;
   3945                                             *p++ = '0';
   3946                                             *p++ = decimal_point_char ();
   3947                                             for (; count > 0; count--)
   3948                                               *p++ = '0';
   3949                                             while (ndigits > nzeroes)
   3950                                               {
   3951                                                 --ndigits;
   3952                                                 *p++ = digits[ndigits];
   3953                                               }
   3954                                           }
   3955                                       }
   3956                                     else
   3957                                       {
   3958                                         /* Exponential notation.  */
   3959                                         *p++ = digits[--ndigits];
   3960                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
   3961                                           {
   3962                                             *p++ = decimal_point_char ();
   3963                                             while (ndigits > nzeroes)
   3964                                               {
   3965                                                 --ndigits;
   3966                                                 *p++ = digits[ndigits];
   3967                                               }
   3968                                           }
   3969                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
   3970 #   if WIDE_CHAR_VERSION
   3971                                         {
   3972                                           static const wchar_t decimal_format[] =
   3973                                             { '%', '+', '.', '2', 'd', '\0' };
   3974                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
   3975                                         }
   3976                                         while (*p != '\0')
   3977                                           p++;
   3978 #   else
   3979                                         if (sizeof (DCHAR_T) == 1)
   3980                                           {
   3981                                             sprintf ((char *) p, "%+.2d", exponent);
   3982                                             while (*p != '\0')
   3983                                               p++;
   3984                                           }
   3985                                         else
   3986                                           {
   3987                                             char expbuf[6 + 1];
   3988                                             const char *ep;
   3989                                             sprintf (expbuf, "%+.2d", exponent);
   3990                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
   3991                                               p++;
   3992                                           }
   3993 #   endif
   3994                                       }
   3995 
   3996                                     free (digits);
   3997                                   }
   3998                               }
   3999                             else
   4000                               abort ();
   4001 #  else
   4002                             /* arg is finite.  */
   4003                             if (!(arg == 0.0L))
   4004                               abort ();
   4005 
   4006                             pad_ptr = p;
   4007 
   4008                             if (dp->conversion == 'f' || dp->conversion == 'F')
   4009                               {
   4010                                 *p++ = '0';
   4011                                 if ((flags & FLAG_ALT) || precision > 0)
   4012                                   {
   4013                                     *p++ = decimal_point_char ();
   4014                                     for (; precision > 0; precision--)
   4015                                       *p++ = '0';
   4016                                   }
   4017                               }
   4018                             else if (dp->conversion == 'e' || dp->conversion == 'E')
   4019                               {
   4020                                 *p++ = '0';
   4021                                 if ((flags & FLAG_ALT) || precision > 0)
   4022                                   {
   4023                                     *p++ = decimal_point_char ();
   4024                                     for (; precision > 0; precision--)
   4025                                       *p++ = '0';
   4026                                   }
   4027                                 *p++ = dp->conversion; /* 'e' or 'E' */
   4028                                 *p++ = '+';
   4029                                 *p++ = '0';
   4030                                 *p++ = '0';
   4031                               }
   4032                             else if (dp->conversion == 'g' || dp->conversion == 'G')
   4033                               {
   4034                                 *p++ = '0';
   4035                                 if (flags & FLAG_ALT)
   4036                                   {
   4037                                     size_t ndigits =
   4038                                       (precision > 0 ? precision - 1 : 0);
   4039                                     *p++ = decimal_point_char ();
   4040                                     for (; ndigits > 0; --ndigits)
   4041                                       *p++ = '0';
   4042                                   }
   4043                               }
   4044                             else if (dp->conversion == 'a' || dp->conversion == 'A')
   4045                               {
   4046                                 *p++ = '0';
   4047                                 *p++ = dp->conversion - 'A' + 'X';
   4048                                 pad_ptr = p;
   4049                                 *p++ = '0';
   4050                                 if ((flags & FLAG_ALT) || precision > 0)
   4051                                   {
   4052                                     *p++ = decimal_point_char ();
   4053                                     for (; precision > 0; precision--)
   4054                                       *p++ = '0';
   4055                                   }
   4056                                 *p++ = dp->conversion - 'A' + 'P';
   4057                                 *p++ = '+';
   4058                                 *p++ = '0';
   4059                               }
   4060                             else
   4061                               abort ();
   4062 #  endif
   4063                           }
   4064 
   4065                         END_LONG_DOUBLE_ROUNDING ();
   4066                       }
   4067                   }
   4068 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
   4069                 else
   4070 #  endif
   4071 # endif
   4072 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
   4073                   {
   4074                     double arg = a.arg[dp->arg_index].a.a_double;
   4075 
   4076                     if (isnand (arg))
   4077                       {
   4078                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
   4079                           {
   4080                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
   4081                           }
   4082                         else
   4083                           {
   4084                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
   4085                           }
   4086                       }
   4087                     else
   4088                       {
   4089                         int sign = 0;
   4090 
   4091                         if (signbit (arg)) /* arg < 0.0 or negative zero */
   4092                           {
   4093                             sign = -1;
   4094                             arg = -arg;
   4095                           }
   4096 
   4097                         if (sign < 0)
   4098                           *p++ = '-';
   4099                         else if (flags & FLAG_SHOWSIGN)
   4100                           *p++ = '+';
   4101                         else if (flags & FLAG_SPACE)
   4102                           *p++ = ' ';
   4103 
   4104                         if (arg > 0.0 && arg + arg == arg)
   4105                           {
   4106                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
   4107                               {
   4108                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
   4109                               }
   4110                             else
   4111                               {
   4112                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
   4113                               }
   4114                           }
   4115                         else
   4116                           {
   4117 #  if NEED_PRINTF_DOUBLE
   4118                             pad_ptr = p;
   4119 
   4120                             if (dp->conversion == 'f' || dp->conversion == 'F')
   4121                               {
   4122                                 char *digits;
   4123                                 size_t ndigits;
   4124 
   4125                                 digits =
   4126                                   scale10_round_decimal_double (arg, precision);
   4127                                 if (digits == NULL)
   4128                                   goto out_of_memory;
   4129                                 ndigits = strlen (digits);
   4130 
   4131                                 if (ndigits > precision)
   4132                                   do
   4133                                     {
   4134                                       --ndigits;
   4135                                       *p++ = digits[ndigits];
   4136                                     }
   4137                                   while (ndigits > precision);
   4138                                 else
   4139                                   *p++ = '0';
   4140                                 /* Here ndigits <= precision.  */
   4141                                 if ((flags & FLAG_ALT) || precision > 0)
   4142                                   {
   4143                                     *p++ = decimal_point_char ();
   4144                                     for (; precision > ndigits; precision--)
   4145                                       *p++ = '0';
   4146                                     while (ndigits > 0)
   4147                                       {
   4148                                         --ndigits;
   4149                                         *p++ = digits[ndigits];
   4150                                       }
   4151                                   }
   4152 
   4153                                 free (digits);
   4154                               }
   4155                             else if (dp->conversion == 'e' || dp->conversion == 'E')
   4156                               {
   4157                                 int exponent;
   4158 
   4159                                 if (arg == 0.0)
   4160                                   {
   4161                                     exponent = 0;
   4162                                     *p++ = '0';
   4163                                     if ((flags & FLAG_ALT) || precision > 0)
   4164                                       {
   4165                                         *p++ = decimal_point_char ();
   4166                                         for (; precision > 0; precision--)
   4167                                           *p++ = '0';
   4168                                       }
   4169                                   }
   4170                                 else
   4171                                   {
   4172                                     /* arg > 0.0.  */
   4173                                     int adjusted;
   4174                                     char *digits;
   4175                                     size_t ndigits;
   4176 
   4177                                     exponent = floorlog10 (arg);
   4178                                     adjusted = 0;
   4179                                     for (;;)
   4180                                       {
   4181                                         digits =
   4182                                           scale10_round_decimal_double (arg,
   4183                                                                         (int)precision - exponent);
   4184                                         if (digits == NULL)
   4185                                           goto out_of_memory;
   4186                                         ndigits = strlen (digits);
   4187 
   4188                                         if (ndigits == precision + 1)
   4189                                           break;
   4190                                         if (ndigits < precision
   4191                                             || ndigits > precision + 2)
   4192                                           /* The exponent was not guessed
   4193                                              precisely enough.  */
   4194                                           abort ();
   4195                                         if (adjusted)
   4196                                           /* None of two values of exponent is
   4197                                              the right one.  Prevent an endless
   4198                                              loop.  */
   4199                                           abort ();
   4200                                         free (digits);
   4201                                         if (ndigits == precision)
   4202                                           exponent -= 1;
   4203                                         else
   4204                                           exponent += 1;
   4205                                         adjusted = 1;
   4206                                       }
   4207                                     /* Here ndigits = precision+1.  */
   4208                                     if (is_borderline (digits, precision))
   4209                                       {
   4210                                         /* Maybe the exponent guess was too high
   4211                                            and a smaller exponent can be reached
   4212                                            by turning a 10...0 into 9...9x.  */
   4213                                         char *digits2 =
   4214                                           scale10_round_decimal_double (arg,
   4215                                                                         (int)precision - exponent + 1);
   4216                                         if (digits2 == NULL)
   4217                                           {
   4218                                             free (digits);
   4219                                             goto out_of_memory;
   4220                                           }
   4221                                         if (strlen (digits2) == precision + 1)
   4222                                           {
   4223                                             free (digits);
   4224                                             digits = digits2;
   4225                                             exponent -= 1;
   4226                                           }
   4227                                         else
   4228                                           free (digits2);
   4229                                       }
   4230                                     /* Here ndigits = precision+1.  */
   4231 
   4232                                     *p++ = digits[--ndigits];
   4233                                     if ((flags & FLAG_ALT) || precision > 0)
   4234                                       {
   4235                                         *p++ = decimal_point_char ();
   4236                                         while (ndigits > 0)
   4237                                           {
   4238                                             --ndigits;
   4239                                             *p++ = digits[ndigits];
   4240                                           }
   4241                                       }
   4242 
   4243                                     free (digits);
   4244                                   }
   4245 
   4246                                 *p++ = dp->conversion; /* 'e' or 'E' */
   4247 #   if WIDE_CHAR_VERSION
   4248                                 {
   4249                                   static const wchar_t decimal_format[] =
   4250                                     /* Produce the same number of exponent digits
   4251                                        as the native printf implementation.  */
   4252 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
   4253                                     { '%', '+', '.', '3', 'd', '\0' };
   4254 #    else
   4255                                     { '%', '+', '.', '2', 'd', '\0' };
   4256 #    endif
   4257                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
   4258                                 }
   4259                                 while (*p != '\0')
   4260                                   p++;
   4261 #   else
   4262                                 {
   4263                                   static const char decimal_format[] =
   4264                                     /* Produce the same number of exponent digits
   4265                                        as the native printf implementation.  */
   4266 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
   4267                                     "%+.3d";
   4268 #    else
   4269                                     "%+.2d";
   4270 #    endif
   4271                                   if (sizeof (DCHAR_T) == 1)
   4272                                     {
   4273                                       sprintf ((char *) p, decimal_format, exponent);
   4274                                       while (*p != '\0')
   4275                                         p++;
   4276                                     }
   4277                                   else
   4278                                     {
   4279                                       char expbuf[6 + 1];
   4280                                       const char *ep;
   4281                                       sprintf (expbuf, decimal_format, exponent);
   4282                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
   4283                                         p++;
   4284                                     }
   4285                                 }
   4286 #   endif
   4287                               }
   4288                             else if (dp->conversion == 'g' || dp->conversion == 'G')
   4289                               {
   4290                                 if (precision == 0)
   4291                                   precision = 1;
   4292                                 /* precision >= 1.  */
   4293 
   4294                                 if (arg == 0.0)
   4295                                   /* The exponent is 0, >= -4, < precision.
   4296                                      Use fixed-point notation.  */
   4297                                   {
   4298                                     size_t ndigits = precision;
   4299                                     /* Number of trailing zeroes that have to be
   4300                                        dropped.  */
   4301                                     size_t nzeroes =
   4302                                       (flags & FLAG_ALT ? 0 : precision - 1);
   4303 
   4304                                     --ndigits;
   4305                                     *p++ = '0';
   4306                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
   4307                                       {
   4308                                         *p++ = decimal_point_char ();
   4309                                         while (ndigits > nzeroes)
   4310                                           {
   4311                                             --ndigits;
   4312                                             *p++ = '0';
   4313                                           }
   4314                                       }
   4315                                   }
   4316                                 else
   4317                                   {
   4318                                     /* arg > 0.0.  */
   4319                                     int exponent;
   4320                                     int adjusted;
   4321                                     char *digits;
   4322                                     size_t ndigits;
   4323                                     size_t nzeroes;
   4324 
   4325                                     exponent = floorlog10 (arg);
   4326                                     adjusted = 0;
   4327                                     for (;;)
   4328                                       {
   4329                                         digits =
   4330                                           scale10_round_decimal_double (arg,
   4331                                                                         (int)(precision - 1) - exponent);
   4332                                         if (digits == NULL)
   4333                                           goto out_of_memory;
   4334                                         ndigits = strlen (digits);
   4335 
   4336                                         if (ndigits == precision)
   4337                                           break;
   4338                                         if (ndigits < precision - 1
   4339                                             || ndigits > precision + 1)
   4340                                           /* The exponent was not guessed
   4341                                              precisely enough.  */
   4342                                           abort ();
   4343                                         if (adjusted)
   4344                                           /* None of two values of exponent is
   4345                                              the right one.  Prevent an endless
   4346                                              loop.  */
   4347                                           abort ();
   4348                                         free (digits);
   4349                                         if (ndigits < precision)
   4350                                           exponent -= 1;
   4351                                         else
   4352                                           exponent += 1;
   4353                                         adjusted = 1;
   4354                                       }
   4355                                     /* Here ndigits = precision.  */
   4356                                     if (is_borderline (digits, precision - 1))
   4357                                       {
   4358                                         /* Maybe the exponent guess was too high
   4359                                            and a smaller exponent can be reached
   4360                                            by turning a 10...0 into 9...9x.  */
   4361                                         char *digits2 =
   4362                                           scale10_round_decimal_double (arg,
   4363                                                                         (int)(precision - 1) - exponent + 1);
   4364                                         if (digits2 == NULL)
   4365                                           {
   4366                                             free (digits);
   4367                                             goto out_of_memory;
   4368                                           }
   4369                                         if (strlen (digits2) == precision)
   4370                                           {
   4371                                             free (digits);
   4372                                             digits = digits2;
   4373                                             exponent -= 1;
   4374                                           }
   4375                                         else
   4376                                           free (digits2);
   4377                                       }
   4378                                     /* Here ndigits = precision.  */
   4379 
   4380                                     /* Determine the number of trailing zeroes
   4381                                        that have to be dropped.  */
   4382                                     nzeroes = 0;
   4383                                     if ((flags & FLAG_ALT) == 0)
   4384                                       while (nzeroes < ndigits
   4385                                              && digits[nzeroes] == '0')
   4386                                         nzeroes++;
   4387 
   4388                                     /* The exponent is now determined.  */
   4389                                     if (exponent >= -4
   4390                                         && exponent < (long)precision)
   4391                                       {
   4392                                         /* Fixed-point notation:
   4393                                            max(exponent,0)+1 digits, then the
   4394                                            decimal point, then the remaining
   4395                                            digits without trailing zeroes.  */
   4396                                         if (exponent >= 0)
   4397                                           {
   4398                                             size_t count = exponent + 1;
   4399                                             /* Note: count <= precision = ndigits.  */
   4400                                             for (; count > 0; count--)
   4401                                               *p++ = digits[--ndigits];
   4402                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
   4403                                               {
   4404                                                 *p++ = decimal_point_char ();
   4405                                                 while (ndigits > nzeroes)
   4406                                                   {
   4407                                                     --ndigits;
   4408                                                     *p++ = digits[ndigits];
   4409                                                   }
   4410                                               }
   4411                                           }
   4412                                         else
   4413                                           {
   4414                                             size_t count = -exponent - 1;
   4415                                             *p++ = '0';
   4416                                             *p++ = decimal_point_char ();
   4417                                             for (; count > 0; count--)
   4418                                               *p++ = '0';
   4419                                             while (ndigits > nzeroes)
   4420                                               {
   4421                                                 --ndigits;
   4422                                                 *p++ = digits[ndigits];
   4423                                               }
   4424                                           }
   4425                                       }
   4426                                     else
   4427                                       {
   4428                                         /* Exponential notation.  */
   4429                                         *p++ = digits[--ndigits];
   4430                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
   4431                                           {
   4432                                             *p++ = decimal_point_char ();
   4433                                             while (ndigits > nzeroes)
   4434                                               {
   4435                                                 --ndigits;
   4436                                                 *p++ = digits[ndigits];
   4437                                               }
   4438                                           }
   4439                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
   4440 #   if WIDE_CHAR_VERSION
   4441                                         {
   4442                                           static const wchar_t decimal_format[] =
   4443                                             /* Produce the same number of exponent digits
   4444                                                as the native printf implementation.  */
   4445 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
   4446                                             { '%', '+', '.', '3', 'd', '\0' };
   4447 #    else
   4448                                             { '%', '+', '.', '2', 'd', '\0' };
   4449 #    endif
   4450                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
   4451                                         }
   4452                                         while (*p != '\0')
   4453                                           p++;
   4454 #   else
   4455                                         {
   4456                                           static const char decimal_format[] =
   4457                                             /* Produce the same number of exponent digits
   4458                                                as the native printf implementation.  */
   4459 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
   4460                                             "%+.3d";
   4461 #    else
   4462                                             "%+.2d";
   4463 #    endif
   4464                                           if (sizeof (DCHAR_T) == 1)
   4465                                             {
   4466                                               sprintf ((char *) p, decimal_format, exponent);
   4467                                               while (*p != '\0')
   4468                                                 p++;
   4469                                             }
   4470                                           else
   4471                                             {
   4472                                               char expbuf[6 + 1];
   4473                                               const char *ep;
   4474                                               sprintf (expbuf, decimal_format, exponent);
   4475                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
   4476                                                 p++;
   4477                                             }
   4478                                         }
   4479 #   endif
   4480                                       }
   4481 
   4482                                     free (digits);
   4483                                   }
   4484                               }
   4485                             else
   4486                               abort ();
   4487 #  else
   4488                             /* arg is finite.  */
   4489                             if (!(arg == 0.0))
   4490                               abort ();
   4491 
   4492                             pad_ptr = p;
   4493 
   4494                             if (dp->conversion == 'f' || dp->conversion == 'F')
   4495                               {
   4496                                 *p++ = '0';
   4497                                 if ((flags & FLAG_ALT) || precision > 0)
   4498                                   {
   4499                                     *p++ = decimal_point_char ();
   4500                                     for (; precision > 0; precision--)
   4501                                       *p++ = '0';
   4502                                   }
   4503                               }
   4504                             else if (dp->conversion == 'e' || dp->conversion == 'E')
   4505                               {
   4506                                 *p++ = '0';
   4507                                 if ((flags & FLAG_ALT) || precision > 0)
   4508                                   {
   4509                                     *p++ = decimal_point_char ();
   4510                                     for (; precision > 0; precision--)
   4511                                       *p++ = '0';
   4512                                   }
   4513                                 *p++ = dp->conversion; /* 'e' or 'E' */
   4514                                 *p++ = '+';
   4515                                 /* Produce the same number of exponent digits as
   4516                                    the native printf implementation.  */
   4517 #   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
   4518                                 *p++ = '0';
   4519 #   endif
   4520                                 *p++ = '0';
   4521                                 *p++ = '0';
   4522                               }
   4523                             else if (dp->conversion == 'g' || dp->conversion == 'G')
   4524                               {
   4525                                 *p++ = '0';
   4526                                 if (flags & FLAG_ALT)
   4527                                   {
   4528                                     size_t ndigits =
   4529                                       (precision > 0 ? precision - 1 : 0);
   4530                                     *p++ = decimal_point_char ();
   4531                                     for (; ndigits > 0; --ndigits)
   4532                                       *p++ = '0';
   4533                                   }
   4534                               }
   4535                             else
   4536                               abort ();
   4537 #  endif
   4538                           }
   4539                       }
   4540                   }
   4541 # endif
   4542 
   4543                 /* The generated string now extends from tmp to p, with the
   4544                    zero padding insertion point being at pad_ptr.  */
   4545                 if (has_width && p - tmp < width)
   4546                   {
   4547                     size_t pad = width - (p - tmp);
   4548                     DCHAR_T *end = p + pad;
   4549 
   4550                     if (flags & FLAG_LEFT)
   4551                       {
   4552                         /* Pad with spaces on the right.  */
   4553                         for (; pad > 0; pad--)
   4554                           *p++ = ' ';
   4555                       }
   4556                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
   4557                       {
   4558                         /* Pad with zeroes.  */
   4559                         DCHAR_T *q = end;
   4560 
   4561                         while (p > pad_ptr)
   4562                           *--q = *--p;
   4563                         for (; pad > 0; pad--)
   4564                           *p++ = '0';
   4565                       }
   4566                     else
   4567                       {
   4568                         /* Pad with spaces on the left.  */
   4569                         DCHAR_T *q = end;
   4570 
   4571                         while (p > tmp)
   4572                           *--q = *--p;
   4573                         for (; pad > 0; pad--)
   4574                           *p++ = ' ';
   4575                       }
   4576 
   4577                     p = end;
   4578                   }
   4579 
   4580                 {
   4581                   size_t count = p - tmp;
   4582 
   4583                   if (count >= tmp_length)
   4584                     /* tmp_length was incorrectly calculated - fix the
   4585                        code above!  */
   4586                     abort ();
   4587 
   4588                   /* Make room for the result.  */
   4589                   if (count >= allocated - length)
   4590                     {
   4591                       size_t n = xsum (length, count);
   4592 
   4593                       ENSURE_ALLOCATION (n);
   4594                     }
   4595 
   4596                   /* Append the result.  */
   4597                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
   4598                   if (tmp != tmpbuf)
   4599                     free (tmp);
   4600                   length += count;
   4601                 }
   4602               }
   4603 #endif
   4604             else
   4605               {
   4606                 arg_type type = a.arg[dp->arg_index].type;
   4607                 int flags = dp->flags;
   4608 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
   4609                 int has_width;
   4610                 size_t width;
   4611 #endif
   4612 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
   4613                 int has_precision;
   4614                 size_t precision;
   4615 #endif
   4616 #if NEED_PRINTF_UNBOUNDED_PRECISION
   4617                 int prec_ourselves;
   4618 #else
   4619 #               define prec_ourselves 0
   4620 #endif
   4621 #if NEED_PRINTF_FLAG_LEFTADJUST
   4622 #               define pad_ourselves 1
   4623 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
   4624                 int pad_ourselves;
   4625 #else
   4626 #               define pad_ourselves 0
   4627 #endif
   4628                 TCHAR_T *fbp;
   4629                 unsigned int prefix_count;
   4630                 int prefixes[2] IF_LINT (= { 0 });
   4631                 int orig_errno;
   4632 #if !USE_SNPRINTF
   4633                 size_t tmp_length;
   4634                 TCHAR_T tmpbuf[700];
   4635                 TCHAR_T *tmp;
   4636 #endif
   4637 
   4638 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
   4639                 has_width = 0;
   4640                 width = 0;
   4641                 if (dp->width_start != dp->width_end)
   4642                   {
   4643                     if (dp->width_arg_index != ARG_NONE)
   4644                       {
   4645                         int arg;
   4646 
   4647                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
   4648                           abort ();
   4649                         arg = a.arg[dp->width_arg_index].a.a_int;
   4650                         if (arg < 0)
   4651                           {
   4652                             /* "A negative field width is taken as a '-' flag
   4653                                 followed by a positive field width."  */
   4654                             flags |= FLAG_LEFT;
   4655                             width = (unsigned int) (-arg);
   4656                           }
   4657                         else
   4658                           width = arg;
   4659                       }
   4660                     else
   4661                       {
   4662                         const FCHAR_T *digitp = dp->width_start;
   4663 
   4664                         do
   4665                           width = xsum (xtimes (width, 10), *digitp++ - '0');
   4666                         while (digitp != dp->width_end);
   4667                       }
   4668                     has_width = 1;
   4669                   }
   4670 #endif
   4671 
   4672 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
   4673                 has_precision = 0;
   4674                 precision = 6;
   4675                 if (dp->precision_start != dp->precision_end)
   4676                   {
   4677                     if (dp->precision_arg_index != ARG_NONE)
   4678                       {
   4679                         int arg;
   4680 
   4681                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
   4682                           abort ();
   4683                         arg = a.arg[dp->precision_arg_index].a.a_int;
   4684                         /* "A negative precision is taken as if the precision
   4685                             were omitted."  */
   4686                         if (arg >= 0)
   4687                           {
   4688                             precision = arg;
   4689                             has_precision = 1;
   4690                           }
   4691                       }
   4692                     else
   4693                       {
   4694                         const FCHAR_T *digitp = dp->precision_start + 1;
   4695 
   4696                         precision = 0;
   4697                         while (digitp != dp->precision_end)
   4698                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
   4699                         has_precision = 1;
   4700                       }
   4701                   }
   4702 #endif
   4703 
   4704                 /* Decide whether to handle the precision ourselves.  */
   4705 #if NEED_PRINTF_UNBOUNDED_PRECISION
   4706                 switch (dp->conversion)
   4707                   {
   4708                   case 'd': case 'i': case 'u':
   4709                   case 'o':
   4710                   case 'x': case 'X': case 'p':
   4711                     prec_ourselves = has_precision && (precision > 0);
   4712                     break;
   4713                   default:
   4714                     prec_ourselves = 0;
   4715                     break;
   4716                   }
   4717 #endif
   4718 
   4719                 /* Decide whether to perform the padding ourselves.  */
   4720 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
   4721                 switch (dp->conversion)
   4722                   {
   4723 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
   4724                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
   4725                      to perform the padding after this conversion.  Functions
   4726                      with unistdio extensions perform the padding based on
   4727                      character count rather than element count.  */
   4728                   case 'c': case 's':
   4729 # endif
   4730 # if NEED_PRINTF_FLAG_ZERO
   4731                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
   4732                   case 'a': case 'A':
   4733 # endif
   4734                     pad_ourselves = 1;
   4735                     break;
   4736                   default:
   4737                     pad_ourselves = prec_ourselves;
   4738                     break;
   4739                   }
   4740 #endif
   4741 
   4742 #if !USE_SNPRINTF
   4743                 /* Allocate a temporary buffer of sufficient size for calling
   4744                    sprintf.  */
   4745                 tmp_length =
   4746                   MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
   4747                                    flags, width, has_precision, precision,
   4748                                    pad_ourselves);
   4749 
   4750                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
   4751                   tmp = tmpbuf;
   4752                 else
   4753                   {
   4754                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
   4755 
   4756                     if (size_overflow_p (tmp_memsize))
   4757                       /* Overflow, would lead to out of memory.  */
   4758                       goto out_of_memory;
   4759                     tmp = (TCHAR_T *) malloc (tmp_memsize);
   4760                     if (tmp == NULL)
   4761                       /* Out of memory.  */
   4762                       goto out_of_memory;
   4763                   }
   4764 #endif
   4765 
   4766                 /* Construct the format string for calling snprintf or
   4767                    sprintf.  */
   4768                 fbp = buf;
   4769                 *fbp++ = '%';
   4770 #if NEED_PRINTF_FLAG_GROUPING
   4771                 /* The underlying implementation doesn't support the ' flag.
   4772                    Produce no grouping characters in this case; this is
   4773                    acceptable because the grouping is locale dependent.  */
   4774 #else
   4775                 if (flags & FLAG_GROUP)
   4776                   *fbp++ = '\'';
   4777 #endif
   4778                 if (flags & FLAG_LEFT)
   4779                   *fbp++ = '-';
   4780                 if (flags & FLAG_SHOWSIGN)
   4781                   *fbp++ = '+';
   4782                 if (flags & FLAG_SPACE)
   4783                   *fbp++ = ' ';
   4784                 if (flags & FLAG_ALT)
   4785                   *fbp++ = '#';
   4786 #if __GLIBC__ >= 2 && !defined __UCLIBC__
   4787                 if (flags & FLAG_LOCALIZED)
   4788                   *fbp++ = 'I';
   4789 #endif
   4790                 if (!pad_ourselves)
   4791                   {
   4792                     if (flags & FLAG_ZERO)
   4793                       *fbp++ = '0';
   4794                     if (dp->width_start != dp->width_end)
   4795                       {
   4796                         size_t n = dp->width_end - dp->width_start;
   4797                         /* The width specification is known to consist only
   4798                            of standard ASCII characters.  */
   4799                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
   4800                           {
   4801                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
   4802                             fbp += n;
   4803                           }
   4804                         else
   4805                           {
   4806                             const FCHAR_T *mp = dp->width_start;
   4807                             do
   4808                               *fbp++ = (unsigned char) *mp++;
   4809                             while (--n > 0);
   4810                           }
   4811                       }
   4812                   }
   4813                 if (!prec_ourselves)
   4814                   {
   4815                     if (dp->precision_start != dp->precision_end)
   4816                       {
   4817                         size_t n = dp->precision_end - dp->precision_start;
   4818                         /* The precision specification is known to consist only
   4819                            of standard ASCII characters.  */
   4820                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
   4821                           {
   4822                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
   4823                             fbp += n;
   4824                           }
   4825                         else
   4826                           {
   4827                             const FCHAR_T *mp = dp->precision_start;
   4828                             do
   4829                               *fbp++ = (unsigned char) *mp++;
   4830                             while (--n > 0);
   4831                           }
   4832                       }
   4833                   }
   4834 
   4835                 switch (type)
   4836                   {
   4837 #if HAVE_LONG_LONG_INT
   4838                   case TYPE_LONGLONGINT:
   4839                   case TYPE_ULONGLONGINT:
   4840 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
   4841                     *fbp++ = 'I';
   4842                     *fbp++ = '6';
   4843                     *fbp++ = '4';
   4844                     break;
   4845 # else
   4846                     *fbp++ = 'l';
   4847                     /*FALLTHROUGH*/
   4848 # endif
   4849 #endif
   4850                   case TYPE_LONGINT:
   4851                   case TYPE_ULONGINT:
   4852 #if HAVE_WINT_T
   4853                   case TYPE_WIDE_CHAR:
   4854 #endif
   4855 #if HAVE_WCHAR_T
   4856                   case TYPE_WIDE_STRING:
   4857 #endif
   4858                     *fbp++ = 'l';
   4859                     break;
   4860                   case TYPE_LONGDOUBLE:
   4861                     *fbp++ = 'L';
   4862                     break;
   4863                   default:
   4864                     break;
   4865                   }
   4866 #if NEED_PRINTF_DIRECTIVE_F
   4867                 if (dp->conversion == 'F')
   4868                   *fbp = 'f';
   4869                 else
   4870 #endif
   4871                   *fbp = dp->conversion;
   4872 #if USE_SNPRINTF
   4873 # if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
   4874                 fbp[1] = '%';
   4875                 fbp[2] = 'n';
   4876                 fbp[3] = '\0';
   4877 # else
   4878                 /* On glibc2 systems from glibc >= 2.3 - probably also older
   4879                    ones - we know that snprintf's return value conforms to
   4880                    ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
   4881                    gl_SNPRINTF_TRUNCATION_C99 pass.
   4882                    Therefore we can avoid using %n in this situation.
   4883                    On glibc2 systems from 2004-10-18 or newer, the use of %n
   4884                    in format strings in writable memory may crash the program
   4885                    (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
   4886                    in this situation.  */
   4887                 /* On native Windows systems (such as mingw), we can avoid using
   4888                    %n because:
   4889                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
   4890                        snprintf does not write more than the specified number
   4891                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
   4892                        '4', '5', '6' into buf, not '4', '5', '\0'.)
   4893                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
   4894                        allows us to recognize the case of an insufficient
   4895                        buffer size: it returns -1 in this case.
   4896                    On native Windows systems (such as mingw) where the OS is
   4897                    Windows Vista, the use of %n in format strings by default
   4898                    crashes the program. See
   4899                      <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
   4900                      <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
   4901                    So we should avoid %n in this situation.  */
   4902                 fbp[1] = '\0';
   4903 # endif
   4904 #else
   4905                 fbp[1] = '\0';
   4906 #endif
   4907 
   4908                 /* Construct the arguments for calling snprintf or sprintf.  */
   4909                 prefix_count = 0;
   4910                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
   4911                   {
   4912                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
   4913                       abort ();
   4914                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
   4915                   }
   4916                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
   4917                   {
   4918                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
   4919                       abort ();
   4920                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
   4921                   }
   4922 
   4923 #if USE_SNPRINTF
   4924                 /* The SNPRINTF result is appended after result[0..length].
   4925                    The latter is an array of DCHAR_T; SNPRINTF appends an
   4926                    array of TCHAR_T to it.  This is possible because
   4927                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
   4928                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
   4929 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
   4930                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
   4931                    where an snprintf() with maxlen==1 acts like sprintf().  */
   4932                 ENSURE_ALLOCATION (xsum (length,
   4933                                          (2 + TCHARS_PER_DCHAR - 1)
   4934                                          / TCHARS_PER_DCHAR));
   4935                 /* Prepare checking whether snprintf returns the count
   4936                    via %n.  */
   4937                 *(TCHAR_T *) (result + length) = '\0';
   4938 #endif
   4939 
   4940                 orig_errno = errno;
   4941 
   4942                 for (;;)
   4943                   {
   4944                     int count = -1;
   4945 
   4946 #if USE_SNPRINTF
   4947                     int retcount = 0;
   4948                     size_t maxlen = allocated - length;
   4949                     /* SNPRINTF can fail if its second argument is
   4950                        > INT_MAX.  */
   4951                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
   4952                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
   4953                     maxlen = maxlen * TCHARS_PER_DCHAR;
   4954 # define SNPRINTF_BUF(arg) \
   4955                     switch (prefix_count)                                   \
   4956                       {                                                     \
   4957                       case 0:                                               \
   4958                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
   4959                                              maxlen, buf,                   \
   4960                                              arg, &count);                  \
   4961                         break;                                              \
   4962                       case 1:                                               \
   4963                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
   4964                                              maxlen, buf,                   \
   4965                                              prefixes[0], arg, &count);     \
   4966                         break;                                              \
   4967                       case 2:                                               \
   4968                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
   4969                                              maxlen, buf,                   \
   4970                                              prefixes[0], prefixes[1], arg, \
   4971                                              &count);                       \
   4972                         break;                                              \
   4973                       default:                                              \
   4974                         abort ();                                           \
   4975                       }
   4976 #else
   4977 # define SNPRINTF_BUF(arg) \
   4978                     switch (prefix_count)                                   \
   4979                       {                                                     \
   4980                       case 0:                                               \
   4981                         count = sprintf (tmp, buf, arg);                    \
   4982                         break;                                              \
   4983                       case 1:                                               \
   4984                         count = sprintf (tmp, buf, prefixes[0], arg);       \
   4985                         break;                                              \
   4986                       case 2:                                               \
   4987                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
   4988                                          arg);                              \
   4989                         break;                                              \
   4990                       default:                                              \
   4991                         abort ();                                           \
   4992                       }
   4993 #endif
   4994 
   4995                     errno = 0;
   4996                     switch (type)
   4997                       {
   4998                       case TYPE_SCHAR:
   4999                         {
   5000                           int arg = a.arg[dp->arg_index].a.a_schar;
   5001                           SNPRINTF_BUF (arg);
   5002                         }
   5003                         break;
   5004                       case TYPE_UCHAR:
   5005                         {
   5006                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
   5007                           SNPRINTF_BUF (arg);
   5008                         }
   5009                         break;
   5010                       case TYPE_SHORT:
   5011                         {
   5012                           int arg = a.arg[dp->arg_index].a.a_short;
   5013                           SNPRINTF_BUF (arg);
   5014                         }
   5015                         break;
   5016                       case TYPE_USHORT:
   5017                         {
   5018                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
   5019                           SNPRINTF_BUF (arg);
   5020                         }
   5021                         break;
   5022                       case TYPE_INT:
   5023                         {
   5024                           int arg = a.arg[dp->arg_index].a.a_int;
   5025                           SNPRINTF_BUF (arg);
   5026                         }
   5027                         break;
   5028                       case TYPE_UINT:
   5029                         {
   5030                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
   5031                           SNPRINTF_BUF (arg);
   5032                         }
   5033                         break;
   5034                       case TYPE_LONGINT:
   5035                         {
   5036                           long int arg = a.arg[dp->arg_index].a.a_longint;
   5037                           SNPRINTF_BUF (arg);
   5038                         }
   5039                         break;
   5040                       case TYPE_ULONGINT:
   5041                         {
   5042                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
   5043                           SNPRINTF_BUF (arg);
   5044                         }
   5045                         break;
   5046 #if HAVE_LONG_LONG_INT
   5047                       case TYPE_LONGLONGINT:
   5048                         {
   5049                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
   5050                           SNPRINTF_BUF (arg);
   5051                         }
   5052                         break;
   5053                       case TYPE_ULONGLONGINT:
   5054                         {
   5055                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
   5056                           SNPRINTF_BUF (arg);
   5057                         }
   5058                         break;
   5059 #endif
   5060                       case TYPE_DOUBLE:
   5061                         {
   5062                           double arg = a.arg[dp->arg_index].a.a_double;
   5063                           SNPRINTF_BUF (arg);
   5064                         }
   5065                         break;
   5066                       case TYPE_LONGDOUBLE:
   5067                         {
   5068                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
   5069                           SNPRINTF_BUF (arg);
   5070                         }
   5071                         break;
   5072                       case TYPE_CHAR:
   5073                         {
   5074                           int arg = a.arg[dp->arg_index].a.a_char;
   5075                           SNPRINTF_BUF (arg);
   5076                         }
   5077                         break;
   5078 #if HAVE_WINT_T
   5079                       case TYPE_WIDE_CHAR:
   5080                         {
   5081                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
   5082                           SNPRINTF_BUF (arg);
   5083                         }
   5084                         break;
   5085 #endif
   5086                       case TYPE_STRING:
   5087                         {
   5088                           const char *arg = a.arg[dp->arg_index].a.a_string;
   5089                           SNPRINTF_BUF (arg);
   5090                         }
   5091                         break;
   5092 #if HAVE_WCHAR_T
   5093                       case TYPE_WIDE_STRING:
   5094                         {
   5095                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
   5096                           SNPRINTF_BUF (arg);
   5097                         }
   5098                         break;
   5099 #endif
   5100                       case TYPE_POINTER:
   5101                         {
   5102                           void *arg = a.arg[dp->arg_index].a.a_pointer;
   5103                           SNPRINTF_BUF (arg);
   5104                         }
   5105                         break;
   5106                       default:
   5107                         abort ();
   5108                       }
   5109 
   5110 #if USE_SNPRINTF
   5111                     /* Portability: Not all implementations of snprintf()
   5112                        are ISO C 99 compliant.  Determine the number of
   5113                        bytes that snprintf() has produced or would have
   5114                        produced.  */
   5115                     if (count >= 0)
   5116                       {
   5117                         /* Verify that snprintf() has NUL-terminated its
   5118                            result.  */
   5119                         if (count < maxlen
   5120                             && ((TCHAR_T *) (result + length)) [count] != '\0')
   5121                           abort ();
   5122                         /* Portability hack.  */
   5123                         if (retcount > count)
   5124                           count = retcount;
   5125                       }
   5126                     else
   5127                       {
   5128                         /* snprintf() doesn't understand the '%n'
   5129                            directive.  */
   5130                         if (fbp[1] != '\0')
   5131                           {
   5132                             /* Don't use the '%n' directive; instead, look
   5133                                at the snprintf() return value.  */
   5134                             fbp[1] = '\0';
   5135                             continue;
   5136                           }
   5137                         else
   5138                           {
   5139                             /* Look at the snprintf() return value.  */
   5140                             if (retcount < 0)
   5141                               {
   5142 # if !HAVE_SNPRINTF_RETVAL_C99
   5143                                 /* HP-UX 10.20 snprintf() is doubly deficient:
   5144                                    It doesn't understand the '%n' directive,
   5145                                    *and* it returns -1 (rather than the length
   5146                                    that would have been required) when the
   5147                                    buffer is too small.
   5148                                    But a failure at this point can also come
   5149                                    from other reasons than a too small buffer,
   5150                                    such as an invalid wide string argument to
   5151                                    the %ls directive, or possibly an invalid
   5152                                    floating-point argument.  */
   5153                                 size_t tmp_length =
   5154                                   MAX_ROOM_NEEDED (&a, dp->arg_index,
   5155                                                    dp->conversion, type, flags,
   5156                                                    width, has_precision,
   5157                                                    precision, pad_ourselves);
   5158 
   5159                                 if (maxlen < tmp_length)
   5160                                   {
   5161                                     /* Make more room.  But try to do through
   5162                                        this reallocation only once.  */
   5163                                     size_t bigger_need =
   5164                                       xsum (length,
   5165                                             xsum (tmp_length,
   5166                                                   TCHARS_PER_DCHAR - 1)
   5167                                             / TCHARS_PER_DCHAR);
   5168                                     /* And always grow proportionally.
   5169                                        (There may be several arguments, each
   5170                                        needing a little more room than the
   5171                                        previous one.)  */
   5172                                     size_t bigger_need2 =
   5173                                       xsum (xtimes (allocated, 2), 12);
   5174                                     if (bigger_need < bigger_need2)
   5175                                       bigger_need = bigger_need2;
   5176                                     ENSURE_ALLOCATION (bigger_need);
   5177                                     continue;
   5178                                   }
   5179 # endif
   5180                               }
   5181                             else
   5182                               count = retcount;
   5183                           }
   5184                       }
   5185 #endif
   5186 
   5187                     /* Attempt to handle failure.  */
   5188                     if (count < 0)
   5189                       {
   5190                         /* SNPRINTF or sprintf failed.  Save and use the errno
   5191                            that it has set, if any.  */
   5192                         int saved_errno = errno;
   5193 
   5194                         if (!(result == resultbuf || result == NULL))
   5195                           free (result);
   5196                         if (buf_malloced != NULL)
   5197                           free (buf_malloced);
   5198                         CLEANUP ();
   5199                         errno =
   5200                           (saved_errno != 0
   5201                            ? saved_errno
   5202                            : (dp->conversion == 'c' || dp->conversion == 's'
   5203                               ? EILSEQ
   5204                               : EINVAL));
   5205                         return NULL;
   5206                       }
   5207 
   5208 #if USE_SNPRINTF
   5209                     /* Handle overflow of the allocated buffer.
   5210                        If such an overflow occurs, a C99 compliant snprintf()
   5211                        returns a count >= maxlen.  However, a non-compliant
   5212                        snprintf() function returns only count = maxlen - 1.  To
   5213                        cover both cases, test whether count >= maxlen - 1.  */
   5214                     if ((unsigned int) count + 1 >= maxlen)
   5215                       {
   5216                         /* If maxlen already has attained its allowed maximum,
   5217                            allocating more memory will not increase maxlen.
   5218                            Instead of looping, bail out.  */
   5219                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
   5220                           goto overflow;
   5221                         else
   5222                           {
   5223                             /* Need at least (count + 1) * sizeof (TCHAR_T)
   5224                                bytes.  (The +1 is for the trailing NUL.)
   5225                                But ask for (count + 2) * sizeof (TCHAR_T)
   5226                                bytes, so that in the next round, we likely get
   5227                                  maxlen > (unsigned int) count + 1
   5228                                and so we don't get here again.
   5229                                And allocate proportionally, to avoid looping
   5230                                eternally if snprintf() reports a too small
   5231                                count.  */
   5232                             size_t n =
   5233                               xmax (xsum (length,
   5234                                           ((unsigned int) count + 2
   5235                                            + TCHARS_PER_DCHAR - 1)
   5236                                           / TCHARS_PER_DCHAR),
   5237                                     xtimes (allocated, 2));
   5238 
   5239                             ENSURE_ALLOCATION (n);
   5240                             continue;
   5241                           }
   5242                       }
   5243 #endif
   5244 
   5245 #if NEED_PRINTF_UNBOUNDED_PRECISION
   5246                     if (prec_ourselves)
   5247                       {
   5248                         /* Handle the precision.  */
   5249                         TCHAR_T *prec_ptr =
   5250 # if USE_SNPRINTF
   5251                           (TCHAR_T *) (result + length);
   5252 # else
   5253                           tmp;
   5254 # endif
   5255                         size_t prefix_count;
   5256                         size_t move;
   5257 
   5258                         prefix_count = 0;
   5259                         /* Put the additional zeroes after the sign.  */
   5260                         if (count >= 1
   5261                             && (*prec_ptr == '-' || *prec_ptr == '+'
   5262                                 || *prec_ptr == ' '))
   5263                           prefix_count = 1;
   5264                         /* Put the additional zeroes after the 0x prefix if
   5265                            (flags & FLAG_ALT) || (dp->conversion == 'p').  */
   5266                         else if (count >= 2
   5267                                  && prec_ptr[0] == '0'
   5268                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
   5269                           prefix_count = 2;
   5270 
   5271                         move = count - prefix_count;
   5272                         if (precision > move)
   5273                           {
   5274                             /* Insert zeroes.  */
   5275                             size_t insert = precision - move;
   5276                             TCHAR_T *prec_end;
   5277 
   5278 # if USE_SNPRINTF
   5279                             size_t n =
   5280                               xsum (length,
   5281                                     (count + insert + TCHARS_PER_DCHAR - 1)
   5282                                     / TCHARS_PER_DCHAR);
   5283                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
   5284                             ENSURE_ALLOCATION (n);
   5285                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
   5286                             prec_ptr = (TCHAR_T *) (result + length);
   5287 # endif
   5288 
   5289                             prec_end = prec_ptr + count;
   5290                             prec_ptr += prefix_count;
   5291 
   5292                             while (prec_end > prec_ptr)
   5293                               {
   5294                                 prec_end--;
   5295                                 prec_end[insert] = prec_end[0];
   5296                               }
   5297 
   5298                             prec_end += insert;
   5299                             do
   5300                               *--prec_end = '0';
   5301                             while (prec_end > prec_ptr);
   5302 
   5303                             count += insert;
   5304                           }
   5305                       }
   5306 #endif
   5307 
   5308 #if !USE_SNPRINTF
   5309                     if (count >= tmp_length)
   5310                       /* tmp_length was incorrectly calculated - fix the
   5311                          code above!  */
   5312                       abort ();
   5313 #endif
   5314 
   5315 #if !DCHAR_IS_TCHAR
   5316                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
   5317                     if (dp->conversion == 'c' || dp->conversion == 's')
   5318                       {
   5319                         /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
   5320                            TYPE_WIDE_STRING.
   5321                            The result string is not certainly ASCII.  */
   5322                         const TCHAR_T *tmpsrc;
   5323                         DCHAR_T *tmpdst;
   5324                         size_t tmpdst_len;
   5325                         /* This code assumes that TCHAR_T is 'char'.  */
   5326                         verify (sizeof (TCHAR_T) == 1);
   5327 # if USE_SNPRINTF
   5328                         tmpsrc = (TCHAR_T *) (result + length);
   5329 # else
   5330                         tmpsrc = tmp;
   5331 # endif
   5332                         tmpdst =
   5333                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
   5334                                                     iconveh_question_mark,
   5335                                                     tmpsrc, count,
   5336                                                     NULL,
   5337                                                     NULL, &tmpdst_len);
   5338                         if (tmpdst == NULL)
   5339                           {
   5340                             int saved_errno = errno;
   5341                             if (!(result == resultbuf || result == NULL))
   5342                               free (result);
   5343                             if (buf_malloced != NULL)
   5344                               free (buf_malloced);
   5345                             CLEANUP ();
   5346                             errno = saved_errno;
   5347                             return NULL;
   5348                           }
   5349                         ENSURE_ALLOCATION (xsum (length, tmpdst_len));
   5350                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
   5351                         free (tmpdst);
   5352                         count = tmpdst_len;
   5353                       }
   5354                     else
   5355                       {
   5356                         /* The result string is ASCII.
   5357                            Simple 1:1 conversion.  */
   5358 # if USE_SNPRINTF
   5359                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
   5360                            no-op conversion, in-place on the array starting
   5361                            at (result + length).  */
   5362                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
   5363 # endif
   5364                           {
   5365                             const TCHAR_T *tmpsrc;
   5366                             DCHAR_T *tmpdst;
   5367                             size_t n;
   5368 
   5369 # if USE_SNPRINTF
   5370                             if (result == resultbuf)
   5371                               {
   5372                                 tmpsrc = (TCHAR_T *) (result + length);
   5373                                 /* ENSURE_ALLOCATION will not move tmpsrc
   5374                                    (because it's part of resultbuf).  */
   5375                                 ENSURE_ALLOCATION (xsum (length, count));
   5376                               }
   5377                             else
   5378                               {
   5379                                 /* ENSURE_ALLOCATION will move the array
   5380                                    (because it uses realloc().  */
   5381                                 ENSURE_ALLOCATION (xsum (length, count));
   5382                                 tmpsrc = (TCHAR_T *) (result + length);
   5383                               }
   5384 # else
   5385                             tmpsrc = tmp;
   5386                             ENSURE_ALLOCATION (xsum (length, count));
   5387 # endif
   5388                             tmpdst = result + length;
   5389                             /* Copy backwards, because of overlapping.  */
   5390                             tmpsrc += count;
   5391                             tmpdst += count;
   5392                             for (n = count; n > 0; n--)
   5393                               *--tmpdst = (unsigned char) *--tmpsrc;
   5394                           }
   5395                       }
   5396 #endif
   5397 
   5398 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
   5399                     /* Make room for the result.  */
   5400                     if (count > allocated - length)
   5401                       {
   5402                         /* Need at least count elements.  But allocate
   5403                            proportionally.  */
   5404                         size_t n =
   5405                           xmax (xsum (length, count), xtimes (allocated, 2));
   5406 
   5407                         ENSURE_ALLOCATION (n);
   5408                       }
   5409 #endif
   5410 
   5411                     /* Here count <= allocated - length.  */
   5412 
   5413                     /* Perform padding.  */
   5414 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
   5415                     if (pad_ourselves && has_width)
   5416                       {
   5417                         size_t w;
   5418 # if ENABLE_UNISTDIO
   5419                         /* Outside POSIX, it's preferable to compare the width
   5420                            against the number of _characters_ of the converted
   5421                            value.  */
   5422                         w = DCHAR_MBSNLEN (result + length, count);
   5423 # else
   5424                         /* The width is compared against the number of _bytes_
   5425                            of the converted value, says POSIX.  */
   5426                         w = count;
   5427 # endif
   5428                         if (w < width)
   5429                           {
   5430                             size_t pad = width - w;
   5431 
   5432                             /* Make room for the result.  */
   5433                             if (xsum (count, pad) > allocated - length)
   5434                               {
   5435                                 /* Need at least count + pad elements.  But
   5436                                    allocate proportionally.  */
   5437                                 size_t n =
   5438                                   xmax (xsum3 (length, count, pad),
   5439                                         xtimes (allocated, 2));
   5440 
   5441 # if USE_SNPRINTF
   5442                                 length += count;
   5443                                 ENSURE_ALLOCATION (n);
   5444                                 length -= count;
   5445 # else
   5446                                 ENSURE_ALLOCATION (n);
   5447 # endif
   5448                               }
   5449                             /* Here count + pad <= allocated - length.  */
   5450 
   5451                             {
   5452 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
   5453                               DCHAR_T * const rp = result + length;
   5454 # else
   5455                               DCHAR_T * const rp = tmp;
   5456 # endif
   5457                               DCHAR_T *p = rp + count;
   5458                               DCHAR_T *end = p + pad;
   5459                               DCHAR_T *pad_ptr;
   5460 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
   5461                               if (dp->conversion == 'c'
   5462                                   || dp->conversion == 's')
   5463                                 /* No zero-padding for string directives.  */
   5464                                 pad_ptr = NULL;
   5465                               else
   5466 # endif
   5467                                 {
   5468                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
   5469                                   /* No zero-padding of "inf" and "nan".  */
   5470                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
   5471                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
   5472                                     pad_ptr = NULL;
   5473                                 }
   5474                               /* The generated string now extends from rp to p,
   5475                                  with the zero padding insertion point being at
   5476                                  pad_ptr.  */
   5477 
   5478                               count = count + pad; /* = end - rp */
   5479 
   5480                               if (flags & FLAG_LEFT)
   5481                                 {
   5482                                   /* Pad with spaces on the right.  */
   5483                                   for (; pad > 0; pad--)
   5484                                     *p++ = ' ';
   5485                                 }
   5486                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
   5487                                 {
   5488                                   /* Pad with zeroes.  */
   5489                                   DCHAR_T *q = end;
   5490 
   5491                                   while (p > pad_ptr)
   5492                                     *--q = *--p;
   5493                                   for (; pad > 0; pad--)
   5494                                     *p++ = '0';
   5495                                 }
   5496                               else
   5497                                 {
   5498                                   /* Pad with spaces on the left.  */
   5499                                   DCHAR_T *q = end;
   5500 
   5501                                   while (p > rp)
   5502                                     *--q = *--p;
   5503                                   for (; pad > 0; pad--)
   5504                                     *p++ = ' ';
   5505                                 }
   5506                             }
   5507                           }
   5508                       }
   5509 #endif
   5510 
   5511                     /* Here still count <= allocated - length.  */
   5512 
   5513 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
   5514                     /* The snprintf() result did fit.  */
   5515 #else
   5516                     /* Append the sprintf() result.  */
   5517                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
   5518 #endif
   5519 #if !USE_SNPRINTF
   5520                     if (tmp != tmpbuf)
   5521                       free (tmp);
   5522 #endif
   5523 
   5524 #if NEED_PRINTF_DIRECTIVE_F
   5525                     if (dp->conversion == 'F')
   5526                       {
   5527                         /* Convert the %f result to upper case for %F.  */
   5528                         DCHAR_T *rp = result + length;
   5529                         size_t rc;
   5530                         for (rc = count; rc > 0; rc--, rp++)
   5531                           if (*rp >= 'a' && *rp <= 'z')
   5532                             *rp = *rp - 'a' + 'A';
   5533                       }
   5534 #endif
   5535 
   5536                     length += count;
   5537                     break;
   5538                   }
   5539                 errno = orig_errno;
   5540 #undef pad_ourselves
   5541 #undef prec_ourselves
   5542               }
   5543           }
   5544       }
   5545 
   5546     /* Add the final NUL.  */
   5547     ENSURE_ALLOCATION (xsum (length, 1));
   5548     result[length] = '\0';
   5549 
   5550     if (result != resultbuf && length + 1 < allocated)
   5551       {
   5552         /* Shrink the allocated memory if possible.  */
   5553         DCHAR_T *memory;
   5554 
   5555         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
   5556         if (memory != NULL)
   5557           result = memory;
   5558       }
   5559 
   5560     if (buf_malloced != NULL)
   5561       free (buf_malloced);
   5562     CLEANUP ();
   5563     *lengthp = length;
   5564     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
   5565        says that snprintf() fails with errno = EOVERFLOW in this case, but
   5566        that's only because snprintf() returns an 'int'.  This function does
   5567        not have this limitation.  */
   5568     return result;
   5569 
   5570 #if USE_SNPRINTF
   5571   overflow:
   5572     if (!(result == resultbuf || result == NULL))
   5573       free (result);
   5574     if (buf_malloced != NULL)
   5575       free (buf_malloced);
   5576     CLEANUP ();
   5577     errno = EOVERFLOW;
   5578     return NULL;
   5579 #endif
   5580 
   5581   out_of_memory:
   5582     if (!(result == resultbuf || result == NULL))
   5583       free (result);
   5584     if (buf_malloced != NULL)
   5585       free (buf_malloced);
   5586   out_of_memory_1:
   5587     CLEANUP ();
   5588     errno = ENOMEM;
   5589     return NULL;
   5590   }
   5591 }
   5592 
   5593 #undef MAX_ROOM_NEEDED
   5594 #undef TCHARS_PER_DCHAR
   5595 #undef SNPRINTF
   5596 #undef USE_SNPRINTF
   5597 #undef DCHAR_SET
   5598 #undef DCHAR_CPY
   5599 #undef PRINTF_PARSE
   5600 #undef DIRECTIVES
   5601 #undef DIRECTIVE
   5602 #undef DCHAR_IS_TCHAR
   5603 #undef TCHAR_T
   5604 #undef DCHAR_T
   5605 #undef FCHAR_T
   5606 #undef VASNPRINTF
   5607