Optimize the case of huge precision.
[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;;)
627       {
628         mp_limb_t r_i =
629           (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
630           | (i < r_len ? r_ptr[i] << 1 : 0);
631         mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
632         if (r_i > b_i)
633           goto increment_q;
634         if (r_i < b_i)
635           goto keep_q;
636         if (i == 0)
637           break;
638         i--;
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, multiplied with 10^extra_zeroes, to decimal
660    representation.
661    Destroys the contents of a.
662    Return the allocated memory - containing the decimal digits in low-to-high
663    order, terminated with a NUL character - in case of success, NULL in case
664    of memory allocation failure.  */
665 static char *
666 convert_to_decimal (mpn_t a, size_t extra_zeroes)
667 {
668   mp_limb_t *a_ptr = a.limbs;
669   size_t a_len = a.nlimbs;
670   /* 0.03345 is slightly larger than log(2)/(9*log(10)).  */
671   size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
672   char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
673   if (c_ptr != NULL)
674     {
675       char *d_ptr = c_ptr;
676       for (; extra_zeroes > 0; extra_zeroes--)
677         *d_ptr++ = '0';
678       while (a_len > 0)
679         {
680           /* Divide a by 10^9, in-place.  */
681           mp_limb_t remainder = 0;
682           mp_limb_t *ptr = a_ptr + a_len;
683           size_t count;
684           for (count = a_len; count > 0; count--)
685             {
686               mp_twolimb_t num =
687                 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
688               *ptr = num / 1000000000;
689               remainder = num % 1000000000;
690             }
691           /* Store the remainder as 9 decimal digits.  */
692           for (count = 9; count > 0; count--)
693             {
694               *d_ptr++ = '0' + (remainder % 10);
695               remainder = remainder / 10;
696             }
697           /* Normalize a.  */
698           if (a_ptr[a_len - 1] == 0)
699             a_len--;
700         }
701       /* Remove leading zeroes.  */
702       while (d_ptr > c_ptr && d_ptr[-1] == '0')
703         d_ptr--;
704       /* But keep at least one zero.  */
705       if (d_ptr == c_ptr)
706         *d_ptr++ = '0';
707       /* Terminate the string.  */
708       *d_ptr = '\0';
709     }
710   return c_ptr;
711 }
712
713 /* Assuming x is finite and >= 0:
714    write x as x = 2^e * m, where m is a bignum.
715    Return the allocated memory in case of success, NULL in case of memory
716    allocation failure.  */
717 static void *
718 decode_long_double (long double x, int *ep, mpn_t *mp)
719 {
720   mpn_t m;
721   int exp;
722   long double y;
723   size_t i;
724
725   /* Allocate memory for result.  */
726   m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
727   m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
728   if (m.limbs == NULL)
729     return NULL;
730   /* Split into exponential part and mantissa.  */
731   y = frexpl (x, &exp);
732   if (!(y >= 0.0L && y < 1.0L))
733     abort ();
734   /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
735      latter is an integer.  */
736   /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
737      I'm not sure whether it's safe to cast a 'long double' value between
738      2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
739      'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
740      doesn't matter).  */
741 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
742 #  if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
743     {
744       mp_limb_t hi, lo;
745       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
746       hi = (int) y;
747       y -= hi;
748       if (!(y >= 0.0L && y < 1.0L))
749         abort ();
750       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
751       lo = (int) y;
752       y -= lo;
753       if (!(y >= 0.0L && y < 1.0L))
754         abort ();
755       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
756     }
757 #  else
758     {
759       mp_limb_t d;
760       y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
761       d = (int) y;
762       y -= d;
763       if (!(y >= 0.0L && y < 1.0L))
764         abort ();
765       m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
766     }
767 #  endif
768 # endif
769   for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
770     {
771       mp_limb_t hi, lo;
772       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
773       hi = (int) y;
774       y -= hi;
775       if (!(y >= 0.0L && y < 1.0L))
776         abort ();
777       y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
778       lo = (int) y;
779       y -= lo;
780       if (!(y >= 0.0L && y < 1.0L))
781         abort ();
782       m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
783     }
784   if (!(y == 0.0L))
785     abort ();
786   /* Normalise.  */
787   while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
788     m.nlimbs--;
789   *mp = m;
790   *ep = exp - LDBL_MANT_BIT;
791   return m.limbs;
792 }
793
794 /* Assuming x is finite and >= 0, and n is an integer:
795    Returns the decimal representation of round (x * 10^n).
796    Return the allocated memory - containing the decimal digits in low-to-high
797    order, terminated with a NUL character - in case of success, NULL in case
798    of memory allocation failure.  */
799 static char *
800 scale10_round_decimal_long_double (long double x, int n)
801 {
802   int e;
803   mpn_t m;
804   void *memory = decode_long_double (x, &e, &m);
805   int s;
806   size_t extra_zeroes;
807   unsigned int abs_n;
808   unsigned int abs_s;
809   mp_limb_t *pow5_ptr;
810   size_t pow5_len;
811   unsigned int s_limbs;
812   unsigned int s_bits;
813   mpn_t pow5;
814   mpn_t z;
815   void *z_memory;
816   char *digits;
817
818   if (memory == NULL)
819     return NULL;
820   /* x = 2^e * m, hence
821      y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
822        = round (2^s * 5^n * m).  */
823   s = e + n;
824   extra_zeroes = 0;
825   /* Factor out a common power of 10 if possible.  */
826   if (s > 0 && n > 0)
827     {
828       extra_zeroes = (s < n ? s : n);
829       s -= extra_zeroes;
830       n -= extra_zeroes;
831     }
832   /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
833      Before converting to decimal, we need to compute
834      z = round (2^s * 5^n * m).  */
835   /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
836      sign.  2.322 is slightly larger than log(5)/log(2).  */
837   abs_n = (n >= 0 ? n : -n);
838   abs_s = (s >= 0 ? s : -s);
839   pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
840                                     + abs_s / GMP_LIMB_BITS + 1)
841                                    * sizeof (mp_limb_t));
842   if (pow5_ptr == NULL)
843     {
844       free (memory);
845       return NULL;
846     }
847   /* Initialize with 1.  */
848   pow5_ptr[0] = 1;
849   pow5_len = 1;
850   /* Multiply with 5^|n|.  */
851   if (abs_n > 0)
852     {
853       static mp_limb_t const small_pow5[13 + 1] =
854         {
855           1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
856           48828125, 244140625, 1220703125
857         };
858       unsigned int n13;
859       for (n13 = 0; n13 <= abs_n; n13 += 13)
860         {
861           mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
862           size_t j;
863           mp_twolimb_t carry = 0;
864           for (j = 0; j < pow5_len; j++)
865             {
866               mp_limb_t digit2 = pow5_ptr[j];
867               carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
868               pow5_ptr[j] = (mp_limb_t) carry;
869               carry = carry >> GMP_LIMB_BITS;
870             }
871           if (carry > 0)
872             pow5_ptr[pow5_len++] = (mp_limb_t) carry;
873         }
874     }
875   s_limbs = abs_s / GMP_LIMB_BITS;
876   s_bits = abs_s % GMP_LIMB_BITS;
877   if (n >= 0 ? s >= 0 : s <= 0)
878     {
879       /* Multiply with 2^|s|.  */
880       if (s_bits > 0)
881         {
882           mp_limb_t *ptr = pow5_ptr;
883           mp_twolimb_t accu = 0;
884           size_t count;
885           for (count = pow5_len; count > 0; count--)
886             {
887               accu += (mp_twolimb_t) *ptr << s_bits;
888               *ptr++ = (mp_limb_t) accu;
889               accu = accu >> GMP_LIMB_BITS;
890             }
891           if (accu > 0)
892             {
893               *ptr = (mp_limb_t) accu;
894               pow5_len++;
895             }
896         }
897       if (s_limbs > 0)
898         {
899           size_t count;
900           for (count = pow5_len; count > 0;)
901             {
902               count--;
903               pow5_ptr[s_limbs + count] = pow5_ptr[count];
904             }
905           for (count = s_limbs; count > 0;)
906             {
907               count--;
908               pow5_ptr[count] = 0;
909             }
910           pow5_len += s_limbs;
911         }
912       pow5.limbs = pow5_ptr;
913       pow5.nlimbs = pow5_len;
914       if (n >= 0)
915         {
916           /* Multiply m with pow5.  No division needed.  */
917           z_memory = multiply (m, pow5, &z);
918         }
919       else
920         {
921           /* Divide m by pow5 and round.  */
922           z_memory = divide (m, pow5, &z);
923         }
924     }
925   else
926     {
927       pow5.limbs = pow5_ptr;
928       pow5.nlimbs = pow5_len;
929       if (n >= 0)
930         {
931           /* n >= 0, s < 0.
932              Multiply m with pow5, then divide by 2^|s|.  */
933           mpn_t numerator;
934           mpn_t denominator;
935           void *tmp_memory;
936           tmp_memory = multiply (m, pow5, &numerator);
937           if (tmp_memory == NULL)
938             {
939               free (pow5_ptr);
940               free (memory);
941               return NULL;
942             }
943           /* Construct 2^|s|.  */
944           {
945             mp_limb_t *ptr = pow5_ptr + pow5_len;
946             size_t i;
947             for (i = 0; i < s_limbs; i++)
948               ptr[i] = 0;
949             ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
950             denominator.limbs = ptr;
951             denominator.nlimbs = s_limbs + 1;
952           }
953           z_memory = divide (numerator, denominator, &z);
954           free (tmp_memory);
955         }
956       else
957         {
958           /* n < 0, s > 0.
959              Multiply m with 2^s, then divide by pow5.  */
960           mpn_t numerator;
961           mp_limb_t *num_ptr;
962           num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
963                                           * sizeof (mp_limb_t));
964           if (num_ptr == NULL)
965             {
966               free (pow5_ptr);
967               free (memory);
968               return NULL;
969             }
970           {
971             mp_limb_t *destptr = num_ptr;
972             {
973               size_t i;
974               for (i = 0; i < s_limbs; i++)
975                 *destptr++ = 0;
976             }
977             if (s_bits > 0)
978               {
979                 const mp_limb_t *sourceptr = m.limbs;
980                 mp_twolimb_t accu = 0;
981                 size_t count;
982                 for (count = m.nlimbs; count > 0; count--)
983                   {
984                     accu += (mp_twolimb_t) *sourceptr++ << s;
985                     *destptr++ = (mp_limb_t) accu;
986                     accu = accu >> GMP_LIMB_BITS;
987                   }
988                 if (accu > 0)
989                   *destptr++ = (mp_limb_t) accu;
990               }
991             else
992               {
993                 const mp_limb_t *sourceptr = m.limbs;
994                 size_t count;
995                 for (count = m.nlimbs; count > 0; count--)
996                   *destptr++ = *sourceptr++;
997               }
998             numerator.limbs = num_ptr;
999             numerator.nlimbs = destptr - num_ptr;
1000           }
1001           z_memory = divide (numerator, pow5, &z);
1002           free (num_ptr);
1003         }
1004     }
1005   free (pow5_ptr);
1006   free (memory);
1007
1008   /* Here y = round (x * 10^n) = z * 10^extra_zeroes.  */
1009
1010   if (z_memory == NULL)
1011     return NULL;
1012   digits = convert_to_decimal (z, extra_zeroes);
1013   free (z_memory);
1014   return digits;
1015 }
1016
1017 /* Assuming x is finite and > 0:
1018    Return an approximation for n with 10^n <= x < 10^(n+1).
1019    The approximation is usually the right n, but may be off by 1 sometimes.  */
1020 static int
1021 floorlog10l (long double x)
1022 {
1023   int exp;
1024   long double y;
1025   double z;
1026   double l;
1027
1028   /* Split into exponential part and mantissa.  */
1029   y = frexpl (x, &exp);
1030   if (!(y >= 0.0L && y < 1.0L))
1031     abort ();
1032   if (y == 0.0L)
1033     return INT_MIN;
1034   if (y < 0.5L)
1035     {
1036       while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1037         {
1038           y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1039           exp -= GMP_LIMB_BITS;
1040         }
1041       if (y < (1.0L / (1 << 16)))
1042         {
1043           y *= 1.0L * (1 << 16);
1044           exp -= 16;
1045         }
1046       if (y < (1.0L / (1 << 8)))
1047         {
1048           y *= 1.0L * (1 << 8);
1049           exp -= 8;
1050         }
1051       if (y < (1.0L / (1 << 4)))
1052         {
1053           y *= 1.0L * (1 << 4);
1054           exp -= 4;
1055         }
1056       if (y < (1.0L / (1 << 2)))
1057         {
1058           y *= 1.0L * (1 << 2);
1059           exp -= 2;
1060         }
1061       if (y < (1.0L / (1 << 1)))
1062         {
1063           y *= 1.0L * (1 << 1);
1064           exp -= 1;
1065         }
1066     }
1067   if (!(y >= 0.5L && y < 1.0L))
1068     abort ();
1069   /* Compute an approximation for l = log2(x) = exp + log2(y).  */
1070   l = exp;
1071   z = y;
1072   if (z < 0.70710678118654752444)
1073     {
1074       z *= 1.4142135623730950488;
1075       l -= 0.5;
1076     }
1077   if (z < 0.8408964152537145431)
1078     {
1079       z *= 1.1892071150027210667;
1080       l -= 0.25;
1081     }
1082   if (z < 0.91700404320467123175)
1083     {
1084       z *= 1.0905077326652576592;
1085       l -= 0.125;
1086     }
1087   if (z < 0.9576032806985736469)
1088     {
1089       z *= 1.0442737824274138403;
1090       l -= 0.0625;
1091     }
1092   /* Now 0.95 <= z <= 1.01.  */
1093   z = 1 - z;
1094   /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
1095      Four terms are enough to get an approximation with error < 10^-7.  */
1096   l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1097   /* Finally multiply with log(2)/log(10), yields an approximation for
1098      log10(x).  */
1099   l *= 0.30102999566398119523;
1100   /* Round down to the next integer.  */
1101   return (int) l + (l < 0 ? -1 : 0);
1102 }
1103
1104 #endif
1105
1106 CHAR_T *
1107 VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args)
1108 {
1109   DIRECTIVES d;
1110   arguments a;
1111
1112   if (PRINTF_PARSE (format, &d, &a) < 0)
1113     {
1114       errno = EINVAL;
1115       return NULL;
1116     }
1117
1118 #define CLEANUP() \
1119   free (d.dir);                                                         \
1120   if (a.arg)                                                            \
1121     free (a.arg);
1122
1123   if (printf_fetchargs (args, &a) < 0)
1124     {
1125       CLEANUP ();
1126       errno = EINVAL;
1127       return NULL;
1128     }
1129
1130   {
1131     size_t buf_neededlength;
1132     CHAR_T *buf;
1133     CHAR_T *buf_malloced;
1134     const CHAR_T *cp;
1135     size_t i;
1136     DIRECTIVE *dp;
1137     /* Output string accumulator.  */
1138     CHAR_T *result;
1139     size_t allocated;
1140     size_t length;
1141
1142     /* Allocate a small buffer that will hold a directive passed to
1143        sprintf or snprintf.  */
1144     buf_neededlength =
1145       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1146 #if HAVE_ALLOCA
1147     if (buf_neededlength < 4000 / sizeof (CHAR_T))
1148       {
1149         buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
1150         buf_malloced = NULL;
1151       }
1152     else
1153 #endif
1154       {
1155         size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));
1156         if (size_overflow_p (buf_memsize))
1157           goto out_of_memory_1;
1158         buf = (CHAR_T *) malloc (buf_memsize);
1159         if (buf == NULL)
1160           goto out_of_memory_1;
1161         buf_malloced = buf;
1162       }
1163
1164     if (resultbuf != NULL)
1165       {
1166         result = resultbuf;
1167         allocated = *lengthp;
1168       }
1169     else
1170       {
1171         result = NULL;
1172         allocated = 0;
1173       }
1174     length = 0;
1175     /* Invariants:
1176        result is either == resultbuf or == NULL or malloc-allocated.
1177        If length > 0, then result != NULL.  */
1178
1179     /* Ensures that allocated >= needed.  Aborts through a jump to
1180        out_of_memory if needed is SIZE_MAX or otherwise too big.  */
1181 #define ENSURE_ALLOCATION(needed) \
1182     if ((needed) > allocated)                                                \
1183       {                                                                      \
1184         size_t memory_size;                                                  \
1185         CHAR_T *memory;                                                      \
1186                                                                              \
1187         allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
1188         if ((needed) > allocated)                                            \
1189           allocated = (needed);                                              \
1190         memory_size = xtimes (allocated, sizeof (CHAR_T));                   \
1191         if (size_overflow_p (memory_size))                                   \
1192           goto out_of_memory;                                                \
1193         if (result == resultbuf || result == NULL)                           \
1194           memory = (CHAR_T *) malloc (memory_size);                          \
1195         else                                                                 \
1196           memory = (CHAR_T *) realloc (result, memory_size);                 \
1197         if (memory == NULL)                                                  \
1198           goto out_of_memory;                                                \
1199         if (result == resultbuf && length > 0)                               \
1200           memcpy (memory, result, length * sizeof (CHAR_T));                 \
1201         result = memory;                                                     \
1202       }
1203
1204     for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1205       {
1206         if (cp != dp->dir_start)
1207           {
1208             size_t n = dp->dir_start - cp;
1209             size_t augmented_length = xsum (length, n);
1210
1211             ENSURE_ALLOCATION (augmented_length);
1212             memcpy (result + length, cp, n * sizeof (CHAR_T));
1213             length = augmented_length;
1214           }
1215         if (i == d.count)
1216           break;
1217
1218         /* Execute a single directive.  */
1219         if (dp->conversion == '%')
1220           {
1221             size_t augmented_length;
1222
1223             if (!(dp->arg_index == ARG_NONE))
1224               abort ();
1225             augmented_length = xsum (length, 1);
1226             ENSURE_ALLOCATION (augmented_length);
1227             result[length] = '%';
1228             length = augmented_length;
1229           }
1230         else
1231           {
1232             if (!(dp->arg_index != ARG_NONE))
1233               abort ();
1234
1235             if (dp->conversion == 'n')
1236               {
1237                 switch (a.arg[dp->arg_index].type)
1238                   {
1239                   case TYPE_COUNT_SCHAR_POINTER:
1240                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1241                     break;
1242                   case TYPE_COUNT_SHORT_POINTER:
1243                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1244                     break;
1245                   case TYPE_COUNT_INT_POINTER:
1246                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1247                     break;
1248                   case TYPE_COUNT_LONGINT_POINTER:
1249                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1250                     break;
1251 #if HAVE_LONG_LONG_INT
1252                   case TYPE_COUNT_LONGLONGINT_POINTER:
1253                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1254                     break;
1255 #endif
1256                   default:
1257                     abort ();
1258                   }
1259               }
1260 #if NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
1261             else if ((dp->conversion == 'f' || dp->conversion == 'F'
1262                       || dp->conversion == 'e' || dp->conversion == 'E'
1263                       || dp->conversion == 'g' || dp->conversion == 'G')
1264                      && a.arg[dp->arg_index].type == TYPE_LONGDOUBLE)
1265               {
1266                 int flags = dp->flags;
1267                 int has_width;
1268                 size_t width;
1269                 int has_precision;
1270                 size_t precision;
1271                 long double arg;
1272                 size_t tmp_length;
1273                 CHAR_T tmpbuf[700];
1274                 CHAR_T *tmp;
1275                 CHAR_T *pad_ptr;
1276                 CHAR_T *p;
1277
1278                 has_width = 0;
1279                 width = 0;
1280                 if (dp->width_start != dp->width_end)
1281                   {
1282                     if (dp->width_arg_index != ARG_NONE)
1283                       {
1284                         int arg;
1285
1286                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1287                           abort ();
1288                         arg = a.arg[dp->width_arg_index].a.a_int;
1289                         if (arg < 0)
1290                           {
1291                             /* "A negative field width is taken as a '-' flag
1292                                 followed by a positive field width."  */
1293                             flags |= FLAG_LEFT;
1294                             width = (unsigned int) (-arg);
1295                           }
1296                         else
1297                           width = arg;
1298                       }
1299                     else
1300                       {
1301                         const CHAR_T *digitp = dp->width_start;
1302
1303                         do
1304                           width = xsum (xtimes (width, 10), *digitp++ - '0');
1305                         while (digitp != dp->width_end);
1306                       }
1307                     has_width = 1;
1308                   }
1309
1310                 has_precision = 0;
1311                 precision = 0;
1312                 if (dp->precision_start != dp->precision_end)
1313                   {
1314                     if (dp->precision_arg_index != ARG_NONE)
1315                       {
1316                         int arg;
1317
1318                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1319                           abort ();
1320                         arg = a.arg[dp->precision_arg_index].a.a_int;
1321                         /* "A negative precision is taken as if the precision
1322                             were omitted."  */
1323                         if (arg >= 0)
1324                           {
1325                             precision = arg;
1326                             has_precision = 1;
1327                           }
1328                       }
1329                     else
1330                       {
1331                         const CHAR_T *digitp = dp->precision_start + 1;
1332
1333                         precision = 0;
1334                         while (digitp != dp->precision_end)
1335                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1336                         has_precision = 1;
1337                       }
1338                   }
1339
1340                 arg = a.arg[dp->arg_index].a.a_longdouble;
1341
1342                 /* Allocate a temporary buffer of sufficient size.  */
1343                 tmp_length = LDBL_DIG + 1;
1344                 if (tmp_length < precision)
1345                   tmp_length = precision;
1346                 if (dp->conversion == 'f' || dp->conversion == 'F')
1347                   if (!(isnanl (arg) || arg + arg == arg))
1348                     {
1349                       int exponent = floorlog10l (arg < 0 ? -arg : arg);
1350                       if (exponent >= 0 && tmp_length < exponent + precision)
1351                         tmp_length = exponent + precision;
1352                     }
1353                 /* Account for sign, decimal point etc. */
1354                 tmp_length = xsum (tmp_length, 12);
1355
1356                 if (tmp_length < width)
1357                   tmp_length = width;
1358
1359                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1360
1361                 if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
1362                   tmp = tmpbuf;
1363                 else
1364                   {
1365                     size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
1366
1367                     if (size_overflow_p (tmp_memsize))
1368                       /* Overflow, would lead to out of memory.  */
1369                       goto out_of_memory;
1370                     tmp = (CHAR_T *) malloc (tmp_memsize);
1371                     if (tmp == NULL)
1372                       /* Out of memory.  */
1373                       goto out_of_memory;
1374                   }
1375
1376                 pad_ptr = NULL;
1377                 p = tmp;
1378
1379                 if (isnanl (arg))
1380                   {
1381                     if (dp->conversion >= 'A' && dp->conversion <= 'Z')
1382                       {
1383                         *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
1384                       }
1385                     else
1386                       {
1387                         *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
1388                       }
1389                   }
1390                 else
1391                   {
1392                     int sign = 0;
1393                     DECL_LONG_DOUBLE_ROUNDING
1394
1395                     BEGIN_LONG_DOUBLE_ROUNDING ();
1396
1397                     if (signbit (arg)) /* arg < 0.0L or negative zero */
1398                       {
1399                         sign = -1;
1400                         arg = -arg;
1401                       }
1402
1403                     if (sign < 0)
1404                       *p++ = '-';
1405                     else if (flags & FLAG_SHOWSIGN)
1406                       *p++ = '+';
1407                     else if (flags & FLAG_SPACE)
1408                       *p++ = ' ';
1409
1410                     if (arg > 0.0L && arg + arg == arg)
1411                       {
1412                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
1413                           {
1414                             *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
1415                           }
1416                         else
1417                           {
1418                             *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
1419                           }
1420                       }
1421                     else
1422                       {
1423                         pad_ptr = p;
1424
1425                         if (dp->conversion == 'f' || dp->conversion == 'F')
1426                           {
1427                             char *digits;
1428                             size_t ndigits;
1429
1430                             if (!has_precision)
1431                               precision = 6;
1432
1433                             digits =
1434                               scale10_round_decimal_long_double (arg, precision);
1435                             if (digits == NULL)
1436                               {
1437                                 END_LONG_DOUBLE_ROUNDING ();
1438                                 goto out_of_memory;
1439                               }
1440                             ndigits = strlen (digits);
1441
1442                             if (ndigits > precision)
1443                               do
1444                                 {
1445                                   --ndigits;
1446                                   *p++ = digits[ndigits];
1447                                 }
1448                               while (ndigits > precision);
1449                             else
1450                               *p++ = '0';
1451                             /* Here ndigits <= precision.  */
1452                             if ((flags & FLAG_ALT) || precision > 0)
1453                               {
1454                                 *p++ = decimal_point_char ();
1455                                 for (; precision > ndigits; precision--)
1456                                   *p++ = '0';
1457                                 while (ndigits > 0)
1458                                   {
1459                                     --ndigits;
1460                                     *p++ = digits[ndigits];
1461                                   }
1462                               }
1463
1464                             free (digits);
1465                           }
1466                         else if (dp->conversion == 'e' || dp->conversion == 'E')
1467                           {
1468                             int exponent;
1469
1470                             if (!has_precision)
1471                               precision = 6;
1472
1473                             if (arg == 0.0L)
1474                               {
1475                                 exponent = 0;
1476                                 *p++ = '0';
1477                                 if ((flags & FLAG_ALT) || precision > 0)
1478                                   {
1479                                     *p++ = decimal_point_char ();
1480                                     for (; precision > 0; precision--)
1481                                       *p++ = '0';
1482                                   }
1483                               }
1484                             else
1485                               {
1486                                 /* arg > 0.0L.  */
1487                                 int adjusted;
1488                                 char *digits;
1489                                 size_t ndigits;
1490
1491                                 exponent = floorlog10l (arg);
1492                                 adjusted = 0;
1493                                 for (;;)
1494                                   {
1495                                     digits =
1496                                       scale10_round_decimal_long_double (arg,
1497                                                                          (int)precision - exponent);
1498                                     if (digits == NULL)
1499                                       {
1500                                         END_LONG_DOUBLE_ROUNDING ();
1501                                         goto out_of_memory;
1502                                       }
1503                                     ndigits = strlen (digits);
1504
1505                                     if (ndigits == precision + 1)
1506                                       break;
1507                                     if (ndigits < precision
1508                                         || ndigits > precision + 2)
1509                                       /* The exponent was not guessed precisely
1510                                          enough.  */
1511                                       abort ();
1512                                     if (adjusted)
1513                                       /* None of two values of exponent is the
1514                                          right one.  Prevent an endless loop.  */
1515                                       abort ();
1516                                     free (digits);
1517                                     if (ndigits == precision)
1518                                       exponent -= 1;
1519                                     else
1520                                       exponent += 1;
1521                                     adjusted = 1;
1522                                   }
1523
1524                                 /* Here ndigits = precision+1.  */
1525                                 *p++ = digits[--ndigits];
1526                                 if ((flags & FLAG_ALT) || precision > 0)
1527                                   {
1528                                     *p++ = decimal_point_char ();
1529                                     while (ndigits > 0)
1530                                       {
1531                                         --ndigits;
1532                                         *p++ = digits[ndigits];
1533                                       }
1534                                   }
1535
1536                                 free (digits);
1537                               }
1538
1539                             *p++ = dp->conversion; /* 'e' or 'E' */
1540 # if WIDE_CHAR_VERSION
1541                             {
1542                               static const wchar_t decimal_format[] =
1543                                 { '%', '+', '.', '2', 'd', '\0' };
1544                               SNPRINTF (p, 6 + 1, decimal_format, exponent);
1545                             }
1546 # else
1547                             sprintf (p, "%+.2d", exponent);
1548 # endif
1549                             while (*p != '\0')
1550                               p++;
1551                           }
1552                         else if (dp->conversion == 'g' || dp->conversion == 'G')
1553                           {
1554                             /* This is not specified by POSIX, but
1555                                implementations appear to do this.  */
1556                             if (!has_precision)
1557                               precision = 6;
1558
1559                             if (precision == 0)
1560                               precision = 1;
1561                             /* precision >= 1.  */
1562
1563                             if (arg == 0.0L)
1564                               /* The exponent is 0, >= -4, < precision.
1565                                  Use fixed-point notation.  */
1566                               {
1567                                 size_t ndigits = precision;
1568                                 /* Number of trailing zeroes that have to be
1569                                    dropped.  */
1570                                 size_t nzeroes =
1571                                   (flags & FLAG_ALT ? 0 : precision - 1);
1572
1573                                 --ndigits;
1574                                 *p++ = '0';
1575                                 if ((flags & FLAG_ALT) || ndigits > nzeroes)
1576                                   {
1577                                     *p++ = decimal_point_char ();
1578                                     while (ndigits > nzeroes)
1579                                       {
1580                                         --ndigits;
1581                                         *p++ = '0';
1582                                       }
1583                                   }
1584                               }
1585                             else
1586                               {
1587                                 /* arg > 0.0L.  */
1588                                 int exponent;
1589                                 int adjusted;
1590                                 char *digits;
1591                                 size_t ndigits;
1592                                 size_t nzeroes;
1593
1594                                 exponent = floorlog10l (arg);
1595                                 adjusted = 0;
1596                                 for (;;)
1597                                   {
1598                                     digits =
1599                                       scale10_round_decimal_long_double (arg,
1600                                                                          (int)(precision - 1) - exponent);
1601                                     if (digits == NULL)
1602                                       {
1603                                         END_LONG_DOUBLE_ROUNDING ();
1604                                         goto out_of_memory;
1605                                       }
1606                                     ndigits = strlen (digits);
1607
1608                                     if (ndigits == precision)
1609                                       break;
1610                                     if (ndigits < precision - 1
1611                                         || ndigits > precision + 1)
1612                                       /* The exponent was not guessed precisely
1613                                          enough.  */
1614                                       abort ();
1615                                     if (adjusted)
1616                                       /* None of two values of exponent is the
1617                                          right one.  Prevent an endless loop.  */
1618                                       abort ();
1619                                     free (digits);
1620                                     if (ndigits < precision)
1621                                       exponent -= 1;
1622                                     else
1623                                       exponent += 1;
1624                                     adjusted = 1;
1625                                   }
1626                                 /* Here ndigits = precision.  */
1627
1628                                 /* Determine the number of trailing zeroes that
1629                                    have to be dropped.  */
1630                                 nzeroes = 0;
1631                                 if ((flags & FLAG_ALT) == 0)
1632                                   while (nzeroes < ndigits
1633                                          && digits[nzeroes] == '0')
1634                                     nzeroes++;
1635
1636                                 /* The exponent is now determined.  */
1637                                 if (exponent >= -4 && exponent < (long)precision)
1638                                   {
1639                                     /* Fixed-point notation: max(exponent,0)+1
1640                                        digits, then the decimal point, then the
1641                                        remaining digits without trailing zeroes.  */
1642                                     if (exponent >= 0)
1643                                       {
1644                                         size_t count = exponent + 1;
1645                                         /* Note: count <= precision = ndigits.  */
1646                                         for (; count > 0; count--)
1647                                           *p++ = digits[--ndigits];
1648                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
1649                                           {
1650                                             *p++ = decimal_point_char ();
1651                                             while (ndigits > nzeroes)
1652                                               {
1653                                                 --ndigits;
1654                                                 *p++ = digits[ndigits];
1655                                               }
1656                                           }
1657                                       }
1658                                     else
1659                                       {
1660                                         size_t count = -exponent - 1;
1661                                         *p++ = '0';
1662                                         *p++ = decimal_point_char ();
1663                                         for (; count > 0; count--)
1664                                           *p++ = '0';
1665                                         while (ndigits > nzeroes)
1666                                           {
1667                                             --ndigits;
1668                                             *p++ = digits[ndigits];
1669                                           }
1670                                       }
1671                                   }
1672                                 else
1673                                   {
1674                                     /* Exponential notation.  */
1675                                     *p++ = digits[--ndigits];
1676                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
1677                                       {
1678                                         *p++ = decimal_point_char ();
1679                                         while (ndigits > nzeroes)
1680                                           {
1681                                             --ndigits;
1682                                             *p++ = digits[ndigits];
1683                                           }
1684                                       }
1685                                     *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
1686 # if WIDE_CHAR_VERSION
1687                                     {
1688                                       static const wchar_t decimal_format[] =
1689                                         { '%', '+', '.', '2', 'd', '\0' };
1690                                       SNPRINTF (p, 6 + 1, decimal_format, exponent);
1691                                     }
1692 # else
1693                                     sprintf (p, "%+.2d", exponent);
1694 # endif
1695                                     while (*p != '\0')
1696                                       p++;
1697                                   }
1698
1699                                 free (digits);
1700                               }
1701                           }
1702                         else
1703                           abort ();
1704                       }
1705
1706                     END_LONG_DOUBLE_ROUNDING ();
1707                   }
1708
1709                 /* The generated string now extends from tmp to p, with the
1710                    zero padding insertion point being at pad_ptr.  */
1711                 if (has_width && p - tmp < width)
1712                   {
1713                     size_t pad = width - (p - tmp);
1714                     CHAR_T *end = p + pad;
1715
1716                     if (flags & FLAG_LEFT)
1717                       {
1718                         /* Pad with spaces on the right.  */
1719                         for (; pad > 0; pad--)
1720                           *p++ = ' ';
1721                       }
1722                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
1723                       {
1724                         /* Pad with zeroes.  */
1725                         CHAR_T *q = end;
1726
1727                         while (p > pad_ptr)
1728                           *--q = *--p;
1729                         for (; pad > 0; pad--)
1730                           *p++ = '0';
1731                       }
1732                     else
1733                       {
1734                         /* Pad with spaces on the left.  */
1735                         CHAR_T *q = end;
1736
1737                         while (p > tmp)
1738                           *--q = *--p;
1739                         for (; pad > 0; pad--)
1740                           *p++ = ' ';
1741                       }
1742
1743                     p = end;
1744                   }
1745
1746                 {
1747                   size_t count = p - tmp;
1748
1749                   if (count >= tmp_length)
1750                     /* tmp_length was incorrectly calculated - fix the
1751                        code above!  */
1752                     abort ();
1753
1754                   /* Make room for the result.  */
1755                   if (count >= allocated - length)
1756                     {
1757                       size_t n = xsum (length, count);
1758
1759                       ENSURE_ALLOCATION (n);
1760                     }
1761
1762                   /* Append the result.  */
1763                   memcpy (result + length, tmp, count * sizeof (CHAR_T));
1764                   if (tmp != tmpbuf)
1765                     free (tmp);
1766                   length += count;
1767                 }
1768               }
1769 #endif
1770 #if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
1771             else if (dp->conversion == 'a' || dp->conversion == 'A')
1772               {
1773                 arg_type type = a.arg[dp->arg_index].type;
1774                 int flags = dp->flags;
1775                 int has_width;
1776                 size_t width;
1777                 int has_precision;
1778                 size_t precision;
1779                 size_t tmp_length;
1780                 CHAR_T tmpbuf[700];
1781                 CHAR_T *tmp;
1782                 CHAR_T *pad_ptr;
1783                 CHAR_T *p;
1784
1785                 has_width = 0;
1786                 width = 0;
1787                 if (dp->width_start != dp->width_end)
1788                   {
1789                     if (dp->width_arg_index != ARG_NONE)
1790                       {
1791                         int arg;
1792
1793                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1794                           abort ();
1795                         arg = a.arg[dp->width_arg_index].a.a_int;
1796                         if (arg < 0)
1797                           {
1798                             /* "A negative field width is taken as a '-' flag
1799                                 followed by a positive field width."  */
1800                             flags |= FLAG_LEFT;
1801                             width = (unsigned int) (-arg);
1802                           }
1803                         else
1804                           width = arg;
1805                       }
1806                     else
1807                       {
1808                         const CHAR_T *digitp = dp->width_start;
1809
1810                         do
1811                           width = xsum (xtimes (width, 10), *digitp++ - '0');
1812                         while (digitp != dp->width_end);
1813                       }
1814                     has_width = 1;
1815                   }
1816
1817                 has_precision = 0;
1818                 precision = 0;
1819                 if (dp->precision_start != dp->precision_end)
1820                   {
1821                     if (dp->precision_arg_index != ARG_NONE)
1822                       {
1823                         int arg;
1824
1825                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1826                           abort ();
1827                         arg = a.arg[dp->precision_arg_index].a.a_int;
1828                         /* "A negative precision is taken as if the precision
1829                             were omitted."  */
1830                         if (arg >= 0)
1831                           {
1832                             precision = arg;
1833                             has_precision = 1;
1834                           }
1835                       }
1836                     else
1837                       {
1838                         const CHAR_T *digitp = dp->precision_start + 1;
1839
1840                         precision = 0;
1841                         while (digitp != dp->precision_end)
1842                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1843                         has_precision = 1;
1844                       }
1845                   }
1846
1847                 /* Allocate a temporary buffer of sufficient size.  */
1848                 if (type == TYPE_LONGDOUBLE)
1849                   tmp_length =
1850                     (unsigned int) ((LDBL_DIG + 1)
1851                                     * 0.831 /* decimal -> hexadecimal */
1852                                    )
1853                     + 1; /* turn floor into ceil */
1854                 else
1855                   tmp_length =
1856                     (unsigned int) ((DBL_DIG + 1)
1857                                     * 0.831 /* decimal -> hexadecimal */
1858                                    )
1859                     + 1; /* turn floor into ceil */
1860                 if (tmp_length < precision)
1861                   tmp_length = precision;
1862                 /* Account for sign, decimal point etc. */
1863                 tmp_length = xsum (tmp_length, 12);
1864
1865                 if (tmp_length < width)
1866                   tmp_length = width;
1867
1868                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1869
1870                 if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
1871                   tmp = tmpbuf;
1872                 else
1873                   {
1874                     size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
1875
1876                     if (size_overflow_p (tmp_memsize))
1877                       /* Overflow, would lead to out of memory.  */
1878                       goto out_of_memory;
1879                     tmp = (CHAR_T *) malloc (tmp_memsize);
1880                     if (tmp == NULL)
1881                       /* Out of memory.  */
1882                       goto out_of_memory;
1883                   }
1884
1885                 pad_ptr = NULL;
1886                 p = tmp;
1887                 if (type == TYPE_LONGDOUBLE)
1888                   {
1889                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
1890
1891                     if (isnanl (arg))
1892                       {
1893                         if (dp->conversion == 'A')
1894                           {
1895                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
1896                           }
1897                         else
1898                           {
1899                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
1900                           }
1901                       }
1902                     else
1903                       {
1904                         int sign = 0;
1905                         DECL_LONG_DOUBLE_ROUNDING
1906
1907                         BEGIN_LONG_DOUBLE_ROUNDING ();
1908
1909                         if (signbit (arg)) /* arg < 0.0L or negative zero */
1910                           {
1911                             sign = -1;
1912                             arg = -arg;
1913                           }
1914
1915                         if (sign < 0)
1916                           *p++ = '-';
1917                         else if (flags & FLAG_SHOWSIGN)
1918                           *p++ = '+';
1919                         else if (flags & FLAG_SPACE)
1920                           *p++ = ' ';
1921
1922                         if (arg > 0.0L && arg + arg == arg)
1923                           {
1924                             if (dp->conversion == 'A')
1925                               {
1926                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
1927                               }
1928                             else
1929                               {
1930                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
1931                               }
1932                           }
1933                         else
1934                           {
1935                             int exponent;
1936                             long double mantissa;
1937
1938                             if (arg > 0.0L)
1939                               mantissa = printf_frexpl (arg, &exponent);
1940                             else
1941                               {
1942                                 exponent = 0;
1943                                 mantissa = 0.0L;
1944                               }
1945
1946                             if (has_precision
1947                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
1948                               {
1949                                 /* Round the mantissa.  */
1950                                 long double tail = mantissa;
1951                                 size_t q;
1952
1953                                 for (q = precision; ; q--)
1954                                   {
1955                                     int digit = (int) tail;
1956                                     tail -= digit;
1957                                     if (q == 0)
1958                                       {
1959                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
1960                                           tail = 1 - tail;
1961                                         else
1962                                           tail = - tail;
1963                                         break;
1964                                       }
1965                                     tail *= 16.0L;
1966                                   }
1967                                 if (tail != 0.0L)
1968                                   for (q = precision; q > 0; q--)
1969                                     tail *= 0.0625L;
1970                                 mantissa += tail;
1971                               }
1972
1973                             *p++ = '0';
1974                             *p++ = dp->conversion - 'A' + 'X';
1975                             pad_ptr = p;
1976                             {
1977                               int digit;
1978
1979                               digit = (int) mantissa;
1980                               mantissa -= digit;
1981                               *p++ = '0' + digit;
1982                               if ((flags & FLAG_ALT)
1983                                   || mantissa > 0.0L || precision > 0)
1984                                 {
1985                                   *p++ = decimal_point_char ();
1986                                   /* This loop terminates because we assume
1987                                      that FLT_RADIX is a power of 2.  */
1988                                   while (mantissa > 0.0L)
1989                                     {
1990                                       mantissa *= 16.0L;
1991                                       digit = (int) mantissa;
1992                                       mantissa -= digit;
1993                                       *p++ = digit
1994                                              + (digit < 10
1995                                                 ? '0'
1996                                                 : dp->conversion - 10);
1997                                       if (precision > 0)
1998                                         precision--;
1999                                     }
2000                                   while (precision > 0)
2001                                     {
2002                                       *p++ = '0';
2003                                       precision--;
2004                                     }
2005                                 }
2006                               }
2007                               *p++ = dp->conversion - 'A' + 'P';
2008 # if WIDE_CHAR_VERSION
2009                               {
2010                                 static const wchar_t decimal_format[] =
2011                                   { '%', '+', 'd', '\0' };
2012                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
2013                               }
2014 # else
2015                               sprintf (p, "%+d", exponent);
2016 # endif
2017                               while (*p != '\0')
2018                                 p++;
2019                           }
2020
2021                         END_LONG_DOUBLE_ROUNDING ();
2022                       }
2023                   }
2024                 else
2025                   {
2026                     double arg = a.arg[dp->arg_index].a.a_double;
2027
2028                     if (isnan (arg))
2029                       {
2030                         if (dp->conversion == 'A')
2031                           {
2032                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2033                           }
2034                         else
2035                           {
2036                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2037                           }
2038                       }
2039                     else
2040                       {
2041                         int sign = 0;
2042
2043                         if (signbit (arg)) /* arg < 0.0 or negative zero */
2044                           {
2045                             sign = -1;
2046                             arg = -arg;
2047                           }
2048
2049                         if (sign < 0)
2050                           *p++ = '-';
2051                         else if (flags & FLAG_SHOWSIGN)
2052                           *p++ = '+';
2053                         else if (flags & FLAG_SPACE)
2054                           *p++ = ' ';
2055
2056                         if (arg > 0.0 && arg + arg == arg)
2057                           {
2058                             if (dp->conversion == 'A')
2059                               {
2060                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2061                               }
2062                             else
2063                               {
2064                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2065                               }
2066                           }
2067                         else
2068                           {
2069                             int exponent;
2070                             double mantissa;
2071
2072                             if (arg > 0.0)
2073                               mantissa = printf_frexp (arg, &exponent);
2074                             else
2075                               {
2076                                 exponent = 0;
2077                                 mantissa = 0.0;
2078                               }
2079
2080                             if (has_precision
2081                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
2082                               {
2083                                 /* Round the mantissa.  */
2084                                 double tail = mantissa;
2085                                 size_t q;
2086
2087                                 for (q = precision; ; q--)
2088                                   {
2089                                     int digit = (int) tail;
2090                                     tail -= digit;
2091                                     if (q == 0)
2092                                       {
2093                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
2094                                           tail = 1 - tail;
2095                                         else
2096                                           tail = - tail;
2097                                         break;
2098                                       }
2099                                     tail *= 16.0;
2100                                   }
2101                                 if (tail != 0.0)
2102                                   for (q = precision; q > 0; q--)
2103                                     tail *= 0.0625;
2104                                 mantissa += tail;
2105                               }
2106
2107                             *p++ = '0';
2108                             *p++ = dp->conversion - 'A' + 'X';
2109                             pad_ptr = p;
2110                             {
2111                               int digit;
2112
2113                               digit = (int) mantissa;
2114                               mantissa -= digit;
2115                               *p++ = '0' + digit;
2116                               if ((flags & FLAG_ALT)
2117                                   || mantissa > 0.0 || precision > 0)
2118                                 {
2119                                   *p++ = decimal_point_char ();
2120                                   /* This loop terminates because we assume
2121                                      that FLT_RADIX is a power of 2.  */
2122                                   while (mantissa > 0.0)
2123                                     {
2124                                       mantissa *= 16.0;
2125                                       digit = (int) mantissa;
2126                                       mantissa -= digit;
2127                                       *p++ = digit
2128                                              + (digit < 10
2129                                                 ? '0'
2130                                                 : dp->conversion - 10);
2131                                       if (precision > 0)
2132                                         precision--;
2133                                     }
2134                                   while (precision > 0)
2135                                     {
2136                                       *p++ = '0';
2137                                       precision--;
2138                                     }
2139                                 }
2140                               }
2141                               *p++ = dp->conversion - 'A' + 'P';
2142 # if WIDE_CHAR_VERSION
2143                               {
2144                                 static const wchar_t decimal_format[] =
2145                                   { '%', '+', 'd', '\0' };
2146                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
2147                               }
2148 # else
2149                               sprintf (p, "%+d", exponent);
2150 # endif
2151                               while (*p != '\0')
2152                                 p++;
2153                           }
2154                       }
2155                   }
2156                 /* The generated string now extends from tmp to p, with the
2157                    zero padding insertion point being at pad_ptr.  */
2158                 if (has_width && p - tmp < width)
2159                   {
2160                     size_t pad = width - (p - tmp);
2161                     CHAR_T *end = p + pad;
2162
2163                     if (flags & FLAG_LEFT)
2164                       {
2165                         /* Pad with spaces on the right.  */
2166                         for (; pad > 0; pad--)
2167                           *p++ = ' ';
2168                       }
2169                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
2170                       {
2171                         /* Pad with zeroes.  */
2172                         CHAR_T *q = end;
2173
2174                         while (p > pad_ptr)
2175                           *--q = *--p;
2176                         for (; pad > 0; pad--)
2177                           *p++ = '0';
2178                       }
2179                     else
2180                       {
2181                         /* Pad with spaces on the left.  */
2182                         CHAR_T *q = end;
2183
2184                         while (p > tmp)
2185                           *--q = *--p;
2186                         for (; pad > 0; pad--)
2187                           *p++ = ' ';
2188                       }
2189
2190                     p = end;
2191                   }
2192
2193                 {
2194                   size_t count = p - tmp;
2195
2196                   if (count >= tmp_length)
2197                     /* tmp_length was incorrectly calculated - fix the
2198                        code above!  */
2199                     abort ();
2200
2201                   /* Make room for the result.  */
2202                   if (count >= allocated - length)
2203                     {
2204                       size_t n = xsum (length, count);
2205
2206                       ENSURE_ALLOCATION (n);
2207                     }
2208
2209                   /* Append the result.  */
2210                   memcpy (result + length, tmp, count * sizeof (CHAR_T));
2211                   if (tmp != tmpbuf)
2212                     free (tmp);
2213                   length += count;
2214                 }
2215               }
2216 #endif
2217             else
2218               {
2219                 arg_type type = a.arg[dp->arg_index].type;
2220                 int flags = dp->flags;
2221 #if !USE_SNPRINTF || NEED_PRINTF_FLAG_ZERO
2222                 int has_width;
2223                 size_t width;
2224 #endif
2225 #if NEED_PRINTF_FLAG_ZERO
2226                 int pad_ourselves;
2227 #else
2228 #               define pad_ourselves 0
2229 #endif
2230                 CHAR_T *fbp;
2231                 unsigned int prefix_count;
2232                 int prefixes[2];
2233 #if !USE_SNPRINTF
2234                 size_t tmp_length;
2235                 CHAR_T tmpbuf[700];
2236                 CHAR_T *tmp;
2237 #endif
2238
2239 #if !USE_SNPRINTF || NEED_PRINTF_FLAG_ZERO
2240                 has_width = 0;
2241                 width = 0;
2242                 if (dp->width_start != dp->width_end)
2243                   {
2244                     if (dp->width_arg_index != ARG_NONE)
2245                       {
2246                         int arg;
2247
2248                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2249                           abort ();
2250                         arg = a.arg[dp->width_arg_index].a.a_int;
2251                         if (arg < 0)
2252                           {
2253                             /* "A negative field width is taken as a '-' flag
2254                                 followed by a positive field width."  */
2255                             flags |= FLAG_LEFT;
2256                             width = (unsigned int) (-arg);
2257                           }
2258                         else
2259                           width = arg;
2260                       }
2261                     else
2262                       {
2263                         const CHAR_T *digitp = dp->width_start;
2264
2265                         do
2266                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2267                         while (digitp != dp->width_end);
2268                       }
2269                     has_width = 1;
2270                   }
2271 #endif
2272
2273 #if !USE_SNPRINTF
2274                 /* Allocate a temporary buffer of sufficient size for calling
2275                    sprintf.  */
2276                 {
2277                   size_t precision;
2278
2279                   precision = 6;
2280                   if (dp->precision_start != dp->precision_end)
2281                     {
2282                       if (dp->precision_arg_index != ARG_NONE)
2283                         {
2284                           int arg;
2285
2286                           if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2287                             abort ();
2288                           arg = a.arg[dp->precision_arg_index].a.a_int;
2289                           precision = (arg < 0 ? 0 : arg);
2290                         }
2291                       else
2292                         {
2293                           const CHAR_T *digitp = dp->precision_start + 1;
2294
2295                           precision = 0;
2296                           while (digitp != dp->precision_end)
2297                             precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2298                         }
2299                     }
2300
2301                   switch (dp->conversion)
2302                     {
2303
2304                     case 'd': case 'i': case 'u':
2305 # if HAVE_LONG_LONG_INT
2306                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
2307                         tmp_length =
2308                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
2309                                           * 0.30103 /* binary -> decimal */
2310                                          )
2311                           + 1; /* turn floor into ceil */
2312                       else
2313 # endif
2314                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
2315                         tmp_length =
2316                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
2317                                           * 0.30103 /* binary -> decimal */
2318                                          )
2319                           + 1; /* turn floor into ceil */
2320                       else
2321                         tmp_length =
2322                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
2323                                           * 0.30103 /* binary -> decimal */
2324                                          )
2325                           + 1; /* turn floor into ceil */
2326                       if (tmp_length < precision)
2327                         tmp_length = precision;
2328                       /* Multiply by 2, as an estimate for FLAG_GROUP.  */
2329                       tmp_length = xsum (tmp_length, tmp_length);
2330                       /* Add 1, to account for a leading sign.  */
2331                       tmp_length = xsum (tmp_length, 1);
2332                       break;
2333
2334                     case 'o':
2335 # if HAVE_LONG_LONG_INT
2336                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
2337                         tmp_length =
2338                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
2339                                           * 0.333334 /* binary -> octal */
2340                                          )
2341                           + 1; /* turn floor into ceil */
2342                       else
2343 # endif
2344                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
2345                         tmp_length =
2346                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
2347                                           * 0.333334 /* binary -> octal */
2348                                          )
2349                           + 1; /* turn floor into ceil */
2350                       else
2351                         tmp_length =
2352                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
2353                                           * 0.333334 /* binary -> octal */
2354                                          )
2355                           + 1; /* turn floor into ceil */
2356                       if (tmp_length < precision)
2357                         tmp_length = precision;
2358                       /* Add 1, to account for a leading sign.  */
2359                       tmp_length = xsum (tmp_length, 1);
2360                       break;
2361
2362                     case 'x': case 'X':
2363 # if HAVE_LONG_LONG_INT
2364                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
2365                         tmp_length =
2366                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
2367                                           * 0.25 /* binary -> hexadecimal */
2368                                          )
2369                           + 1; /* turn floor into ceil */
2370                       else
2371 # endif
2372                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
2373                         tmp_length =
2374                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
2375                                           * 0.25 /* binary -> hexadecimal */
2376                                          )
2377                           + 1; /* turn floor into ceil */
2378                       else
2379                         tmp_length =
2380                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
2381                                           * 0.25 /* binary -> hexadecimal */
2382                                          )
2383                           + 1; /* turn floor into ceil */
2384                       if (tmp_length < precision)
2385                         tmp_length = precision;
2386                       /* Add 2, to account for a leading sign or alternate form.  */
2387                       tmp_length = xsum (tmp_length, 2);
2388                       break;
2389
2390                     case 'f': case 'F':
2391                       if (type == TYPE_LONGDOUBLE)
2392                         tmp_length =
2393                           (unsigned int) (LDBL_MAX_EXP
2394                                           * 0.30103 /* binary -> decimal */
2395                                           * 2 /* estimate for FLAG_GROUP */
2396                                          )
2397                           + 1 /* turn floor into ceil */
2398                           + 10; /* sign, decimal point etc. */
2399                       else
2400                         tmp_length =
2401                           (unsigned int) (DBL_MAX_EXP
2402                                           * 0.30103 /* binary -> decimal */
2403                                           * 2 /* estimate for FLAG_GROUP */
2404                                          )
2405                           + 1 /* turn floor into ceil */
2406                           + 10; /* sign, decimal point etc. */
2407                       tmp_length = xsum (tmp_length, precision);
2408                       break;
2409
2410                     case 'e': case 'E': case 'g': case 'G':
2411                       tmp_length =
2412                         12; /* sign, decimal point, exponent etc. */
2413                       tmp_length = xsum (tmp_length, precision);
2414                       break;
2415
2416                     case 'a': case 'A':
2417                       if (type == TYPE_LONGDOUBLE)
2418                         tmp_length =
2419                           (unsigned int) (LDBL_DIG
2420                                           * 0.831 /* decimal -> hexadecimal */
2421                                          )
2422                           + 1; /* turn floor into ceil */
2423                       else
2424                         tmp_length =
2425                           (unsigned int) (DBL_DIG
2426                                           * 0.831 /* decimal -> hexadecimal */
2427                                          )
2428                           + 1; /* turn floor into ceil */
2429                       if (tmp_length < precision)
2430                         tmp_length = precision;
2431                       /* Account for sign, decimal point etc. */
2432                       tmp_length = xsum (tmp_length, 12);
2433                       break;
2434
2435                     case 'c':
2436 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
2437                       if (type == TYPE_WIDE_CHAR)
2438                         tmp_length = MB_CUR_MAX;
2439                       else
2440 # endif
2441                         tmp_length = 1;
2442                       break;
2443
2444                     case 's':
2445 # if HAVE_WCHAR_T
2446                       if (type == TYPE_WIDE_STRING)
2447                         {
2448                           tmp_length =
2449                             local_wcslen (a.arg[dp->arg_index].a.a_wide_string);
2450
2451 #  if !WIDE_CHAR_VERSION
2452                           tmp_length = xtimes (tmp_length, MB_CUR_MAX);
2453 #  endif
2454                         }
2455                       else
2456 # endif
2457                         tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
2458                       break;
2459
2460                     case 'p':
2461                       tmp_length =
2462                         (unsigned int) (sizeof (void *) * CHAR_BIT
2463                                         * 0.25 /* binary -> hexadecimal */
2464                                        )
2465                           + 1 /* turn floor into ceil */
2466                           + 2; /* account for leading 0x */
2467                       break;
2468
2469                     default:
2470                       abort ();
2471                     }
2472
2473                   if (tmp_length < width)
2474                     tmp_length = width;
2475
2476                   tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2477                 }
2478
2479                 if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
2480                   tmp = tmpbuf;
2481                 else
2482                   {
2483                     size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
2484
2485                     if (size_overflow_p (tmp_memsize))
2486                       /* Overflow, would lead to out of memory.  */
2487                       goto out_of_memory;
2488                     tmp = (CHAR_T *) malloc (tmp_memsize);
2489                     if (tmp == NULL)
2490                       /* Out of memory.  */
2491                       goto out_of_memory;
2492                   }
2493 #endif
2494
2495                 /* Decide whether to perform the padding ourselves.  */
2496 #if NEED_PRINTF_FLAG_ZERO
2497                 switch (dp->conversion)
2498                   {
2499                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
2500                   case 'a': case 'A':
2501                     pad_ourselves = 1;
2502                     break;
2503                   default:
2504                     pad_ourselves = 0;
2505                     break;
2506                   }
2507 #endif
2508
2509                 /* Construct the format string for calling snprintf or
2510                    sprintf.  */
2511                 fbp = buf;
2512                 *fbp++ = '%';
2513 #if NEED_PRINTF_FLAG_GROUPING
2514                 /* The underlying implementation doesn't support the ' flag.
2515                    Produce no grouping characters in this case; this is
2516                    acceptable because the grouping is locale dependent.  */
2517 #else
2518                 if (flags & FLAG_GROUP)
2519                   *fbp++ = '\'';
2520 #endif
2521                 if (flags & FLAG_LEFT)
2522                   *fbp++ = '-';
2523                 if (flags & FLAG_SHOWSIGN)
2524                   *fbp++ = '+';
2525                 if (flags & FLAG_SPACE)
2526                   *fbp++ = ' ';
2527                 if (flags & FLAG_ALT)
2528                   *fbp++ = '#';
2529                 if (!pad_ourselves)
2530                   {
2531                     if (flags & FLAG_ZERO)
2532                       *fbp++ = '0';
2533                     if (dp->width_start != dp->width_end)
2534                       {
2535                         size_t n = dp->width_end - dp->width_start;
2536                         memcpy (fbp, dp->width_start, n * sizeof (CHAR_T));
2537                         fbp += n;
2538                       }
2539                   }
2540                 if (dp->precision_start != dp->precision_end)
2541                   {
2542                     size_t n = dp->precision_end - dp->precision_start;
2543                     memcpy (fbp, dp->precision_start, n * sizeof (CHAR_T));
2544                     fbp += n;
2545                   }
2546
2547                 switch (type)
2548                   {
2549 #if HAVE_LONG_LONG_INT
2550                   case TYPE_LONGLONGINT:
2551                   case TYPE_ULONGLONGINT:
2552 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
2553                     *fbp++ = 'I';
2554                     *fbp++ = '6';
2555                     *fbp++ = '4';
2556                     break;
2557 # else
2558                     *fbp++ = 'l';
2559                     /*FALLTHROUGH*/
2560 # endif
2561 #endif
2562                   case TYPE_LONGINT:
2563                   case TYPE_ULONGINT:
2564 #if HAVE_WINT_T
2565                   case TYPE_WIDE_CHAR:
2566 #endif
2567 #if HAVE_WCHAR_T
2568                   case TYPE_WIDE_STRING:
2569 #endif
2570                     *fbp++ = 'l';
2571                     break;
2572                   case TYPE_LONGDOUBLE:
2573                     *fbp++ = 'L';
2574                     break;
2575                   default:
2576                     break;
2577                   }
2578 #if NEED_PRINTF_DIRECTIVE_F
2579                 if (dp->conversion == 'F')
2580                   *fbp = 'f';
2581                 else
2582 #endif
2583                   *fbp = dp->conversion;
2584 #if USE_SNPRINTF
2585                 fbp[1] = '%';
2586                 fbp[2] = 'n';
2587                 fbp[3] = '\0';
2588 #else
2589                 fbp[1] = '\0';
2590 #endif
2591
2592                 /* Construct the arguments for calling snprintf or sprintf.  */
2593                 prefix_count = 0;
2594                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
2595                   {
2596                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2597                       abort ();
2598                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
2599                   }
2600                 if (dp->precision_arg_index != ARG_NONE)
2601                   {
2602                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2603                       abort ();
2604                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
2605                   }
2606
2607 #if USE_SNPRINTF
2608                 /* Prepare checking whether snprintf returns the count
2609                    via %n.  */
2610                 ENSURE_ALLOCATION (xsum (length, 1));
2611                 result[length] = '\0';
2612 #endif
2613
2614                 for (;;)
2615                   {
2616                     size_t maxlen;
2617                     int count;
2618                     int retcount;
2619
2620                     maxlen = allocated - length;
2621                     count = -1;
2622                     retcount = 0;
2623
2624 #if USE_SNPRINTF
2625                     /* SNPRINTF can fail if maxlen > INT_MAX.  */
2626                     if (maxlen > INT_MAX)
2627                       goto overflow;
2628 # define SNPRINTF_BUF(arg) \
2629                     switch (prefix_count)                                   \
2630                       {                                                     \
2631                       case 0:                                               \
2632                         retcount = SNPRINTF (result + length, maxlen, buf,  \
2633                                              arg, &count);                  \
2634                         break;                                              \
2635                       case 1:                                               \
2636                         retcount = SNPRINTF (result + length, maxlen, buf,  \
2637                                              prefixes[0], arg, &count);     \
2638                         break;                                              \
2639                       case 2:                                               \
2640                         retcount = SNPRINTF (result + length, maxlen, buf,  \
2641                                              prefixes[0], prefixes[1], arg, \
2642                                              &count);                       \
2643                         break;                                              \
2644                       default:                                              \
2645                         abort ();                                           \
2646                       }
2647 #else
2648 # define SNPRINTF_BUF(arg) \
2649                     switch (prefix_count)                                   \
2650                       {                                                     \
2651                       case 0:                                               \
2652                         count = sprintf (tmp, buf, arg);                    \
2653                         break;                                              \
2654                       case 1:                                               \
2655                         count = sprintf (tmp, buf, prefixes[0], arg);       \
2656                         break;                                              \
2657                       case 2:                                               \
2658                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
2659                                          arg);                              \
2660                         break;                                              \
2661                       default:                                              \
2662                         abort ();                                           \
2663                       }
2664 #endif
2665
2666                     switch (type)
2667                       {
2668                       case TYPE_SCHAR:
2669                         {
2670                           int arg = a.arg[dp->arg_index].a.a_schar;
2671                           SNPRINTF_BUF (arg);
2672                         }
2673                         break;
2674                       case TYPE_UCHAR:
2675                         {
2676                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
2677                           SNPRINTF_BUF (arg);
2678                         }
2679                         break;
2680                       case TYPE_SHORT:
2681                         {
2682                           int arg = a.arg[dp->arg_index].a.a_short;
2683                           SNPRINTF_BUF (arg);
2684                         }
2685                         break;
2686                       case TYPE_USHORT:
2687                         {
2688                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
2689                           SNPRINTF_BUF (arg);
2690                         }
2691                         break;
2692                       case TYPE_INT:
2693                         {
2694                           int arg = a.arg[dp->arg_index].a.a_int;
2695                           SNPRINTF_BUF (arg);
2696                         }
2697                         break;
2698                       case TYPE_UINT:
2699                         {
2700                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
2701                           SNPRINTF_BUF (arg);
2702                         }
2703                         break;
2704                       case TYPE_LONGINT:
2705                         {
2706                           long int arg = a.arg[dp->arg_index].a.a_longint;
2707                           SNPRINTF_BUF (arg);
2708                         }
2709                         break;
2710                       case TYPE_ULONGINT:
2711                         {
2712                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
2713                           SNPRINTF_BUF (arg);
2714                         }
2715                         break;
2716 #if HAVE_LONG_LONG_INT
2717                       case TYPE_LONGLONGINT:
2718                         {
2719                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
2720                           SNPRINTF_BUF (arg);
2721                         }
2722                         break;
2723                       case TYPE_ULONGLONGINT:
2724                         {
2725                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
2726                           SNPRINTF_BUF (arg);
2727                         }
2728                         break;
2729 #endif
2730                       case TYPE_DOUBLE:
2731                         {
2732                           double arg = a.arg[dp->arg_index].a.a_double;
2733                           SNPRINTF_BUF (arg);
2734                         }
2735                         break;
2736                       case TYPE_LONGDOUBLE:
2737                         {
2738                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
2739                           SNPRINTF_BUF (arg);
2740                         }
2741                         break;
2742                       case TYPE_CHAR:
2743                         {
2744                           int arg = a.arg[dp->arg_index].a.a_char;
2745                           SNPRINTF_BUF (arg);
2746                         }
2747                         break;
2748 #if HAVE_WINT_T
2749                       case TYPE_WIDE_CHAR:
2750                         {
2751                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
2752                           SNPRINTF_BUF (arg);
2753                         }
2754                         break;
2755 #endif
2756                       case TYPE_STRING:
2757                         {
2758                           const char *arg = a.arg[dp->arg_index].a.a_string;
2759                           SNPRINTF_BUF (arg);
2760                         }
2761                         break;
2762 #if HAVE_WCHAR_T
2763                       case TYPE_WIDE_STRING:
2764                         {
2765                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2766                           SNPRINTF_BUF (arg);
2767                         }
2768                         break;
2769 #endif
2770                       case TYPE_POINTER:
2771                         {
2772                           void *arg = a.arg[dp->arg_index].a.a_pointer;
2773                           SNPRINTF_BUF (arg);
2774                         }
2775                         break;
2776                       default:
2777                         abort ();
2778                       }
2779
2780 #if USE_SNPRINTF
2781                     /* Portability: Not all implementations of snprintf()
2782                        are ISO C 99 compliant.  Determine the number of
2783                        bytes that snprintf() has produced or would have
2784                        produced.  */
2785                     if (count >= 0)
2786                       {
2787                         /* Verify that snprintf() has NUL-terminated its
2788                            result.  */
2789                         if (count < maxlen && result[length + count] != '\0')
2790                           abort ();
2791                         /* Portability hack.  */
2792                         if (retcount > count)
2793                           count = retcount;
2794                       }
2795                     else
2796                       {
2797                         /* snprintf() doesn't understand the '%n'
2798                            directive.  */
2799                         if (fbp[1] != '\0')
2800                           {
2801                             /* Don't use the '%n' directive; instead, look
2802                                at the snprintf() return value.  */
2803                             fbp[1] = '\0';
2804                             continue;
2805                           }
2806                         else
2807                           {
2808                             /* Look at the snprintf() return value.  */
2809                             if (retcount < 0)
2810                               {
2811                                 /* HP-UX 10.20 snprintf() is doubly deficient:
2812                                    It doesn't understand the '%n' directive,
2813                                    *and* it returns -1 (rather than the length
2814                                    that would have been required) when the
2815                                    buffer is too small.  */
2816                                 size_t bigger_need =
2817                                   xsum (xtimes (allocated, 2), 12);
2818                                 ENSURE_ALLOCATION (bigger_need);
2819                                 continue;
2820                               }
2821                             else
2822                               count = retcount;
2823                           }
2824                       }
2825 #endif
2826
2827                     /* Attempt to handle failure.  */
2828                     if (count < 0)
2829                       {
2830                         if (!(result == resultbuf || result == NULL))
2831                           free (result);
2832                         if (buf_malloced != NULL)
2833                           free (buf_malloced);
2834                         CLEANUP ();
2835                         errno = EINVAL;
2836                         return NULL;
2837                       }
2838
2839                     /* Make room for the result.  */
2840                     if (count >= maxlen)
2841                       {
2842                         /* Need at least count bytes.  But allocate
2843                            proportionally, to avoid looping eternally if
2844                            snprintf() reports a too small count.  */
2845                         size_t n =
2846                           xmax (xsum (length, count), xtimes (allocated, 2));
2847
2848                         ENSURE_ALLOCATION (n);
2849 #if USE_SNPRINTF
2850                         continue;
2851 #else
2852                         maxlen = allocated - length;
2853 #endif
2854                       }
2855
2856                     /* Perform padding.  */
2857 #if NEED_PRINTF_FLAG_ZERO
2858                     if (pad_ourselves && has_width && count < width)
2859                       {
2860 # if USE_SNPRINTF
2861                         /* Make room for the result.  */
2862                         if (width >= maxlen)
2863                           {
2864                             /* Need at least width bytes.  But allocate
2865                                proportionally, to avoid looping eternally if
2866                                snprintf() reports a too small count.  */
2867                             size_t n =
2868                               xmax (xsum (length + 1, width),
2869                                     xtimes (allocated, 2));
2870
2871                             length += count;
2872                             ENSURE_ALLOCATION (n);
2873                             length -= count;
2874                             maxlen = allocated - length; /* > width */
2875                           }
2876                         /* Here width < maxlen.  */
2877 # endif
2878                         {
2879 # if USE_SNPRINTF
2880                           CHAR_T * const rp = result + length;
2881 # else
2882                           CHAR_T * const rp = tmp;
2883 # endif
2884                           CHAR_T *p = rp + count;
2885                           size_t pad = width - count;
2886                           CHAR_T *end = p + pad;
2887                           CHAR_T *pad_ptr = (*rp == '-' ? rp + 1 : rp);
2888                           /* No zero-padding of "inf" and "nan".  */
2889                           if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
2890                               || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
2891                             pad_ptr = NULL;
2892                           /* The generated string now extends from rp to p,
2893                              with the zero padding insertion point being at
2894                              pad_ptr.  */
2895
2896                           if (flags & FLAG_LEFT)
2897                             {
2898                               /* Pad with spaces on the right.  */
2899                               for (; pad > 0; pad--)
2900                                 *p++ = ' ';
2901                             }
2902                           else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
2903                             {
2904                               /* Pad with zeroes.  */
2905                               CHAR_T *q = end;
2906
2907                               while (p > pad_ptr)
2908                                 *--q = *--p;
2909                               for (; pad > 0; pad--)
2910                                 *p++ = '0';
2911                             }
2912                           else
2913                             {
2914                               /* Pad with spaces on the left.  */
2915                               CHAR_T *q = end;
2916
2917                               while (p > rp)
2918                                 *--q = *--p;
2919                               for (; pad > 0; pad--)
2920                                 *p++ = ' ';
2921                             }
2922
2923                           count = width; /* = count + pad = end - rp */
2924                         }
2925                       }
2926 #endif
2927
2928 #if !USE_SNPRINTF
2929                     if (count >= tmp_length)
2930                       /* tmp_length was incorrectly calculated - fix the
2931                          code above!  */
2932                       abort ();
2933 #endif
2934
2935                     /* Here still count < maxlen.  */
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