"Fossies" - the Fresh Open Source Software Archive

Member "bison-3.4.1/lib/vasnprintf.c" (21 Apr 2019, 225166 Bytes) of package /linux/misc/bison-3.4.1.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "vasnprintf.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 3.3.2_vs_3.4.

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