Code

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