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