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