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