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