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