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