]> git.cworth.org Git - tar/blob - gnu/vasnprintf.c
Imported Upstream version 1.24
[tar] / gnu / vasnprintf.c
1 /* -*- buffer-read-only: t -*- vi: set ro: */
2 /* DO NOT EDIT! GENERATED AUTOMATICALLY! */
3 /* vsprintf with automatic memory allocation.
4    Copyright (C) 1999, 2002-2010 Free Software Foundation, Inc.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License along
17    with this program; if not, write to the Free Software Foundation,
18    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20 /* This file can be parametrized with the following macros:
21      VASNPRINTF         The name of the function being defined.
22      FCHAR_T            The element type of the format string.
23      DCHAR_T            The element type of the destination (result) string.
24      FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
25                         in the format string are ASCII. MUST be set if
26                         FCHAR_T and DCHAR_T are not the same type.
27      DIRECTIVE          Structure denoting a format directive.
28                         Depends on FCHAR_T.
29      DIRECTIVES         Structure denoting the set of format directives of a
30                         format string.  Depends on FCHAR_T.
31      PRINTF_PARSE       Function that parses a format string.
32                         Depends on FCHAR_T.
33      DCHAR_CPY          memcpy like function for DCHAR_T[] arrays.
34      DCHAR_SET          memset like function for DCHAR_T[] arrays.
35      DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
36      SNPRINTF           The system's snprintf (or similar) function.
37                         This may be either snprintf or swprintf.
38      TCHAR_T            The element type of the argument and result string
39                         of the said SNPRINTF function.  This may be either
40                         char or wchar_t.  The code exploits that
41                         sizeof (TCHAR_T) | sizeof (DCHAR_T) and
42                         alignof (TCHAR_T) <= alignof (DCHAR_T).
43      DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
44      DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
45      DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
46      DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
47      DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.  */
48
49 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
50    This must come before <config.h> because <config.h> may include
51    <features.h>, and once <features.h> has been included, it's too late.  */
52 #ifndef _GNU_SOURCE
53 # define _GNU_SOURCE    1
54 #endif
55
56 #ifndef VASNPRINTF
57 # include <config.h>
58 #endif
59 #ifndef IN_LIBINTL
60 # include <alloca.h>
61 #endif
62
63 /* Specification.  */
64 #ifndef VASNPRINTF
65 # if WIDE_CHAR_VERSION
66 #  include "vasnwprintf.h"
67 # else
68 #  include "vasnprintf.h"
69 # endif
70 #endif
71
72 #include <locale.h>     /* localeconv() */
73 #include <stdio.h>      /* snprintf(), sprintf() */
74 #include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
75 #include <string.h>     /* memcpy(), strlen() */
76 #include <errno.h>      /* errno */
77 #include <limits.h>     /* CHAR_BIT */
78 #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP */
79 #if HAVE_NL_LANGINFO
80 # include <langinfo.h>
81 #endif
82 #ifndef VASNPRINTF
83 # if WIDE_CHAR_VERSION
84 #  include "wprintf-parse.h"
85 # else
86 #  include "printf-parse.h"
87 # endif
88 #endif
89
90 /* Checked size_t computations.  */
91 #include "xsize.h"
92
93 #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 __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   free (d.dir);                                                         \
1759   if (a.arg)                                                            \
1760     free (a.arg);
1761
1762   if (PRINTF_FETCHARGS (args, &a) < 0)
1763     {
1764       CLEANUP ();
1765       errno = EINVAL;
1766       return NULL;
1767     }
1768
1769   {
1770     size_t buf_neededlength;
1771     TCHAR_T *buf;
1772     TCHAR_T *buf_malloced;
1773     const FCHAR_T *cp;
1774     size_t i;
1775     DIRECTIVE *dp;
1776     /* Output string accumulator.  */
1777     DCHAR_T *result;
1778     size_t allocated;
1779     size_t length;
1780
1781     /* Allocate a small buffer that will hold a directive passed to
1782        sprintf or snprintf.  */
1783     buf_neededlength =
1784       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1785 #if HAVE_ALLOCA
1786     if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1787       {
1788         buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1789         buf_malloced = NULL;
1790       }
1791     else
1792 #endif
1793       {
1794         size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1795         if (size_overflow_p (buf_memsize))
1796           goto out_of_memory_1;
1797         buf = (TCHAR_T *) malloc (buf_memsize);
1798         if (buf == NULL)
1799           goto out_of_memory_1;
1800         buf_malloced = buf;
1801       }
1802
1803     if (resultbuf != NULL)
1804       {
1805         result = resultbuf;
1806         allocated = *lengthp;
1807       }
1808     else
1809       {
1810         result = NULL;
1811         allocated = 0;
1812       }
1813     length = 0;
1814     /* Invariants:
1815        result is either == resultbuf or == NULL or malloc-allocated.
1816        If length > 0, then result != NULL.  */
1817
1818     /* Ensures that allocated >= needed.  Aborts through a jump to
1819        out_of_memory if needed is SIZE_MAX or otherwise too big.  */
1820 #define ENSURE_ALLOCATION(needed) \
1821     if ((needed) > allocated)                                                \
1822       {                                                                      \
1823         size_t memory_size;                                                  \
1824         DCHAR_T *memory;                                                     \
1825                                                                              \
1826         allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
1827         if ((needed) > allocated)                                            \
1828           allocated = (needed);                                              \
1829         memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
1830         if (size_overflow_p (memory_size))                                   \
1831           goto out_of_memory;                                                \
1832         if (result == resultbuf || result == NULL)                           \
1833           memory = (DCHAR_T *) malloc (memory_size);                         \
1834         else                                                                 \
1835           memory = (DCHAR_T *) realloc (result, memory_size);                \
1836         if (memory == NULL)                                                  \
1837           goto out_of_memory;                                                \
1838         if (result == resultbuf && length > 0)                               \
1839           DCHAR_CPY (memory, result, length);                                \
1840         result = memory;                                                     \
1841       }
1842
1843     for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1844       {
1845         if (cp != dp->dir_start)
1846           {
1847             size_t n = dp->dir_start - cp;
1848             size_t augmented_length = xsum (length, n);
1849
1850             ENSURE_ALLOCATION (augmented_length);
1851             /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
1852                need that the format string contains only ASCII characters
1853                if FCHAR_T and DCHAR_T are not the same type.  */
1854             if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1855               {
1856                 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1857                 length = augmented_length;
1858               }
1859             else
1860               {
1861                 do
1862                   result[length++] = (unsigned char) *cp++;
1863                 while (--n > 0);
1864               }
1865           }
1866         if (i == d.count)
1867           break;
1868
1869         /* Execute a single directive.  */
1870         if (dp->conversion == '%')
1871           {
1872             size_t augmented_length;
1873
1874             if (!(dp->arg_index == ARG_NONE))
1875               abort ();
1876             augmented_length = xsum (length, 1);
1877             ENSURE_ALLOCATION (augmented_length);
1878             result[length] = '%';
1879             length = augmented_length;
1880           }
1881         else
1882           {
1883             if (!(dp->arg_index != ARG_NONE))
1884               abort ();
1885
1886             if (dp->conversion == 'n')
1887               {
1888                 switch (a.arg[dp->arg_index].type)
1889                   {
1890                   case TYPE_COUNT_SCHAR_POINTER:
1891                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1892                     break;
1893                   case TYPE_COUNT_SHORT_POINTER:
1894                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1895                     break;
1896                   case TYPE_COUNT_INT_POINTER:
1897                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1898                     break;
1899                   case TYPE_COUNT_LONGINT_POINTER:
1900                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1901                     break;
1902 #if HAVE_LONG_LONG_INT
1903                   case TYPE_COUNT_LONGLONGINT_POINTER:
1904                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1905                     break;
1906 #endif
1907                   default:
1908                     abort ();
1909                   }
1910               }
1911 #if ENABLE_UNISTDIO
1912             /* The unistdio extensions.  */
1913             else if (dp->conversion == 'U')
1914               {
1915                 arg_type type = a.arg[dp->arg_index].type;
1916                 int flags = dp->flags;
1917                 int has_width;
1918                 size_t width;
1919                 int has_precision;
1920                 size_t precision;
1921
1922                 has_width = 0;
1923                 width = 0;
1924                 if (dp->width_start != dp->width_end)
1925                   {
1926                     if (dp->width_arg_index != ARG_NONE)
1927                       {
1928                         int arg;
1929
1930                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1931                           abort ();
1932                         arg = a.arg[dp->width_arg_index].a.a_int;
1933                         if (arg < 0)
1934                           {
1935                             /* "A negative field width is taken as a '-' flag
1936                                 followed by a positive field width."  */
1937                             flags |= FLAG_LEFT;
1938                             width = (unsigned int) (-arg);
1939                           }
1940                         else
1941                           width = arg;
1942                       }
1943                     else
1944                       {
1945                         const FCHAR_T *digitp = dp->width_start;
1946
1947                         do
1948                           width = xsum (xtimes (width, 10), *digitp++ - '0');
1949                         while (digitp != dp->width_end);
1950                       }
1951                     has_width = 1;
1952                   }
1953
1954                 has_precision = 0;
1955                 precision = 0;
1956                 if (dp->precision_start != dp->precision_end)
1957                   {
1958                     if (dp->precision_arg_index != ARG_NONE)
1959                       {
1960                         int arg;
1961
1962                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1963                           abort ();
1964                         arg = a.arg[dp->precision_arg_index].a.a_int;
1965                         /* "A negative precision is taken as if the precision
1966                             were omitted."  */
1967                         if (arg >= 0)
1968                           {
1969                             precision = arg;
1970                             has_precision = 1;
1971                           }
1972                       }
1973                     else
1974                       {
1975                         const FCHAR_T *digitp = dp->precision_start + 1;
1976
1977                         precision = 0;
1978                         while (digitp != dp->precision_end)
1979                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1980                         has_precision = 1;
1981                       }
1982                   }
1983
1984                 switch (type)
1985                   {
1986                   case TYPE_U8_STRING:
1987                     {
1988                       const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
1989                       const uint8_t *arg_end;
1990                       size_t characters;
1991
1992                       if (has_precision)
1993                         {
1994                           /* Use only PRECISION characters, from the left.  */
1995                           arg_end = arg;
1996                           characters = 0;
1997                           for (; precision > 0; precision--)
1998                             {
1999                               int count = u8_strmblen (arg_end);
2000                               if (count == 0)
2001                                 break;
2002                               if (count < 0)
2003                                 {
2004                                   if (!(result == resultbuf || result == NULL))
2005                                     free (result);
2006                                   if (buf_malloced != NULL)
2007                                     free (buf_malloced);
2008                                   CLEANUP ();
2009                                   errno = EILSEQ;
2010                                   return NULL;
2011                                 }
2012                               arg_end += count;
2013                               characters++;
2014                             }
2015                         }
2016                       else if (has_width)
2017                         {
2018                           /* Use the entire string, and count the number of
2019                              characters.  */
2020                           arg_end = arg;
2021                           characters = 0;
2022                           for (;;)
2023                             {
2024                               int count = u8_strmblen (arg_end);
2025                               if (count == 0)
2026                                 break;
2027                               if (count < 0)
2028                                 {
2029                                   if (!(result == resultbuf || result == NULL))
2030                                     free (result);
2031                                   if (buf_malloced != NULL)
2032                                     free (buf_malloced);
2033                                   CLEANUP ();
2034                                   errno = EILSEQ;
2035                                   return NULL;
2036                                 }
2037                               arg_end += count;
2038                               characters++;
2039                             }
2040                         }
2041                       else
2042                         {
2043                           /* Use the entire string.  */
2044                           arg_end = arg + u8_strlen (arg);
2045                           /* The number of characters doesn't matter.  */
2046                           characters = 0;
2047                         }
2048
2049                       if (has_width && width > characters
2050                           && !(dp->flags & FLAG_LEFT))
2051                         {
2052                           size_t n = width - characters;
2053                           ENSURE_ALLOCATION (xsum (length, n));
2054                           DCHAR_SET (result + length, ' ', n);
2055                           length += n;
2056                         }
2057
2058 # if DCHAR_IS_UINT8_T
2059                       {
2060                         size_t n = arg_end - arg;
2061                         ENSURE_ALLOCATION (xsum (length, n));
2062                         DCHAR_CPY (result + length, arg, n);
2063                         length += n;
2064                       }
2065 # else
2066                       { /* Convert.  */
2067                         DCHAR_T *converted = result + length;
2068                         size_t converted_len = allocated - length;
2069 #  if DCHAR_IS_TCHAR
2070                         /* Convert from UTF-8 to locale encoding.  */
2071                         converted =
2072                           u8_conv_to_encoding (locale_charset (),
2073                                                iconveh_question_mark,
2074                                                arg, arg_end - arg, NULL,
2075                                                converted, &converted_len);
2076 #  else
2077                         /* Convert from UTF-8 to UTF-16/UTF-32.  */
2078                         converted =
2079                           U8_TO_DCHAR (arg, arg_end - arg,
2080                                        converted, &converted_len);
2081 #  endif
2082                         if (converted == NULL)
2083                           {
2084                             int saved_errno = errno;
2085                             if (!(result == resultbuf || result == NULL))
2086                               free (result);
2087                             if (buf_malloced != NULL)
2088                               free (buf_malloced);
2089                             CLEANUP ();
2090                             errno = saved_errno;
2091                             return NULL;
2092                           }
2093                         if (converted != result + length)
2094                           {
2095                             ENSURE_ALLOCATION (xsum (length, converted_len));
2096                             DCHAR_CPY (result + length, converted, converted_len);
2097                             free (converted);
2098                           }
2099                         length += converted_len;
2100                       }
2101 # endif
2102
2103                       if (has_width && width > characters
2104                           && (dp->flags & FLAG_LEFT))
2105                         {
2106                           size_t n = width - characters;
2107                           ENSURE_ALLOCATION (xsum (length, n));
2108                           DCHAR_SET (result + length, ' ', n);
2109                           length += n;
2110                         }
2111                     }
2112                     break;
2113
2114                   case TYPE_U16_STRING:
2115                     {
2116                       const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2117                       const uint16_t *arg_end;
2118                       size_t characters;
2119
2120                       if (has_precision)
2121                         {
2122                           /* Use only PRECISION characters, from the left.  */
2123                           arg_end = arg;
2124                           characters = 0;
2125                           for (; precision > 0; precision--)
2126                             {
2127                               int count = u16_strmblen (arg_end);
2128                               if (count == 0)
2129                                 break;
2130                               if (count < 0)
2131                                 {
2132                                   if (!(result == resultbuf || result == NULL))
2133                                     free (result);
2134                                   if (buf_malloced != NULL)
2135                                     free (buf_malloced);
2136                                   CLEANUP ();
2137                                   errno = EILSEQ;
2138                                   return NULL;
2139                                 }
2140                               arg_end += count;
2141                               characters++;
2142                             }
2143                         }
2144                       else if (has_width)
2145                         {
2146                           /* Use the entire string, and count the number of
2147                              characters.  */
2148                           arg_end = arg;
2149                           characters = 0;
2150                           for (;;)
2151                             {
2152                               int count = u16_strmblen (arg_end);
2153                               if (count == 0)
2154                                 break;
2155                               if (count < 0)
2156                                 {
2157                                   if (!(result == resultbuf || result == NULL))
2158                                     free (result);
2159                                   if (buf_malloced != NULL)
2160                                     free (buf_malloced);
2161                                   CLEANUP ();
2162                                   errno = EILSEQ;
2163                                   return NULL;
2164                                 }
2165                               arg_end += count;
2166                               characters++;
2167                             }
2168                         }
2169                       else
2170                         {
2171                           /* Use the entire string.  */
2172                           arg_end = arg + u16_strlen (arg);
2173                           /* The number of characters doesn't matter.  */
2174                           characters = 0;
2175                         }
2176
2177                       if (has_width && width > characters
2178                           && !(dp->flags & FLAG_LEFT))
2179                         {
2180                           size_t n = width - characters;
2181                           ENSURE_ALLOCATION (xsum (length, n));
2182                           DCHAR_SET (result + length, ' ', n);
2183                           length += n;
2184                         }
2185
2186 # if DCHAR_IS_UINT16_T
2187                       {
2188                         size_t n = arg_end - arg;
2189                         ENSURE_ALLOCATION (xsum (length, n));
2190                         DCHAR_CPY (result + length, arg, n);
2191                         length += n;
2192                       }
2193 # else
2194                       { /* Convert.  */
2195                         DCHAR_T *converted = result + length;
2196                         size_t converted_len = allocated - length;
2197 #  if DCHAR_IS_TCHAR
2198                         /* Convert from UTF-16 to locale encoding.  */
2199                         converted =
2200                           u16_conv_to_encoding (locale_charset (),
2201                                                 iconveh_question_mark,
2202                                                 arg, arg_end - arg, NULL,
2203                                                 converted, &converted_len);
2204 #  else
2205                         /* Convert from UTF-16 to UTF-8/UTF-32.  */
2206                         converted =
2207                           U16_TO_DCHAR (arg, arg_end - arg,
2208                                         converted, &converted_len);
2209 #  endif
2210                         if (converted == NULL)
2211                           {
2212                             int saved_errno = errno;
2213                             if (!(result == resultbuf || result == NULL))
2214                               free (result);
2215                             if (buf_malloced != NULL)
2216                               free (buf_malloced);
2217                             CLEANUP ();
2218                             errno = saved_errno;
2219                             return NULL;
2220                           }
2221                         if (converted != result + length)
2222                           {
2223                             ENSURE_ALLOCATION (xsum (length, converted_len));
2224                             DCHAR_CPY (result + length, converted, converted_len);
2225                             free (converted);
2226                           }
2227                         length += converted_len;
2228                       }
2229 # endif
2230
2231                       if (has_width && width > characters
2232                           && (dp->flags & FLAG_LEFT))
2233                         {
2234                           size_t n = width - characters;
2235                           ENSURE_ALLOCATION (xsum (length, n));
2236                           DCHAR_SET (result + length, ' ', n);
2237                           length += n;
2238                         }
2239                     }
2240                     break;
2241
2242                   case TYPE_U32_STRING:
2243                     {
2244                       const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2245                       const uint32_t *arg_end;
2246                       size_t characters;
2247
2248                       if (has_precision)
2249                         {
2250                           /* Use only PRECISION characters, from the left.  */
2251                           arg_end = arg;
2252                           characters = 0;
2253                           for (; precision > 0; precision--)
2254                             {
2255                               int count = u32_strmblen (arg_end);
2256                               if (count == 0)
2257                                 break;
2258                               if (count < 0)
2259                                 {
2260                                   if (!(result == resultbuf || result == NULL))
2261                                     free (result);
2262                                   if (buf_malloced != NULL)
2263                                     free (buf_malloced);
2264                                   CLEANUP ();
2265                                   errno = EILSEQ;
2266                                   return NULL;
2267                                 }
2268                               arg_end += count;
2269                               characters++;
2270                             }
2271                         }
2272                       else if (has_width)
2273                         {
2274                           /* Use the entire string, and count the number of
2275                              characters.  */
2276                           arg_end = arg;
2277                           characters = 0;
2278                           for (;;)
2279                             {
2280                               int count = u32_strmblen (arg_end);
2281                               if (count == 0)
2282                                 break;
2283                               if (count < 0)
2284                                 {
2285                                   if (!(result == resultbuf || result == NULL))
2286                                     free (result);
2287                                   if (buf_malloced != NULL)
2288                                     free (buf_malloced);
2289                                   CLEANUP ();
2290                                   errno = EILSEQ;
2291                                   return NULL;
2292                                 }
2293                               arg_end += count;
2294                               characters++;
2295                             }
2296                         }
2297                       else
2298                         {
2299                           /* Use the entire string.  */
2300                           arg_end = arg + u32_strlen (arg);
2301                           /* The number of characters doesn't matter.  */
2302                           characters = 0;
2303                         }
2304
2305                       if (has_width && width > characters
2306                           && !(dp->flags & FLAG_LEFT))
2307                         {
2308                           size_t n = width - characters;
2309                           ENSURE_ALLOCATION (xsum (length, n));
2310                           DCHAR_SET (result + length, ' ', n);
2311                           length += n;
2312                         }
2313
2314 # if DCHAR_IS_UINT32_T
2315                       {
2316                         size_t n = arg_end - arg;
2317                         ENSURE_ALLOCATION (xsum (length, n));
2318                         DCHAR_CPY (result + length, arg, n);
2319                         length += n;
2320                       }
2321 # else
2322                       { /* Convert.  */
2323                         DCHAR_T *converted = result + length;
2324                         size_t converted_len = allocated - length;
2325 #  if DCHAR_IS_TCHAR
2326                         /* Convert from UTF-32 to locale encoding.  */
2327                         converted =
2328                           u32_conv_to_encoding (locale_charset (),
2329                                                 iconveh_question_mark,
2330                                                 arg, arg_end - arg, NULL,
2331                                                 converted, &converted_len);
2332 #  else
2333                         /* Convert from UTF-32 to UTF-8/UTF-16.  */
2334                         converted =
2335                           U32_TO_DCHAR (arg, arg_end - arg,
2336                                         converted, &converted_len);
2337 #  endif
2338                         if (converted == NULL)
2339                           {
2340                             int saved_errno = errno;
2341                             if (!(result == resultbuf || result == NULL))
2342                               free (result);
2343                             if (buf_malloced != NULL)
2344                               free (buf_malloced);
2345                             CLEANUP ();
2346                             errno = saved_errno;
2347                             return NULL;
2348                           }
2349                         if (converted != result + length)
2350                           {
2351                             ENSURE_ALLOCATION (xsum (length, converted_len));
2352                             DCHAR_CPY (result + length, converted, converted_len);
2353                             free (converted);
2354                           }
2355                         length += converted_len;
2356                       }
2357 # endif
2358
2359                       if (has_width && width > characters
2360                           && (dp->flags & FLAG_LEFT))
2361                         {
2362                           size_t n = width - characters;
2363                           ENSURE_ALLOCATION (xsum (length, n));
2364                           DCHAR_SET (result + length, ' ', n);
2365                           length += n;
2366                         }
2367                     }
2368                     break;
2369
2370                   default:
2371                     abort ();
2372                   }
2373               }
2374 #endif
2375 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
2376             else if (dp->conversion == 's'
2377 # if WIDE_CHAR_VERSION
2378                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2379 # else
2380                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2381 # endif
2382                     )
2383               {
2384                 /* The normal handling of the 's' directive below requires
2385                    allocating a temporary buffer.  The determination of its
2386                    length (tmp_length), in the case when a precision is
2387                    specified, below requires a conversion between a char[]
2388                    string and a wchar_t[] wide string.  It could be done, but
2389                    we have no guarantee that the implementation of sprintf will
2390                    use the exactly same algorithm.  Without this guarantee, it
2391                    is possible to have buffer overrun bugs.  In order to avoid
2392                    such bugs, we implement the entire processing of the 's'
2393                    directive ourselves.  */
2394                 int flags = dp->flags;
2395                 int has_width;
2396                 size_t width;
2397                 int has_precision;
2398                 size_t precision;
2399
2400                 has_width = 0;
2401                 width = 0;
2402                 if (dp->width_start != dp->width_end)
2403                   {
2404                     if (dp->width_arg_index != ARG_NONE)
2405                       {
2406                         int arg;
2407
2408                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2409                           abort ();
2410                         arg = a.arg[dp->width_arg_index].a.a_int;
2411                         if (arg < 0)
2412                           {
2413                             /* "A negative field width is taken as a '-' flag
2414                                 followed by a positive field width."  */
2415                             flags |= FLAG_LEFT;
2416                             width = (unsigned int) (-arg);
2417                           }
2418                         else
2419                           width = arg;
2420                       }
2421                     else
2422                       {
2423                         const FCHAR_T *digitp = dp->width_start;
2424
2425                         do
2426                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2427                         while (digitp != dp->width_end);
2428                       }
2429                     has_width = 1;
2430                   }
2431
2432                 has_precision = 0;
2433                 precision = 6;
2434                 if (dp->precision_start != dp->precision_end)
2435                   {
2436                     if (dp->precision_arg_index != ARG_NONE)
2437                       {
2438                         int arg;
2439
2440                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2441                           abort ();
2442                         arg = a.arg[dp->precision_arg_index].a.a_int;
2443                         /* "A negative precision is taken as if the precision
2444                             were omitted."  */
2445                         if (arg >= 0)
2446                           {
2447                             precision = arg;
2448                             has_precision = 1;
2449                           }
2450                       }
2451                     else
2452                       {
2453                         const FCHAR_T *digitp = dp->precision_start + 1;
2454
2455                         precision = 0;
2456                         while (digitp != dp->precision_end)
2457                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2458                         has_precision = 1;
2459                       }
2460                   }
2461
2462 # if WIDE_CHAR_VERSION
2463                 /* %s in vasnwprintf.  See the specification of fwprintf.  */
2464                 {
2465                   const char *arg = a.arg[dp->arg_index].a.a_string;
2466                   const char *arg_end;
2467                   size_t characters;
2468
2469                   if (has_precision)
2470                     {
2471                       /* Use only as many bytes as needed to produce PRECISION
2472                          wide characters, from the left.  */
2473 #  if HAVE_MBRTOWC
2474                       mbstate_t state;
2475                       memset (&state, '\0', sizeof (mbstate_t));
2476 #  endif
2477                       arg_end = arg;
2478                       characters = 0;
2479                       for (; precision > 0; precision--)
2480                         {
2481                           int count;
2482 #  if HAVE_MBRTOWC
2483                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
2484 #  else
2485                           count = mblen (arg_end, MB_CUR_MAX);
2486 #  endif
2487                           if (count == 0)
2488                             /* Found the terminating NUL.  */
2489                             break;
2490                           if (count < 0)
2491                             {
2492                               /* Invalid or incomplete multibyte character.  */
2493                               if (!(result == resultbuf || result == NULL))
2494                                 free (result);
2495                               if (buf_malloced != NULL)
2496                                 free (buf_malloced);
2497                               CLEANUP ();
2498                               errno = EILSEQ;
2499                               return NULL;
2500                             }
2501                           arg_end += count;
2502                           characters++;
2503                         }
2504                     }
2505                   else if (has_width)
2506                     {
2507                       /* Use the entire string, and count the number of wide
2508                          characters.  */
2509 #  if HAVE_MBRTOWC
2510                       mbstate_t state;
2511                       memset (&state, '\0', sizeof (mbstate_t));
2512 #  endif
2513                       arg_end = arg;
2514                       characters = 0;
2515                       for (;;)
2516                         {
2517                           int count;
2518 #  if HAVE_MBRTOWC
2519                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
2520 #  else
2521                           count = mblen (arg_end, MB_CUR_MAX);
2522 #  endif
2523                           if (count == 0)
2524                             /* Found the terminating NUL.  */
2525                             break;
2526                           if (count < 0)
2527                             {
2528                               /* Invalid or incomplete multibyte character.  */
2529                               if (!(result == resultbuf || result == NULL))
2530                                 free (result);
2531                               if (buf_malloced != NULL)
2532                                 free (buf_malloced);
2533                               CLEANUP ();
2534                               errno = EILSEQ;
2535                               return NULL;
2536                             }
2537                           arg_end += count;
2538                           characters++;
2539                         }
2540                     }
2541                   else
2542                     {
2543                       /* Use the entire string.  */
2544                       arg_end = arg + strlen (arg);
2545                       /* The number of characters doesn't matter.  */
2546                       characters = 0;
2547                     }
2548
2549                   if (has_width && width > characters
2550                       && !(dp->flags & FLAG_LEFT))
2551                     {
2552                       size_t n = width - characters;
2553                       ENSURE_ALLOCATION (xsum (length, n));
2554                       DCHAR_SET (result + length, ' ', n);
2555                       length += n;
2556                     }
2557
2558                   if (has_precision || has_width)
2559                     {
2560                       /* We know the number of wide characters in advance.  */
2561                       size_t remaining;
2562 #  if HAVE_MBRTOWC
2563                       mbstate_t state;
2564                       memset (&state, '\0', sizeof (mbstate_t));
2565 #  endif
2566                       ENSURE_ALLOCATION (xsum (length, characters));
2567                       for (remaining = characters; remaining > 0; remaining--)
2568                         {
2569                           wchar_t wc;
2570                           int count;
2571 #  if HAVE_MBRTOWC
2572                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
2573 #  else
2574                           count = mbtowc (&wc, arg, arg_end - arg);
2575 #  endif
2576                           if (count <= 0)
2577                             /* mbrtowc not consistent with mbrlen, or mbtowc
2578                                not consistent with mblen.  */
2579                             abort ();
2580                           result[length++] = wc;
2581                           arg += count;
2582                         }
2583                       if (!(arg == arg_end))
2584                         abort ();
2585                     }
2586                   else
2587                     {
2588 #  if HAVE_MBRTOWC
2589                       mbstate_t state;
2590                       memset (&state, '\0', sizeof (mbstate_t));
2591 #  endif
2592                       while (arg < arg_end)
2593                         {
2594                           wchar_t wc;
2595                           int count;
2596 #  if HAVE_MBRTOWC
2597                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
2598 #  else
2599                           count = mbtowc (&wc, arg, arg_end - arg);
2600 #  endif
2601                           if (count <= 0)
2602                             /* mbrtowc not consistent with mbrlen, or mbtowc
2603                                not consistent with mblen.  */
2604                             abort ();
2605                           ENSURE_ALLOCATION (xsum (length, 1));
2606                           result[length++] = wc;
2607                           arg += count;
2608                         }
2609                     }
2610
2611                   if (has_width && width > characters
2612                       && (dp->flags & FLAG_LEFT))
2613                     {
2614                       size_t n = width - characters;
2615                       ENSURE_ALLOCATION (xsum (length, n));
2616                       DCHAR_SET (result + length, ' ', n);
2617                       length += n;
2618                     }
2619                 }
2620 # else
2621                 /* %ls in vasnprintf.  See the specification of fprintf.  */
2622                 {
2623                   const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2624                   const wchar_t *arg_end;
2625                   size_t characters;
2626 #  if !DCHAR_IS_TCHAR
2627                   /* This code assumes that TCHAR_T is 'char'.  */
2628                   verify (sizeof (TCHAR_T) == 1);
2629                   TCHAR_T *tmpsrc;
2630                   DCHAR_T *tmpdst;
2631                   size_t tmpdst_len;
2632 #  endif
2633                   size_t w;
2634
2635                   if (has_precision)
2636                     {
2637                       /* Use only as many wide characters as needed to produce
2638                          at most PRECISION bytes, from the left.  */
2639 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2640                       mbstate_t state;
2641                       memset (&state, '\0', sizeof (mbstate_t));
2642 #  endif
2643                       arg_end = arg;
2644                       characters = 0;
2645                       while (precision > 0)
2646                         {
2647                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2648                           int count;
2649
2650                           if (*arg_end == 0)
2651                             /* Found the terminating null wide character.  */
2652                             break;
2653 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2654                           count = wcrtomb (cbuf, *arg_end, &state);
2655 #  else
2656                           count = wctomb (cbuf, *arg_end);
2657 #  endif
2658                           if (count < 0)
2659                             {
2660                               /* Cannot convert.  */
2661                               if (!(result == resultbuf || result == NULL))
2662                                 free (result);
2663                               if (buf_malloced != NULL)
2664                                 free (buf_malloced);
2665                               CLEANUP ();
2666                               errno = EILSEQ;
2667                               return NULL;
2668                             }
2669                           if (precision < count)
2670                             break;
2671                           arg_end++;
2672                           characters += count;
2673                           precision -= count;
2674                         }
2675                     }
2676 #  if DCHAR_IS_TCHAR
2677                   else if (has_width)
2678 #  else
2679                   else
2680 #  endif
2681                     {
2682                       /* Use the entire string, and count the number of
2683                          bytes.  */
2684 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2685                       mbstate_t state;
2686                       memset (&state, '\0', sizeof (mbstate_t));
2687 #  endif
2688                       arg_end = arg;
2689                       characters = 0;
2690                       for (;;)
2691                         {
2692                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2693                           int count;
2694
2695                           if (*arg_end == 0)
2696                             /* Found the terminating null wide character.  */
2697                             break;
2698 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2699                           count = wcrtomb (cbuf, *arg_end, &state);
2700 #  else
2701                           count = wctomb (cbuf, *arg_end);
2702 #  endif
2703                           if (count < 0)
2704                             {
2705                               /* Cannot convert.  */
2706                               if (!(result == resultbuf || result == NULL))
2707                                 free (result);
2708                               if (buf_malloced != NULL)
2709                                 free (buf_malloced);
2710                               CLEANUP ();
2711                               errno = EILSEQ;
2712                               return NULL;
2713                             }
2714                           arg_end++;
2715                           characters += count;
2716                         }
2717                     }
2718 #  if DCHAR_IS_TCHAR
2719                   else
2720                     {
2721                       /* Use the entire string.  */
2722                       arg_end = arg + local_wcslen (arg);
2723                       /* The number of bytes doesn't matter.  */
2724                       characters = 0;
2725                     }
2726 #  endif
2727
2728 #  if !DCHAR_IS_TCHAR
2729                   /* Convert the string into a piece of temporary memory.  */
2730                   tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2731                   if (tmpsrc == NULL)
2732                     goto out_of_memory;
2733                   {
2734                     TCHAR_T *tmpptr = tmpsrc;
2735                     size_t remaining;
2736 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2737                     mbstate_t state;
2738                     memset (&state, '\0', sizeof (mbstate_t));
2739 #   endif
2740                     for (remaining = characters; remaining > 0; )
2741                       {
2742                         char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2743                         int count;
2744
2745                         if (*arg == 0)
2746                           abort ();
2747 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2748                         count = wcrtomb (cbuf, *arg, &state);
2749 #   else
2750                         count = wctomb (cbuf, *arg);
2751 #   endif
2752                         if (count <= 0)
2753                           /* Inconsistency.  */
2754                           abort ();
2755                         memcpy (tmpptr, cbuf, count);
2756                         tmpptr += count;
2757                         arg++;
2758                         remaining -= count;
2759                       }
2760                     if (!(arg == arg_end))
2761                       abort ();
2762                   }
2763
2764                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
2765                   tmpdst =
2766                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
2767                                               iconveh_question_mark,
2768                                               tmpsrc, characters,
2769                                               NULL,
2770                                               NULL, &tmpdst_len);
2771                   if (tmpdst == NULL)
2772                     {
2773                       int saved_errno = errno;
2774                       free (tmpsrc);
2775                       if (!(result == resultbuf || result == NULL))
2776                         free (result);
2777                       if (buf_malloced != NULL)
2778                         free (buf_malloced);
2779                       CLEANUP ();
2780                       errno = saved_errno;
2781                       return NULL;
2782                     }
2783                   free (tmpsrc);
2784 #  endif
2785
2786                   if (has_width)
2787                     {
2788 #  if ENABLE_UNISTDIO
2789                       /* Outside POSIX, it's preferrable to compare the width
2790                          against the number of _characters_ of the converted
2791                          value.  */
2792                       w = DCHAR_MBSNLEN (result + length, characters);
2793 #  else
2794                       /* The width is compared against the number of _bytes_
2795                          of the converted value, says POSIX.  */
2796                       w = characters;
2797 #  endif
2798                     }
2799                   else
2800                     /* w doesn't matter.  */
2801                     w = 0;
2802
2803                   if (has_width && width > w
2804                       && !(dp->flags & FLAG_LEFT))
2805                     {
2806                       size_t n = width - w;
2807                       ENSURE_ALLOCATION (xsum (length, n));
2808                       DCHAR_SET (result + length, ' ', n);
2809                       length += n;
2810                     }
2811
2812 #  if DCHAR_IS_TCHAR
2813                   if (has_precision || has_width)
2814                     {
2815                       /* We know the number of bytes in advance.  */
2816                       size_t remaining;
2817 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2818                       mbstate_t state;
2819                       memset (&state, '\0', sizeof (mbstate_t));
2820 #   endif
2821                       ENSURE_ALLOCATION (xsum (length, characters));
2822                       for (remaining = characters; remaining > 0; )
2823                         {
2824                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2825                           int count;
2826
2827                           if (*arg == 0)
2828                             abort ();
2829 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2830                           count = wcrtomb (cbuf, *arg, &state);
2831 #   else
2832                           count = wctomb (cbuf, *arg);
2833 #   endif
2834                           if (count <= 0)
2835                             /* Inconsistency.  */
2836                             abort ();
2837                           memcpy (result + length, cbuf, count);
2838                           length += count;
2839                           arg++;
2840                           remaining -= count;
2841                         }
2842                       if (!(arg == arg_end))
2843                         abort ();
2844                     }
2845                   else
2846                     {
2847 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2848                       mbstate_t state;
2849                       memset (&state, '\0', sizeof (mbstate_t));
2850 #   endif
2851                       while (arg < arg_end)
2852                         {
2853                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2854                           int count;
2855
2856                           if (*arg == 0)
2857                             abort ();
2858 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2859                           count = wcrtomb (cbuf, *arg, &state);
2860 #   else
2861                           count = wctomb (cbuf, *arg);
2862 #   endif
2863                           if (count <= 0)
2864                             {
2865                               /* Cannot convert.  */
2866                               if (!(result == resultbuf || result == NULL))
2867                                 free (result);
2868                               if (buf_malloced != NULL)
2869                                 free (buf_malloced);
2870                               CLEANUP ();
2871                               errno = EILSEQ;
2872                               return NULL;
2873                             }
2874                           ENSURE_ALLOCATION (xsum (length, count));
2875                           memcpy (result + length, cbuf, count);
2876                           length += count;
2877                           arg++;
2878                         }
2879                     }
2880 #  else
2881                   ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2882                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2883                   free (tmpdst);
2884                   length += tmpdst_len;
2885 #  endif
2886
2887                   if (has_width && width > w
2888                       && (dp->flags & FLAG_LEFT))
2889                     {
2890                       size_t n = width - w;
2891                       ENSURE_ALLOCATION (xsum (length, n));
2892                       DCHAR_SET (result + length, ' ', n);
2893                       length += n;
2894                     }
2895                 }
2896 # endif
2897               }
2898 #endif
2899 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2900             else if ((dp->conversion == 'a' || dp->conversion == 'A')
2901 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2902                      && (0
2903 #  if NEED_PRINTF_DOUBLE
2904                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
2905 #  endif
2906 #  if NEED_PRINTF_LONG_DOUBLE
2907                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2908 #  endif
2909                         )
2910 # endif
2911                     )
2912               {
2913                 arg_type type = a.arg[dp->arg_index].type;
2914                 int flags = dp->flags;
2915                 int has_width;
2916                 size_t width;
2917                 int has_precision;
2918                 size_t precision;
2919                 size_t tmp_length;
2920                 DCHAR_T tmpbuf[700];
2921                 DCHAR_T *tmp;
2922                 DCHAR_T *pad_ptr;
2923                 DCHAR_T *p;
2924
2925                 has_width = 0;
2926                 width = 0;
2927                 if (dp->width_start != dp->width_end)
2928                   {
2929                     if (dp->width_arg_index != ARG_NONE)
2930                       {
2931                         int arg;
2932
2933                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2934                           abort ();
2935                         arg = a.arg[dp->width_arg_index].a.a_int;
2936                         if (arg < 0)
2937                           {
2938                             /* "A negative field width is taken as a '-' flag
2939                                 followed by a positive field width."  */
2940                             flags |= FLAG_LEFT;
2941                             width = (unsigned int) (-arg);
2942                           }
2943                         else
2944                           width = arg;
2945                       }
2946                     else
2947                       {
2948                         const FCHAR_T *digitp = dp->width_start;
2949
2950                         do
2951                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2952                         while (digitp != dp->width_end);
2953                       }
2954                     has_width = 1;
2955                   }
2956
2957                 has_precision = 0;
2958                 precision = 0;
2959                 if (dp->precision_start != dp->precision_end)
2960                   {
2961                     if (dp->precision_arg_index != ARG_NONE)
2962                       {
2963                         int arg;
2964
2965                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2966                           abort ();
2967                         arg = a.arg[dp->precision_arg_index].a.a_int;
2968                         /* "A negative precision is taken as if the precision
2969                             were omitted."  */
2970                         if (arg >= 0)
2971                           {
2972                             precision = arg;
2973                             has_precision = 1;
2974                           }
2975                       }
2976                     else
2977                       {
2978                         const FCHAR_T *digitp = dp->precision_start + 1;
2979
2980                         precision = 0;
2981                         while (digitp != dp->precision_end)
2982                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2983                         has_precision = 1;
2984                       }
2985                   }
2986
2987                 /* Allocate a temporary buffer of sufficient size.  */
2988                 if (type == TYPE_LONGDOUBLE)
2989                   tmp_length =
2990                     (unsigned int) ((LDBL_DIG + 1)
2991                                     * 0.831 /* decimal -> hexadecimal */
2992                                    )
2993                     + 1; /* turn floor into ceil */
2994                 else
2995                   tmp_length =
2996                     (unsigned int) ((DBL_DIG + 1)
2997                                     * 0.831 /* decimal -> hexadecimal */
2998                                    )
2999                     + 1; /* turn floor into ceil */
3000                 if (tmp_length < precision)
3001                   tmp_length = precision;
3002                 /* Account for sign, decimal point etc. */
3003                 tmp_length = xsum (tmp_length, 12);
3004
3005                 if (tmp_length < width)
3006                   tmp_length = width;
3007
3008                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3009
3010                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3011                   tmp = tmpbuf;
3012                 else
3013                   {
3014                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3015
3016                     if (size_overflow_p (tmp_memsize))
3017                       /* Overflow, would lead to out of memory.  */
3018                       goto out_of_memory;
3019                     tmp = (DCHAR_T *) malloc (tmp_memsize);
3020                     if (tmp == NULL)
3021                       /* Out of memory.  */
3022                       goto out_of_memory;
3023                   }
3024
3025                 pad_ptr = NULL;
3026                 p = tmp;
3027                 if (type == TYPE_LONGDOUBLE)
3028                   {
3029 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3030                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
3031
3032                     if (isnanl (arg))
3033                       {
3034                         if (dp->conversion == 'A')
3035                           {
3036                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3037                           }
3038                         else
3039                           {
3040                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3041                           }
3042                       }
3043                     else
3044                       {
3045                         int sign = 0;
3046                         DECL_LONG_DOUBLE_ROUNDING
3047
3048                         BEGIN_LONG_DOUBLE_ROUNDING ();
3049
3050                         if (signbit (arg)) /* arg < 0.0L or negative zero */
3051                           {
3052                             sign = -1;
3053                             arg = -arg;
3054                           }
3055
3056                         if (sign < 0)
3057                           *p++ = '-';
3058                         else if (flags & FLAG_SHOWSIGN)
3059                           *p++ = '+';
3060                         else if (flags & FLAG_SPACE)
3061                           *p++ = ' ';
3062
3063                         if (arg > 0.0L && arg + arg == arg)
3064                           {
3065                             if (dp->conversion == 'A')
3066                               {
3067                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3068                               }
3069                             else
3070                               {
3071                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3072                               }
3073                           }
3074                         else
3075                           {
3076                             int exponent;
3077                             long double mantissa;
3078
3079                             if (arg > 0.0L)
3080                               mantissa = printf_frexpl (arg, &exponent);
3081                             else
3082                               {
3083                                 exponent = 0;
3084                                 mantissa = 0.0L;
3085                               }
3086
3087                             if (has_precision
3088                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3089                               {
3090                                 /* Round the mantissa.  */
3091                                 long double tail = mantissa;
3092                                 size_t q;
3093
3094                                 for (q = precision; ; q--)
3095                                   {
3096                                     int digit = (int) tail;
3097                                     tail -= digit;
3098                                     if (q == 0)
3099                                       {
3100                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3101                                           tail = 1 - tail;
3102                                         else
3103                                           tail = - tail;
3104                                         break;
3105                                       }
3106                                     tail *= 16.0L;
3107                                   }
3108                                 if (tail != 0.0L)
3109                                   for (q = precision; q > 0; q--)
3110                                     tail *= 0.0625L;
3111                                 mantissa += tail;
3112                               }
3113
3114                             *p++ = '0';
3115                             *p++ = dp->conversion - 'A' + 'X';
3116                             pad_ptr = p;
3117                             {
3118                               int digit;
3119
3120                               digit = (int) mantissa;
3121                               mantissa -= digit;
3122                               *p++ = '0' + digit;
3123                               if ((flags & FLAG_ALT)
3124                                   || mantissa > 0.0L || precision > 0)
3125                                 {
3126                                   *p++ = decimal_point_char ();
3127                                   /* This loop terminates because we assume
3128                                      that FLT_RADIX is a power of 2.  */
3129                                   while (mantissa > 0.0L)
3130                                     {
3131                                       mantissa *= 16.0L;
3132                                       digit = (int) mantissa;
3133                                       mantissa -= digit;
3134                                       *p++ = digit
3135                                              + (digit < 10
3136                                                 ? '0'
3137                                                 : dp->conversion - 10);
3138                                       if (precision > 0)
3139                                         precision--;
3140                                     }
3141                                   while (precision > 0)
3142                                     {
3143                                       *p++ = '0';
3144                                       precision--;
3145                                     }
3146                                 }
3147                               }
3148                               *p++ = dp->conversion - 'A' + 'P';
3149 #  if WIDE_CHAR_VERSION
3150                               {
3151                                 static const wchar_t decimal_format[] =
3152                                   { '%', '+', 'd', '\0' };
3153                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3154                               }
3155                               while (*p != '\0')
3156                                 p++;
3157 #  else
3158                               if (sizeof (DCHAR_T) == 1)
3159                                 {
3160                                   sprintf ((char *) p, "%+d", exponent);
3161                                   while (*p != '\0')
3162                                     p++;
3163                                 }
3164                               else
3165                                 {
3166                                   char expbuf[6 + 1];
3167                                   const char *ep;
3168                                   sprintf (expbuf, "%+d", exponent);
3169                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3170                                     p++;
3171                                 }
3172 #  endif
3173                           }
3174
3175                         END_LONG_DOUBLE_ROUNDING ();
3176                       }
3177 # else
3178                     abort ();
3179 # endif
3180                   }
3181                 else
3182                   {
3183 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3184                     double arg = a.arg[dp->arg_index].a.a_double;
3185
3186                     if (isnand (arg))
3187                       {
3188                         if (dp->conversion == 'A')
3189                           {
3190                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3191                           }
3192                         else
3193                           {
3194                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3195                           }
3196                       }
3197                     else
3198                       {
3199                         int sign = 0;
3200
3201                         if (signbit (arg)) /* arg < 0.0 or negative zero */
3202                           {
3203                             sign = -1;
3204                             arg = -arg;
3205                           }
3206
3207                         if (sign < 0)
3208                           *p++ = '-';
3209                         else if (flags & FLAG_SHOWSIGN)
3210                           *p++ = '+';
3211                         else if (flags & FLAG_SPACE)
3212                           *p++ = ' ';
3213
3214                         if (arg > 0.0 && arg + arg == arg)
3215                           {
3216                             if (dp->conversion == 'A')
3217                               {
3218                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3219                               }
3220                             else
3221                               {
3222                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3223                               }
3224                           }
3225                         else
3226                           {
3227                             int exponent;
3228                             double mantissa;
3229
3230                             if (arg > 0.0)
3231                               mantissa = printf_frexp (arg, &exponent);
3232                             else
3233                               {
3234                                 exponent = 0;
3235                                 mantissa = 0.0;
3236                               }
3237
3238                             if (has_precision
3239                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3240                               {
3241                                 /* Round the mantissa.  */
3242                                 double tail = mantissa;
3243                                 size_t q;
3244
3245                                 for (q = precision; ; q--)
3246                                   {
3247                                     int digit = (int) tail;
3248                                     tail -= digit;
3249                                     if (q == 0)
3250                                       {
3251                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3252                                           tail = 1 - tail;
3253                                         else
3254                                           tail = - tail;
3255                                         break;
3256                                       }
3257                                     tail *= 16.0;
3258                                   }
3259                                 if (tail != 0.0)
3260                                   for (q = precision; q > 0; q--)
3261                                     tail *= 0.0625;
3262                                 mantissa += tail;
3263                               }
3264
3265                             *p++ = '0';
3266                             *p++ = dp->conversion - 'A' + 'X';
3267                             pad_ptr = p;
3268                             {
3269                               int digit;
3270
3271                               digit = (int) mantissa;
3272                               mantissa -= digit;
3273                               *p++ = '0' + digit;
3274                               if ((flags & FLAG_ALT)
3275                                   || mantissa > 0.0 || precision > 0)
3276                                 {
3277                                   *p++ = decimal_point_char ();
3278                                   /* This loop terminates because we assume
3279                                      that FLT_RADIX is a power of 2.  */
3280                                   while (mantissa > 0.0)
3281                                     {
3282                                       mantissa *= 16.0;
3283                                       digit = (int) mantissa;
3284                                       mantissa -= digit;
3285                                       *p++ = digit
3286                                              + (digit < 10
3287                                                 ? '0'
3288                                                 : dp->conversion - 10);
3289                                       if (precision > 0)
3290                                         precision--;
3291                                     }
3292                                   while (precision > 0)
3293                                     {
3294                                       *p++ = '0';
3295                                       precision--;
3296                                     }
3297                                 }
3298                               }
3299                               *p++ = dp->conversion - 'A' + 'P';
3300 #  if WIDE_CHAR_VERSION
3301                               {
3302                                 static const wchar_t decimal_format[] =
3303                                   { '%', '+', 'd', '\0' };
3304                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3305                               }
3306                               while (*p != '\0')
3307                                 p++;
3308 #  else
3309                               if (sizeof (DCHAR_T) == 1)
3310                                 {
3311                                   sprintf ((char *) p, "%+d", exponent);
3312                                   while (*p != '\0')
3313                                     p++;
3314                                 }
3315                               else
3316                                 {
3317                                   char expbuf[6 + 1];
3318                                   const char *ep;
3319                                   sprintf (expbuf, "%+d", exponent);
3320                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3321                                     p++;
3322                                 }
3323 #  endif
3324                           }
3325                       }
3326 # else
3327                     abort ();
3328 # endif
3329                   }
3330                 /* The generated string now extends from tmp to p, with the
3331                    zero padding insertion point being at pad_ptr.  */
3332                 if (has_width && p - tmp < width)
3333                   {
3334                     size_t pad = width - (p - tmp);
3335                     DCHAR_T *end = p + pad;
3336
3337                     if (flags & FLAG_LEFT)
3338                       {
3339                         /* Pad with spaces on the right.  */
3340                         for (; pad > 0; pad--)
3341                           *p++ = ' ';
3342                       }
3343                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3344                       {
3345                         /* Pad with zeroes.  */
3346                         DCHAR_T *q = end;
3347
3348                         while (p > pad_ptr)
3349                           *--q = *--p;
3350                         for (; pad > 0; pad--)
3351                           *p++ = '0';
3352                       }
3353                     else
3354                       {
3355                         /* Pad with spaces on the left.  */
3356                         DCHAR_T *q = end;
3357
3358                         while (p > tmp)
3359                           *--q = *--p;
3360                         for (; pad > 0; pad--)
3361                           *p++ = ' ';
3362                       }
3363
3364                     p = end;
3365                   }
3366
3367                 {
3368                   size_t count = p - tmp;
3369
3370                   if (count >= tmp_length)
3371                     /* tmp_length was incorrectly calculated - fix the
3372                        code above!  */
3373                     abort ();
3374
3375                   /* Make room for the result.  */
3376                   if (count >= allocated - length)
3377                     {
3378                       size_t n = xsum (length, count);
3379
3380                       ENSURE_ALLOCATION (n);
3381                     }
3382
3383                   /* Append the result.  */
3384                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3385                   if (tmp != tmpbuf)
3386                     free (tmp);
3387                   length += count;
3388                 }
3389               }
3390 #endif
3391 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3392             else if ((dp->conversion == 'f' || dp->conversion == 'F'
3393                       || dp->conversion == 'e' || dp->conversion == 'E'
3394                       || dp->conversion == 'g' || dp->conversion == 'G'
3395                       || dp->conversion == 'a' || dp->conversion == 'A')
3396                      && (0
3397 # if NEED_PRINTF_DOUBLE
3398                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
3399 # elif NEED_PRINTF_INFINITE_DOUBLE
3400                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3401                              /* The systems (mingw) which produce wrong output
3402                                 for Inf, -Inf, and NaN also do so for -0.0.
3403                                 Therefore we treat this case here as well.  */
3404                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3405 # endif
3406 # if NEED_PRINTF_LONG_DOUBLE
3407                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3408 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3409                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3410                              /* Some systems produce wrong output for Inf,
3411                                 -Inf, and NaN.  Some systems in this category
3412                                 (IRIX 5.3) also do so for -0.0.  Therefore we
3413                                 treat this case here as well.  */
3414                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3415 # endif
3416                         ))
3417               {
3418 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3419                 arg_type type = a.arg[dp->arg_index].type;
3420 # endif
3421                 int flags = dp->flags;
3422                 int has_width;
3423                 size_t width;
3424                 int has_precision;
3425                 size_t precision;
3426                 size_t tmp_length;
3427                 DCHAR_T tmpbuf[700];
3428                 DCHAR_T *tmp;
3429                 DCHAR_T *pad_ptr;
3430                 DCHAR_T *p;
3431
3432                 has_width = 0;
3433                 width = 0;
3434                 if (dp->width_start != dp->width_end)
3435                   {
3436                     if (dp->width_arg_index != ARG_NONE)
3437                       {
3438                         int arg;
3439
3440                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3441                           abort ();
3442                         arg = a.arg[dp->width_arg_index].a.a_int;
3443                         if (arg < 0)
3444                           {
3445                             /* "A negative field width is taken as a '-' flag
3446                                 followed by a positive field width."  */
3447                             flags |= FLAG_LEFT;
3448                             width = (unsigned int) (-arg);
3449                           }
3450                         else
3451                           width = arg;
3452                       }
3453                     else
3454                       {
3455                         const FCHAR_T *digitp = dp->width_start;
3456
3457                         do
3458                           width = xsum (xtimes (width, 10), *digitp++ - '0');
3459                         while (digitp != dp->width_end);
3460                       }
3461                     has_width = 1;
3462                   }
3463
3464                 has_precision = 0;
3465                 precision = 0;
3466                 if (dp->precision_start != dp->precision_end)
3467                   {
3468                     if (dp->precision_arg_index != ARG_NONE)
3469                       {
3470                         int arg;
3471
3472                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3473                           abort ();
3474                         arg = a.arg[dp->precision_arg_index].a.a_int;
3475                         /* "A negative precision is taken as if the precision
3476                             were omitted."  */
3477                         if (arg >= 0)
3478                           {
3479                             precision = arg;
3480                             has_precision = 1;
3481                           }
3482                       }
3483                     else
3484                       {
3485                         const FCHAR_T *digitp = dp->precision_start + 1;
3486
3487                         precision = 0;
3488                         while (digitp != dp->precision_end)
3489                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3490                         has_precision = 1;
3491                       }
3492                   }
3493
3494                 /* POSIX specifies the default precision to be 6 for %f, %F,
3495                    %e, %E, but not for %g, %G.  Implementations appear to use
3496                    the same default precision also for %g, %G.  But for %a, %A,
3497                    the default precision is 0.  */
3498                 if (!has_precision)
3499                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3500                     precision = 6;
3501
3502                 /* Allocate a temporary buffer of sufficient size.  */
3503 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3504                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3505 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3506                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3507 # elif NEED_PRINTF_LONG_DOUBLE
3508                 tmp_length = LDBL_DIG + 1;
3509 # elif NEED_PRINTF_DOUBLE
3510                 tmp_length = DBL_DIG + 1;
3511 # else
3512                 tmp_length = 0;
3513 # endif
3514                 if (tmp_length < precision)
3515                   tmp_length = precision;
3516 # if NEED_PRINTF_LONG_DOUBLE
3517 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3518                 if (type == TYPE_LONGDOUBLE)
3519 #  endif
3520                   if (dp->conversion == 'f' || dp->conversion == 'F')
3521                     {
3522                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
3523                       if (!(isnanl (arg) || arg + arg == arg))
3524                         {
3525                           /* arg is finite and nonzero.  */
3526                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
3527                           if (exponent >= 0 && tmp_length < exponent + precision)
3528                             tmp_length = exponent + precision;
3529                         }
3530                     }
3531 # endif
3532 # if NEED_PRINTF_DOUBLE
3533 #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3534                 if (type == TYPE_DOUBLE)
3535 #  endif
3536                   if (dp->conversion == 'f' || dp->conversion == 'F')
3537                     {
3538                       double arg = a.arg[dp->arg_index].a.a_double;
3539                       if (!(isnand (arg) || arg + arg == arg))
3540                         {
3541                           /* arg is finite and nonzero.  */
3542                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
3543                           if (exponent >= 0 && tmp_length < exponent + precision)
3544                             tmp_length = exponent + precision;
3545                         }
3546                     }
3547 # endif
3548                 /* Account for sign, decimal point etc. */
3549                 tmp_length = xsum (tmp_length, 12);
3550
3551                 if (tmp_length < width)
3552                   tmp_length = width;
3553
3554                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3555
3556                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3557                   tmp = tmpbuf;
3558                 else
3559                   {
3560                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3561
3562                     if (size_overflow_p (tmp_memsize))
3563                       /* Overflow, would lead to out of memory.  */
3564                       goto out_of_memory;
3565                     tmp = (DCHAR_T *) malloc (tmp_memsize);
3566                     if (tmp == NULL)
3567                       /* Out of memory.  */
3568                       goto out_of_memory;
3569                   }
3570
3571                 pad_ptr = NULL;
3572                 p = tmp;
3573
3574 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3575 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3576                 if (type == TYPE_LONGDOUBLE)
3577 #  endif
3578                   {
3579                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
3580
3581                     if (isnanl (arg))
3582                       {
3583                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3584                           {
3585                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3586                           }
3587                         else
3588                           {
3589                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3590                           }
3591                       }
3592                     else
3593                       {
3594                         int sign = 0;
3595                         DECL_LONG_DOUBLE_ROUNDING
3596
3597                         BEGIN_LONG_DOUBLE_ROUNDING ();
3598
3599                         if (signbit (arg)) /* arg < 0.0L or negative zero */
3600                           {
3601                             sign = -1;
3602                             arg = -arg;
3603                           }
3604
3605                         if (sign < 0)
3606                           *p++ = '-';
3607                         else if (flags & FLAG_SHOWSIGN)
3608                           *p++ = '+';
3609                         else if (flags & FLAG_SPACE)
3610                           *p++ = ' ';
3611
3612                         if (arg > 0.0L && arg + arg == arg)
3613                           {
3614                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3615                               {
3616                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3617                               }
3618                             else
3619                               {
3620                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3621                               }
3622                           }
3623                         else
3624                           {
3625 #  if NEED_PRINTF_LONG_DOUBLE
3626                             pad_ptr = p;
3627
3628                             if (dp->conversion == 'f' || dp->conversion == 'F')
3629                               {
3630                                 char *digits;
3631                                 size_t ndigits;
3632
3633                                 digits =
3634                                   scale10_round_decimal_long_double (arg, precision);
3635                                 if (digits == NULL)
3636                                   {
3637                                     END_LONG_DOUBLE_ROUNDING ();
3638                                     goto out_of_memory;
3639                                   }
3640                                 ndigits = strlen (digits);
3641
3642                                 if (ndigits > precision)
3643                                   do
3644                                     {
3645                                       --ndigits;
3646                                       *p++ = digits[ndigits];
3647                                     }
3648                                   while (ndigits > precision);
3649                                 else
3650                                   *p++ = '0';
3651                                 /* Here ndigits <= precision.  */
3652                                 if ((flags & FLAG_ALT) || precision > 0)
3653                                   {
3654                                     *p++ = decimal_point_char ();
3655                                     for (; precision > ndigits; precision--)
3656                                       *p++ = '0';
3657                                     while (ndigits > 0)
3658                                       {
3659                                         --ndigits;
3660                                         *p++ = digits[ndigits];
3661                                       }
3662                                   }
3663
3664                                 free (digits);
3665                               }
3666                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3667                               {
3668                                 int exponent;
3669
3670                                 if (arg == 0.0L)
3671                                   {
3672                                     exponent = 0;
3673                                     *p++ = '0';
3674                                     if ((flags & FLAG_ALT) || precision > 0)
3675                                       {
3676                                         *p++ = decimal_point_char ();
3677                                         for (; precision > 0; precision--)
3678                                           *p++ = '0';
3679                                       }
3680                                   }
3681                                 else
3682                                   {
3683                                     /* arg > 0.0L.  */
3684                                     int adjusted;
3685                                     char *digits;
3686                                     size_t ndigits;
3687
3688                                     exponent = floorlog10l (arg);
3689                                     adjusted = 0;
3690                                     for (;;)
3691                                       {
3692                                         digits =
3693                                           scale10_round_decimal_long_double (arg,
3694                                                                              (int)precision - exponent);
3695                                         if (digits == NULL)
3696                                           {
3697                                             END_LONG_DOUBLE_ROUNDING ();
3698                                             goto out_of_memory;
3699                                           }
3700                                         ndigits = strlen (digits);
3701
3702                                         if (ndigits == precision + 1)
3703                                           break;
3704                                         if (ndigits < precision
3705                                             || ndigits > precision + 2)
3706                                           /* The exponent was not guessed
3707                                              precisely enough.  */
3708                                           abort ();
3709                                         if (adjusted)
3710                                           /* None of two values of exponent is
3711                                              the right one.  Prevent an endless
3712                                              loop.  */
3713                                           abort ();
3714                                         free (digits);
3715                                         if (ndigits == precision)
3716                                           exponent -= 1;
3717                                         else
3718                                           exponent += 1;
3719                                         adjusted = 1;
3720                                       }
3721                                     /* Here ndigits = precision+1.  */
3722                                     if (is_borderline (digits, precision))
3723                                       {
3724                                         /* Maybe the exponent guess was too high
3725                                            and a smaller exponent can be reached
3726                                            by turning a 10...0 into 9...9x.  */
3727                                         char *digits2 =
3728                                           scale10_round_decimal_long_double (arg,
3729                                                                              (int)precision - exponent + 1);
3730                                         if (digits2 == NULL)
3731                                           {
3732                                             free (digits);
3733                                             END_LONG_DOUBLE_ROUNDING ();
3734                                             goto out_of_memory;
3735                                           }
3736                                         if (strlen (digits2) == precision + 1)
3737                                           {
3738                                             free (digits);
3739                                             digits = digits2;
3740                                             exponent -= 1;
3741                                           }
3742                                         else
3743                                           free (digits2);
3744                                       }
3745                                     /* Here ndigits = precision+1.  */
3746
3747                                     *p++ = digits[--ndigits];
3748                                     if ((flags & FLAG_ALT) || precision > 0)
3749                                       {
3750                                         *p++ = decimal_point_char ();
3751                                         while (ndigits > 0)
3752                                           {
3753                                             --ndigits;
3754                                             *p++ = digits[ndigits];
3755                                           }
3756                                       }
3757
3758                                     free (digits);
3759                                   }
3760
3761                                 *p++ = dp->conversion; /* 'e' or 'E' */
3762 #   if WIDE_CHAR_VERSION
3763                                 {
3764                                   static const wchar_t decimal_format[] =
3765                                     { '%', '+', '.', '2', 'd', '\0' };
3766                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
3767                                 }
3768                                 while (*p != '\0')
3769                                   p++;
3770 #   else
3771                                 if (sizeof (DCHAR_T) == 1)
3772                                   {
3773                                     sprintf ((char *) p, "%+.2d", exponent);
3774                                     while (*p != '\0')
3775                                       p++;
3776                                   }
3777                                 else
3778                                   {
3779                                     char expbuf[6 + 1];
3780                                     const char *ep;
3781                                     sprintf (expbuf, "%+.2d", exponent);
3782                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3783                                       p++;
3784                                   }
3785 #   endif
3786                               }
3787                             else if (dp->conversion == 'g' || dp->conversion == 'G')
3788                               {
3789                                 if (precision == 0)
3790                                   precision = 1;
3791                                 /* precision >= 1.  */
3792
3793                                 if (arg == 0.0L)
3794                                   /* The exponent is 0, >= -4, < precision.
3795                                      Use fixed-point notation.  */
3796                                   {
3797                                     size_t ndigits = precision;
3798                                     /* Number of trailing zeroes that have to be
3799                                        dropped.  */
3800                                     size_t nzeroes =
3801                                       (flags & FLAG_ALT ? 0 : precision - 1);
3802
3803                                     --ndigits;
3804                                     *p++ = '0';
3805                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
3806                                       {
3807                                         *p++ = decimal_point_char ();
3808                                         while (ndigits > nzeroes)
3809                                           {
3810                                             --ndigits;
3811                                             *p++ = '0';
3812                                           }
3813                                       }
3814                                   }
3815                                 else
3816                                   {
3817                                     /* arg > 0.0L.  */
3818                                     int exponent;
3819                                     int adjusted;
3820                                     char *digits;
3821                                     size_t ndigits;
3822                                     size_t nzeroes;
3823
3824                                     exponent = floorlog10l (arg);
3825                                     adjusted = 0;
3826                                     for (;;)
3827                                       {
3828                                         digits =
3829                                           scale10_round_decimal_long_double (arg,
3830                                                                              (int)(precision - 1) - exponent);
3831                                         if (digits == NULL)
3832                                           {
3833                                             END_LONG_DOUBLE_ROUNDING ();
3834                                             goto out_of_memory;
3835                                           }
3836                                         ndigits = strlen (digits);
3837
3838                                         if (ndigits == precision)
3839                                           break;
3840                                         if (ndigits < precision - 1
3841                                             || ndigits > precision + 1)
3842                                           /* The exponent was not guessed
3843                                              precisely enough.  */
3844                                           abort ();
3845                                         if (adjusted)
3846                                           /* None of two values of exponent is
3847                                              the right one.  Prevent an endless
3848                                              loop.  */
3849                                           abort ();
3850                                         free (digits);
3851                                         if (ndigits < precision)
3852                                           exponent -= 1;
3853                                         else
3854                                           exponent += 1;
3855                                         adjusted = 1;
3856                                       }
3857                                     /* Here ndigits = precision.  */
3858                                     if (is_borderline (digits, precision - 1))
3859                                       {
3860                                         /* Maybe the exponent guess was too high
3861                                            and a smaller exponent can be reached
3862                                            by turning a 10...0 into 9...9x.  */
3863                                         char *digits2 =
3864                                           scale10_round_decimal_long_double (arg,
3865                                                                              (int)(precision - 1) - exponent + 1);
3866                                         if (digits2 == NULL)
3867                                           {
3868                                             free (digits);
3869                                             END_LONG_DOUBLE_ROUNDING ();
3870                                             goto out_of_memory;
3871                                           }
3872                                         if (strlen (digits2) == precision)
3873                                           {
3874                                             free (digits);
3875                                             digits = digits2;
3876                                             exponent -= 1;
3877                                           }
3878                                         else
3879                                           free (digits2);
3880                                       }
3881                                     /* Here ndigits = precision.  */
3882
3883                                     /* Determine the number of trailing zeroes
3884                                        that have to be dropped.  */
3885                                     nzeroes = 0;
3886                                     if ((flags & FLAG_ALT) == 0)
3887                                       while (nzeroes < ndigits
3888                                              && digits[nzeroes] == '0')
3889                                         nzeroes++;
3890
3891                                     /* The exponent is now determined.  */
3892                                     if (exponent >= -4
3893                                         && exponent < (long)precision)
3894                                       {
3895                                         /* Fixed-point notation:
3896                                            max(exponent,0)+1 digits, then the
3897                                            decimal point, then the remaining
3898                                            digits without trailing zeroes.  */
3899                                         if (exponent >= 0)
3900                                           {
3901                                             size_t count = exponent + 1;
3902                                             /* Note: count <= precision = ndigits.  */
3903                                             for (; count > 0; count--)
3904                                               *p++ = digits[--ndigits];
3905                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
3906                                               {
3907                                                 *p++ = decimal_point_char ();
3908                                                 while (ndigits > nzeroes)
3909                                                   {
3910                                                     --ndigits;
3911                                                     *p++ = digits[ndigits];
3912                                                   }
3913                                               }
3914                                           }
3915                                         else
3916                                           {
3917                                             size_t count = -exponent - 1;
3918                                             *p++ = '0';
3919                                             *p++ = decimal_point_char ();
3920                                             for (; count > 0; count--)
3921                                               *p++ = '0';
3922                                             while (ndigits > nzeroes)
3923                                               {
3924                                                 --ndigits;
3925                                                 *p++ = digits[ndigits];
3926                                               }
3927                                           }
3928                                       }
3929                                     else
3930                                       {
3931                                         /* Exponential notation.  */
3932                                         *p++ = digits[--ndigits];
3933                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
3934                                           {
3935                                             *p++ = decimal_point_char ();
3936                                             while (ndigits > nzeroes)
3937                                               {
3938                                                 --ndigits;
3939                                                 *p++ = digits[ndigits];
3940                                               }
3941                                           }
3942                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3943 #   if WIDE_CHAR_VERSION
3944                                         {
3945                                           static const wchar_t decimal_format[] =
3946                                             { '%', '+', '.', '2', 'd', '\0' };
3947                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
3948                                         }
3949                                         while (*p != '\0')
3950                                           p++;
3951 #   else
3952                                         if (sizeof (DCHAR_T) == 1)
3953                                           {
3954                                             sprintf ((char *) p, "%+.2d", exponent);
3955                                             while (*p != '\0')
3956                                               p++;
3957                                           }
3958                                         else
3959                                           {
3960                                             char expbuf[6 + 1];
3961                                             const char *ep;
3962                                             sprintf (expbuf, "%+.2d", exponent);
3963                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3964                                               p++;
3965                                           }
3966 #   endif
3967                                       }
3968
3969                                     free (digits);
3970                                   }
3971                               }
3972                             else
3973                               abort ();
3974 #  else
3975                             /* arg is finite.  */
3976                             if (!(arg == 0.0L))
3977                               abort ();
3978
3979                             pad_ptr = p;
3980
3981                             if (dp->conversion == 'f' || dp->conversion == 'F')
3982                               {
3983                                 *p++ = '0';
3984                                 if ((flags & FLAG_ALT) || precision > 0)
3985                                   {
3986                                     *p++ = decimal_point_char ();
3987                                     for (; precision > 0; precision--)
3988                                       *p++ = '0';
3989                                   }
3990                               }
3991                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3992                               {
3993                                 *p++ = '0';
3994                                 if ((flags & FLAG_ALT) || precision > 0)
3995                                   {
3996                                     *p++ = decimal_point_char ();
3997                                     for (; precision > 0; precision--)
3998                                       *p++ = '0';
3999                                   }
4000                                 *p++ = dp->conversion; /* 'e' or 'E' */
4001                                 *p++ = '+';
4002                                 *p++ = '0';
4003                                 *p++ = '0';
4004                               }
4005                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4006                               {
4007                                 *p++ = '0';
4008                                 if (flags & FLAG_ALT)
4009                                   {
4010                                     size_t ndigits =
4011                                       (precision > 0 ? precision - 1 : 0);
4012                                     *p++ = decimal_point_char ();
4013                                     for (; ndigits > 0; --ndigits)
4014                                       *p++ = '0';
4015                                   }
4016                               }
4017                             else if (dp->conversion == 'a' || dp->conversion == 'A')
4018                               {
4019                                 *p++ = '0';
4020                                 *p++ = dp->conversion - 'A' + 'X';
4021                                 pad_ptr = p;
4022                                 *p++ = '0';
4023                                 if ((flags & FLAG_ALT) || precision > 0)
4024                                   {
4025                                     *p++ = decimal_point_char ();
4026                                     for (; precision > 0; precision--)
4027                                       *p++ = '0';
4028                                   }
4029                                 *p++ = dp->conversion - 'A' + 'P';
4030                                 *p++ = '+';
4031                                 *p++ = '0';
4032                               }
4033                             else
4034                               abort ();
4035 #  endif
4036                           }
4037
4038                         END_LONG_DOUBLE_ROUNDING ();
4039                       }
4040                   }
4041 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4042                 else
4043 #  endif
4044 # endif
4045 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4046                   {
4047                     double arg = a.arg[dp->arg_index].a.a_double;
4048
4049                     if (isnand (arg))
4050                       {
4051                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4052                           {
4053                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4054                           }
4055                         else
4056                           {
4057                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4058                           }
4059                       }
4060                     else
4061                       {
4062                         int sign = 0;
4063
4064                         if (signbit (arg)) /* arg < 0.0 or negative zero */
4065                           {
4066                             sign = -1;
4067                             arg = -arg;
4068                           }
4069
4070                         if (sign < 0)
4071                           *p++ = '-';
4072                         else if (flags & FLAG_SHOWSIGN)
4073                           *p++ = '+';
4074                         else if (flags & FLAG_SPACE)
4075                           *p++ = ' ';
4076
4077                         if (arg > 0.0 && arg + arg == arg)
4078                           {
4079                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4080                               {
4081                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4082                               }
4083                             else
4084                               {
4085                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4086                               }
4087                           }
4088                         else
4089                           {
4090 #  if NEED_PRINTF_DOUBLE
4091                             pad_ptr = p;
4092
4093                             if (dp->conversion == 'f' || dp->conversion == 'F')
4094                               {
4095                                 char *digits;
4096                                 size_t ndigits;
4097
4098                                 digits =
4099                                   scale10_round_decimal_double (arg, precision);
4100                                 if (digits == NULL)
4101                                   goto out_of_memory;
4102                                 ndigits = strlen (digits);
4103
4104                                 if (ndigits > precision)
4105                                   do
4106                                     {
4107                                       --ndigits;
4108                                       *p++ = digits[ndigits];
4109                                     }
4110                                   while (ndigits > precision);
4111                                 else
4112                                   *p++ = '0';
4113                                 /* Here ndigits <= precision.  */
4114                                 if ((flags & FLAG_ALT) || precision > 0)
4115                                   {
4116                                     *p++ = decimal_point_char ();
4117                                     for (; precision > ndigits; precision--)
4118                                       *p++ = '0';
4119                                     while (ndigits > 0)
4120                                       {
4121                                         --ndigits;
4122                                         *p++ = digits[ndigits];
4123                                       }
4124                                   }
4125
4126                                 free (digits);
4127                               }
4128                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4129                               {
4130                                 int exponent;
4131
4132                                 if (arg == 0.0)
4133                                   {
4134                                     exponent = 0;
4135                                     *p++ = '0';
4136                                     if ((flags & FLAG_ALT) || precision > 0)
4137                                       {
4138                                         *p++ = decimal_point_char ();
4139                                         for (; precision > 0; precision--)
4140                                           *p++ = '0';
4141                                       }
4142                                   }
4143                                 else
4144                                   {
4145                                     /* arg > 0.0.  */
4146                                     int adjusted;
4147                                     char *digits;
4148                                     size_t ndigits;
4149
4150                                     exponent = floorlog10 (arg);
4151                                     adjusted = 0;
4152                                     for (;;)
4153                                       {
4154                                         digits =
4155                                           scale10_round_decimal_double (arg,
4156                                                                         (int)precision - exponent);
4157                                         if (digits == NULL)
4158                                           goto out_of_memory;
4159                                         ndigits = strlen (digits);
4160
4161                                         if (ndigits == precision + 1)
4162                                           break;
4163                                         if (ndigits < precision
4164                                             || ndigits > precision + 2)
4165                                           /* The exponent was not guessed
4166                                              precisely enough.  */
4167                                           abort ();
4168                                         if (adjusted)
4169                                           /* None of two values of exponent is
4170                                              the right one.  Prevent an endless
4171                                              loop.  */
4172                                           abort ();
4173                                         free (digits);
4174                                         if (ndigits == precision)
4175                                           exponent -= 1;
4176                                         else
4177                                           exponent += 1;
4178                                         adjusted = 1;
4179                                       }
4180                                     /* Here ndigits = precision+1.  */
4181                                     if (is_borderline (digits, precision))
4182                                       {
4183                                         /* Maybe the exponent guess was too high
4184                                            and a smaller exponent can be reached
4185                                            by turning a 10...0 into 9...9x.  */
4186                                         char *digits2 =
4187                                           scale10_round_decimal_double (arg,
4188                                                                         (int)precision - exponent + 1);
4189                                         if (digits2 == NULL)
4190                                           {
4191                                             free (digits);
4192                                             goto out_of_memory;
4193                                           }
4194                                         if (strlen (digits2) == precision + 1)
4195                                           {
4196                                             free (digits);
4197                                             digits = digits2;
4198                                             exponent -= 1;
4199                                           }
4200                                         else
4201                                           free (digits2);
4202                                       }
4203                                     /* Here ndigits = precision+1.  */
4204
4205                                     *p++ = digits[--ndigits];
4206                                     if ((flags & FLAG_ALT) || precision > 0)
4207                                       {
4208                                         *p++ = decimal_point_char ();
4209                                         while (ndigits > 0)
4210                                           {
4211                                             --ndigits;
4212                                             *p++ = digits[ndigits];
4213                                           }
4214                                       }
4215
4216                                     free (digits);
4217                                   }
4218
4219                                 *p++ = dp->conversion; /* 'e' or 'E' */
4220 #   if WIDE_CHAR_VERSION
4221                                 {
4222                                   static const wchar_t decimal_format[] =
4223                                     /* Produce the same number of exponent digits
4224                                        as the native printf implementation.  */
4225 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4226                                     { '%', '+', '.', '3', 'd', '\0' };
4227 #    else
4228                                     { '%', '+', '.', '2', 'd', '\0' };
4229 #    endif
4230                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
4231                                 }
4232                                 while (*p != '\0')
4233                                   p++;
4234 #   else
4235                                 {
4236                                   static const char decimal_format[] =
4237                                     /* Produce the same number of exponent digits
4238                                        as the native printf implementation.  */
4239 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4240                                     "%+.3d";
4241 #    else
4242                                     "%+.2d";
4243 #    endif
4244                                   if (sizeof (DCHAR_T) == 1)
4245                                     {
4246                                       sprintf ((char *) p, decimal_format, exponent);
4247                                       while (*p != '\0')
4248                                         p++;
4249                                     }
4250                                   else
4251                                     {
4252                                       char expbuf[6 + 1];
4253                                       const char *ep;
4254                                       sprintf (expbuf, decimal_format, exponent);
4255                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4256                                         p++;
4257                                     }
4258                                 }
4259 #   endif
4260                               }
4261                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4262                               {
4263                                 if (precision == 0)
4264                                   precision = 1;
4265                                 /* precision >= 1.  */
4266
4267                                 if (arg == 0.0)
4268                                   /* The exponent is 0, >= -4, < precision.
4269                                      Use fixed-point notation.  */
4270                                   {
4271                                     size_t ndigits = precision;
4272                                     /* Number of trailing zeroes that have to be
4273                                        dropped.  */
4274                                     size_t nzeroes =
4275                                       (flags & FLAG_ALT ? 0 : precision - 1);
4276
4277                                     --ndigits;
4278                                     *p++ = '0';
4279                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
4280                                       {
4281                                         *p++ = decimal_point_char ();
4282                                         while (ndigits > nzeroes)
4283                                           {
4284                                             --ndigits;
4285                                             *p++ = '0';
4286                                           }
4287                                       }
4288                                   }
4289                                 else
4290                                   {
4291                                     /* arg > 0.0.  */
4292                                     int exponent;
4293                                     int adjusted;
4294                                     char *digits;
4295                                     size_t ndigits;
4296                                     size_t nzeroes;
4297
4298                                     exponent = floorlog10 (arg);
4299                                     adjusted = 0;
4300                                     for (;;)
4301                                       {
4302                                         digits =
4303                                           scale10_round_decimal_double (arg,
4304                                                                         (int)(precision - 1) - exponent);
4305                                         if (digits == NULL)
4306                                           goto out_of_memory;
4307                                         ndigits = strlen (digits);
4308
4309                                         if (ndigits == precision)
4310                                           break;
4311                                         if (ndigits < precision - 1
4312                                             || ndigits > precision + 1)
4313                                           /* The exponent was not guessed
4314                                              precisely enough.  */
4315                                           abort ();
4316                                         if (adjusted)
4317                                           /* None of two values of exponent is
4318                                              the right one.  Prevent an endless
4319                                              loop.  */
4320                                           abort ();
4321                                         free (digits);
4322                                         if (ndigits < precision)
4323                                           exponent -= 1;
4324                                         else
4325                                           exponent += 1;
4326                                         adjusted = 1;
4327                                       }
4328                                     /* Here ndigits = precision.  */
4329                                     if (is_borderline (digits, precision - 1))
4330                                       {
4331                                         /* Maybe the exponent guess was too high
4332                                            and a smaller exponent can be reached
4333                                            by turning a 10...0 into 9...9x.  */
4334                                         char *digits2 =
4335                                           scale10_round_decimal_double (arg,
4336                                                                         (int)(precision - 1) - exponent + 1);
4337                                         if (digits2 == NULL)
4338                                           {
4339                                             free (digits);
4340                                             goto out_of_memory;
4341                                           }
4342                                         if (strlen (digits2) == precision)
4343                                           {
4344                                             free (digits);
4345                                             digits = digits2;
4346                                             exponent -= 1;
4347                                           }
4348                                         else
4349                                           free (digits2);
4350                                       }
4351                                     /* Here ndigits = precision.  */
4352
4353                                     /* Determine the number of trailing zeroes
4354                                        that have to be dropped.  */
4355                                     nzeroes = 0;
4356                                     if ((flags & FLAG_ALT) == 0)
4357                                       while (nzeroes < ndigits
4358                                              && digits[nzeroes] == '0')
4359                                         nzeroes++;
4360
4361                                     /* The exponent is now determined.  */
4362                                     if (exponent >= -4
4363                                         && exponent < (long)precision)
4364                                       {
4365                                         /* Fixed-point notation:
4366                                            max(exponent,0)+1 digits, then the
4367                                            decimal point, then the remaining
4368                                            digits without trailing zeroes.  */
4369                                         if (exponent >= 0)
4370                                           {
4371                                             size_t count = exponent + 1;
4372                                             /* Note: count <= precision = ndigits.  */
4373                                             for (; count > 0; count--)
4374                                               *p++ = digits[--ndigits];
4375                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
4376                                               {
4377                                                 *p++ = decimal_point_char ();
4378                                                 while (ndigits > nzeroes)
4379                                                   {
4380                                                     --ndigits;
4381                                                     *p++ = digits[ndigits];
4382                                                   }
4383                                               }
4384                                           }
4385                                         else
4386                                           {
4387                                             size_t count = -exponent - 1;
4388                                             *p++ = '0';
4389                                             *p++ = decimal_point_char ();
4390                                             for (; count > 0; count--)
4391                                               *p++ = '0';
4392                                             while (ndigits > nzeroes)
4393                                               {
4394                                                 --ndigits;
4395                                                 *p++ = digits[ndigits];
4396                                               }
4397                                           }
4398                                       }
4399                                     else
4400                                       {
4401                                         /* Exponential notation.  */
4402                                         *p++ = digits[--ndigits];
4403                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
4404                                           {
4405                                             *p++ = decimal_point_char ();
4406                                             while (ndigits > nzeroes)
4407                                               {
4408                                                 --ndigits;
4409                                                 *p++ = digits[ndigits];
4410                                               }
4411                                           }
4412                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4413 #   if WIDE_CHAR_VERSION
4414                                         {
4415                                           static const wchar_t decimal_format[] =
4416                                             /* Produce the same number of exponent digits
4417                                                as the native printf implementation.  */
4418 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4419                                             { '%', '+', '.', '3', 'd', '\0' };
4420 #    else
4421                                             { '%', '+', '.', '2', 'd', '\0' };
4422 #    endif
4423                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
4424                                         }
4425                                         while (*p != '\0')
4426                                           p++;
4427 #   else
4428                                         {
4429                                           static const char decimal_format[] =
4430                                             /* Produce the same number of exponent digits
4431                                                as the native printf implementation.  */
4432 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4433                                             "%+.3d";
4434 #    else
4435                                             "%+.2d";
4436 #    endif
4437                                           if (sizeof (DCHAR_T) == 1)
4438                                             {
4439                                               sprintf ((char *) p, decimal_format, exponent);
4440                                               while (*p != '\0')
4441                                                 p++;
4442                                             }
4443                                           else
4444                                             {
4445                                               char expbuf[6 + 1];
4446                                               const char *ep;
4447                                               sprintf (expbuf, decimal_format, exponent);
4448                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4449                                                 p++;
4450                                             }
4451                                         }
4452 #   endif
4453                                       }
4454
4455                                     free (digits);
4456                                   }
4457                               }
4458                             else
4459                               abort ();
4460 #  else
4461                             /* arg is finite.  */
4462                             if (!(arg == 0.0))
4463                               abort ();
4464
4465                             pad_ptr = p;
4466
4467                             if (dp->conversion == 'f' || dp->conversion == 'F')
4468                               {
4469                                 *p++ = '0';
4470                                 if ((flags & FLAG_ALT) || precision > 0)
4471                                   {
4472                                     *p++ = decimal_point_char ();
4473                                     for (; precision > 0; precision--)
4474                                       *p++ = '0';
4475                                   }
4476                               }
4477                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4478                               {
4479                                 *p++ = '0';
4480                                 if ((flags & FLAG_ALT) || precision > 0)
4481                                   {
4482                                     *p++ = decimal_point_char ();
4483                                     for (; precision > 0; precision--)
4484                                       *p++ = '0';
4485                                   }
4486                                 *p++ = dp->conversion; /* 'e' or 'E' */
4487                                 *p++ = '+';
4488                                 /* Produce the same number of exponent digits as
4489                                    the native printf implementation.  */
4490 #   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4491                                 *p++ = '0';
4492 #   endif
4493                                 *p++ = '0';
4494                                 *p++ = '0';
4495                               }
4496                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4497                               {
4498                                 *p++ = '0';
4499                                 if (flags & FLAG_ALT)
4500                                   {
4501                                     size_t ndigits =
4502                                       (precision > 0 ? precision - 1 : 0);
4503                                     *p++ = decimal_point_char ();
4504                                     for (; ndigits > 0; --ndigits)
4505                                       *p++ = '0';
4506                                   }
4507                               }
4508                             else
4509                               abort ();
4510 #  endif
4511                           }
4512                       }
4513                   }
4514 # endif
4515
4516                 /* The generated string now extends from tmp to p, with the
4517                    zero padding insertion point being at pad_ptr.  */
4518                 if (has_width && p - tmp < width)
4519                   {
4520                     size_t pad = width - (p - tmp);
4521                     DCHAR_T *end = p + pad;
4522
4523                     if (flags & FLAG_LEFT)
4524                       {
4525                         /* Pad with spaces on the right.  */
4526                         for (; pad > 0; pad--)
4527                           *p++ = ' ';
4528                       }
4529                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4530                       {
4531                         /* Pad with zeroes.  */
4532                         DCHAR_T *q = end;
4533
4534                         while (p > pad_ptr)
4535                           *--q = *--p;
4536                         for (; pad > 0; pad--)
4537                           *p++ = '0';
4538                       }
4539                     else
4540                       {
4541                         /* Pad with spaces on the left.  */
4542                         DCHAR_T *q = end;
4543
4544                         while (p > tmp)
4545                           *--q = *--p;
4546                         for (; pad > 0; pad--)
4547                           *p++ = ' ';
4548                       }
4549
4550                     p = end;
4551                   }
4552
4553                 {
4554                   size_t count = p - tmp;
4555
4556                   if (count >= tmp_length)
4557                     /* tmp_length was incorrectly calculated - fix the
4558                        code above!  */
4559                     abort ();
4560
4561                   /* Make room for the result.  */
4562                   if (count >= allocated - length)
4563                     {
4564                       size_t n = xsum (length, count);
4565
4566                       ENSURE_ALLOCATION (n);
4567                     }
4568
4569                   /* Append the result.  */
4570                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4571                   if (tmp != tmpbuf)
4572                     free (tmp);
4573                   length += count;
4574                 }
4575               }
4576 #endif
4577             else
4578               {
4579                 arg_type type = a.arg[dp->arg_index].type;
4580                 int flags = dp->flags;
4581 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4582                 int has_width;
4583                 size_t width;
4584 #endif
4585 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4586                 int has_precision;
4587                 size_t precision;
4588 #endif
4589 #if NEED_PRINTF_UNBOUNDED_PRECISION
4590                 int prec_ourselves;
4591 #else
4592 #               define prec_ourselves 0
4593 #endif
4594 #if NEED_PRINTF_FLAG_LEFTADJUST
4595 #               define pad_ourselves 1
4596 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4597                 int pad_ourselves;
4598 #else
4599 #               define pad_ourselves 0
4600 #endif
4601                 TCHAR_T *fbp;
4602                 unsigned int prefix_count;
4603                 int prefixes[2] IF_LINT (= { 0 });
4604                 int orig_errno;
4605 #if !USE_SNPRINTF
4606                 size_t tmp_length;
4607                 TCHAR_T tmpbuf[700];
4608                 TCHAR_T *tmp;
4609 #endif
4610
4611 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4612                 has_width = 0;
4613                 width = 0;
4614                 if (dp->width_start != dp->width_end)
4615                   {
4616                     if (dp->width_arg_index != ARG_NONE)
4617                       {
4618                         int arg;
4619
4620                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4621                           abort ();
4622                         arg = a.arg[dp->width_arg_index].a.a_int;
4623                         if (arg < 0)
4624                           {
4625                             /* "A negative field width is taken as a '-' flag
4626                                 followed by a positive field width."  */
4627                             flags |= FLAG_LEFT;
4628                             width = (unsigned int) (-arg);
4629                           }
4630                         else
4631                           width = arg;
4632                       }
4633                     else
4634                       {
4635                         const FCHAR_T *digitp = dp->width_start;
4636
4637                         do
4638                           width = xsum (xtimes (width, 10), *digitp++ - '0');
4639                         while (digitp != dp->width_end);
4640                       }
4641                     has_width = 1;
4642                   }
4643 #endif
4644
4645 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
4646                 has_precision = 0;
4647                 precision = 6;
4648                 if (dp->precision_start != dp->precision_end)
4649                   {
4650                     if (dp->precision_arg_index != ARG_NONE)
4651                       {
4652                         int arg;
4653
4654                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4655                           abort ();
4656                         arg = a.arg[dp->precision_arg_index].a.a_int;
4657                         /* "A negative precision is taken as if the precision
4658                             were omitted."  */
4659                         if (arg >= 0)
4660                           {
4661                             precision = arg;
4662                             has_precision = 1;
4663                           }
4664                       }
4665                     else
4666                       {
4667                         const FCHAR_T *digitp = dp->precision_start + 1;
4668
4669                         precision = 0;
4670                         while (digitp != dp->precision_end)
4671                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4672                         has_precision = 1;
4673                       }
4674                   }
4675 #endif
4676
4677                 /* Decide whether to handle the precision ourselves.  */
4678 #if NEED_PRINTF_UNBOUNDED_PRECISION
4679                 switch (dp->conversion)
4680                   {
4681                   case 'd': case 'i': case 'u':
4682                   case 'o':
4683                   case 'x': case 'X': case 'p':
4684                     prec_ourselves = has_precision && (precision > 0);
4685                     break;
4686                   default:
4687                     prec_ourselves = 0;
4688                     break;
4689                   }
4690 #endif
4691
4692                 /* Decide whether to perform the padding ourselves.  */
4693 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4694                 switch (dp->conversion)
4695                   {
4696 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4697                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4698                      to perform the padding after this conversion.  Functions
4699                      with unistdio extensions perform the padding based on
4700                      character count rather than element count.  */
4701                   case 'c': case 's':
4702 # endif
4703 # if NEED_PRINTF_FLAG_ZERO
4704                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4705                   case 'a': case 'A':
4706 # endif
4707                     pad_ourselves = 1;
4708                     break;
4709                   default:
4710                     pad_ourselves = prec_ourselves;
4711                     break;
4712                   }
4713 #endif
4714
4715 #if !USE_SNPRINTF
4716                 /* Allocate a temporary buffer of sufficient size for calling
4717                    sprintf.  */
4718                 tmp_length =
4719                   MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
4720                                    flags, width, has_precision, precision,
4721                                    pad_ourselves);
4722
4723                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4724                   tmp = tmpbuf;
4725                 else
4726                   {
4727                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4728
4729                     if (size_overflow_p (tmp_memsize))
4730                       /* Overflow, would lead to out of memory.  */
4731                       goto out_of_memory;
4732                     tmp = (TCHAR_T *) malloc (tmp_memsize);
4733                     if (tmp == NULL)
4734                       /* Out of memory.  */
4735                       goto out_of_memory;
4736                   }
4737 #endif
4738
4739                 /* Construct the format string for calling snprintf or
4740                    sprintf.  */
4741                 fbp = buf;
4742                 *fbp++ = '%';
4743 #if NEED_PRINTF_FLAG_GROUPING
4744                 /* The underlying implementation doesn't support the ' flag.
4745                    Produce no grouping characters in this case; this is
4746                    acceptable because the grouping is locale dependent.  */
4747 #else
4748                 if (flags & FLAG_GROUP)
4749                   *fbp++ = '\'';
4750 #endif
4751                 if (flags & FLAG_LEFT)
4752                   *fbp++ = '-';
4753                 if (flags & FLAG_SHOWSIGN)
4754                   *fbp++ = '+';
4755                 if (flags & FLAG_SPACE)
4756                   *fbp++ = ' ';
4757                 if (flags & FLAG_ALT)
4758                   *fbp++ = '#';
4759                 if (!pad_ourselves)
4760                   {
4761                     if (flags & FLAG_ZERO)
4762                       *fbp++ = '0';
4763                     if (dp->width_start != dp->width_end)
4764                       {
4765                         size_t n = dp->width_end - dp->width_start;
4766                         /* The width specification is known to consist only
4767                            of standard ASCII characters.  */
4768                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4769                           {
4770                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4771                             fbp += n;
4772                           }
4773                         else
4774                           {
4775                             const FCHAR_T *mp = dp->width_start;
4776                             do
4777                               *fbp++ = (unsigned char) *mp++;
4778                             while (--n > 0);
4779                           }
4780                       }
4781                   }
4782                 if (!prec_ourselves)
4783                   {
4784                     if (dp->precision_start != dp->precision_end)
4785                       {
4786                         size_t n = dp->precision_end - dp->precision_start;
4787                         /* The precision specification is known to consist only
4788                            of standard ASCII characters.  */
4789                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4790                           {
4791                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4792                             fbp += n;
4793                           }
4794                         else
4795                           {
4796                             const FCHAR_T *mp = dp->precision_start;
4797                             do
4798                               *fbp++ = (unsigned char) *mp++;
4799                             while (--n > 0);
4800                           }
4801                       }
4802                   }
4803
4804                 switch (type)
4805                   {
4806 #if HAVE_LONG_LONG_INT
4807                   case TYPE_LONGLONGINT:
4808                   case TYPE_ULONGLONGINT:
4809 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4810                     *fbp++ = 'I';
4811                     *fbp++ = '6';
4812                     *fbp++ = '4';
4813                     break;
4814 # else
4815                     *fbp++ = 'l';
4816                     /*FALLTHROUGH*/
4817 # endif
4818 #endif
4819                   case TYPE_LONGINT:
4820                   case TYPE_ULONGINT:
4821 #if HAVE_WINT_T
4822                   case TYPE_WIDE_CHAR:
4823 #endif
4824 #if HAVE_WCHAR_T
4825                   case TYPE_WIDE_STRING:
4826 #endif
4827                     *fbp++ = 'l';
4828                     break;
4829                   case TYPE_LONGDOUBLE:
4830                     *fbp++ = 'L';
4831                     break;
4832                   default:
4833                     break;
4834                   }
4835 #if NEED_PRINTF_DIRECTIVE_F
4836                 if (dp->conversion == 'F')
4837                   *fbp = 'f';
4838                 else
4839 #endif
4840                   *fbp = dp->conversion;
4841 #if USE_SNPRINTF
4842 # if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4843                 fbp[1] = '%';
4844                 fbp[2] = 'n';
4845                 fbp[3] = '\0';
4846 # else
4847                 /* On glibc2 systems from glibc >= 2.3 - probably also older
4848                    ones - we know that snprintf's returns value conforms to
4849                    ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
4850                    Therefore we can avoid using %n in this situation.
4851                    On glibc2 systems from 2004-10-18 or newer, the use of %n
4852                    in format strings in writable memory may crash the program
4853                    (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4854                    in this situation.  */
4855                 /* On native Win32 systems (such as mingw), we can avoid using
4856                    %n because:
4857                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4858                        snprintf does not write more than the specified number
4859                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4860                        '4', '5', '6' into buf, not '4', '5', '\0'.)
4861                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4862                        allows us to recognize the case of an insufficient
4863                        buffer size: it returns -1 in this case.
4864                    On native Win32 systems (such as mingw) where the OS is
4865                    Windows Vista, the use of %n in format strings by default
4866                    crashes the program. See
4867                      <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4868                      <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4869                    So we should avoid %n in this situation.  */
4870                 fbp[1] = '\0';
4871 # endif
4872 #else
4873                 fbp[1] = '\0';
4874 #endif
4875
4876                 /* Construct the arguments for calling snprintf or sprintf.  */
4877                 prefix_count = 0;
4878                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4879                   {
4880                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4881                       abort ();
4882                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4883                   }
4884                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4885                   {
4886                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4887                       abort ();
4888                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4889                   }
4890
4891 #if USE_SNPRINTF
4892                 /* The SNPRINTF result is appended after result[0..length].
4893                    The latter is an array of DCHAR_T; SNPRINTF appends an
4894                    array of TCHAR_T to it.  This is possible because
4895                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4896                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
4897 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4898                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
4899                    where an snprintf() with maxlen==1 acts like sprintf().  */
4900                 ENSURE_ALLOCATION (xsum (length,
4901                                          (2 + TCHARS_PER_DCHAR - 1)
4902                                          / TCHARS_PER_DCHAR));
4903                 /* Prepare checking whether snprintf returns the count
4904                    via %n.  */
4905                 *(TCHAR_T *) (result + length) = '\0';
4906 #endif
4907
4908                 orig_errno = errno;
4909
4910                 for (;;)
4911                   {
4912                     int count = -1;
4913
4914 #if USE_SNPRINTF
4915                     int retcount = 0;
4916                     size_t maxlen = allocated - length;
4917                     /* SNPRINTF can fail if its second argument is
4918                        > INT_MAX.  */
4919                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4920                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
4921                     maxlen = maxlen * TCHARS_PER_DCHAR;
4922 # define SNPRINTF_BUF(arg) \
4923                     switch (prefix_count)                                   \
4924                       {                                                     \
4925                       case 0:                                               \
4926                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4927                                              maxlen, buf,                   \
4928                                              arg, &count);                  \
4929                         break;                                              \
4930                       case 1:                                               \
4931                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4932                                              maxlen, buf,                   \
4933                                              prefixes[0], arg, &count);     \
4934                         break;                                              \
4935                       case 2:                                               \
4936                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4937                                              maxlen, buf,                   \
4938                                              prefixes[0], prefixes[1], arg, \
4939                                              &count);                       \
4940                         break;                                              \
4941                       default:                                              \
4942                         abort ();                                           \
4943                       }
4944 #else
4945 # define SNPRINTF_BUF(arg) \
4946                     switch (prefix_count)                                   \
4947                       {                                                     \
4948                       case 0:                                               \
4949                         count = sprintf (tmp, buf, arg);                    \
4950                         break;                                              \
4951                       case 1:                                               \
4952                         count = sprintf (tmp, buf, prefixes[0], arg);       \
4953                         break;                                              \
4954                       case 2:                                               \
4955                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4956                                          arg);                              \
4957                         break;                                              \
4958                       default:                                              \
4959                         abort ();                                           \
4960                       }
4961 #endif
4962
4963                     errno = 0;
4964                     switch (type)
4965                       {
4966                       case TYPE_SCHAR:
4967                         {
4968                           int arg = a.arg[dp->arg_index].a.a_schar;
4969                           SNPRINTF_BUF (arg);
4970                         }
4971                         break;
4972                       case TYPE_UCHAR:
4973                         {
4974                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4975                           SNPRINTF_BUF (arg);
4976                         }
4977                         break;
4978                       case TYPE_SHORT:
4979                         {
4980                           int arg = a.arg[dp->arg_index].a.a_short;
4981                           SNPRINTF_BUF (arg);
4982                         }
4983                         break;
4984                       case TYPE_USHORT:
4985                         {
4986                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
4987                           SNPRINTF_BUF (arg);
4988                         }
4989                         break;
4990                       case TYPE_INT:
4991                         {
4992                           int arg = a.arg[dp->arg_index].a.a_int;
4993                           SNPRINTF_BUF (arg);
4994                         }
4995                         break;
4996                       case TYPE_UINT:
4997                         {
4998                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
4999                           SNPRINTF_BUF (arg);
5000                         }
5001                         break;
5002                       case TYPE_LONGINT:
5003                         {
5004                           long int arg = a.arg[dp->arg_index].a.a_longint;
5005                           SNPRINTF_BUF (arg);
5006                         }
5007                         break;
5008                       case TYPE_ULONGINT:
5009                         {
5010                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5011                           SNPRINTF_BUF (arg);
5012                         }
5013                         break;
5014 #if HAVE_LONG_LONG_INT
5015                       case TYPE_LONGLONGINT:
5016                         {
5017                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5018                           SNPRINTF_BUF (arg);
5019                         }
5020                         break;
5021                       case TYPE_ULONGLONGINT:
5022                         {
5023                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5024                           SNPRINTF_BUF (arg);
5025                         }
5026                         break;
5027 #endif
5028                       case TYPE_DOUBLE:
5029                         {
5030                           double arg = a.arg[dp->arg_index].a.a_double;
5031                           SNPRINTF_BUF (arg);
5032                         }
5033                         break;
5034                       case TYPE_LONGDOUBLE:
5035                         {
5036                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
5037                           SNPRINTF_BUF (arg);
5038                         }
5039                         break;
5040                       case TYPE_CHAR:
5041                         {
5042                           int arg = a.arg[dp->arg_index].a.a_char;
5043                           SNPRINTF_BUF (arg);
5044                         }
5045                         break;
5046 #if HAVE_WINT_T
5047                       case TYPE_WIDE_CHAR:
5048                         {
5049                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5050                           SNPRINTF_BUF (arg);
5051                         }
5052                         break;
5053 #endif
5054                       case TYPE_STRING:
5055                         {
5056                           const char *arg = a.arg[dp->arg_index].a.a_string;
5057                           SNPRINTF_BUF (arg);
5058                         }
5059                         break;
5060 #if HAVE_WCHAR_T
5061                       case TYPE_WIDE_STRING:
5062                         {
5063                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5064                           SNPRINTF_BUF (arg);
5065                         }
5066                         break;
5067 #endif
5068                       case TYPE_POINTER:
5069                         {
5070                           void *arg = a.arg[dp->arg_index].a.a_pointer;
5071                           SNPRINTF_BUF (arg);
5072                         }
5073                         break;
5074                       default:
5075                         abort ();
5076                       }
5077
5078 #if USE_SNPRINTF
5079                     /* Portability: Not all implementations of snprintf()
5080                        are ISO C 99 compliant.  Determine the number of
5081                        bytes that snprintf() has produced or would have
5082                        produced.  */
5083                     if (count >= 0)
5084                       {
5085                         /* Verify that snprintf() has NUL-terminated its
5086                            result.  */
5087                         if (count < maxlen
5088                             && ((TCHAR_T *) (result + length)) [count] != '\0')
5089                           abort ();
5090                         /* Portability hack.  */
5091                         if (retcount > count)
5092                           count = retcount;
5093                       }
5094                     else
5095                       {
5096                         /* snprintf() doesn't understand the '%n'
5097                            directive.  */
5098                         if (fbp[1] != '\0')
5099                           {
5100                             /* Don't use the '%n' directive; instead, look
5101                                at the snprintf() return value.  */
5102                             fbp[1] = '\0';
5103                             continue;
5104                           }
5105                         else
5106                           {
5107                             /* Look at the snprintf() return value.  */
5108                             if (retcount < 0)
5109                               {
5110 # if !HAVE_SNPRINTF_RETVAL_C99
5111                                 /* HP-UX 10.20 snprintf() is doubly deficient:
5112                                    It doesn't understand the '%n' directive,
5113                                    *and* it returns -1 (rather than the length
5114                                    that would have been required) when the
5115                                    buffer is too small.
5116                                    But a failure at this point can also come
5117                                    from other reasons than a too small buffer,
5118                                    such as an invalid wide string argument to
5119                                    the %ls directive, or possibly an invalid
5120                                    floating-point argument.  */
5121                                 size_t tmp_length =
5122                                   MAX_ROOM_NEEDED (&a, dp->arg_index,
5123                                                    dp->conversion, type, flags,
5124                                                    width, has_precision,
5125                                                    precision, pad_ourselves);
5126
5127                                 if (maxlen < tmp_length)
5128                                   {
5129                                     /* Make more room.  But try to do through
5130                                        this reallocation only once.  */
5131                                     size_t bigger_need =
5132                                       xsum (length,
5133                                             xsum (tmp_length,
5134                                                   TCHARS_PER_DCHAR - 1)
5135                                             / TCHARS_PER_DCHAR);
5136                                     /* And always grow proportionally.
5137                                        (There may be several arguments, each
5138                                        needing a little more room than the
5139                                        previous one.)  */
5140                                     size_t bigger_need2 =
5141                                       xsum (xtimes (allocated, 2), 12);
5142                                     if (bigger_need < bigger_need2)
5143                                       bigger_need = bigger_need2;
5144                                     ENSURE_ALLOCATION (bigger_need);
5145                                     continue;
5146                                   }
5147 # endif
5148                               }
5149                             else
5150                               count = retcount;
5151                           }
5152                       }
5153 #endif
5154
5155                     /* Attempt to handle failure.  */
5156                     if (count < 0)
5157                       {
5158                         /* SNPRINTF or sprintf failed.  Save and use the errno
5159                            that it has set, if any.  */
5160                         int saved_errno = errno;
5161
5162                         if (!(result == resultbuf || result == NULL))
5163                           free (result);
5164                         if (buf_malloced != NULL)
5165                           free (buf_malloced);
5166                         CLEANUP ();
5167                         errno =
5168                           (saved_errno != 0
5169                            ? saved_errno
5170                            : (dp->conversion == 'c' || dp->conversion == 's'
5171                               ? EILSEQ
5172                               : EINVAL));
5173                         return NULL;
5174                       }
5175
5176 #if USE_SNPRINTF
5177                     /* Handle overflow of the allocated buffer.
5178                        If such an overflow occurs, a C99 compliant snprintf()
5179                        returns a count >= maxlen.  However, a non-compliant
5180                        snprintf() function returns only count = maxlen - 1.  To
5181                        cover both cases, test whether count >= maxlen - 1.  */
5182                     if ((unsigned int) count + 1 >= maxlen)
5183                       {
5184                         /* If maxlen already has attained its allowed maximum,
5185                            allocating more memory will not increase maxlen.
5186                            Instead of looping, bail out.  */
5187                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5188                           goto overflow;
5189                         else
5190                           {
5191                             /* Need at least (count + 1) * sizeof (TCHAR_T)
5192                                bytes.  (The +1 is for the trailing NUL.)
5193                                But ask for (count + 2) * sizeof (TCHAR_T)
5194                                bytes, so that in the next round, we likely get
5195                                  maxlen > (unsigned int) count + 1
5196                                and so we don't get here again.
5197                                And allocate proportionally, to avoid looping
5198                                eternally if snprintf() reports a too small
5199                                count.  */
5200                             size_t n =
5201                               xmax (xsum (length,
5202                                           ((unsigned int) count + 2
5203                                            + TCHARS_PER_DCHAR - 1)
5204                                           / TCHARS_PER_DCHAR),
5205                                     xtimes (allocated, 2));
5206
5207                             ENSURE_ALLOCATION (n);
5208                             continue;
5209                           }
5210                       }
5211 #endif
5212
5213 #if NEED_PRINTF_UNBOUNDED_PRECISION
5214                     if (prec_ourselves)
5215                       {
5216                         /* Handle the precision.  */
5217                         TCHAR_T *prec_ptr =
5218 # if USE_SNPRINTF
5219                           (TCHAR_T *) (result + length);
5220 # else
5221                           tmp;
5222 # endif
5223                         size_t prefix_count;
5224                         size_t move;
5225
5226                         prefix_count = 0;
5227                         /* Put the additional zeroes after the sign.  */
5228                         if (count >= 1
5229                             && (*prec_ptr == '-' || *prec_ptr == '+'
5230                                 || *prec_ptr == ' '))
5231                           prefix_count = 1;
5232                         /* Put the additional zeroes after the 0x prefix if
5233                            (flags & FLAG_ALT) || (dp->conversion == 'p').  */
5234                         else if (count >= 2
5235                                  && prec_ptr[0] == '0'
5236                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5237                           prefix_count = 2;
5238
5239                         move = count - prefix_count;
5240                         if (precision > move)
5241                           {
5242                             /* Insert zeroes.  */
5243                             size_t insert = precision - move;
5244                             TCHAR_T *prec_end;
5245
5246 # if USE_SNPRINTF
5247                             size_t n =
5248                               xsum (length,
5249                                     (count + insert + TCHARS_PER_DCHAR - 1)
5250                                     / TCHARS_PER_DCHAR);
5251                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5252                             ENSURE_ALLOCATION (n);
5253                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5254                             prec_ptr = (TCHAR_T *) (result + length);
5255 # endif
5256
5257                             prec_end = prec_ptr + count;
5258                             prec_ptr += prefix_count;
5259
5260                             while (prec_end > prec_ptr)
5261                               {
5262                                 prec_end--;
5263                                 prec_end[insert] = prec_end[0];
5264                               }
5265
5266                             prec_end += insert;
5267                             do
5268                               *--prec_end = '0';
5269                             while (prec_end > prec_ptr);
5270
5271                             count += insert;
5272                           }
5273                       }
5274 #endif
5275
5276 #if !USE_SNPRINTF
5277                     if (count >= tmp_length)
5278                       /* tmp_length was incorrectly calculated - fix the
5279                          code above!  */
5280                       abort ();
5281 #endif
5282
5283 #if !DCHAR_IS_TCHAR
5284                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
5285                     if (dp->conversion == 'c' || dp->conversion == 's')
5286                       {
5287                         /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5288                            TYPE_WIDE_STRING.
5289                            The result string is not certainly ASCII.  */
5290                         const TCHAR_T *tmpsrc;
5291                         DCHAR_T *tmpdst;
5292                         size_t tmpdst_len;
5293                         /* This code assumes that TCHAR_T is 'char'.  */
5294                         verify (sizeof (TCHAR_T) == 1);
5295 # if USE_SNPRINTF
5296                         tmpsrc = (TCHAR_T *) (result + length);
5297 # else
5298                         tmpsrc = tmp;
5299 # endif
5300                         tmpdst =
5301                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
5302                                                     iconveh_question_mark,
5303                                                     tmpsrc, count,
5304                                                     NULL,
5305                                                     NULL, &tmpdst_len);
5306                         if (tmpdst == NULL)
5307                           {
5308                             int saved_errno = errno;
5309                             if (!(result == resultbuf || result == NULL))
5310                               free (result);
5311                             if (buf_malloced != NULL)
5312                               free (buf_malloced);
5313                             CLEANUP ();
5314                             errno = saved_errno;
5315                             return NULL;
5316                           }
5317                         ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5318                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5319                         free (tmpdst);
5320                         count = tmpdst_len;
5321                       }
5322                     else
5323                       {
5324                         /* The result string is ASCII.
5325                            Simple 1:1 conversion.  */
5326 # if USE_SNPRINTF
5327                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5328                            no-op conversion, in-place on the array starting
5329                            at (result + length).  */
5330                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5331 # endif
5332                           {
5333                             const TCHAR_T *tmpsrc;
5334                             DCHAR_T *tmpdst;
5335                             size_t n;
5336
5337 # if USE_SNPRINTF
5338                             if (result == resultbuf)
5339                               {
5340                                 tmpsrc = (TCHAR_T *) (result + length);
5341                                 /* ENSURE_ALLOCATION will not move tmpsrc
5342                                    (because it's part of resultbuf).  */
5343                                 ENSURE_ALLOCATION (xsum (length, count));
5344                               }
5345                             else
5346                               {
5347                                 /* ENSURE_ALLOCATION will move the array
5348                                    (because it uses realloc().  */
5349                                 ENSURE_ALLOCATION (xsum (length, count));
5350                                 tmpsrc = (TCHAR_T *) (result + length);
5351                               }
5352 # else
5353                             tmpsrc = tmp;
5354                             ENSURE_ALLOCATION (xsum (length, count));
5355 # endif
5356                             tmpdst = result + length;
5357                             /* Copy backwards, because of overlapping.  */
5358                             tmpsrc += count;
5359                             tmpdst += count;
5360                             for (n = count; n > 0; n--)
5361                               *--tmpdst = (unsigned char) *--tmpsrc;
5362                           }
5363                       }
5364 #endif
5365
5366 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5367                     /* Make room for the result.  */
5368                     if (count > allocated - length)
5369                       {
5370                         /* Need at least count elements.  But allocate
5371                            proportionally.  */
5372                         size_t n =
5373                           xmax (xsum (length, count), xtimes (allocated, 2));
5374
5375                         ENSURE_ALLOCATION (n);
5376                       }
5377 #endif
5378
5379                     /* Here count <= allocated - length.  */
5380
5381                     /* Perform padding.  */
5382 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5383                     if (pad_ourselves && has_width)
5384                       {
5385                         size_t w;
5386 # if ENABLE_UNISTDIO
5387                         /* Outside POSIX, it's preferrable to compare the width
5388                            against the number of _characters_ of the converted
5389                            value.  */
5390                         w = DCHAR_MBSNLEN (result + length, count);
5391 # else
5392                         /* The width is compared against the number of _bytes_
5393                            of the converted value, says POSIX.  */
5394                         w = count;
5395 # endif
5396                         if (w < width)
5397                           {
5398                             size_t pad = width - w;
5399
5400                             /* Make room for the result.  */
5401                             if (xsum (count, pad) > allocated - length)
5402                               {
5403                                 /* Need at least count + pad elements.  But
5404                                    allocate proportionally.  */
5405                                 size_t n =
5406                                   xmax (xsum3 (length, count, pad),
5407                                         xtimes (allocated, 2));
5408
5409 # if USE_SNPRINTF
5410                                 length += count;
5411                                 ENSURE_ALLOCATION (n);
5412                                 length -= count;
5413 # else
5414                                 ENSURE_ALLOCATION (n);
5415 # endif
5416                               }
5417                             /* Here count + pad <= allocated - length.  */
5418
5419                             {
5420 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5421                               DCHAR_T * const rp = result + length;
5422 # else
5423                               DCHAR_T * const rp = tmp;
5424 # endif
5425                               DCHAR_T *p = rp + count;
5426                               DCHAR_T *end = p + pad;
5427                               DCHAR_T *pad_ptr;
5428 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5429                               if (dp->conversion == 'c'
5430                                   || dp->conversion == 's')
5431                                 /* No zero-padding for string directives.  */
5432                                 pad_ptr = NULL;
5433                               else
5434 # endif
5435                                 {
5436                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
5437                                   /* No zero-padding of "inf" and "nan".  */
5438                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5439                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5440                                     pad_ptr = NULL;
5441                                 }
5442                               /* The generated string now extends from rp to p,
5443                                  with the zero padding insertion point being at
5444                                  pad_ptr.  */
5445
5446                               count = count + pad; /* = end - rp */
5447
5448                               if (flags & FLAG_LEFT)
5449                                 {
5450                                   /* Pad with spaces on the right.  */
5451                                   for (; pad > 0; pad--)
5452                                     *p++ = ' ';
5453                                 }
5454                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5455                                 {
5456                                   /* Pad with zeroes.  */
5457                                   DCHAR_T *q = end;
5458
5459                                   while (p > pad_ptr)
5460                                     *--q = *--p;
5461                                   for (; pad > 0; pad--)
5462                                     *p++ = '0';
5463                                 }
5464                               else
5465                                 {
5466                                   /* Pad with spaces on the left.  */
5467                                   DCHAR_T *q = end;
5468
5469                                   while (p > rp)
5470                                     *--q = *--p;
5471                                   for (; pad > 0; pad--)
5472                                     *p++ = ' ';
5473                                 }
5474                             }
5475                           }
5476                       }
5477 #endif
5478
5479                     /* Here still count <= allocated - length.  */
5480
5481 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5482                     /* The snprintf() result did fit.  */
5483 #else
5484                     /* Append the sprintf() result.  */
5485                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5486 #endif
5487 #if !USE_SNPRINTF
5488                     if (tmp != tmpbuf)
5489                       free (tmp);
5490 #endif
5491
5492 #if NEED_PRINTF_DIRECTIVE_F
5493                     if (dp->conversion == 'F')
5494                       {
5495                         /* Convert the %f result to upper case for %F.  */
5496                         DCHAR_T *rp = result + length;
5497                         size_t rc;
5498                         for (rc = count; rc > 0; rc--, rp++)
5499                           if (*rp >= 'a' && *rp <= 'z')
5500                             *rp = *rp - 'a' + 'A';
5501                       }
5502 #endif
5503
5504                     length += count;
5505                     break;
5506                   }
5507                 errno = orig_errno;
5508 #undef pad_ourselves
5509 #undef prec_ourselves
5510               }
5511           }
5512       }
5513
5514     /* Add the final NUL.  */
5515     ENSURE_ALLOCATION (xsum (length, 1));
5516     result[length] = '\0';
5517
5518     if (result != resultbuf && length + 1 < allocated)
5519       {
5520         /* Shrink the allocated memory if possible.  */
5521         DCHAR_T *memory;
5522
5523         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5524         if (memory != NULL)
5525           result = memory;
5526       }
5527
5528     if (buf_malloced != NULL)
5529       free (buf_malloced);
5530     CLEANUP ();
5531     *lengthp = length;
5532     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
5533        says that snprintf() fails with errno = EOVERFLOW in this case, but
5534        that's only because snprintf() returns an 'int'.  This function does
5535        not have this limitation.  */
5536     return result;
5537
5538 #if USE_SNPRINTF
5539   overflow:
5540     if (!(result == resultbuf || result == NULL))
5541       free (result);
5542     if (buf_malloced != NULL)
5543       free (buf_malloced);
5544     CLEANUP ();
5545     errno = EOVERFLOW;
5546     return NULL;
5547 #endif
5548
5549   out_of_memory:
5550     if (!(result == resultbuf || result == NULL))
5551       free (result);
5552     if (buf_malloced != NULL)
5553       free (buf_malloced);
5554   out_of_memory_1:
5555     CLEANUP ();
5556     errno = ENOMEM;
5557     return NULL;
5558   }
5559 }
5560
5561 #undef MAX_ROOM_NEEDED
5562 #undef TCHARS_PER_DCHAR
5563 #undef SNPRINTF
5564 #undef USE_SNPRINTF
5565 #undef DCHAR_SET
5566 #undef DCHAR_CPY
5567 #undef PRINTF_PARSE
5568 #undef DIRECTIVES
5569 #undef DIRECTIVE
5570 #undef DCHAR_IS_TCHAR
5571 #undef TCHAR_T
5572 #undef DCHAR_T
5573 #undef FCHAR_T
5574 #undef VASNPRINTF