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