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