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