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