LCOV - code coverage report
Current view: top level - lib - vasnprintf.c (source / functions) Hit Total Coverage
Test: coreutils.info Lines: 136 361 37.7 %
Date: 2018-01-30 Functions: 2 2 100.0 %

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

Generated by: LCOV version 1.10