Code

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