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