Add support for 'long double' number output.
[gnulib.git] / lib / 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 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
19    This must come before <config.h> because <config.h> may include
20    <features.h>, and once <features.h> has been included, it's too late.  */
21 #ifndef _GNU_SOURCE
22 # define _GNU_SOURCE    1
23 #endif
24
25 #include <config.h>
26 #ifndef IN_LIBINTL
27 # include <alloca.h>
28 #endif
29
30 /* Specification.  */
31 #if WIDE_CHAR_VERSION
32 # include "vasnwprintf.h"
33 #else
34 # include "vasnprintf.h"
35 #endif
36
37 #include <locale.h>     /* localeconv() */
38 #include <stdio.h>      /* snprintf(), sprintf() */
39 #include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
40 #include <string.h>     /* memcpy(), strlen() */
41 #include <errno.h>      /* errno */
42 #include <limits.h>     /* CHAR_BIT */
43 #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP */
44 #if HAVE_NL_LANGINFO
45 # include <langinfo.h>
46 #endif
47 #if WIDE_CHAR_VERSION
48 # include "wprintf-parse.h"
49 #else
50 # include "printf-parse.h"
51 #endif
52
53 /* Checked size_t computations.  */
54 #include "xsize.h"
55
56 #if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
57 # include <math.h>
58 # include "isnan.h"
59 # include "printf-frexp.h"
60 # include "isnanl-nolibm.h"
61 # include "printf-frexpl.h"
62 # include "fpucw.h"
63 #endif
64
65 #if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
66 # include <math.h>
67 # include "float+.h"
68 #endif
69
70 /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
71 #ifndef EOVERFLOW
72 # define EOVERFLOW E2BIG
73 #endif
74
75 #if HAVE_WCHAR_T
76 # if HAVE_WCSLEN
77 #  define local_wcslen wcslen
78 # else
79    /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
80       a dependency towards this library, here is a local substitute.
81       Define this substitute only once, even if this file is included
82       twice in the same compilation unit.  */
83 #  ifndef local_wcslen_defined
84 #   define local_wcslen_defined 1
85 static size_t
86 local_wcslen (const wchar_t *s)
87 {
88   const wchar_t *ptr;
89
90   for (ptr = s; *ptr != (wchar_t) 0; ptr++)
91     ;
92   return ptr - s;
93 }
94 #  endif
95 # endif
96 #endif
97
98 #if WIDE_CHAR_VERSION
99 # define VASNPRINTF vasnwprintf
100 # define CHAR_T wchar_t
101 # define DIRECTIVE wchar_t_directive
102 # define DIRECTIVES wchar_t_directives
103 # define PRINTF_PARSE wprintf_parse
104 # define USE_SNPRINTF 1
105 # if HAVE_DECL__SNWPRINTF
106    /* On Windows, the function swprintf() has a different signature than
107       on Unix; we use the _snwprintf() function instead.  */
108 #  define SNPRINTF _snwprintf
109 # else
110    /* Unix.  */
111 #  define SNPRINTF swprintf
112 # endif
113 #else
114 # define VASNPRINTF vasnprintf
115 # define CHAR_T char
116 # define DIRECTIVE char_directive
117 # define DIRECTIVES char_directives
118 # define PRINTF_PARSE printf_parse
119 # /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
120      But don't use it on BeOS, since BeOS snprintf produces no output if the
121      size argument is >= 0x3000000.  */
122 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__
123 #  define USE_SNPRINTF 1
124 # else
125 #  define USE_SNPRINTF 0
126 # endif
127 # if HAVE_DECL__SNPRINTF
128    /* Windows.  */
129 #  define SNPRINTF _snprintf
130 # else
131    /* Unix.  */
132 #  define SNPRINTF snprintf
133    /* Here we need to call the native snprintf, not rpl_snprintf.  */
134 #  undef snprintf
135 # endif
136 #endif
137 /* Here we need to call the native sprintf, not rpl_sprintf.  */
138 #undef sprintf
139
140 #if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
141 /* Determine the decimal-point character according to the current locale.  */
142 # ifndef decimal_point_char_defined
143 #  define decimal_point_char_defined 1
144 static char
145 decimal_point_char ()
146 {
147   const char *point;
148   /* Determine it in a multithread-safe way.  We know nl_langinfo is
149      multithread-safe on glibc systems, but is not required to be multithread-
150      safe by POSIX.  sprintf(), however, is multithread-safe.  localeconv()
151      is rarely multithread-safe.  */
152 #  if HAVE_NL_LANGINFO && __GLIBC__
153   point = nl_langinfo (RADIXCHAR);
154 #  elif 1
155   char pointbuf[5];
156   sprintf (pointbuf, "%#.0f", 1.0);
157   point = &pointbuf[1];
158 #  else
159   point = localeconv () -> decimal_point;
160 #  endif
161   /* The decimal point is always a single byte: either '.' or ','.  */
162   return (point[0] != '\0' ? point[0] : '.');
163 }
164 # endif
165 #endif
166
167 #if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
168
169 /* Converting 'long double' to decimal without rare rounding bugs requires
170    real bignums.  We use the naming conventions of GNU gmp, but vastly simpler
171    (and slower) algorithms.  */
172
173 typedef unsigned int mp_limb_t;
174 # define GMP_LIMB_BITS 32
175 typedef int mp_limb_verify[2 * (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS) - 1];
176
177 typedef unsigned long long mp_twolimb_t;
178 # define GMP_TWOLIMB_BITS 64
179 typedef int mp_twolimb_verify[2 * (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS) - 1];
180
181 /* Representation of a bignum >= 0.  */
182 typedef struct
183 {
184   size_t nlimbs;
185   mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc().  */
186 } mpn_t;
187
188 /* Compute the product of two bignums >= 0.
189    Return the allocated memory in case of success, NULL in case of memory
190    allocation failure.  */
191 static void *
192 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
193 {
194   const mp_limb_t *p1;
195   const mp_limb_t *p2;
196   size_t len1;
197   size_t len2;
198
199   if (src1.nlimbs <= src2.nlimbs)
200     {
201       len1 = src1.nlimbs;
202       p1 = src1.limbs;
203       len2 = src2.nlimbs;
204       p2 = src2.limbs;
205     }
206   else
207     {
208       len1 = src2.nlimbs;
209       p1 = src2.limbs;
210       len2 = src1.nlimbs;
211       p2 = src1.limbs;
212     }
213   /* Now 0 <= len1 <= len2.  */
214   if (len1 == 0)
215     {
216       /* src1 or src2 is zero.  */
217       dest->nlimbs = 0;
218       dest->limbs = (mp_limb_t *) malloc (1);
219     }
220   else
221     {
222       /* Here 1 <= len1 <= len2.  */
223       size_t dlen;
224       mp_limb_t *dp;
225       size_t k, i, j;
226
227       dlen = len1 + len2;
228       dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
229       if (dp == NULL)
230         return NULL;
231       for (k = len2; k > 0; )
232         dp[--k] = 0;
233       for (i = 0; i < len1; i++)
234         {
235           mp_limb_t digit1 = p1[i];
236           mp_twolimb_t carry = 0;
237           for (j = 0; j < len2; j++)
238             {
239               mp_limb_t digit2 = p2[j];
240               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
241               carry += dp[i + j];
242               dp[i + j] = (mp_limb_t) carry;
243               carry = carry >> GMP_LIMB_BITS;
244             }
245           dp[i + len2] = (mp_limb_t) carry;
246         }
247       /* Normalise.  */
248       while (dlen > 0 && dp[dlen - 1] == 0)
249         dlen--;
250       dest->nlimbs = dlen;
251       dest->limbs = dp;
252     }
253   return dest->limbs;
254 }
255
256 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
257    a is written as  a = q * b + r  with 0 <= r < b.  q is the quotient, r
258    the remainder.
259    Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
260    q is incremented.
261    Return the allocated memory in case of success, NULL in case of memory
262    allocation failure.  */
263 static void *
264 divide (mpn_t a, mpn_t b, mpn_t *q)
265 {
266   /* Algorithm:
267      First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
268      with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
269      If m<n, then q:=0 and r:=a.
270      If m>=n=1, perform a single-precision division:
271        r:=0, j:=m,
272        while j>0 do
273          {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
274                = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
275          j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
276        Normalise [q[m-1],...,q[0]], yields q.
277      If m>=n>1, perform a multiple-precision division:
278        We have a/b < beta^(m-n+1).
279        s:=intDsize-1-(hightest bit in b[n-1]), 0<=s<intDsize.
280        Shift a and b left by s bits, copying them. r:=a.
281        r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
282        For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
283          Compute q* :
284            q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
285            In case of overflow (q* >= beta) set q* := beta-1.
286            Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
287            and c3 := b[n-2] * q*.
288            {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
289             occurred.  Furthermore 0 <= c3 < beta^2.
290             If there was overflow and
291             r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
292             the next test can be skipped.}
293            While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
294              Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
295            If q* > 0:
296              Put r := r - b * q* * beta^j. In detail:
297                [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
298                hence: u:=0, for i:=0 to n-1 do
299                               u := u + q* * b[i],
300                               r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
301                               u:=u div beta (+ 1, if carry in subtraction)
302                       r[n+j]:=r[n+j]-u.
303                {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
304                                < q* + 1 <= beta,
305                 the carry u does not overflow.}
306              If a negative carry occurs, put q* := q* - 1
307                and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
308          Set q[j] := q*.
309        Normalise [q[m-n],..,q[0]]; this yields the quotient q.
310        Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
311        rest r.
312        The room for q[j] can be allocated at the memory location of r[n+j].
313      Finally, round-to-even:
314        Shift r left by 1 bit.
315        If r > b or if r = b and q[0] is odd, q := q+1.
316    */
317   const mp_limb_t *a_ptr = a.limbs;
318   size_t a_len = a.nlimbs;
319   const mp_limb_t *b_ptr = b.limbs;
320   size_t b_len = b.nlimbs;
321   mp_limb_t *roomptr;
322   mp_limb_t *tmp_roomptr = NULL;
323   mp_limb_t *q_ptr;
324   size_t q_len;
325   mp_limb_t *r_ptr;
326   size_t r_len;
327
328   /* Allocate room for a_len+2 digits.
329      (Need a_len+1 digits for the real division and 1 more digit for the
330      final rounding of q.)  */
331   roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
332   if (roomptr == NULL)
333     return NULL;
334
335   /* Normalise a.  */
336   while (a_len > 0 && a_ptr[a_len - 1] == 0)
337     a_len--;
338
339   /* Normalise b.  */
340   for (;;)
341     {
342       if (b_len == 0)
343         /* Division by zero.  */
344         abort ();
345       if (b_ptr[b_len - 1] == 0)
346         b_len--;
347       else
348         break;
349     }
350
351   /* Here m = a_len >= 0 and n = b_len > 0.  */
352
353   if (a_len < b_len)
354     {
355       /* m<n: trivial case.  q=0, r := copy of a.  */
356       r_ptr = roomptr;
357       r_len = a_len;
358       memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
359       q_ptr = roomptr + a_len;
360       q_len = 0;
361     }
362   else if (b_len == 1)
363     {
364       /* n=1: single precision division.
365          beta^(m-1) <= a < beta^m  ==>  beta^(m-2) <= a/b < beta^m  */
366       r_ptr = roomptr;
367       q_ptr = roomptr + 1;
368       {
369         mp_limb_t den = b_ptr[0];
370         mp_limb_t remainder = 0;
371         const mp_limb_t *sourceptr = a_ptr + a_len;
372         mp_limb_t *destptr = q_ptr + a_len;
373         size_t count;
374         for (count = a_len; count > 0; count--)
375           {
376             mp_twolimb_t num =
377               ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
378             *--destptr = num / den;
379             remainder = num % den;
380           }
381         /* Normalise and store r.  */
382         if (remainder > 0)
383           {
384             r_ptr[0] = remainder;
385             r_len = 1;
386           }
387         else
388           r_len = 0;
389         /* Normalise q.  */
390         q_len = a_len;
391         if (q_ptr[q_len - 1] == 0)
392           q_len--;
393       }
394     }
395   else
396     {
397       /* n>1: multiple precision division.
398          beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n  ==>
399          beta^(m-n-1) <= a/b < beta^(m-n+1).  */
400       /* Determine s.  */
401       size_t s;
402       {
403         mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
404         s = 31;
405         if (msd >= 0x10000)
406           {
407             msd = msd >> 16;
408             s -= 16;
409           }
410         if (msd >= 0x100)
411           {
412             msd = msd >> 8;
413             s -= 8;
414           }
415         if (msd >= 0x10)
416           {
417             msd = msd >> 4;
418             s -= 4;
419           }
420         if (msd >= 0x4)
421           {
422             msd = msd >> 2;
423             s -= 2;
424           }
425         if (msd >= 0x2)
426           {
427             msd = msd >> 1;
428             s -= 1;
429           }
430       }
431       /* 0 <= s < GMP_LIMB_BITS.
432          Copy b, shifting it left by s bits.  */
433       if (s > 0)
434         {
435           tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
436           if (tmp_roomptr == NULL)
437             {
438               free (roomptr);
439               return NULL;
440             }
441           {
442             const mp_limb_t *sourceptr = b_ptr;
443             mp_limb_t *destptr = tmp_roomptr;
444             mp_twolimb_t accu = 0;
445             size_t count;
446             for (count = b_len; count > 0; count--)
447               {
448                 accu += (mp_twolimb_t) *sourceptr++ << s;
449                 *destptr++ = (mp_limb_t) accu;
450                 accu = accu >> GMP_LIMB_BITS;
451               }
452             /* accu must be zero, since that was how s was determined.  */
453             if (accu != 0)
454               abort ();
455           }
456           b_ptr = tmp_roomptr;
457         }
458       /* Copy a, shifting it left by s bits, yields r.
459          Memory layout:
460          At the beginning: r = roomptr[0..a_len],
461          at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len]  */
462       r_ptr = roomptr;
463       if (s == 0)
464         {
465           memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
466           r_ptr[a_len] = 0;
467         }
468       else
469         {
470           const mp_limb_t *sourceptr = a_ptr;
471           mp_limb_t *destptr = r_ptr;
472           mp_twolimb_t accu = 0;
473           size_t count;
474           for (count = a_len; count > 0; count--)
475             {
476               accu += (mp_twolimb_t) *sourceptr++ << s;
477               *destptr++ = (mp_limb_t) accu;
478               accu = accu >> GMP_LIMB_BITS;
479             }
480           *destptr++ = (mp_limb_t) accu;
481         }
482       q_ptr = roomptr + b_len;
483       q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
484       {
485         size_t j = a_len - b_len; /* m-n */
486         mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
487         mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
488         mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
489           ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
490         /* Division loop, traversed m-n+1 times.
491            j counts down, b is unchanged, beta/2 <= b[n-1] < beta.  */
492         for (;;)
493           {
494             mp_limb_t q_star;
495             mp_limb_t c1;
496             if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
497               {
498                 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow.  */
499                 mp_twolimb_t num =
500                   ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
501                   | r_ptr[j + b_len - 1];
502                 q_star = num / b_msd;
503                 c1 = num % b_msd;
504               }
505             else
506               {
507                 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1].  */
508                 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
509                 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
510                    <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
511                    <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
512                         {<= beta !}.
513                    If yes, jump directly to the subtraction loop.
514                    (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
515                     <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
516                 if (r_ptr[j + b_len] > b_msd
517                     || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
518                   /* r[j+n] >= b[n-1]+1 or
519                      r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
520                      carry.  */
521                   goto subtract;
522               }
523             /* q_star = q*,
524                c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta).  */
525             {
526               mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
527                 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
528               mp_twolimb_t c3 = /* b[n-2] * q* */
529                 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
530               /* While c2 < c3, increase c2 and decrease c3.
531                  Consider c3-c2.  While it is > 0, decrease it by
532                  b[n-1]*beta+b[n-2].  Because of b[n-1]*beta+b[n-2] >= beta^2/2
533                  this can happen only twice.  */
534               if (c3 > c2)
535                 {
536                   q_star = q_star - 1; /* q* := q* - 1 */
537                   if (c3 - c2 > b_msdd)
538                     q_star = q_star - 1; /* q* := q* - 1 */
539                 }
540             }
541             if (q_star > 0)
542               subtract:
543               {
544                 /* Subtract r := r - b * q* * beta^j.  */
545                 mp_limb_t cr;
546                 {
547                   const mp_limb_t *sourceptr = b_ptr;
548                   mp_limb_t *destptr = r_ptr + j;
549                   mp_twolimb_t carry = 0;
550                   size_t count;
551                   for (count = b_len; count > 0; count--)
552                     {
553                       /* Here 0 <= carry <= q*.  */
554                       carry =
555                         carry
556                         + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
557                         + (mp_limb_t) ~(*destptr);
558                       /* Here 0 <= carry <= beta*q* + beta-1.  */
559                       *destptr++ = ~(mp_limb_t) carry;
560                       carry = carry >> GMP_LIMB_BITS; /* <= q* */
561                     }
562                   cr = (mp_limb_t) carry;
563                 }
564                 /* Subtract cr from r_ptr[j + b_len], then forget about
565                    r_ptr[j + b_len].  */
566                 if (cr > r_ptr[j + b_len])
567                   {
568                     /* Subtraction gave a carry.  */
569                     q_star = q_star - 1; /* q* := q* - 1 */
570                     /* Add b back.  */
571                     {
572                       const mp_limb_t *sourceptr = b_ptr;
573                       mp_limb_t *destptr = r_ptr + j;
574                       mp_limb_t carry = 0;
575                       size_t count;
576                       for (count = b_len; count > 0; count--)
577                         {
578                           mp_limb_t source1 = *sourceptr++;
579                           mp_limb_t source2 = *destptr;
580                           *destptr++ = source1 + source2 + carry;
581                           carry =
582                             (carry
583                              ? source1 >= (mp_limb_t) ~source2
584                              : source1 > (mp_limb_t) ~source2);
585                         }
586                     }
587                     /* Forget about the carry and about r[j+n].  */
588                   }
589               }
590             /* q* is determined.  Store it as q[j].  */
591             q_ptr[j] = q_star;
592             if (j == 0)
593               break;
594             j--;
595           }
596       }
597       r_len = b_len;
598       /* Normalise q.  */
599       if (q_ptr[q_len - 1] == 0)
600         q_len--;
601 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
602           b is shifted left by s bits.  */
603       /* Shift r right by s bits.  */
604       if (s > 0)
605         {
606           mp_limb_t ptr = r_ptr + r_len;
607           mp_twolimb_t accu = 0;
608           size_t count;
609           for (count = r_len; count > 0; count--)
610             {
611               accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
612               accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
613               *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
614             }
615         }
616 # endif
617       /* Normalise r.  */
618       while (r_len > 0 && r_ptr[r_len - 1] == 0)
619         r_len--;
620     }
621   /* Compare r << 1 with b.  */
622   if (r_len > b_len)
623     goto increment_q;
624   {
625     size_t i;
626     for (i = b_len; i > 0; )
627       {
628         i--;
629         {
630           mp_limb_t r_i =
631             (i + 1 < r_len ? r_ptr[i + 1] >> (GMP_LIMB_BITS - 1) : 0)
632             | (i < r_len ? r_ptr[i] << 1 : 0);
633           mp_limb_t b_i = b_ptr[i];
634           if (r_i > b_i)
635             goto increment_q;
636           if (r_i < b_i)
637             goto keep_q;
638         }
639       }
640   }
641   if (q_len > 0 && ((q_ptr[0] & 1) != 0))
642     /* q is odd.  */
643     increment_q:
644     {
645       size_t i;
646       for (i = 0; i < q_len; i++)
647         if (++(q_ptr[i]) != 0)
648           goto keep_q;
649       q_ptr[q_len++] = 1;
650     }
651   keep_q:
652   if (tmp_roomptr != NULL)
653     free (tmp_roomptr);
654   q->limbs = q_ptr;
655   q->nlimbs = q_len;
656   return roomptr;
657 }
658
659 /* Convert a bignum a >= 0 to decimal representation.
660    Destroys the contents of a.
661    Return the allocated memory - containing the decimal digits in low-to-high
662    order, terminated with a NUL character - in case of success, NULL in case
663    of memory allocation failure.  */
664 static char *
665 convert_to_decimal (mpn_t a)
666 {
667   mp_limb_t *a_ptr = a.limbs;
668   size_t a_len = a.nlimbs;
669   /* 0.03345 is slightly larger than log(2)/(9*log(10)).  */
670   size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
671   char *c_ptr = (char *) malloc (c_len);
672   if (c_ptr != NULL)
673     {
674       char *d_ptr = c_ptr;
675       while (a_len > 0)
676         {
677           /* Divide a by 10^9, in-place.  */
678           mp_limb_t remainder = 0;
679           mp_limb_t *ptr = a_ptr + a_len;
680           size_t count;
681           for (count = a_len; count > 0; count--)
682             {
683               mp_twolimb_t num =
684                 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
685               *ptr = num / 1000000000;
686               remainder = num % 1000000000;
687             }
688           /* Store the remainder as 9 decimal digits.  */
689           for (count = 9; count > 0; count--)
690             {
691               *d_ptr++ = '0' + (remainder % 10);
692               remainder = remainder / 10;
693             }
694           /* Normalize a.  */
695           if (a_ptr[a_len - 1] == 0)
696             a_len--;
697         }
698       /* Remove leading zeroes.  */
699       while (d_ptr > c_ptr && d_ptr[-1] == '0')
700         d_ptr--;
701       /* But keep at least one zero.  */
702       if (d_ptr == c_ptr)
703         *d_ptr++ = '0';
704       /* Terminate the string.  */
705       *d_ptr = '\0';
706     }
707   return c_ptr;
708 }
709
710 /* Assuming x is finite and >= 0:
711    write x as x = 2^e * m, where m is a bignum.
712    Return the allocated memory in case of success, NULL in case of memory
713    allocation failure.  */
714 static void *
715 decode_long_double (long double x, int *ep, mpn_t *mp)
716 {
717   mpn_t m;
718   int exp;
719   long double y;
720   size_t i;
721
722   /* Allocate memory for result.  */
723   m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
724   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
725   if (m.limbs == NULL)
726     return NULL;
727   /* Split into exponential part and mantissa.  */
728   y = frexpl (x, &exp);
729   if (!(y >= 0.0L && y < 1.0L))
730     abort ();
731   /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
732      latter is an integer.  */
733   /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
734      I'm not sure whether it's safe to cast a 'long double' value between
735      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
736      'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
737      doesn't matter).  */
738 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
739 #  if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
740     {
741       mp_limb_t hi, lo;
742       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
743       hi = (int) y;
744       y -= hi;
745       if (!(y >= 0.0L && y < 1.0L))
746         abort ();
747       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
748       lo = (int) y;
749       y -= lo;
750       if (!(y >= 0.0L && y < 1.0L))
751         abort ();
752       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
753     }
754 #  else
755     {
756       mp_limb_t d;
757       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
758       d = (int) y;
759       y -= d;
760       if (!(y >= 0.0L && y < 1.0L))
761         abort ();
762       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
763     }
764 #  endif
765 # endif
766   for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
767     {
768       mp_limb_t hi, lo;
769       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
770       hi = (int) y;
771       y -= hi;
772       if (!(y >= 0.0L && y < 1.0L))
773         abort ();
774       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
775       lo = (int) y;
776       y -= lo;
777       if (!(y >= 0.0L && y < 1.0L))
778         abort ();
779       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
780     }
781   if (!(y == 0.0L))
782     abort ();
783   /* Normalise.  */
784   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
785     m.nlimbs--;
786   *mp = m;
787   *ep = exp - LDBL_MANT_BIT;
788   return m.limbs;
789 }
790
791 /* Assuming x is finite and >= 0, and n is an integer:
792    Compute y = round (x * 10^n) as a bignum >= 0.
793    Return the allocated memory in case of success, NULL in case of memory
794    allocation failure.  */
795 static void *
796 scale10_round_long_double (long double x, int n, mpn_t *yp)
797 {
798   int e;
799   mpn_t m;
800   void *memory = decode_long_double (x, &e, &m);
801   int s;
802   unsigned int abs_n;
803   unsigned int abs_s;
804   mp_limb_t *pow5_ptr;
805   size_t pow5_len;
806   unsigned int s_limbs;
807   unsigned int s_bits;
808   mpn_t pow5;
809
810   if (memory == NULL)
811     return NULL;
812   /* x = 2^e * m, hence
813      y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
814        = round (2^s * 5^n * m).  */
815   s = e + n;
816   /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
817      sign.  2.322 is slightly larger than log(5)/log(2).  */
818   abs_n = (n >= 0 ? n : -n);
819   abs_s = (s >= 0 ? s : -s);
820   pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
821                                     + abs_s / GMP_LIMB_BITS + 1)
822                                    * sizeof (mp_limb_t));
823   if (pow5_ptr == NULL)
824     {
825       free (memory);
826       return NULL;
827     }
828   /* Initialize with 1.  */
829   pow5_ptr[0] = 1;
830   pow5_len = 1;
831   /* Multiply with 5^|n|.  */
832   if (abs_n > 0)
833     {
834       static mp_limb_t const small_pow5[13 + 1] =
835         {
836           1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
837           48828125, 244140625, 1220703125
838         };
839       unsigned int n13;
840       for (n13 = 0; n13 <= abs_n; n13 += 13)
841         {
842           mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
843           size_t j;
844           mp_twolimb_t carry = 0;
845           for (j = 0; j < pow5_len; j++)
846             {
847               mp_limb_t digit2 = pow5_ptr[j];
848               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
849               pow5_ptr[j] = (mp_limb_t) carry;
850               carry = carry >> GMP_LIMB_BITS;
851             }
852           if (carry > 0)
853             pow5_ptr[pow5_len++] = (mp_limb_t) carry;
854         }
855     }
856   s_limbs = abs_s / GMP_LIMB_BITS;
857   s_bits = abs_s % GMP_LIMB_BITS;
858   if (n >= 0 ? s >= 0 : s <= 0)
859     {
860       /* Multiply with 2^|s|.  */
861       if (s_bits > 0)
862         {
863           mp_limb_t *ptr = pow5_ptr;
864           mp_twolimb_t accu = 0;
865           size_t count;
866           for (count = pow5_len; count > 0; count--)
867             {
868               accu += (mp_twolimb_t) *ptr << s_bits;
869               *ptr++ = (mp_limb_t) accu;
870               accu = accu >> GMP_LIMB_BITS;
871             }
872           if (accu > 0)
873             {
874               *ptr = (mp_limb_t) accu;
875               pow5_len++;
876             }
877         }
878       if (s_limbs > 0)
879         {
880           size_t count;
881           for (count = pow5_len; count > 0;)
882             {
883               count--;
884               pow5_ptr[s_limbs + count] = pow5_ptr[count];
885             }
886           for (count = s_limbs; count > 0;)
887             {
888               count--;
889               pow5_ptr[count] = 0;
890             }
891           pow5_len += s_limbs;
892         }
893       pow5.limbs = pow5_ptr;
894       pow5.nlimbs = pow5_len;
895       if (n >= 0)
896         {
897           /* Multiply m with pow5.  No division needed.  */
898           void *result_memory = multiply (m, pow5, yp);
899           free (pow5_ptr);
900           free (memory);
901           return result_memory;
902         }
903       else
904         {
905           /* Divide m by pow5 and round.  */
906           void *result_memory = divide (m, pow5, yp);
907           free (pow5_ptr);
908           free (memory);
909           return result_memory;
910         }
911     }
912   else
913     {
914       pow5.limbs = pow5_ptr;
915       pow5.nlimbs = pow5_len;
916       if (n >= 0)
917         {
918           /* n >= 0, s < 0.
919              Multiply m with pow5, then divide by 2^|s|.  */
920           mpn_t numerator;
921           mpn_t denominator;
922           void *tmp_memory;
923           void *result_memory;
924           tmp_memory = multiply (m, pow5, &numerator);
925           if (tmp_memory == NULL)
926             {
927               free (pow5_ptr);
928               free (memory);
929               return NULL;
930             }
931           /* Construct 2^|s|.  */
932           {
933             mp_limb_t *ptr = pow5_ptr + pow5_len;
934             size_t i;
935             for (i = 0; i < s_limbs; i++)
936               ptr[i] = 0;
937             ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
938             denominator.limbs = ptr;
939             denominator.nlimbs = s_limbs + 1;
940           }
941           result_memory = divide (numerator, denominator, yp);
942           free (tmp_memory);
943           free (pow5_ptr);
944           free (memory);
945           return result_memory;
946         }
947       else
948         {
949           /* n < 0, s > 0.
950              Multiply m with 2^s, then divide by pow5.  */
951           mpn_t numerator;
952           mp_limb_t *num_ptr;
953           void *result_memory;
954           num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
955                                           * sizeof (mp_limb_t));
956           if (num_ptr == NULL)
957             {
958               free (pow5_ptr);
959               free (memory);
960               return NULL;
961             }
962           {
963             mp_limb_t *destptr = num_ptr;
964             {
965               size_t i;
966               for (i = 0; i < s_limbs; i++)
967                 *destptr++ = 0;
968             }
969             if (s_bits > 0)
970               {
971                 const mp_limb_t *sourceptr = m.limbs;
972                 mp_twolimb_t accu = 0;
973                 size_t count;
974                 for (count = m.nlimbs; count > 0; count--)
975                   {
976                     accu += (mp_twolimb_t) *sourceptr++ << s;
977                     *destptr++ = (mp_limb_t) accu;
978                     accu = accu >> GMP_LIMB_BITS;
979                   }
980                 if (accu > 0)
981                   *destptr++ = (mp_limb_t) accu;
982               }
983             else
984               {
985                 const mp_limb_t *sourceptr = m.limbs;
986                 size_t count;
987                 for (count = m.nlimbs; count > 0; count--)
988                   *destptr++ = *sourceptr++;
989               }
990             numerator.limbs = num_ptr;
991             numerator.nlimbs = destptr - num_ptr;
992           }
993           result_memory = divide (numerator, pow5, yp);
994           free (num_ptr);
995           free (pow5_ptr);
996           free (memory);
997           return result_memory;
998         }
999     }
1000 }
1001
1002 /* Assuming x is finite and >= 0, and n is an integer:
1003    Returns the decimal representation of round (x * 10^n).
1004    Return the allocated memory - containing the decimal digits in low-to-high
1005    order, terminated with a NUL character - in case of success, NULL in case
1006    of memory allocation failure.  */
1007 static char *
1008 scale10_round_decimal_long_double (long double x, int n)
1009 {
1010   mpn_t y;
1011   void *memory;
1012   char *digits;
1013
1014   memory = scale10_round_long_double (x, n, &y);
1015   if (memory == NULL)
1016     return NULL;
1017   digits = convert_to_decimal (y);
1018   free (memory);
1019   return digits;
1020 }
1021
1022 /* Assuming x is finite and > 0:
1023    Return an approximation for n with 10^n <= x < 10^(n+1).
1024    The approximation is usually the right n, but may be off by 1 sometimes.  */
1025 static int
1026 floorlog10l (long double x)
1027 {
1028   int exp;
1029   long double y;
1030   double z;
1031   double l;
1032
1033   /* Split into exponential part and mantissa.  */
1034   y = frexpl (x, &exp);
1035   if (!(y >= 0.0L && y < 1.0L))
1036     abort ();
1037   if (y == 0.0L)
1038     return INT_MIN;
1039   if (y < 0.5L)
1040     {
1041       while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1042         {
1043           y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1044           exp -= GMP_LIMB_BITS;
1045         }
1046       if (y < (1.0L / (1 << 16)))
1047         {
1048           y *= 1.0L * (1 << 16);
1049           exp -= 16;
1050         }
1051       if (y < (1.0L / (1 << 8)))
1052         {
1053           y *= 1.0L * (1 << 8);
1054           exp -= 8;
1055         }
1056       if (y < (1.0L / (1 << 4)))
1057         {
1058           y *= 1.0L * (1 << 4);
1059           exp -= 4;
1060         }
1061       if (y < (1.0L / (1 << 2)))
1062         {
1063           y *= 1.0L * (1 << 2);
1064           exp -= 2;
1065         }
1066       if (y < (1.0L / (1 << 1)))
1067         {
1068           y *= 1.0L * (1 << 1);
1069           exp -= 1;
1070         }
1071     }
1072   if (!(y >= 0.5L && y < 1.0L))
1073     abort ();
1074   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
1075   l = exp;
1076   z = y;
1077   if (z < 0.70710678118654752444)
1078     {
1079       z *= 1.4142135623730950488;
1080       l -= 0.5;
1081     }
1082   if (z < 0.8408964152537145431)
1083     {
1084       z *= 1.1892071150027210667;
1085       l -= 0.25;
1086     }
1087   if (z < 0.91700404320467123175)
1088     {
1089       z *= 1.0905077326652576592;
1090       l -= 0.125;
1091     }
1092   if (z < 0.9576032806985736469)
1093     {
1094       z *= 1.0442737824274138403;
1095       l -= 0.0625;
1096     }
1097   /* Now 0.95 <= z <= 1.01.  */
1098   z = 1 - z;
1099   /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
1100      Four terms are enough to get an approximation with error < 10^-7.  */
1101   l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1102   /* Finally multiply with log(2)/log(10), yields an approximation for
1103      log10(x).  */
1104   l *= 0.30102999566398119523;
1105   /* Round down to the next integer.  */
1106   return (int) l + (l < 0 ? -1 : 0);
1107 }
1108
1109 #endif
1110
1111 CHAR_T *
1112 VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args)
1113 {
1114   DIRECTIVES d;
1115   arguments a;
1116
1117   if (PRINTF_PARSE (format, &d, &a) < 0)
1118     {
1119       errno = EINVAL;
1120       return NULL;
1121     }
1122
1123 #define CLEANUP() \
1124   free (d.dir);                                                         \
1125   if (a.arg)                                                            \
1126     free (a.arg);
1127
1128   if (printf_fetchargs (args, &a) < 0)
1129     {
1130       CLEANUP ();
1131       errno = EINVAL;
1132       return NULL;
1133     }
1134
1135   {
1136     size_t buf_neededlength;
1137     CHAR_T *buf;
1138     CHAR_T *buf_malloced;
1139     const CHAR_T *cp;
1140     size_t i;
1141     DIRECTIVE *dp;
1142     /* Output string accumulator.  */
1143     CHAR_T *result;
1144     size_t allocated;
1145     size_t length;
1146
1147     /* Allocate a small buffer that will hold a directive passed to
1148        sprintf or snprintf.  */
1149     buf_neededlength =
1150       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1151 #if HAVE_ALLOCA
1152     if (buf_neededlength < 4000 / sizeof (CHAR_T))
1153       {
1154         buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
1155         buf_malloced = NULL;
1156       }
1157     else
1158 #endif
1159       {
1160         size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));
1161         if (size_overflow_p (buf_memsize))
1162           goto out_of_memory_1;
1163         buf = (CHAR_T *) malloc (buf_memsize);
1164         if (buf == NULL)
1165           goto out_of_memory_1;
1166         buf_malloced = buf;
1167       }
1168
1169     if (resultbuf != NULL)
1170       {
1171         result = resultbuf;
1172         allocated = *lengthp;
1173       }
1174     else
1175       {
1176         result = NULL;
1177         allocated = 0;
1178       }
1179     length = 0;
1180     /* Invariants:
1181        result is either == resultbuf or == NULL or malloc-allocated.
1182        If length > 0, then result != NULL.  */
1183
1184     /* Ensures that allocated >= needed.  Aborts through a jump to
1185        out_of_memory if needed is SIZE_MAX or otherwise too big.  */
1186 #define ENSURE_ALLOCATION(needed) \
1187     if ((needed) > allocated)                                                \
1188       {                                                                      \
1189         size_t memory_size;                                                  \
1190         CHAR_T *memory;                                                      \
1191                                                                              \
1192         allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
1193         if ((needed) > allocated)                                            \
1194           allocated = (needed);                                              \
1195         memory_size = xtimes (allocated, sizeof (CHAR_T));                   \
1196         if (size_overflow_p (memory_size))                                   \
1197           goto out_of_memory;                                                \
1198         if (result == resultbuf || result == NULL)                           \
1199           memory = (CHAR_T *) malloc (memory_size);                          \
1200         else                                                                 \
1201           memory = (CHAR_T *) realloc (result, memory_size);                 \
1202         if (memory == NULL)                                                  \
1203           goto out_of_memory;                                                \
1204         if (result == resultbuf && length > 0)                               \
1205           memcpy (memory, result, length * sizeof (CHAR_T));                 \
1206         result = memory;                                                     \
1207       }
1208
1209     for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1210       {
1211         if (cp != dp->dir_start)
1212           {
1213             size_t n = dp->dir_start - cp;
1214             size_t augmented_length = xsum (length, n);
1215
1216             ENSURE_ALLOCATION (augmented_length);
1217             memcpy (result + length, cp, n * sizeof (CHAR_T));
1218             length = augmented_length;
1219           }
1220         if (i == d.count)
1221           break;
1222
1223         /* Execute a single directive.  */
1224         if (dp->conversion == '%')
1225           {
1226             size_t augmented_length;
1227
1228             if (!(dp->arg_index == ARG_NONE))
1229               abort ();
1230             augmented_length = xsum (length, 1);
1231             ENSURE_ALLOCATION (augmented_length);
1232             result[length] = '%';
1233             length = augmented_length;
1234           }
1235         else
1236           {
1237             if (!(dp->arg_index != ARG_NONE))
1238               abort ();
1239
1240             if (dp->conversion == 'n')
1241               {
1242                 switch (a.arg[dp->arg_index].type)
1243                   {
1244                   case TYPE_COUNT_SCHAR_POINTER:
1245                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1246                     break;
1247                   case TYPE_COUNT_SHORT_POINTER:
1248                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1249                     break;
1250                   case TYPE_COUNT_INT_POINTER:
1251                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1252                     break;
1253                   case TYPE_COUNT_LONGINT_POINTER:
1254                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1255                     break;
1256 #if HAVE_LONG_LONG_INT
1257                   case TYPE_COUNT_LONGLONGINT_POINTER:
1258                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1259                     break;
1260 #endif
1261                   default:
1262                     abort ();
1263                   }
1264               }
1265 #if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
1266             else if ((dp->conversion == 'f' || dp->conversion == 'F'
1267                       || dp->conversion == 'e' || dp->conversion == 'E'
1268                       || dp->conversion == 'g' || dp->conversion == 'G')
1269                      && a.arg[dp->arg_index].type == TYPE_LONGDOUBLE)
1270               {
1271                 int flags = dp->flags;
1272                 int has_width;
1273                 size_t width;
1274                 int has_precision;
1275                 size_t precision;
1276                 long double arg;
1277                 size_t tmp_length;
1278                 CHAR_T tmpbuf[700];
1279                 CHAR_T *tmp;
1280                 CHAR_T *pad_ptr;
1281                 CHAR_T *p;
1282
1283                 has_width = 0;
1284                 width = 0;
1285                 if (dp->width_start != dp->width_end)
1286                   {
1287                     if (dp->width_arg_index != ARG_NONE)
1288                       {
1289                         int arg;
1290
1291                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1292                           abort ();
1293                         arg = a.arg[dp->width_arg_index].a.a_int;
1294                         if (arg < 0)
1295                           {
1296                             /* "A negative field width is taken as a '-' flag
1297                                 followed by a positive field width."  */
1298                             flags |= FLAG_LEFT;
1299                             width = (unsigned int) (-arg);
1300                           }
1301                         else
1302                           width = arg;
1303                       }
1304                     else
1305                       {
1306                         const CHAR_T *digitp = dp->width_start;
1307
1308                         do
1309                           width = xsum (xtimes (width, 10), *digitp++ - '0');
1310                         while (digitp != dp->width_end);
1311                       }
1312                     has_width = 1;
1313                   }
1314
1315                 has_precision = 0;
1316                 precision = 0;
1317                 if (dp->precision_start != dp->precision_end)
1318                   {
1319                     if (dp->precision_arg_index != ARG_NONE)
1320                       {
1321                         int arg;
1322
1323                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1324                           abort ();
1325                         arg = a.arg[dp->precision_arg_index].a.a_int;
1326                         /* "A negative precision is taken as if the precision
1327                             were omitted."  */
1328                         if (arg >= 0)
1329                           {
1330                             precision = arg;
1331                             has_precision = 1;
1332                           }
1333                       }
1334                     else
1335                       {
1336                         const CHAR_T *digitp = dp->precision_start + 1;
1337
1338                         precision = 0;
1339                         while (digitp != dp->precision_end)
1340                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1341                         has_precision = 1;
1342                       }
1343                   }
1344
1345                 arg = a.arg[dp->arg_index].a.a_longdouble;
1346
1347                 /* Allocate a temporary buffer of sufficient size.  */
1348                 tmp_length = LDBL_DIG + 1;
1349                 if (tmp_length < precision)
1350                   tmp_length = precision;
1351                 if (dp->conversion == 'f' || dp->conversion == 'F')
1352                   if (!(isnanl (arg) || arg + arg == arg))
1353                     {
1354                       int exponent = floorlog10l (arg < 0 ? -arg : arg);
1355                       if (exponent >= 0 && tmp_length < exponent + precision)
1356                         tmp_length = exponent + precision;
1357                     }
1358                 /* Account for sign, decimal point etc. */
1359                 tmp_length = xsum (tmp_length, 12);
1360
1361                 if (tmp_length < width)
1362                   tmp_length = width;
1363
1364                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1365
1366                 if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
1367                   tmp = tmpbuf;
1368                 else
1369                   {
1370                     size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
1371
1372                     if (size_overflow_p (tmp_memsize))
1373                       /* Overflow, would lead to out of memory.  */
1374                       goto out_of_memory;
1375                     tmp = (CHAR_T *) malloc (tmp_memsize);
1376                     if (tmp == NULL)
1377                       /* Out of memory.  */
1378                       goto out_of_memory;
1379                   }
1380
1381                 pad_ptr = NULL;
1382                 p = tmp;
1383
1384                 if (isnanl (arg))
1385                   {
1386                     if (dp->conversion >= 'A' && dp->conversion <= 'Z')
1387                       {
1388                         *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
1389                       }
1390                     else
1391                       {
1392                         *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
1393                       }
1394                   }
1395                 else
1396                   {
1397                     int sign = 0;
1398                     DECL_LONG_DOUBLE_ROUNDING
1399
1400                     BEGIN_LONG_DOUBLE_ROUNDING ();
1401
1402                     if (signbit (arg)) /* arg < 0.0L or negative zero */
1403                       {
1404                         sign = -1;
1405                         arg = -arg;
1406                       }
1407
1408                     if (sign < 0)
1409                       *p++ = '-';
1410                     else if (flags & FLAG_SHOWSIGN)
1411                       *p++ = '+';
1412                     else if (flags & FLAG_SPACE)
1413                       *p++ = ' ';
1414
1415                     if (arg > 0.0L && arg + arg == arg)
1416                       {
1417                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
1418                           {
1419                             *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
1420                           }
1421                         else
1422                           {
1423                             *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
1424                           }
1425                       }
1426                     else
1427                       {
1428                         pad_ptr = p;
1429
1430                         if (dp->conversion == 'f' || dp->conversion == 'F')
1431                           {
1432                             char *digits;
1433                             size_t ndigits;
1434
1435                             if (!has_precision)
1436                               precision = 6;
1437
1438                             digits =
1439                               scale10_round_decimal_long_double (arg, precision);
1440                             if (digits == NULL)
1441                               {
1442                                 END_LONG_DOUBLE_ROUNDING ();
1443                                 goto out_of_memory;
1444                               }
1445                             ndigits = strlen (digits);
1446
1447                             if (ndigits > precision)
1448                               do
1449                                 {
1450                                   --ndigits;
1451                                   *p++ = digits[ndigits];
1452                                 }
1453                               while (ndigits > precision);
1454                             else
1455                               *p++ = '0';
1456                             /* Here ndigits <= precision.  */
1457                             if ((flags & FLAG_ALT) || precision > 0)
1458                               {
1459                                 *p++ = decimal_point_char ();
1460                                 for (; precision > ndigits; precision--)
1461                                   *p++ = '0';
1462                                 while (ndigits > 0)
1463                                   {
1464                                     --ndigits;
1465                                     *p++ = digits[ndigits];
1466                                   }
1467                               }
1468
1469                             free (digits);
1470                           }
1471                         else if (dp->conversion == 'e' || dp->conversion == 'E')
1472                           {
1473                             int exponent;
1474
1475                             if (!has_precision)
1476                               precision = 6;
1477
1478                             if (arg == 0.0L)
1479                               {
1480                                 exponent = 0;
1481                                 *p++ = '0';
1482                                 if ((flags & FLAG_ALT) || precision > 0)
1483                                   {
1484                                     *p++ = decimal_point_char ();
1485                                     for (; precision > 0; precision--)
1486                                       *p++ = '0';
1487                                   }
1488                               }
1489                             else
1490                               {
1491                                 /* arg > 0.0L.  */
1492                                 int adjusted;
1493                                 char *digits;
1494                                 size_t ndigits;
1495
1496                                 exponent = floorlog10l (arg);
1497                                 adjusted = 0;
1498                                 for (;;)
1499                                   {
1500                                     digits =
1501                                       scale10_round_decimal_long_double (arg,
1502                                                                          (int)precision - exponent);
1503                                     if (digits == NULL)
1504                                       {
1505                                         END_LONG_DOUBLE_ROUNDING ();
1506                                         goto out_of_memory;
1507                                       }
1508                                     ndigits = strlen (digits);
1509
1510                                     if (ndigits == precision + 1)
1511                                       break;
1512                                     if (ndigits < precision
1513                                         || ndigits > precision + 2)
1514                                       /* The exponent was not guessed precisely
1515                                          enough.  */
1516                                       abort ();
1517                                     if (adjusted)
1518                                       /* None of two values of exponent is the
1519                                          right one.  Prevent an endless loop.  */
1520                                       abort ();
1521                                     free (digits);
1522                                     if (ndigits == precision)
1523                                       exponent -= 1;
1524                                     else
1525                                       exponent += 1;
1526                                     adjusted = 1;
1527                                   }
1528
1529                                 /* Here ndigits = precision+1.  */
1530                                 *p++ = digits[--ndigits];
1531                                 if ((flags & FLAG_ALT) || precision > 0)
1532                                   {
1533                                     *p++ = decimal_point_char ();
1534                                     while (ndigits > 0)
1535                                       {
1536                                         --ndigits;
1537                                         *p++ = digits[ndigits];
1538                                       }
1539                                   }
1540
1541                                 free (digits);
1542                               }
1543
1544                             *p++ = dp->conversion; /* 'e' or 'E' */
1545 # if WIDE_CHAR_VERSION
1546                             {
1547                               static const wchar_t decimal_format[] =
1548                                 { '%', '+', '.', '2', 'd', '\0' };
1549                               SNPRINTF (p, 6 + 1, decimal_format, exponent);
1550                             }
1551 # else
1552                             sprintf (p, "%+.2d", exponent);
1553 # endif
1554                             while (*p != '\0')
1555                               p++;
1556                           }
1557                         else if (dp->conversion == 'g' || dp->conversion == 'G')
1558                           {
1559                             /* This is not specified by POSIX, but
1560                                implementations appear to do this.  */
1561                             if (!has_precision)
1562                               precision = 6;
1563
1564                             if (precision == 0)
1565                               precision = 1;
1566                             /* precision >= 1.  */
1567
1568                             if (arg == 0.0L)
1569                               /* The exponent is 0, >= -4, < precision.
1570                                  Use fixed-point notation.  */
1571                               {
1572                                 size_t ndigits = precision;
1573                                 /* Number of trailing zeroes that have to be
1574                                    dropped.  */
1575                                 size_t nzeroes =
1576                                   (flags & FLAG_ALT ? 0 : precision - 1);
1577
1578                                 --ndigits;
1579                                 *p++ = '0';
1580                                 if ((flags & FLAG_ALT) || ndigits > nzeroes)
1581                                   {
1582                                     *p++ = decimal_point_char ();
1583                                     while (ndigits > nzeroes)
1584                                       {
1585                                         --ndigits;
1586                                         *p++ = '0';
1587                                       }
1588                                   }
1589                               }
1590                             else
1591                               {
1592                                 /* arg > 0.0L.  */
1593                                 int exponent;
1594                                 int adjusted;
1595                                 char *digits;
1596                                 size_t ndigits;
1597                                 size_t nzeroes;
1598
1599                                 exponent = floorlog10l (arg);
1600                                 adjusted = 0;
1601                                 for (;;)
1602                                   {
1603                                     digits =
1604                                       scale10_round_decimal_long_double (arg,
1605                                                                          (int)(precision - 1) - exponent);
1606                                     if (digits == NULL)
1607                                       {
1608                                         END_LONG_DOUBLE_ROUNDING ();
1609                                         goto out_of_memory;
1610                                       }
1611                                     ndigits = strlen (digits);
1612
1613                                     if (ndigits == precision)
1614                                       break;
1615                                     if (ndigits < precision - 1
1616                                         || ndigits > precision + 1)
1617                                       /* The exponent was not guessed precisely
1618                                          enough.  */
1619                                       abort ();
1620                                     if (adjusted)
1621                                       /* None of two values of exponent is the
1622                                          right one.  Prevent an endless loop.  */
1623                                       abort ();
1624                                     free (digits);
1625                                     if (ndigits < precision)
1626                                       exponent -= 1;
1627                                     else
1628                                       exponent += 1;
1629                                     adjusted = 1;
1630                                   }
1631                                 /* Here ndigits = precision.  */
1632
1633                                 /* Determine the number of trailing zeroes that
1634                                    have to be dropped.  */
1635                                 nzeroes = 0;
1636                                 if ((flags & FLAG_ALT) == 0)
1637                                   while (nzeroes < ndigits
1638                                          && digits[nzeroes] == '0')
1639                                     nzeroes++;
1640
1641                                 /* The exponent is now determined.  */
1642                                 if (exponent >= -4 && exponent < (long)precision)
1643                                   {
1644                                     /* Fixed-point notation: max(exponent,0)+1
1645                                        digits, then the decimal point, then the
1646                                        remaining digits without trailing zeroes.  */
1647                                     if (exponent >= 0)
1648                                       {
1649                                         size_t count = exponent + 1;
1650                                         /* Note: count <= precision = ndigits.  */
1651                                         for (; count > 0; count--)
1652                                           *p++ = digits[--ndigits];
1653                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
1654                                           {
1655                                             *p++ = decimal_point_char ();
1656                                             while (ndigits > nzeroes)
1657                                               {
1658                                                 --ndigits;
1659                                                 *p++ = digits[ndigits];
1660                                               }
1661                                           }
1662                                       }
1663                                     else
1664                                       {
1665                                         size_t count = -exponent - 1;
1666                                         *p++ = '0';
1667                                         *p++ = decimal_point_char ();
1668                                         for (; count > 0; count--)
1669                                           *p++ = '0';
1670                                         while (ndigits > nzeroes)
1671                                           {
1672                                             --ndigits;
1673                                             *p++ = digits[ndigits];
1674                                           }
1675                                       }
1676                                   }
1677                                 else
1678                                   {
1679                                     /* Exponential notation.  */
1680                                     *p++ = digits[--ndigits];
1681                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
1682                                       {
1683                                         *p++ = decimal_point_char ();
1684                                         while (ndigits > nzeroes)
1685                                           {
1686                                             --ndigits;
1687                                             *p++ = digits[ndigits];
1688                                           }
1689                                       }
1690                                     *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
1691 # if WIDE_CHAR_VERSION
1692                                     {
1693                                       static const wchar_t decimal_format[] =
1694                                         { '%', '+', '.', '2', 'd', '\0' };
1695                                       SNPRINTF (p, 6 + 1, decimal_format, exponent);
1696                                     }
1697 # else
1698                                     sprintf (p, "%+.2d", exponent);
1699 # endif
1700                                     while (*p != '\0')
1701                                       p++;
1702                                   }
1703
1704                                 free (digits);
1705                               }
1706                           }
1707                         else
1708                           abort ();
1709                       }
1710
1711                     END_LONG_DOUBLE_ROUNDING ();
1712                   }
1713
1714                 /* The generated string now extends from tmp to p, with the
1715                    zero padding insertion point being at pad_ptr.  */
1716                 if (has_width && p - tmp < width)
1717                   {
1718                     size_t pad = width - (p - tmp);
1719                     CHAR_T *end = p + pad;
1720
1721                     if (flags & FLAG_LEFT)
1722                       {
1723                         /* Pad with spaces on the right.  */
1724                         for (; pad > 0; pad--)
1725                           *p++ = ' ';
1726                       }
1727                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
1728                       {
1729                         /* Pad with zeroes.  */
1730                         CHAR_T *q = end;
1731
1732                         while (p > pad_ptr)
1733                           *--q = *--p;
1734                         for (; pad > 0; pad--)
1735                           *p++ = '0';
1736                       }
1737                     else
1738                       {
1739                         /* Pad with spaces on the left.  */
1740                         CHAR_T *q = end;
1741
1742                         while (p > tmp)
1743                           *--q = *--p;
1744                         for (; pad > 0; pad--)
1745                           *p++ = ' ';
1746                       }
1747
1748                     p = end;
1749                   }
1750
1751                 {
1752                   size_t count = p - tmp;
1753
1754                   if (count >= tmp_length)
1755                     /* tmp_length was incorrectly calculated - fix the
1756                        code above!  */
1757                     abort ();
1758
1759                   /* Make room for the result.  */
1760                   if (count >= allocated - length)
1761                     {
1762                       size_t n = xsum (length, count);
1763
1764                       ENSURE_ALLOCATION (n);
1765                     }
1766
1767                   /* Append the result.  */
1768                   memcpy (result + length, tmp, count * sizeof (CHAR_T));
1769                   if (tmp != tmpbuf)
1770                     free (tmp);
1771                   length += count;
1772                 }
1773               }
1774 #endif
1775 #if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
1776             else if (dp->conversion == 'a' || dp->conversion == 'A')
1777               {
1778                 arg_type type = a.arg[dp->arg_index].type;
1779                 int flags = dp->flags;
1780                 int has_width;
1781                 size_t width;
1782                 int has_precision;
1783                 size_t precision;
1784                 size_t tmp_length;
1785                 CHAR_T tmpbuf[700];
1786                 CHAR_T *tmp;
1787                 CHAR_T *pad_ptr;
1788                 CHAR_T *p;
1789
1790                 has_width = 0;
1791                 width = 0;
1792                 if (dp->width_start != dp->width_end)
1793                   {
1794                     if (dp->width_arg_index != ARG_NONE)
1795                       {
1796                         int arg;
1797
1798                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1799                           abort ();
1800                         arg = a.arg[dp->width_arg_index].a.a_int;
1801                         if (arg < 0)
1802                           {
1803                             /* "A negative field width is taken as a '-' flag
1804                                 followed by a positive field width."  */
1805                             flags |= FLAG_LEFT;
1806                             width = (unsigned int) (-arg);
1807                           }
1808                         else
1809                           width = arg;
1810                       }
1811                     else
1812                       {
1813                         const CHAR_T *digitp = dp->width_start;
1814
1815                         do
1816                           width = xsum (xtimes (width, 10), *digitp++ - '0');
1817                         while (digitp != dp->width_end);
1818                       }
1819                     has_width = 1;
1820                   }
1821
1822                 has_precision = 0;
1823                 precision = 0;
1824                 if (dp->precision_start != dp->precision_end)
1825                   {
1826                     if (dp->precision_arg_index != ARG_NONE)
1827                       {
1828                         int arg;
1829
1830                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1831                           abort ();
1832                         arg = a.arg[dp->precision_arg_index].a.a_int;
1833                         /* "A negative precision is taken as if the precision
1834                             were omitted."  */
1835                         if (arg >= 0)
1836                           {
1837                             precision = arg;
1838                             has_precision = 1;
1839                           }
1840                       }
1841                     else
1842                       {
1843                         const CHAR_T *digitp = dp->precision_start + 1;
1844
1845                         precision = 0;
1846                         while (digitp != dp->precision_end)
1847                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1848                         has_precision = 1;
1849                       }
1850                   }
1851
1852                 /* Allocate a temporary buffer of sufficient size.  */
1853                 if (type == TYPE_LONGDOUBLE)
1854                   tmp_length =
1855                     (unsigned int) ((LDBL_DIG + 1)
1856                                     * 0.831 /* decimal -> hexadecimal */
1857                                    )
1858                     + 1; /* turn floor into ceil */
1859                 else
1860                   tmp_length =
1861                     (unsigned int) ((DBL_DIG + 1)
1862                                     * 0.831 /* decimal -> hexadecimal */
1863                                    )
1864                     + 1; /* turn floor into ceil */
1865                 if (tmp_length < precision)
1866                   tmp_length = precision;
1867                 /* Account for sign, decimal point etc. */
1868                 tmp_length = xsum (tmp_length, 12);
1869
1870                 if (tmp_length < width)
1871                   tmp_length = width;
1872
1873                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1874
1875                 if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
1876                   tmp = tmpbuf;
1877                 else
1878                   {
1879                     size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
1880
1881                     if (size_overflow_p (tmp_memsize))
1882                       /* Overflow, would lead to out of memory.  */
1883                       goto out_of_memory;
1884                     tmp = (CHAR_T *) malloc (tmp_memsize);
1885                     if (tmp == NULL)
1886                       /* Out of memory.  */
1887                       goto out_of_memory;
1888                   }
1889
1890                 pad_ptr = NULL;
1891                 p = tmp;
1892                 if (type == TYPE_LONGDOUBLE)
1893                   {
1894                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
1895
1896                     if (isnanl (arg))
1897                       {
1898                         if (dp->conversion == 'A')
1899                           {
1900                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
1901                           }
1902                         else
1903                           {
1904                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
1905                           }
1906                       }
1907                     else
1908                       {
1909                         int sign = 0;
1910                         DECL_LONG_DOUBLE_ROUNDING
1911
1912                         BEGIN_LONG_DOUBLE_ROUNDING ();
1913
1914                         if (signbit (arg)) /* arg < 0.0L or negative zero */
1915                           {
1916                             sign = -1;
1917                             arg = -arg;
1918                           }
1919
1920                         if (sign < 0)
1921                           *p++ = '-';
1922                         else if (flags & FLAG_SHOWSIGN)
1923                           *p++ = '+';
1924                         else if (flags & FLAG_SPACE)
1925                           *p++ = ' ';
1926
1927                         if (arg > 0.0L && arg + arg == arg)
1928                           {
1929                             if (dp->conversion == 'A')
1930                               {
1931                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
1932                               }
1933                             else
1934                               {
1935                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
1936                               }
1937                           }
1938                         else
1939                           {
1940                             int exponent;
1941                             long double mantissa;
1942
1943                             if (arg > 0.0L)
1944                               mantissa = printf_frexpl (arg, &exponent);
1945                             else
1946                               {
1947                                 exponent = 0;
1948                                 mantissa = 0.0L;
1949                               }
1950
1951                             if (has_precision
1952                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
1953                               {
1954                                 /* Round the mantissa.  */
1955                                 long double tail = mantissa;
1956                                 size_t q;
1957
1958                                 for (q = precision; ; q--)
1959                                   {
1960                                     int digit = (int) tail;
1961                                     tail -= digit;
1962                                     if (q == 0)
1963                                       {
1964                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
1965                                           tail = 1 - tail;
1966                                         else
1967                                           tail = - tail;
1968                                         break;
1969                                       }
1970                                     tail *= 16.0L;
1971                                   }
1972                                 if (tail != 0.0L)
1973                                   for (q = precision; q > 0; q--)
1974                                     tail *= 0.0625L;
1975                                 mantissa += tail;
1976                               }
1977
1978                             *p++ = '0';
1979                             *p++ = dp->conversion - 'A' + 'X';
1980                             pad_ptr = p;
1981                             {
1982                               int digit;
1983
1984                               digit = (int) mantissa;
1985                               mantissa -= digit;
1986                               *p++ = '0' + digit;
1987                               if ((flags & FLAG_ALT)
1988                                   || mantissa > 0.0L || precision > 0)
1989                                 {
1990                                   *p++ = decimal_point_char ();
1991                                   /* This loop terminates because we assume
1992                                      that FLT_RADIX is a power of 2.  */
1993                                   while (mantissa > 0.0L)
1994                                     {
1995                                       mantissa *= 16.0L;
1996                                       digit = (int) mantissa;
1997                                       mantissa -= digit;
1998                                       *p++ = digit
1999                                              + (digit < 10
2000                                                 ? '0'
2001                                                 : dp->conversion - 10);
2002                                       if (precision > 0)
2003                                         precision--;
2004                                     }
2005                                   while (precision > 0)
2006                                     {
2007                                       *p++ = '0';
2008                                       precision--;
2009                                     }
2010                                 }
2011                               }
2012                               *p++ = dp->conversion - 'A' + 'P';
2013 # if WIDE_CHAR_VERSION
2014                               {
2015                                 static const wchar_t decimal_format[] =
2016                                   { '%', '+', 'd', '\0' };
2017                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
2018                               }
2019 # else
2020                               sprintf (p, "%+d", exponent);
2021 # endif
2022                               while (*p != '\0')
2023                                 p++;
2024                           }
2025
2026                         END_LONG_DOUBLE_ROUNDING ();
2027                       }
2028                   }
2029                 else
2030                   {
2031                     double arg = a.arg[dp->arg_index].a.a_double;
2032
2033                     if (isnan (arg))
2034                       {
2035                         if (dp->conversion == 'A')
2036                           {
2037                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2038                           }
2039                         else
2040                           {
2041                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2042                           }
2043                       }
2044                     else
2045                       {
2046                         int sign = 0;
2047
2048                         if (signbit (arg)) /* arg < 0.0 or negative zero */
2049                           {
2050                             sign = -1;
2051                             arg = -arg;
2052                           }
2053
2054                         if (sign < 0)
2055                           *p++ = '-';
2056                         else if (flags & FLAG_SHOWSIGN)
2057                           *p++ = '+';
2058                         else if (flags & FLAG_SPACE)
2059                           *p++ = ' ';
2060
2061                         if (arg > 0.0 && arg + arg == arg)
2062                           {
2063                             if (dp->conversion == 'A')
2064                               {
2065                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2066                               }
2067                             else
2068                               {
2069                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2070                               }
2071                           }
2072                         else
2073                           {
2074                             int exponent;
2075                             double mantissa;
2076
2077                             if (arg > 0.0)
2078                               mantissa = printf_frexp (arg, &exponent);
2079                             else
2080                               {
2081                                 exponent = 0;
2082                                 mantissa = 0.0;
2083                               }
2084
2085                             if (has_precision
2086                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
2087                               {
2088                                 /* Round the mantissa.  */
2089                                 double tail = mantissa;
2090                                 size_t q;
2091
2092                                 for (q = precision; ; q--)
2093                                   {
2094                                     int digit = (int) tail;
2095                                     tail -= digit;
2096                                     if (q == 0)
2097                                       {
2098                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
2099                                           tail = 1 - tail;
2100                                         else
2101                                           tail = - tail;
2102                                         break;
2103                                       }
2104                                     tail *= 16.0;
2105                                   }
2106                                 if (tail != 0.0)
2107                                   for (q = precision; q > 0; q--)
2108                                     tail *= 0.0625;
2109                                 mantissa += tail;
2110                               }
2111
2112                             *p++ = '0';
2113                             *p++ = dp->conversion - 'A' + 'X';
2114                             pad_ptr = p;
2115                             {
2116                               int digit;
2117
2118                               digit = (int) mantissa;
2119                               mantissa -= digit;
2120                               *p++ = '0' + digit;
2121                               if ((flags & FLAG_ALT)
2122                                   || mantissa > 0.0 || precision > 0)
2123                                 {
2124                                   *p++ = decimal_point_char ();
2125                                   /* This loop terminates because we assume
2126                                      that FLT_RADIX is a power of 2.  */
2127                                   while (mantissa > 0.0)
2128                                     {
2129                                       mantissa *= 16.0;
2130                                       digit = (int) mantissa;
2131                                       mantissa -= digit;
2132                                       *p++ = digit
2133                                              + (digit < 10
2134                                                 ? '0'
2135                                                 : dp->conversion - 10);
2136                                       if (precision > 0)
2137                                         precision--;
2138                                     }
2139                                   while (precision > 0)
2140                                     {
2141                                       *p++ = '0';
2142                                       precision--;
2143                                     }
2144                                 }
2145                               }
2146                               *p++ = dp->conversion - 'A' + 'P';
2147 # if WIDE_CHAR_VERSION
2148                               {
2149                                 static const wchar_t decimal_format[] =
2150                                   { '%', '+', 'd', '\0' };
2151                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
2152                               }
2153 # else
2154                               sprintf (p, "%+d", exponent);
2155 # endif
2156                               while (*p != '\0')
2157                                 p++;
2158                           }
2159                       }
2160                   }
2161                 /* The generated string now extends from tmp to p, with the
2162                    zero padding insertion point being at pad_ptr.  */
2163                 if (has_width && p - tmp < width)
2164                   {
2165                     size_t pad = width - (p - tmp);
2166                     CHAR_T *end = p + pad;
2167
2168                     if (flags & FLAG_LEFT)
2169                       {
2170                         /* Pad with spaces on the right.  */
2171                         for (; pad > 0; pad--)
2172                           *p++ = ' ';
2173                       }
2174                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
2175                       {
2176                         /* Pad with zeroes.  */
2177                         CHAR_T *q = end;
2178
2179                         while (p > pad_ptr)
2180                           *--q = *--p;
2181                         for (; pad > 0; pad--)
2182                           *p++ = '0';
2183                       }
2184                     else
2185                       {
2186                         /* Pad with spaces on the left.  */
2187                         CHAR_T *q = end;
2188
2189                         while (p > tmp)
2190                           *--q = *--p;
2191                         for (; pad > 0; pad--)
2192                           *p++ = ' ';
2193                       }
2194
2195                     p = end;
2196                   }
2197
2198                 {
2199                   size_t count = p - tmp;
2200
2201                   if (count >= tmp_length)
2202                     /* tmp_length was incorrectly calculated - fix the
2203                        code above!  */
2204                     abort ();
2205
2206                   /* Make room for the result.  */
2207                   if (count >= allocated - length)
2208                     {
2209                       size_t n = xsum (length, count);
2210
2211                       ENSURE_ALLOCATION (n);
2212                     }
2213
2214                   /* Append the result.  */
2215                   memcpy (result + length, tmp, count * sizeof (CHAR_T));
2216                   if (tmp != tmpbuf)
2217                     free (tmp);
2218                   length += count;
2219                 }
2220               }
2221 #endif
2222             else
2223               {
2224                 arg_type type = a.arg[dp->arg_index].type;
2225                 int flags = dp->flags;
2226 #if !USE_SNPRINTF || NEED_PRINTF_FLAG_ZERO
2227                 int has_width;
2228                 size_t width;
2229 #endif
2230 #if NEED_PRINTF_FLAG_ZERO
2231                 int pad_ourselves;
2232 #else
2233 #               define pad_ourselves 0
2234 #endif
2235                 CHAR_T *fbp;
2236                 unsigned int prefix_count;
2237                 int prefixes[2];
2238 #if !USE_SNPRINTF
2239                 size_t tmp_length;
2240                 CHAR_T tmpbuf[700];
2241                 CHAR_T *tmp;
2242 #endif
2243
2244 #if !USE_SNPRINTF || NEED_PRINTF_FLAG_ZERO
2245                 has_width = 0;
2246                 width = 0;
2247                 if (dp->width_start != dp->width_end)
2248                   {
2249                     if (dp->width_arg_index != ARG_NONE)
2250                       {
2251                         int arg;
2252
2253                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2254                           abort ();
2255                         arg = a.arg[dp->width_arg_index].a.a_int;
2256                         if (arg < 0)
2257                           {
2258                             /* "A negative field width is taken as a '-' flag
2259                                 followed by a positive field width."  */
2260                             flags |= FLAG_LEFT;
2261                             width = (unsigned int) (-arg);
2262                           }
2263                         else
2264                           width = arg;
2265                       }
2266                     else
2267                       {
2268                         const CHAR_T *digitp = dp->width_start;
2269
2270                         do
2271                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2272                         while (digitp != dp->width_end);
2273                       }
2274                     has_width = 1;
2275                   }
2276 #endif
2277
2278 #if !USE_SNPRINTF
2279                 /* Allocate a temporary buffer of sufficient size for calling
2280                    sprintf.  */
2281                 {
2282                   size_t precision;
2283
2284                   precision = 6;
2285                   if (dp->precision_start != dp->precision_end)
2286                     {
2287                       if (dp->precision_arg_index != ARG_NONE)
2288                         {
2289                           int arg;
2290
2291                           if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2292                             abort ();
2293                           arg = a.arg[dp->precision_arg_index].a.a_int;
2294                           precision = (arg < 0 ? 0 : arg);
2295                         }
2296                       else
2297                         {
2298                           const CHAR_T *digitp = dp->precision_start + 1;
2299
2300                           precision = 0;
2301                           while (digitp != dp->precision_end)
2302                             precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2303                         }
2304                     }
2305
2306                   switch (dp->conversion)
2307                     {
2308
2309                     case 'd': case 'i': case 'u':
2310 # if HAVE_LONG_LONG_INT
2311                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
2312                         tmp_length =
2313                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
2314                                           * 0.30103 /* binary -> decimal */
2315                                          )
2316                           + 1; /* turn floor into ceil */
2317                       else
2318 # endif
2319                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
2320                         tmp_length =
2321                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
2322                                           * 0.30103 /* binary -> decimal */
2323                                          )
2324                           + 1; /* turn floor into ceil */
2325                       else
2326                         tmp_length =
2327                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
2328                                           * 0.30103 /* binary -> decimal */
2329                                          )
2330                           + 1; /* turn floor into ceil */
2331                       if (tmp_length < precision)
2332                         tmp_length = precision;
2333                       /* Multiply by 2, as an estimate for FLAG_GROUP.  */
2334                       tmp_length = xsum (tmp_length, tmp_length);
2335                       /* Add 1, to account for a leading sign.  */
2336                       tmp_length = xsum (tmp_length, 1);
2337                       break;
2338
2339                     case 'o':
2340 # if HAVE_LONG_LONG_INT
2341                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
2342                         tmp_length =
2343                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
2344                                           * 0.333334 /* binary -> octal */
2345                                          )
2346                           + 1; /* turn floor into ceil */
2347                       else
2348 # endif
2349                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
2350                         tmp_length =
2351                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
2352                                           * 0.333334 /* binary -> octal */
2353                                          )
2354                           + 1; /* turn floor into ceil */
2355                       else
2356                         tmp_length =
2357                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
2358                                           * 0.333334 /* binary -> octal */
2359                                          )
2360                           + 1; /* turn floor into ceil */
2361                       if (tmp_length < precision)
2362                         tmp_length = precision;
2363                       /* Add 1, to account for a leading sign.  */
2364                       tmp_length = xsum (tmp_length, 1);
2365                       break;
2366
2367                     case 'x': case 'X':
2368 # if HAVE_LONG_LONG_INT
2369                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
2370                         tmp_length =
2371                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
2372                                           * 0.25 /* binary -> hexadecimal */
2373                                          )
2374                           + 1; /* turn floor into ceil */
2375                       else
2376 # endif
2377                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
2378                         tmp_length =
2379                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
2380                                           * 0.25 /* binary -> hexadecimal */
2381                                          )
2382                           + 1; /* turn floor into ceil */
2383                       else
2384                         tmp_length =
2385                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
2386                                           * 0.25 /* binary -> hexadecimal */
2387                                          )
2388                           + 1; /* turn floor into ceil */
2389                       if (tmp_length < precision)
2390                         tmp_length = precision;
2391                       /* Add 2, to account for a leading sign or alternate form.  */
2392                       tmp_length = xsum (tmp_length, 2);
2393                       break;
2394
2395                     case 'f': case 'F':
2396                       if (type == TYPE_LONGDOUBLE)
2397                         tmp_length =
2398                           (unsigned int) (LDBL_MAX_EXP
2399                                           * 0.30103 /* binary -> decimal */
2400                                           * 2 /* estimate for FLAG_GROUP */
2401                                          )
2402                           + 1 /* turn floor into ceil */
2403                           + 10; /* sign, decimal point etc. */
2404                       else
2405                         tmp_length =
2406                           (unsigned int) (DBL_MAX_EXP
2407                                           * 0.30103 /* binary -> decimal */
2408                                           * 2 /* estimate for FLAG_GROUP */
2409                                          )
2410                           + 1 /* turn floor into ceil */
2411                           + 10; /* sign, decimal point etc. */
2412                       tmp_length = xsum (tmp_length, precision);
2413                       break;
2414
2415                     case 'e': case 'E': case 'g': case 'G':
2416                       tmp_length =
2417                         12; /* sign, decimal point, exponent etc. */
2418                       tmp_length = xsum (tmp_length, precision);
2419                       break;
2420
2421                     case 'a': case 'A':
2422                       if (type == TYPE_LONGDOUBLE)
2423                         tmp_length =
2424                           (unsigned int) (LDBL_DIG
2425                                           * 0.831 /* decimal -> hexadecimal */
2426                                          )
2427                           + 1; /* turn floor into ceil */
2428                       else
2429                         tmp_length =
2430                           (unsigned int) (DBL_DIG
2431                                           * 0.831 /* decimal -> hexadecimal */
2432                                          )
2433                           + 1; /* turn floor into ceil */
2434                       if (tmp_length < precision)
2435                         tmp_length = precision;
2436                       /* Account for sign, decimal point etc. */
2437                       tmp_length = xsum (tmp_length, 12);
2438                       break;
2439
2440                     case 'c':
2441 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
2442                       if (type == TYPE_WIDE_CHAR)
2443                         tmp_length = MB_CUR_MAX;
2444                       else
2445 # endif
2446                         tmp_length = 1;
2447                       break;
2448
2449                     case 's':
2450 # if HAVE_WCHAR_T
2451                       if (type == TYPE_WIDE_STRING)
2452                         {
2453                           tmp_length =
2454                             local_wcslen (a.arg[dp->arg_index].a.a_wide_string);
2455
2456 #  if !WIDE_CHAR_VERSION
2457                           tmp_length = xtimes (tmp_length, MB_CUR_MAX);
2458 #  endif
2459                         }
2460                       else
2461 # endif
2462                         tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
2463                       break;
2464
2465                     case 'p':
2466                       tmp_length =
2467                         (unsigned int) (sizeof (void *) * CHAR_BIT
2468                                         * 0.25 /* binary -> hexadecimal */
2469                                        )
2470                           + 1 /* turn floor into ceil */
2471                           + 2; /* account for leading 0x */
2472                       break;
2473
2474                     default:
2475                       abort ();
2476                     }
2477
2478                   if (tmp_length < width)
2479                     tmp_length = width;
2480
2481                   tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2482                 }
2483
2484                 if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
2485                   tmp = tmpbuf;
2486                 else
2487                   {
2488                     size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
2489
2490                     if (size_overflow_p (tmp_memsize))
2491                       /* Overflow, would lead to out of memory.  */
2492                       goto out_of_memory;
2493                     tmp = (CHAR_T *) malloc (tmp_memsize);
2494                     if (tmp == NULL)
2495                       /* Out of memory.  */
2496                       goto out_of_memory;
2497                   }
2498 #endif
2499
2500                 /* Decide whether to perform the padding ourselves.  */
2501 #if NEED_PRINTF_FLAG_ZERO
2502                 switch (dp->conversion)
2503                   {
2504                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
2505                   case 'a': case 'A':
2506                     pad_ourselves = 1;
2507                     break;
2508                   default:
2509                     pad_ourselves = 0;
2510                     break;
2511                   }
2512 #endif
2513
2514                 /* Construct the format string for calling snprintf or
2515                    sprintf.  */
2516                 fbp = buf;
2517                 *fbp++ = '%';
2518 #if NEED_PRINTF_FLAG_GROUPING
2519                 /* The underlying implementation doesn't support the ' flag.
2520                    Produce no grouping characters in this case; this is
2521                    acceptable because the grouping is locale dependent.  */
2522 #else
2523                 if (flags & FLAG_GROUP)
2524                   *fbp++ = '\'';
2525 #endif
2526                 if (flags & FLAG_LEFT)
2527                   *fbp++ = '-';
2528                 if (flags & FLAG_SHOWSIGN)
2529                   *fbp++ = '+';
2530                 if (flags & FLAG_SPACE)
2531                   *fbp++ = ' ';
2532                 if (flags & FLAG_ALT)
2533                   *fbp++ = '#';
2534                 if (!pad_ourselves)
2535                   {
2536                     if (flags & FLAG_ZERO)
2537                       *fbp++ = '0';
2538                     if (dp->width_start != dp->width_end)
2539                       {
2540                         size_t n = dp->width_end - dp->width_start;
2541                         memcpy (fbp, dp->width_start, n * sizeof (CHAR_T));
2542                         fbp += n;
2543                       }
2544                   }
2545                 if (dp->precision_start != dp->precision_end)
2546                   {
2547                     size_t n = dp->precision_end - dp->precision_start;
2548                     memcpy (fbp, dp->precision_start, n * sizeof (CHAR_T));
2549                     fbp += n;
2550                   }
2551
2552                 switch (type)
2553                   {
2554 #if HAVE_LONG_LONG_INT
2555                   case TYPE_LONGLONGINT:
2556                   case TYPE_ULONGLONGINT:
2557 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
2558                     *fbp++ = 'I';
2559                     *fbp++ = '6';
2560                     *fbp++ = '4';
2561                     break;
2562 # else
2563                     *fbp++ = 'l';
2564                     /*FALLTHROUGH*/
2565 # endif
2566 #endif
2567                   case TYPE_LONGINT:
2568                   case TYPE_ULONGINT:
2569 #if HAVE_WINT_T
2570                   case TYPE_WIDE_CHAR:
2571 #endif
2572 #if HAVE_WCHAR_T
2573                   case TYPE_WIDE_STRING:
2574 #endif
2575                     *fbp++ = 'l';
2576                     break;
2577                   case TYPE_LONGDOUBLE:
2578                     *fbp++ = 'L';
2579                     break;
2580                   default:
2581                     break;
2582                   }
2583 #if NEED_PRINTF_DIRECTIVE_F
2584                 if (dp->conversion == 'F')
2585                   *fbp = 'f';
2586                 else
2587 #endif
2588                   *fbp = dp->conversion;
2589 #if USE_SNPRINTF
2590                 fbp[1] = '%';
2591                 fbp[2] = 'n';
2592                 fbp[3] = '\0';
2593 #else
2594                 fbp[1] = '\0';
2595 #endif
2596
2597                 /* Construct the arguments for calling snprintf or sprintf.  */
2598                 prefix_count = 0;
2599                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
2600                   {
2601                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2602                       abort ();
2603                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
2604                   }
2605                 if (dp->precision_arg_index != ARG_NONE)
2606                   {
2607                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2608                       abort ();
2609                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
2610                   }
2611
2612 #if USE_SNPRINTF
2613                 /* Prepare checking whether snprintf returns the count
2614                    via %n.  */
2615                 ENSURE_ALLOCATION (xsum (length, 1));
2616                 result[length] = '\0';
2617 #endif
2618
2619                 for (;;)
2620                   {
2621                     size_t maxlen;
2622                     int count;
2623                     int retcount;
2624
2625                     maxlen = allocated - length;
2626                     count = -1;
2627                     retcount = 0;
2628
2629 #if USE_SNPRINTF
2630                     /* SNPRINTF can fail if maxlen > INT_MAX.  */
2631                     if (maxlen > INT_MAX)
2632                       goto overflow;
2633 # define SNPRINTF_BUF(arg) \
2634                     switch (prefix_count)                                   \
2635                       {                                                     \
2636                       case 0:                                               \
2637                         retcount = SNPRINTF (result + length, maxlen, buf,  \
2638                                              arg, &count);                  \
2639                         break;                                              \
2640                       case 1:                                               \
2641                         retcount = SNPRINTF (result + length, maxlen, buf,  \
2642                                              prefixes[0], arg, &count);     \
2643                         break;                                              \
2644                       case 2:                                               \
2645                         retcount = SNPRINTF (result + length, maxlen, buf,  \
2646                                              prefixes[0], prefixes[1], arg, \
2647                                              &count);                       \
2648                         break;                                              \
2649                       default:                                              \
2650                         abort ();                                           \
2651                       }
2652 #else
2653 # define SNPRINTF_BUF(arg) \
2654                     switch (prefix_count)                                   \
2655                       {                                                     \
2656                       case 0:                                               \
2657                         count = sprintf (tmp, buf, arg);                    \
2658                         break;                                              \
2659                       case 1:                                               \
2660                         count = sprintf (tmp, buf, prefixes[0], arg);       \
2661                         break;                                              \
2662                       case 2:                                               \
2663                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
2664                                          arg);                              \
2665                         break;                                              \
2666                       default:                                              \
2667                         abort ();                                           \
2668                       }
2669 #endif
2670
2671                     switch (type)
2672                       {
2673                       case TYPE_SCHAR:
2674                         {
2675                           int arg = a.arg[dp->arg_index].a.a_schar;
2676                           SNPRINTF_BUF (arg);
2677                         }
2678                         break;
2679                       case TYPE_UCHAR:
2680                         {
2681                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
2682                           SNPRINTF_BUF (arg);
2683                         }
2684                         break;
2685                       case TYPE_SHORT:
2686                         {
2687                           int arg = a.arg[dp->arg_index].a.a_short;
2688                           SNPRINTF_BUF (arg);
2689                         }
2690                         break;
2691                       case TYPE_USHORT:
2692                         {
2693                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
2694                           SNPRINTF_BUF (arg);
2695                         }
2696                         break;
2697                       case TYPE_INT:
2698                         {
2699                           int arg = a.arg[dp->arg_index].a.a_int;
2700                           SNPRINTF_BUF (arg);
2701                         }
2702                         break;
2703                       case TYPE_UINT:
2704                         {
2705                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
2706                           SNPRINTF_BUF (arg);
2707                         }
2708                         break;
2709                       case TYPE_LONGINT:
2710                         {
2711                           long int arg = a.arg[dp->arg_index].a.a_longint;
2712                           SNPRINTF_BUF (arg);
2713                         }
2714                         break;
2715                       case TYPE_ULONGINT:
2716                         {
2717                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
2718                           SNPRINTF_BUF (arg);
2719                         }
2720                         break;
2721 #if HAVE_LONG_LONG_INT
2722                       case TYPE_LONGLONGINT:
2723                         {
2724                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
2725                           SNPRINTF_BUF (arg);
2726                         }
2727                         break;
2728                       case TYPE_ULONGLONGINT:
2729                         {
2730                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
2731                           SNPRINTF_BUF (arg);
2732                         }
2733                         break;
2734 #endif
2735                       case TYPE_DOUBLE:
2736                         {
2737                           double arg = a.arg[dp->arg_index].a.a_double;
2738                           SNPRINTF_BUF (arg);
2739                         }
2740                         break;
2741                       case TYPE_LONGDOUBLE:
2742                         {
2743                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
2744                           SNPRINTF_BUF (arg);
2745                         }
2746                         break;
2747                       case TYPE_CHAR:
2748                         {
2749                           int arg = a.arg[dp->arg_index].a.a_char;
2750                           SNPRINTF_BUF (arg);
2751                         }
2752                         break;
2753 #if HAVE_WINT_T
2754                       case TYPE_WIDE_CHAR:
2755                         {
2756                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
2757                           SNPRINTF_BUF (arg);
2758                         }
2759                         break;
2760 #endif
2761                       case TYPE_STRING:
2762                         {
2763                           const char *arg = a.arg[dp->arg_index].a.a_string;
2764                           SNPRINTF_BUF (arg);
2765                         }
2766                         break;
2767 #if HAVE_WCHAR_T
2768                       case TYPE_WIDE_STRING:
2769                         {
2770                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2771                           SNPRINTF_BUF (arg);
2772                         }
2773                         break;
2774 #endif
2775                       case TYPE_POINTER:
2776                         {
2777                           void *arg = a.arg[dp->arg_index].a.a_pointer;
2778                           SNPRINTF_BUF (arg);
2779                         }
2780                         break;
2781                       default:
2782                         abort ();
2783                       }
2784
2785 #if USE_SNPRINTF
2786                     /* Portability: Not all implementations of snprintf()
2787                        are ISO C 99 compliant.  Determine the number of
2788                        bytes that snprintf() has produced or would have
2789                        produced.  */
2790                     if (count >= 0)
2791                       {
2792                         /* Verify that snprintf() has NUL-terminated its
2793                            result.  */
2794                         if (count < maxlen && result[length + count] != '\0')
2795                           abort ();
2796                         /* Portability hack.  */
2797                         if (retcount > count)
2798                           count = retcount;
2799                       }
2800                     else
2801                       {
2802                         /* snprintf() doesn't understand the '%n'
2803                            directive.  */
2804                         if (fbp[1] != '\0')
2805                           {
2806                             /* Don't use the '%n' directive; instead, look
2807                                at the snprintf() return value.  */
2808                             fbp[1] = '\0';
2809                             continue;
2810                           }
2811                         else
2812                           {
2813                             /* Look at the snprintf() return value.  */
2814                             if (retcount < 0)
2815                               {
2816                                 /* HP-UX 10.20 snprintf() is doubly deficient:
2817                                    It doesn't understand the '%n' directive,
2818                                    *and* it returns -1 (rather than the length
2819                                    that would have been required) when the
2820                                    buffer is too small.  */
2821                                 size_t bigger_need =
2822                                   xsum (xtimes (allocated, 2), 12);
2823                                 ENSURE_ALLOCATION (bigger_need);
2824                                 continue;
2825                               }
2826                             else
2827                               count = retcount;
2828                           }
2829                       }
2830 #endif
2831
2832                     /* Attempt to handle failure.  */
2833                     if (count < 0)
2834                       {
2835                         if (!(result == resultbuf || result == NULL))
2836                           free (result);
2837                         if (buf_malloced != NULL)
2838                           free (buf_malloced);
2839                         CLEANUP ();
2840                         errno = EINVAL;
2841                         return NULL;
2842                       }
2843
2844                     /* Perform padding.  */
2845 #if NEED_PRINTF_FLAG_ZERO
2846                     if (pad_ourselves && has_width && count < width)
2847                       {
2848 # if USE_SNPRINTF
2849                         /* Make room for the result.  */
2850                         if (width >= maxlen)
2851                           {
2852                             /* Need at least width bytes.  But allocate
2853                                proportionally, to avoid looping eternally if
2854                                snprintf() reports a too small count.  */
2855                             size_t n =
2856                               xmax (xsum (length, width),
2857                                     xtimes (allocated, 2));
2858
2859                             length += count;
2860                             ENSURE_ALLOCATION (n);
2861                             length -= count;
2862                             maxlen = allocated - length; /* >= width */
2863                           }
2864 # endif
2865                         {
2866 # if USE_SNPRINTF
2867                           CHAR_T * const rp = result + length;
2868 # else
2869                           CHAR_T * const rp = tmp;
2870 # endif
2871                           CHAR_T *p = rp + count;
2872                           size_t pad = width - count;
2873                           CHAR_T *end = p + pad;
2874                           CHAR_T *pad_ptr = (*rp == '-' ? rp + 1 : rp);
2875                           /* No zero-padding of "inf" and "nan".  */
2876                           if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
2877                               || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
2878                             pad_ptr = NULL;
2879                           /* The generated string now extends from rp to p,
2880                              with the zero padding insertion point being at
2881                              pad_ptr.  */
2882
2883                           if (flags & FLAG_LEFT)
2884                             {
2885                               /* Pad with spaces on the right.  */
2886                               for (; pad > 0; pad--)
2887                                 *p++ = ' ';
2888                             }
2889                           else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
2890                             {
2891                               /* Pad with zeroes.  */
2892                               CHAR_T *q = end;
2893
2894                               while (p > pad_ptr)
2895                                 *--q = *--p;
2896                               for (; pad > 0; pad--)
2897                                 *p++ = '0';
2898                             }
2899                           else
2900                             {
2901                               /* Pad with spaces on the left.  */
2902                               CHAR_T *q = end;
2903
2904                               while (p > rp)
2905                                 *--q = *--p;
2906                               for (; pad > 0; pad--)
2907                                 *p++ = ' ';
2908                             }
2909
2910                           count = width; /* = count + pad = end - rp */
2911                         }
2912                       }
2913 #endif
2914
2915 #if !USE_SNPRINTF
2916                     if (count >= tmp_length)
2917                       /* tmp_length was incorrectly calculated - fix the
2918                          code above!  */
2919                       abort ();
2920 #endif
2921
2922                     /* Make room for the result.  */
2923                     if (count >= maxlen)
2924                       {
2925                         /* Need at least count bytes.  But allocate
2926                            proportionally, to avoid looping eternally if
2927                            snprintf() reports a too small count.  */
2928                         size_t n =
2929                           xmax (xsum (length, count), xtimes (allocated, 2));
2930
2931                         ENSURE_ALLOCATION (n);
2932 #if USE_SNPRINTF
2933                         continue;
2934 #endif
2935                       }
2936
2937 #if USE_SNPRINTF
2938                     /* The snprintf() result did fit.  */
2939 #else
2940                     /* Append the sprintf() result.  */
2941                     memcpy (result + length, tmp, count * sizeof (CHAR_T));
2942                     if (tmp != tmpbuf)
2943                       free (tmp);
2944 #endif
2945
2946 #if NEED_PRINTF_DIRECTIVE_F
2947                     if (dp->conversion == 'F')
2948                       {
2949                         /* Convert the %f result to upper case for %F.  */
2950                         CHAR_T *rp = result + length;
2951                         size_t rc;
2952                         for (rc = count; rc > 0; rc--, rp++)
2953                           if (*rp >= 'a' && *rp <= 'z')
2954                             *rp = *rp - 'a' + 'A';
2955                       }
2956 #endif
2957
2958                     length += count;
2959                     break;
2960                   }
2961               }
2962           }
2963       }
2964
2965     /* Add the final NUL.  */
2966     ENSURE_ALLOCATION (xsum (length, 1));
2967     result[length] = '\0';
2968
2969     if (result != resultbuf && length + 1 < allocated)
2970       {
2971         /* Shrink the allocated memory if possible.  */
2972         CHAR_T *memory;
2973
2974         memory = (CHAR_T *) realloc (result, (length + 1) * sizeof (CHAR_T));
2975         if (memory != NULL)
2976           result = memory;
2977       }
2978
2979     if (buf_malloced != NULL)
2980       free (buf_malloced);
2981     CLEANUP ();
2982     *lengthp = length;
2983     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
2984        says that snprintf() fails with errno = EOVERFLOW in this case, but
2985        that's only because snprintf() returns an 'int'.  This function does
2986        not have this limitation.  */
2987     return result;
2988
2989   overflow:
2990     if (!(result == resultbuf || result == NULL))
2991       free (result);
2992     if (buf_malloced != NULL)
2993       free (buf_malloced);
2994     CLEANUP ();
2995     errno = EOVERFLOW;
2996     return NULL;
2997
2998   out_of_memory:
2999     if (!(result == resultbuf || result == NULL))
3000       free (result);
3001     if (buf_malloced != NULL)
3002       free (buf_malloced);
3003   out_of_memory_1:
3004     CLEANUP ();
3005     errno = ENOMEM;
3006     return NULL;
3007   }
3008 }
3009
3010 #undef SNPRINTF
3011 #undef USE_SNPRINTF
3012 #undef PRINTF_PARSE
3013 #undef DIRECTIVES
3014 #undef DIRECTIVE
3015 #undef CHAR_T
3016 #undef VASNPRINTF