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