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