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