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