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