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