vasnprintf: Fix crash in %ls directive.
[gnulib.git] / lib / 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 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License along
15    with this program; if not, write to the Free Software Foundation,
16    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
17
18 /* This file can be parametrized with the following macros:
19      VASNPRINTF         The name of the function being defined.
20      FCHAR_T            The element type of the format string.
21      DCHAR_T            The element type of the destination (result) string.
22      FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
23                         in the format string are ASCII. MUST be set if
24                         FCHAR_T and DCHAR_T are not the same type.
25      DIRECTIVE          Structure denoting a format directive.
26                         Depends on FCHAR_T.
27      DIRECTIVES         Structure denoting the set of format directives of a
28                         format string.  Depends on FCHAR_T.
29      PRINTF_PARSE       Function that parses a format string.
30                         Depends on FCHAR_T.
31      DCHAR_CPY          memcpy like function for DCHAR_T[] arrays.
32      DCHAR_SET          memset like function for DCHAR_T[] arrays.
33      DCHAR_MBSNLEN      mbsnlen like function for DCHAR_T[] arrays.
34      SNPRINTF           The system's snprintf (or similar) function.
35                         This may be either snprintf or swprintf.
36      TCHAR_T            The element type of the argument and result string
37                         of the said SNPRINTF function.  This may be either
38                         char or wchar_t.  The code exploits that
39                         sizeof (TCHAR_T) | sizeof (DCHAR_T) and
40                         alignof (TCHAR_T) <= alignof (DCHAR_T).
41      DCHAR_IS_TCHAR     Set to 1 if DCHAR_T and TCHAR_T are the same type.
42      DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
43      DCHAR_IS_UINT8_T   Set to 1 if DCHAR_T is uint8_t.
44      DCHAR_IS_UINT16_T  Set to 1 if DCHAR_T is uint16_t.
45      DCHAR_IS_UINT32_T  Set to 1 if DCHAR_T is uint32_t.  */
46
47 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
48    This must come before <config.h> because <config.h> may include
49    <features.h>, and once <features.h> has been included, it's too late.  */
50 #ifndef _GNU_SOURCE
51 # define _GNU_SOURCE    1
52 #endif
53
54 #ifndef VASNPRINTF
55 # include <config.h>
56 #endif
57 #ifndef IN_LIBINTL
58 # include <alloca.h>
59 #endif
60
61 /* Specification.  */
62 #ifndef VASNPRINTF
63 # if WIDE_CHAR_VERSION
64 #  include "vasnwprintf.h"
65 # else
66 #  include "vasnprintf.h"
67 # endif
68 #endif
69
70 #include <locale.h>     /* localeconv() */
71 #include <stdio.h>      /* snprintf(), sprintf() */
72 #include <stdlib.h>     /* abort(), malloc(), realloc(), free() */
73 #include <string.h>     /* memcpy(), strlen() */
74 #include <errno.h>      /* errno */
75 #include <limits.h>     /* CHAR_BIT */
76 #include <float.h>      /* DBL_MAX_EXP, LDBL_MAX_EXP */
77 #if HAVE_NL_LANGINFO
78 # include <langinfo.h>
79 #endif
80 #ifndef VASNPRINTF
81 # if WIDE_CHAR_VERSION
82 #  include "wprintf-parse.h"
83 # else
84 #  include "printf-parse.h"
85 # endif
86 #endif
87
88 /* Checked size_t computations.  */
89 #include "xsize.h"
90
91 #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 && !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 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T && (WIDE_CHAR_VERSION || DCHAR_IS_TCHAR)
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_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 DCHAR_T *
1491 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1492             const FCHAR_T *format, va_list args)
1493 {
1494   DIRECTIVES d;
1495   arguments a;
1496
1497   if (PRINTF_PARSE (format, &d, &a) < 0)
1498     /* errno is already set.  */
1499     return NULL;
1500
1501 #define CLEANUP() \
1502   free (d.dir);                                                         \
1503   if (a.arg)                                                            \
1504     free (a.arg);
1505
1506   if (PRINTF_FETCHARGS (args, &a) < 0)
1507     {
1508       CLEANUP ();
1509       errno = EINVAL;
1510       return NULL;
1511     }
1512
1513   {
1514     size_t buf_neededlength;
1515     TCHAR_T *buf;
1516     TCHAR_T *buf_malloced;
1517     const FCHAR_T *cp;
1518     size_t i;
1519     DIRECTIVE *dp;
1520     /* Output string accumulator.  */
1521     DCHAR_T *result;
1522     size_t allocated;
1523     size_t length;
1524
1525     /* Allocate a small buffer that will hold a directive passed to
1526        sprintf or snprintf.  */
1527     buf_neededlength =
1528       xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1529 #if HAVE_ALLOCA
1530     if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1531       {
1532         buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1533         buf_malloced = NULL;
1534       }
1535     else
1536 #endif
1537       {
1538         size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1539         if (size_overflow_p (buf_memsize))
1540           goto out_of_memory_1;
1541         buf = (TCHAR_T *) malloc (buf_memsize);
1542         if (buf == NULL)
1543           goto out_of_memory_1;
1544         buf_malloced = buf;
1545       }
1546
1547     if (resultbuf != NULL)
1548       {
1549         result = resultbuf;
1550         allocated = *lengthp;
1551       }
1552     else
1553       {
1554         result = NULL;
1555         allocated = 0;
1556       }
1557     length = 0;
1558     /* Invariants:
1559        result is either == resultbuf or == NULL or malloc-allocated.
1560        If length > 0, then result != NULL.  */
1561
1562     /* Ensures that allocated >= needed.  Aborts through a jump to
1563        out_of_memory if needed is SIZE_MAX or otherwise too big.  */
1564 #define ENSURE_ALLOCATION(needed) \
1565     if ((needed) > allocated)                                                \
1566       {                                                                      \
1567         size_t memory_size;                                                  \
1568         DCHAR_T *memory;                                                     \
1569                                                                              \
1570         allocated = (allocated > 0 ? xtimes (allocated, 2) : 12);            \
1571         if ((needed) > allocated)                                            \
1572           allocated = (needed);                                              \
1573         memory_size = xtimes (allocated, sizeof (DCHAR_T));                  \
1574         if (size_overflow_p (memory_size))                                   \
1575           goto out_of_memory;                                                \
1576         if (result == resultbuf || result == NULL)                           \
1577           memory = (DCHAR_T *) malloc (memory_size);                         \
1578         else                                                                 \
1579           memory = (DCHAR_T *) realloc (result, memory_size);                \
1580         if (memory == NULL)                                                  \
1581           goto out_of_memory;                                                \
1582         if (result == resultbuf && length > 0)                               \
1583           DCHAR_CPY (memory, result, length);                                \
1584         result = memory;                                                     \
1585       }
1586
1587     for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1588       {
1589         if (cp != dp->dir_start)
1590           {
1591             size_t n = dp->dir_start - cp;
1592             size_t augmented_length = xsum (length, n);
1593
1594             ENSURE_ALLOCATION (augmented_length);
1595             /* This copies a piece of FCHAR_T[] into a DCHAR_T[].  Here we
1596                need that the format string contains only ASCII characters
1597                if FCHAR_T and DCHAR_T are not the same type.  */
1598             if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1599               {
1600                 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1601                 length = augmented_length;
1602               }
1603             else
1604               {
1605                 do
1606                   result[length++] = (unsigned char) *cp++;
1607                 while (--n > 0);
1608               }
1609           }
1610         if (i == d.count)
1611           break;
1612
1613         /* Execute a single directive.  */
1614         if (dp->conversion == '%')
1615           {
1616             size_t augmented_length;
1617
1618             if (!(dp->arg_index == ARG_NONE))
1619               abort ();
1620             augmented_length = xsum (length, 1);
1621             ENSURE_ALLOCATION (augmented_length);
1622             result[length] = '%';
1623             length = augmented_length;
1624           }
1625         else
1626           {
1627             if (!(dp->arg_index != ARG_NONE))
1628               abort ();
1629
1630             if (dp->conversion == 'n')
1631               {
1632                 switch (a.arg[dp->arg_index].type)
1633                   {
1634                   case TYPE_COUNT_SCHAR_POINTER:
1635                     *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1636                     break;
1637                   case TYPE_COUNT_SHORT_POINTER:
1638                     *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1639                     break;
1640                   case TYPE_COUNT_INT_POINTER:
1641                     *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1642                     break;
1643                   case TYPE_COUNT_LONGINT_POINTER:
1644                     *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1645                     break;
1646 #if HAVE_LONG_LONG_INT
1647                   case TYPE_COUNT_LONGLONGINT_POINTER:
1648                     *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
1649                     break;
1650 #endif
1651                   default:
1652                     abort ();
1653                   }
1654               }
1655 #if ENABLE_UNISTDIO
1656             /* The unistdio extensions.  */
1657             else if (dp->conversion == 'U')
1658               {
1659                 arg_type type = a.arg[dp->arg_index].type;
1660                 int flags = dp->flags;
1661                 int has_width;
1662                 size_t width;
1663                 int has_precision;
1664                 size_t precision;
1665
1666                 has_width = 0;
1667                 width = 0;
1668                 if (dp->width_start != dp->width_end)
1669                   {
1670                     if (dp->width_arg_index != ARG_NONE)
1671                       {
1672                         int arg;
1673
1674                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1675                           abort ();
1676                         arg = a.arg[dp->width_arg_index].a.a_int;
1677                         if (arg < 0)
1678                           {
1679                             /* "A negative field width is taken as a '-' flag
1680                                 followed by a positive field width."  */
1681                             flags |= FLAG_LEFT;
1682                             width = (unsigned int) (-arg);
1683                           }
1684                         else
1685                           width = arg;
1686                       }
1687                     else
1688                       {
1689                         const FCHAR_T *digitp = dp->width_start;
1690
1691                         do
1692                           width = xsum (xtimes (width, 10), *digitp++ - '0');
1693                         while (digitp != dp->width_end);
1694                       }
1695                     has_width = 1;
1696                   }
1697
1698                 has_precision = 0;
1699                 precision = 0;
1700                 if (dp->precision_start != dp->precision_end)
1701                   {
1702                     if (dp->precision_arg_index != ARG_NONE)
1703                       {
1704                         int arg;
1705
1706                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1707                           abort ();
1708                         arg = a.arg[dp->precision_arg_index].a.a_int;
1709                         /* "A negative precision is taken as if the precision
1710                             were omitted."  */
1711                         if (arg >= 0)
1712                           {
1713                             precision = arg;
1714                             has_precision = 1;
1715                           }
1716                       }
1717                     else
1718                       {
1719                         const FCHAR_T *digitp = dp->precision_start + 1;
1720
1721                         precision = 0;
1722                         while (digitp != dp->precision_end)
1723                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
1724                         has_precision = 1;
1725                       }
1726                   }
1727
1728                 switch (type)
1729                   {
1730                   case TYPE_U8_STRING:
1731                     {
1732                       const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
1733                       const uint8_t *arg_end;
1734                       size_t characters;
1735
1736                       if (has_precision)
1737                         {
1738                           /* Use only PRECISION characters, from the left.  */
1739                           arg_end = arg;
1740                           characters = 0;
1741                           for (; precision > 0; precision--)
1742                             {
1743                               int count = u8_strmblen (arg_end);
1744                               if (count == 0)
1745                                 break;
1746                               if (count < 0)
1747                                 {
1748                                   if (!(result == resultbuf || result == NULL))
1749                                     free (result);
1750                                   if (buf_malloced != NULL)
1751                                     free (buf_malloced);
1752                                   CLEANUP ();
1753                                   errno = EILSEQ;
1754                                   return NULL;
1755                                 }
1756                               arg_end += count;
1757                               characters++;
1758                             }
1759                         }
1760                       else if (has_width)
1761                         {
1762                           /* Use the entire string, and count the number of
1763                              characters.  */
1764                           arg_end = arg;
1765                           characters = 0;
1766                           for (;;)
1767                             {
1768                               int count = u8_strmblen (arg_end);
1769                               if (count == 0)
1770                                 break;
1771                               if (count < 0)
1772                                 {
1773                                   if (!(result == resultbuf || result == NULL))
1774                                     free (result);
1775                                   if (buf_malloced != NULL)
1776                                     free (buf_malloced);
1777                                   CLEANUP ();
1778                                   errno = EILSEQ;
1779                                   return NULL;
1780                                 }
1781                               arg_end += count;
1782                               characters++;
1783                             }
1784                         }
1785                       else
1786                         {
1787                           /* Use the entire string.  */
1788                           arg_end = arg + u8_strlen (arg);
1789                           /* The number of characters doesn't matter.  */
1790                           characters = 0;
1791                         }
1792
1793                       if (has_width && width > characters
1794                           && !(dp->flags & FLAG_LEFT))
1795                         {
1796                           size_t n = width - characters;
1797                           ENSURE_ALLOCATION (xsum (length, n));
1798                           DCHAR_SET (result + length, ' ', n);
1799                           length += n;
1800                         }
1801
1802 # if DCHAR_IS_UINT8_T
1803                       {
1804                         size_t n = arg_end - arg;
1805                         ENSURE_ALLOCATION (xsum (length, n));
1806                         DCHAR_CPY (result + length, arg, n);
1807                         length += n;
1808                       }
1809 # else
1810                       { /* Convert.  */
1811                         DCHAR_T *converted = result + length;
1812                         size_t converted_len = allocated - length;
1813 #  if DCHAR_IS_TCHAR
1814                         /* Convert from UTF-8 to locale encoding.  */
1815                         converted =
1816                           u8_conv_to_encoding (locale_charset (),
1817                                                iconveh_question_mark,
1818                                                arg, arg_end - arg, NULL,
1819                                                converted, &converted_len);
1820 #  else
1821                         /* Convert from UTF-8 to UTF-16/UTF-32.  */
1822                         converted =
1823                           U8_TO_DCHAR (arg, arg_end - arg,
1824                                        converted, &converted_len);
1825 #  endif
1826                         if (converted == NULL)
1827                           {
1828                             int saved_errno = errno;
1829                             if (!(result == resultbuf || result == NULL))
1830                               free (result);
1831                             if (buf_malloced != NULL)
1832                               free (buf_malloced);
1833                             CLEANUP ();
1834                             errno = saved_errno;
1835                             return NULL;
1836                           }
1837                         if (converted != result + length)
1838                           {
1839                             ENSURE_ALLOCATION (xsum (length, converted_len));
1840                             DCHAR_CPY (result + length, converted, converted_len);
1841                             free (converted);
1842                           }
1843                         length += converted_len;
1844                       }
1845 # endif
1846
1847                       if (has_width && width > characters
1848                           && (dp->flags & FLAG_LEFT))
1849                         {
1850                           size_t n = width - characters;
1851                           ENSURE_ALLOCATION (xsum (length, n));
1852                           DCHAR_SET (result + length, ' ', n);
1853                           length += n;
1854                         }
1855                     }
1856                     break;
1857
1858                   case TYPE_U16_STRING:
1859                     {
1860                       const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
1861                       const uint16_t *arg_end;
1862                       size_t characters;
1863
1864                       if (has_precision)
1865                         {
1866                           /* Use only PRECISION characters, from the left.  */
1867                           arg_end = arg;
1868                           characters = 0;
1869                           for (; precision > 0; precision--)
1870                             {
1871                               int count = u16_strmblen (arg_end);
1872                               if (count == 0)
1873                                 break;
1874                               if (count < 0)
1875                                 {
1876                                   if (!(result == resultbuf || result == NULL))
1877                                     free (result);
1878                                   if (buf_malloced != NULL)
1879                                     free (buf_malloced);
1880                                   CLEANUP ();
1881                                   errno = EILSEQ;
1882                                   return NULL;
1883                                 }
1884                               arg_end += count;
1885                               characters++;
1886                             }
1887                         }
1888                       else if (has_width)
1889                         {
1890                           /* Use the entire string, and count the number of
1891                              characters.  */
1892                           arg_end = arg;
1893                           characters = 0;
1894                           for (;;)
1895                             {
1896                               int count = u16_strmblen (arg_end);
1897                               if (count == 0)
1898                                 break;
1899                               if (count < 0)
1900                                 {
1901                                   if (!(result == resultbuf || result == NULL))
1902                                     free (result);
1903                                   if (buf_malloced != NULL)
1904                                     free (buf_malloced);
1905                                   CLEANUP ();
1906                                   errno = EILSEQ;
1907                                   return NULL;
1908                                 }
1909                               arg_end += count;
1910                               characters++;
1911                             }
1912                         }
1913                       else
1914                         {
1915                           /* Use the entire string.  */
1916                           arg_end = arg + u16_strlen (arg);
1917                           /* The number of characters doesn't matter.  */
1918                           characters = 0;
1919                         }
1920
1921                       if (has_width && width > characters
1922                           && !(dp->flags & FLAG_LEFT))
1923                         {
1924                           size_t n = width - characters;
1925                           ENSURE_ALLOCATION (xsum (length, n));
1926                           DCHAR_SET (result + length, ' ', n);
1927                           length += n;
1928                         }
1929
1930 # if DCHAR_IS_UINT16_T
1931                       {
1932                         size_t n = arg_end - arg;
1933                         ENSURE_ALLOCATION (xsum (length, n));
1934                         DCHAR_CPY (result + length, arg, n);
1935                         length += n;
1936                       }
1937 # else
1938                       { /* Convert.  */
1939                         DCHAR_T *converted = result + length;
1940                         size_t converted_len = allocated - length;
1941 #  if DCHAR_IS_TCHAR
1942                         /* Convert from UTF-16 to locale encoding.  */
1943                         converted =
1944                           u16_conv_to_encoding (locale_charset (),
1945                                                 iconveh_question_mark,
1946                                                 arg, arg_end - arg, NULL,
1947                                                 converted, &converted_len);
1948 #  else
1949                         /* Convert from UTF-16 to UTF-8/UTF-32.  */
1950                         converted =
1951                           U16_TO_DCHAR (arg, arg_end - arg,
1952                                         converted, &converted_len);
1953 #  endif
1954                         if (converted == NULL)
1955                           {
1956                             int saved_errno = errno;
1957                             if (!(result == resultbuf || result == NULL))
1958                               free (result);
1959                             if (buf_malloced != NULL)
1960                               free (buf_malloced);
1961                             CLEANUP ();
1962                             errno = saved_errno;
1963                             return NULL;
1964                           }
1965                         if (converted != result + length)
1966                           {
1967                             ENSURE_ALLOCATION (xsum (length, converted_len));
1968                             DCHAR_CPY (result + length, converted, converted_len);
1969                             free (converted);
1970                           }
1971                         length += converted_len;
1972                       }
1973 # endif
1974
1975                       if (has_width && width > characters
1976                           && (dp->flags & FLAG_LEFT))
1977                         {
1978                           size_t n = width - characters;
1979                           ENSURE_ALLOCATION (xsum (length, n));
1980                           DCHAR_SET (result + length, ' ', n);
1981                           length += n;
1982                         }
1983                     }
1984                     break;
1985
1986                   case TYPE_U32_STRING:
1987                     {
1988                       const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
1989                       const uint32_t *arg_end;
1990                       size_t characters;
1991
1992                       if (has_precision)
1993                         {
1994                           /* Use only PRECISION characters, from the left.  */
1995                           arg_end = arg;
1996                           characters = 0;
1997                           for (; precision > 0; precision--)
1998                             {
1999                               int count = u32_strmblen (arg_end);
2000                               if (count == 0)
2001                                 break;
2002                               if (count < 0)
2003                                 {
2004                                   if (!(result == resultbuf || result == NULL))
2005                                     free (result);
2006                                   if (buf_malloced != NULL)
2007                                     free (buf_malloced);
2008                                   CLEANUP ();
2009                                   errno = EILSEQ;
2010                                   return NULL;
2011                                 }
2012                               arg_end += count;
2013                               characters++;
2014                             }
2015                         }
2016                       else if (has_width)
2017                         {
2018                           /* Use the entire string, and count the number of
2019                              characters.  */
2020                           arg_end = arg;
2021                           characters = 0;
2022                           for (;;)
2023                             {
2024                               int count = u32_strmblen (arg_end);
2025                               if (count == 0)
2026                                 break;
2027                               if (count < 0)
2028                                 {
2029                                   if (!(result == resultbuf || result == NULL))
2030                                     free (result);
2031                                   if (buf_malloced != NULL)
2032                                     free (buf_malloced);
2033                                   CLEANUP ();
2034                                   errno = EILSEQ;
2035                                   return NULL;
2036                                 }
2037                               arg_end += count;
2038                               characters++;
2039                             }
2040                         }
2041                       else
2042                         {
2043                           /* Use the entire string.  */
2044                           arg_end = arg + u32_strlen (arg);
2045                           /* The number of characters doesn't matter.  */
2046                           characters = 0;
2047                         }
2048
2049                       if (has_width && width > characters
2050                           && !(dp->flags & FLAG_LEFT))
2051                         {
2052                           size_t n = width - characters;
2053                           ENSURE_ALLOCATION (xsum (length, n));
2054                           DCHAR_SET (result + length, ' ', n);
2055                           length += n;
2056                         }
2057
2058 # if DCHAR_IS_UINT32_T
2059                       {
2060                         size_t n = arg_end - arg;
2061                         ENSURE_ALLOCATION (xsum (length, n));
2062                         DCHAR_CPY (result + length, arg, n);
2063                         length += n;
2064                       }
2065 # else
2066                       { /* Convert.  */
2067                         DCHAR_T *converted = result + length;
2068                         size_t converted_len = allocated - length;
2069 #  if DCHAR_IS_TCHAR
2070                         /* Convert from UTF-32 to locale encoding.  */
2071                         converted =
2072                           u32_conv_to_encoding (locale_charset (),
2073                                                 iconveh_question_mark,
2074                                                 arg, arg_end - arg, NULL,
2075                                                 converted, &converted_len);
2076 #  else
2077                         /* Convert from UTF-32 to UTF-8/UTF-16.  */
2078                         converted =
2079                           U32_TO_DCHAR (arg, arg_end - arg,
2080                                         converted, &converted_len);
2081 #  endif
2082                         if (converted == NULL)
2083                           {
2084                             int saved_errno = errno;
2085                             if (!(result == resultbuf || result == NULL))
2086                               free (result);
2087                             if (buf_malloced != NULL)
2088                               free (buf_malloced);
2089                             CLEANUP ();
2090                             errno = saved_errno;
2091                             return NULL;
2092                           }
2093                         if (converted != result + length)
2094                           {
2095                             ENSURE_ALLOCATION (xsum (length, converted_len));
2096                             DCHAR_CPY (result + length, converted, converted_len);
2097                             free (converted);
2098                           }
2099                         length += converted_len;
2100                       }
2101 # endif
2102
2103                       if (has_width && width > characters
2104                           && (dp->flags & FLAG_LEFT))
2105                         {
2106                           size_t n = width - characters;
2107                           ENSURE_ALLOCATION (xsum (length, n));
2108                           DCHAR_SET (result + length, ' ', n);
2109                           length += n;
2110                         }
2111                     }
2112                     break;
2113
2114                   default:
2115                     abort ();
2116                   }
2117               }
2118 #endif
2119 #if (!USE_SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
2120             else if (dp->conversion == 's'
2121 # if WIDE_CHAR_VERSION
2122                      && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2123 # else
2124                      && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2125 # endif
2126                     )
2127               {
2128                 /* The normal handling of the 's' directive below requires
2129                    allocating a temporary buffer.  The determination of its
2130                    length (tmp_length), in the case when a precision is
2131                    specified, below requires a conversion between a char[]
2132                    string and a wchar_t[] wide string.  It could be done, but
2133                    we have no guarantee that the implementation of sprintf will
2134                    use the exactly same algorithm.  Without this guarantee, it
2135                    is possible to have buffer overrun bugs.  In order to avoid
2136                    such bugs, we implement the entire processing of the 's'
2137                    directive ourselves.  */
2138                 int flags = dp->flags;
2139                 int has_width;
2140                 size_t width;
2141                 int has_precision;
2142                 size_t precision;
2143
2144                 has_width = 0;
2145                 width = 0;
2146                 if (dp->width_start != dp->width_end)
2147                   {
2148                     if (dp->width_arg_index != ARG_NONE)
2149                       {
2150                         int arg;
2151
2152                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2153                           abort ();
2154                         arg = a.arg[dp->width_arg_index].a.a_int;
2155                         if (arg < 0)
2156                           {
2157                             /* "A negative field width is taken as a '-' flag
2158                                 followed by a positive field width."  */
2159                             flags |= FLAG_LEFT;
2160                             width = (unsigned int) (-arg);
2161                           }
2162                         else
2163                           width = arg;
2164                       }
2165                     else
2166                       {
2167                         const FCHAR_T *digitp = dp->width_start;
2168
2169                         do
2170                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2171                         while (digitp != dp->width_end);
2172                       }
2173                     has_width = 1;
2174                   }
2175
2176                 has_precision = 0;
2177                 precision = 6;
2178                 if (dp->precision_start != dp->precision_end)
2179                   {
2180                     if (dp->precision_arg_index != ARG_NONE)
2181                       {
2182                         int arg;
2183
2184                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2185                           abort ();
2186                         arg = a.arg[dp->precision_arg_index].a.a_int;
2187                         /* "A negative precision is taken as if the precision
2188                             were omitted."  */
2189                         if (arg >= 0)
2190                           {
2191                             precision = arg;
2192                             has_precision = 1;
2193                           }
2194                       }
2195                     else
2196                       {
2197                         const FCHAR_T *digitp = dp->precision_start + 1;
2198
2199                         precision = 0;
2200                         while (digitp != dp->precision_end)
2201                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2202                         has_precision = 1;
2203                       }
2204                   }
2205
2206 # if WIDE_CHAR_VERSION
2207                 /* %s in vasnwprintf.  See the specification of fwprintf.  */
2208                 {
2209                   const char *arg = a.arg[dp->arg_index].a.a_string;
2210                   const char *arg_end;
2211                   size_t characters;
2212
2213                   if (has_precision)
2214                     {
2215                       /* Use only as many bytes as needed to produce PRECISION
2216                          wide characters, from the left.  */
2217 #  if HAVE_MBRTOWC
2218                       mbstate_t state;
2219                       memset (&state, '\0', sizeof (mbstate_t));
2220 #  endif
2221                       arg_end = arg;
2222                       characters = 0;
2223                       for (; precision > 0; precision--)
2224                         {
2225                           int count;
2226 #  if HAVE_MBRTOWC
2227                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
2228 #  else
2229                           count = mblen (arg_end, MB_CUR_MAX);
2230 #  endif
2231                           if (count == 0)
2232                             /* Found the terminating NUL.  */
2233                             break;
2234                           if (count < 0)
2235                             {
2236                               /* Invalid or incomplete multibyte character.  */
2237                               if (!(result == resultbuf || result == NULL))
2238                                 free (result);
2239                               if (buf_malloced != NULL)
2240                                 free (buf_malloced);
2241                               CLEANUP ();
2242                               errno = EILSEQ;
2243                               return NULL;
2244                             }
2245                           arg_end += count;
2246                           characters++;
2247                         }
2248                     }
2249                   else if (has_width)
2250                     {
2251                       /* Use the entire string, and count the number of wide
2252                          characters.  */
2253 #  if HAVE_MBRTOWC
2254                       mbstate_t state;
2255                       memset (&state, '\0', sizeof (mbstate_t));
2256 #  endif
2257                       arg_end = arg;
2258                       characters = 0;
2259                       for (;;)
2260                         {
2261                           int count;
2262 #  if HAVE_MBRTOWC
2263                           count = mbrlen (arg_end, MB_CUR_MAX, &state);
2264 #  else
2265                           count = mblen (arg_end, MB_CUR_MAX);
2266 #  endif
2267                           if (count == 0)
2268                             /* Found the terminating NUL.  */
2269                             break;
2270                           if (count < 0)
2271                             {
2272                               /* Invalid or incomplete multibyte character.  */
2273                               if (!(result == resultbuf || result == NULL))
2274                                 free (result);
2275                               if (buf_malloced != NULL)
2276                                 free (buf_malloced);
2277                               CLEANUP ();
2278                               errno = EILSEQ;
2279                               return NULL;
2280                             }
2281                           arg_end += count;
2282                           characters++;
2283                         }
2284                     }
2285                   else
2286                     {
2287                       /* Use the entire string.  */
2288                       arg_end = arg + strlen (arg);
2289                       /* The number of characters doesn't matter.  */
2290                       characters = 0;
2291                     }
2292
2293                   if (has_width && width > characters
2294                       && !(dp->flags & FLAG_LEFT))
2295                     {
2296                       size_t n = width - characters;
2297                       ENSURE_ALLOCATION (xsum (length, n));
2298                       DCHAR_SET (result + length, ' ', n);
2299                       length += n;
2300                     }
2301
2302                   if (has_precision || has_width)
2303                     {
2304                       /* We know the number of wide characters in advance.  */
2305                       size_t remaining;
2306 #  if HAVE_MBRTOWC
2307                       mbstate_t state;
2308                       memset (&state, '\0', sizeof (mbstate_t));
2309 #  endif
2310                       ENSURE_ALLOCATION (xsum (length, characters));
2311                       for (remaining = characters; remaining > 0; remaining--)
2312                         {
2313                           wchar_t wc;
2314                           int count;
2315 #  if HAVE_MBRTOWC
2316                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
2317 #  else
2318                           count = mbtowc (&wc, arg, arg_end - arg);
2319 #  endif
2320                           if (count <= 0)
2321                             /* mbrtowc not consistent with mbrlen, or mbtowc
2322                                not consistent with mblen.  */
2323                             abort ();
2324                           result[length++] = wc;
2325                           arg += count;
2326                         }
2327                       if (!(arg == arg_end))
2328                         abort ();
2329                     }
2330                   else
2331                     {
2332 #  if HAVE_MBRTOWC
2333                       mbstate_t state;
2334                       memset (&state, '\0', sizeof (mbstate_t));
2335 #  endif
2336                       while (arg < arg_end)
2337                         {
2338                           wchar_t wc;
2339                           int count;
2340 #  if HAVE_MBRTOWC
2341                           count = mbrtowc (&wc, arg, arg_end - arg, &state);
2342 #  else
2343                           count = mbtowc (&wc, arg, arg_end - arg);
2344 #  endif
2345                           if (count <= 0)
2346                             /* mbrtowc not consistent with mbrlen, or mbtowc
2347                                not consistent with mblen.  */
2348                             abort ();
2349                           ENSURE_ALLOCATION (xsum (length, 1));
2350                           result[length++] = wc;
2351                           arg += count;
2352                         }
2353                     }
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 # else
2365                 /* %ls in vasnprintf.  See the specification of fprintf.  */
2366                 {
2367                   const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2368                   const wchar_t *arg_end;
2369                   size_t characters;
2370 #  if !DCHAR_IS_TCHAR
2371                   /* This code assumes that TCHAR_T is 'char'.  */
2372                   typedef int TCHAR_T_verify[2 * (sizeof (TCHAR_T) == 1) - 1];
2373                   TCHAR_T *tmpsrc;
2374                   DCHAR_T *tmpdst;
2375                   size_t tmpdst_len;
2376 #  endif
2377                   size_t w;
2378
2379                   if (has_precision)
2380                     {
2381                       /* Use only as many wide characters as needed to produce
2382                          at most PRECISION bytes, from the left.  */
2383 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2384                       mbstate_t state;
2385                       memset (&state, '\0', sizeof (mbstate_t));
2386 #  endif
2387                       arg_end = arg;
2388                       characters = 0;
2389                       while (precision > 0)
2390                         {
2391                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2392                           int count;
2393
2394                           if (*arg_end == 0)
2395                             /* Found the terminating null wide character.  */
2396                             break;
2397 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2398                           count = wcrtomb (cbuf, *arg_end, &state);
2399 #  else
2400                           count = wctomb (cbuf, *arg_end);
2401 #  endif
2402                           if (count < 0)
2403                             {
2404                               /* Cannot convert.  */
2405                               if (!(result == resultbuf || result == NULL))
2406                                 free (result);
2407                               if (buf_malloced != NULL)
2408                                 free (buf_malloced);
2409                               CLEANUP ();
2410                               errno = EILSEQ;
2411                               return NULL;
2412                             }
2413                           if (precision < count)
2414                             break;
2415                           arg_end++;
2416                           characters += count;
2417                           precision -= count;
2418                         }
2419                     }
2420 #  if DCHAR_IS_TCHAR
2421                   else if (has_width)
2422 #  else
2423                   else
2424 #  endif
2425                     {
2426                       /* Use the entire string, and count the number of
2427                          bytes.  */
2428 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2429                       mbstate_t state;
2430                       memset (&state, '\0', sizeof (mbstate_t));
2431 #  endif
2432                       arg_end = arg;
2433                       characters = 0;
2434                       for (;;)
2435                         {
2436                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2437                           int count;
2438
2439                           if (*arg_end == 0)
2440                             /* Found the terminating null wide character.  */
2441                             break;
2442 #  if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2443                           count = wcrtomb (cbuf, *arg_end, &state);
2444 #  else
2445                           count = wctomb (cbuf, *arg_end);
2446 #  endif
2447                           if (count < 0)
2448                             {
2449                               /* Cannot convert.  */
2450                               if (!(result == resultbuf || result == NULL))
2451                                 free (result);
2452                               if (buf_malloced != NULL)
2453                                 free (buf_malloced);
2454                               CLEANUP ();
2455                               errno = EILSEQ;
2456                               return NULL;
2457                             }
2458                           arg_end++;
2459                           characters += count;
2460                         }
2461                     }
2462 #  if DCHAR_IS_TCHAR
2463                   else
2464                     {
2465                       /* Use the entire string.  */
2466                       arg_end = arg + local_wcslen (arg);
2467                       /* The number of bytes doesn't matter.  */
2468                       characters = 0;
2469                     }
2470 #  endif
2471
2472 #  if !DCHAR_IS_TCHAR
2473                   /* Convert the string into a piece of temporary memory.  */
2474                   tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2475                   if (tmpsrc == NULL)
2476                     goto out_of_memory;
2477                   {
2478                     TCHAR_T *tmpptr = tmpsrc;
2479                     size_t remaining;
2480 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2481                     mbstate_t state;
2482                     memset (&state, '\0', sizeof (mbstate_t));
2483 #   endif
2484                     for (remaining = characters; remaining > 0; )
2485                       {
2486                         char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2487                         int count;
2488
2489                         if (*arg == 0)
2490                           abort ();
2491 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2492                         count = wcrtomb (cbuf, *arg, &state);
2493 #   else
2494                         count = wctomb (cbuf, *arg);
2495 #   endif
2496                         if (count <= 0)
2497                           /* Inconsistency.  */
2498                           abort ();
2499                         memcpy (tmpptr, cbuf, count);
2500                         tmpptr += count;
2501                         arg++;
2502                         remaining -= count;
2503                       }
2504                     if (!(arg == arg_end))
2505                       abort ();
2506                   }
2507
2508                   /* Convert from TCHAR_T[] to DCHAR_T[].  */
2509                   tmpdst =
2510                     DCHAR_CONV_FROM_ENCODING (locale_charset (),
2511                                               iconveh_question_mark,
2512                                               tmpsrc, characters,
2513                                               NULL,
2514                                               NULL, &tmpdst_len);
2515                   if (tmpdst == NULL)
2516                     {
2517                       int saved_errno = errno;
2518                       free (tmpsrc);
2519                       if (!(result == resultbuf || result == NULL))
2520                         free (result);
2521                       if (buf_malloced != NULL)
2522                         free (buf_malloced);
2523                       CLEANUP ();
2524                       errno = saved_errno;
2525                       return NULL;
2526                     }
2527                   free (tmpsrc);
2528 #  endif
2529
2530                   if (has_width)
2531                     {
2532 #  if ENABLE_UNISTDIO
2533                       /* Outside POSIX, it's preferrable to compare the width
2534                          against the number of _characters_ of the converted
2535                          value.  */
2536                       w = DCHAR_MBSNLEN (result + length, characters);
2537 #  else
2538                       /* The width is compared against the number of _bytes_
2539                          of the converted value, says POSIX.  */
2540                       w = characters;
2541 #  endif
2542                     }
2543                   else
2544                     /* w doesn't matter.  */
2545                     w = 0;
2546
2547                   if (has_width && width > w
2548                       && !(dp->flags & FLAG_LEFT))
2549                     {
2550                       size_t n = width - w;
2551                       ENSURE_ALLOCATION (xsum (length, n));
2552                       DCHAR_SET (result + length, ' ', n);
2553                       length += n;
2554                     }
2555
2556 #  if DCHAR_IS_TCHAR
2557                   if (has_precision || has_width)
2558                     {
2559                       /* We know the number of bytes in advance.  */
2560                       size_t remaining;
2561 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2562                       mbstate_t state;
2563                       memset (&state, '\0', sizeof (mbstate_t));
2564 #   endif
2565                       ENSURE_ALLOCATION (xsum (length, characters));
2566                       for (remaining = characters; remaining > 0; )
2567                         {
2568                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2569                           int count;
2570
2571                           if (*arg == 0)
2572                             abort ();
2573 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2574                           count = wcrtomb (cbuf, *arg, &state);
2575 #   else
2576                           count = wctomb (cbuf, *arg);
2577 #   endif
2578                           if (count <= 0)
2579                             /* Inconsistency.  */
2580                             abort ();
2581                           memcpy (result + length, cbuf, count);
2582                           length += count;
2583                           arg++;
2584                           remaining -= count;
2585                         }
2586                       if (!(arg == arg_end))
2587                         abort ();
2588                     }
2589                   else
2590                     {
2591 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2592                       mbstate_t state;
2593                       memset (&state, '\0', sizeof (mbstate_t));
2594 #   endif
2595                       while (arg < arg_end)
2596                         {
2597                           char cbuf[64]; /* Assume MB_CUR_MAX <= 64.  */
2598                           int count;
2599
2600                           if (*arg == 0)
2601                             abort ();
2602 #   if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2603                           count = wcrtomb (cbuf, *arg, &state);
2604 #   else
2605                           count = wctomb (cbuf, *arg);
2606 #   endif
2607                           if (count <= 0)
2608                             {
2609                               /* Cannot convert.  */
2610                               if (!(result == resultbuf || result == NULL))
2611                                 free (result);
2612                               if (buf_malloced != NULL)
2613                                 free (buf_malloced);
2614                               CLEANUP ();
2615                               errno = EILSEQ;
2616                               return NULL;
2617                             }
2618                           ENSURE_ALLOCATION (xsum (length, count));
2619                           memcpy (result + length, cbuf, count);
2620                           length += count;
2621                           arg++;
2622                         }
2623                     }
2624 #  else
2625                   ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2626                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2627                   free (tmpdst);
2628                   length += tmpdst_len;
2629 #  endif
2630
2631                   if (has_width && width > w
2632                       && (dp->flags & FLAG_LEFT))
2633                     {
2634                       size_t n = width - w;
2635                       ENSURE_ALLOCATION (xsum (length, n));
2636                       DCHAR_SET (result + length, ' ', n);
2637                       length += n;
2638                     }
2639                 }
2640               }
2641 # endif
2642 #endif
2643 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2644             else if ((dp->conversion == 'a' || dp->conversion == 'A')
2645 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2646                      && (0
2647 #  if NEED_PRINTF_DOUBLE
2648                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
2649 #  endif
2650 #  if NEED_PRINTF_LONG_DOUBLE
2651                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2652 #  endif
2653                         )
2654 # endif
2655                     )
2656               {
2657                 arg_type type = a.arg[dp->arg_index].type;
2658                 int flags = dp->flags;
2659                 int has_width;
2660                 size_t width;
2661                 int has_precision;
2662                 size_t precision;
2663                 size_t tmp_length;
2664                 DCHAR_T tmpbuf[700];
2665                 DCHAR_T *tmp;
2666                 DCHAR_T *pad_ptr;
2667                 DCHAR_T *p;
2668
2669                 has_width = 0;
2670                 width = 0;
2671                 if (dp->width_start != dp->width_end)
2672                   {
2673                     if (dp->width_arg_index != ARG_NONE)
2674                       {
2675                         int arg;
2676
2677                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2678                           abort ();
2679                         arg = a.arg[dp->width_arg_index].a.a_int;
2680                         if (arg < 0)
2681                           {
2682                             /* "A negative field width is taken as a '-' flag
2683                                 followed by a positive field width."  */
2684                             flags |= FLAG_LEFT;
2685                             width = (unsigned int) (-arg);
2686                           }
2687                         else
2688                           width = arg;
2689                       }
2690                     else
2691                       {
2692                         const FCHAR_T *digitp = dp->width_start;
2693
2694                         do
2695                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2696                         while (digitp != dp->width_end);
2697                       }
2698                     has_width = 1;
2699                   }
2700
2701                 has_precision = 0;
2702                 precision = 0;
2703                 if (dp->precision_start != dp->precision_end)
2704                   {
2705                     if (dp->precision_arg_index != ARG_NONE)
2706                       {
2707                         int arg;
2708
2709                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2710                           abort ();
2711                         arg = a.arg[dp->precision_arg_index].a.a_int;
2712                         /* "A negative precision is taken as if the precision
2713                             were omitted."  */
2714                         if (arg >= 0)
2715                           {
2716                             precision = arg;
2717                             has_precision = 1;
2718                           }
2719                       }
2720                     else
2721                       {
2722                         const FCHAR_T *digitp = dp->precision_start + 1;
2723
2724                         precision = 0;
2725                         while (digitp != dp->precision_end)
2726                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2727                         has_precision = 1;
2728                       }
2729                   }
2730
2731                 /* Allocate a temporary buffer of sufficient size.  */
2732                 if (type == TYPE_LONGDOUBLE)
2733                   tmp_length =
2734                     (unsigned int) ((LDBL_DIG + 1)
2735                                     * 0.831 /* decimal -> hexadecimal */
2736                                    )
2737                     + 1; /* turn floor into ceil */
2738                 else
2739                   tmp_length =
2740                     (unsigned int) ((DBL_DIG + 1)
2741                                     * 0.831 /* decimal -> hexadecimal */
2742                                    )
2743                     + 1; /* turn floor into ceil */
2744                 if (tmp_length < precision)
2745                   tmp_length = precision;
2746                 /* Account for sign, decimal point etc. */
2747                 tmp_length = xsum (tmp_length, 12);
2748
2749                 if (tmp_length < width)
2750                   tmp_length = width;
2751
2752                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2753
2754                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
2755                   tmp = tmpbuf;
2756                 else
2757                   {
2758                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
2759
2760                     if (size_overflow_p (tmp_memsize))
2761                       /* Overflow, would lead to out of memory.  */
2762                       goto out_of_memory;
2763                     tmp = (DCHAR_T *) malloc (tmp_memsize);
2764                     if (tmp == NULL)
2765                       /* Out of memory.  */
2766                       goto out_of_memory;
2767                   }
2768
2769                 pad_ptr = NULL;
2770                 p = tmp;
2771                 if (type == TYPE_LONGDOUBLE)
2772                   {
2773 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
2774                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
2775
2776                     if (isnanl (arg))
2777                       {
2778                         if (dp->conversion == 'A')
2779                           {
2780                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2781                           }
2782                         else
2783                           {
2784                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2785                           }
2786                       }
2787                     else
2788                       {
2789                         int sign = 0;
2790                         DECL_LONG_DOUBLE_ROUNDING
2791
2792                         BEGIN_LONG_DOUBLE_ROUNDING ();
2793
2794                         if (signbit (arg)) /* arg < 0.0L or negative zero */
2795                           {
2796                             sign = -1;
2797                             arg = -arg;
2798                           }
2799
2800                         if (sign < 0)
2801                           *p++ = '-';
2802                         else if (flags & FLAG_SHOWSIGN)
2803                           *p++ = '+';
2804                         else if (flags & FLAG_SPACE)
2805                           *p++ = ' ';
2806
2807                         if (arg > 0.0L && arg + arg == arg)
2808                           {
2809                             if (dp->conversion == 'A')
2810                               {
2811                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2812                               }
2813                             else
2814                               {
2815                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2816                               }
2817                           }
2818                         else
2819                           {
2820                             int exponent;
2821                             long double mantissa;
2822
2823                             if (arg > 0.0L)
2824                               mantissa = printf_frexpl (arg, &exponent);
2825                             else
2826                               {
2827                                 exponent = 0;
2828                                 mantissa = 0.0L;
2829                               }
2830
2831                             if (has_precision
2832                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
2833                               {
2834                                 /* Round the mantissa.  */
2835                                 long double tail = mantissa;
2836                                 size_t q;
2837
2838                                 for (q = precision; ; q--)
2839                                   {
2840                                     int digit = (int) tail;
2841                                     tail -= digit;
2842                                     if (q == 0)
2843                                       {
2844                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
2845                                           tail = 1 - tail;
2846                                         else
2847                                           tail = - tail;
2848                                         break;
2849                                       }
2850                                     tail *= 16.0L;
2851                                   }
2852                                 if (tail != 0.0L)
2853                                   for (q = precision; q > 0; q--)
2854                                     tail *= 0.0625L;
2855                                 mantissa += tail;
2856                               }
2857
2858                             *p++ = '0';
2859                             *p++ = dp->conversion - 'A' + 'X';
2860                             pad_ptr = p;
2861                             {
2862                               int digit;
2863
2864                               digit = (int) mantissa;
2865                               mantissa -= digit;
2866                               *p++ = '0' + digit;
2867                               if ((flags & FLAG_ALT)
2868                                   || mantissa > 0.0L || precision > 0)
2869                                 {
2870                                   *p++ = decimal_point_char ();
2871                                   /* This loop terminates because we assume
2872                                      that FLT_RADIX is a power of 2.  */
2873                                   while (mantissa > 0.0L)
2874                                     {
2875                                       mantissa *= 16.0L;
2876                                       digit = (int) mantissa;
2877                                       mantissa -= digit;
2878                                       *p++ = digit
2879                                              + (digit < 10
2880                                                 ? '0'
2881                                                 : dp->conversion - 10);
2882                                       if (precision > 0)
2883                                         precision--;
2884                                     }
2885                                   while (precision > 0)
2886                                     {
2887                                       *p++ = '0';
2888                                       precision--;
2889                                     }
2890                                 }
2891                               }
2892                               *p++ = dp->conversion - 'A' + 'P';
2893 #  if WIDE_CHAR_VERSION
2894                               {
2895                                 static const wchar_t decimal_format[] =
2896                                   { '%', '+', 'd', '\0' };
2897                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
2898                               }
2899                               while (*p != '\0')
2900                                 p++;
2901 #  else
2902                               if (sizeof (DCHAR_T) == 1)
2903                                 {
2904                                   sprintf ((char *) p, "%+d", exponent);
2905                                   while (*p != '\0')
2906                                     p++;
2907                                 }
2908                               else
2909                                 {
2910                                   char expbuf[6 + 1];
2911                                   const char *ep;
2912                                   sprintf (expbuf, "%+d", exponent);
2913                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2914                                     p++;
2915                                 }
2916 #  endif
2917                           }
2918
2919                         END_LONG_DOUBLE_ROUNDING ();
2920                       }
2921 # else
2922                     abort ();
2923 # endif
2924                   }
2925                 else
2926                   {
2927 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
2928                     double arg = a.arg[dp->arg_index].a.a_double;
2929
2930                     if (isnand (arg))
2931                       {
2932                         if (dp->conversion == 'A')
2933                           {
2934                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2935                           }
2936                         else
2937                           {
2938                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2939                           }
2940                       }
2941                     else
2942                       {
2943                         int sign = 0;
2944
2945                         if (signbit (arg)) /* arg < 0.0 or negative zero */
2946                           {
2947                             sign = -1;
2948                             arg = -arg;
2949                           }
2950
2951                         if (sign < 0)
2952                           *p++ = '-';
2953                         else if (flags & FLAG_SHOWSIGN)
2954                           *p++ = '+';
2955                         else if (flags & FLAG_SPACE)
2956                           *p++ = ' ';
2957
2958                         if (arg > 0.0 && arg + arg == arg)
2959                           {
2960                             if (dp->conversion == 'A')
2961                               {
2962                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2963                               }
2964                             else
2965                               {
2966                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2967                               }
2968                           }
2969                         else
2970                           {
2971                             int exponent;
2972                             double mantissa;
2973
2974                             if (arg > 0.0)
2975                               mantissa = printf_frexp (arg, &exponent);
2976                             else
2977                               {
2978                                 exponent = 0;
2979                                 mantissa = 0.0;
2980                               }
2981
2982                             if (has_precision
2983                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
2984                               {
2985                                 /* Round the mantissa.  */
2986                                 double tail = mantissa;
2987                                 size_t q;
2988
2989                                 for (q = precision; ; q--)
2990                                   {
2991                                     int digit = (int) tail;
2992                                     tail -= digit;
2993                                     if (q == 0)
2994                                       {
2995                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
2996                                           tail = 1 - tail;
2997                                         else
2998                                           tail = - tail;
2999                                         break;
3000                                       }
3001                                     tail *= 16.0;
3002                                   }
3003                                 if (tail != 0.0)
3004                                   for (q = precision; q > 0; q--)
3005                                     tail *= 0.0625;
3006                                 mantissa += tail;
3007                               }
3008
3009                             *p++ = '0';
3010                             *p++ = dp->conversion - 'A' + 'X';
3011                             pad_ptr = p;
3012                             {
3013                               int digit;
3014
3015                               digit = (int) mantissa;
3016                               mantissa -= digit;
3017                               *p++ = '0' + digit;
3018                               if ((flags & FLAG_ALT)
3019                                   || mantissa > 0.0 || precision > 0)
3020                                 {
3021                                   *p++ = decimal_point_char ();
3022                                   /* This loop terminates because we assume
3023                                      that FLT_RADIX is a power of 2.  */
3024                                   while (mantissa > 0.0)
3025                                     {
3026                                       mantissa *= 16.0;
3027                                       digit = (int) mantissa;
3028                                       mantissa -= digit;
3029                                       *p++ = digit
3030                                              + (digit < 10
3031                                                 ? '0'
3032                                                 : dp->conversion - 10);
3033                                       if (precision > 0)
3034                                         precision--;
3035                                     }
3036                                   while (precision > 0)
3037                                     {
3038                                       *p++ = '0';
3039                                       precision--;
3040                                     }
3041                                 }
3042                               }
3043                               *p++ = dp->conversion - 'A' + 'P';
3044 #  if WIDE_CHAR_VERSION
3045                               {
3046                                 static const wchar_t decimal_format[] =
3047                                   { '%', '+', 'd', '\0' };
3048                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3049                               }
3050                               while (*p != '\0')
3051                                 p++;
3052 #  else
3053                               if (sizeof (DCHAR_T) == 1)
3054                                 {
3055                                   sprintf ((char *) p, "%+d", exponent);
3056                                   while (*p != '\0')
3057                                     p++;
3058                                 }
3059                               else
3060                                 {
3061                                   char expbuf[6 + 1];
3062                                   const char *ep;
3063                                   sprintf (expbuf, "%+d", exponent);
3064                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3065                                     p++;
3066                                 }
3067 #  endif
3068                           }
3069                       }
3070 # else
3071                     abort ();
3072 # endif
3073                   }
3074                 /* The generated string now extends from tmp to p, with the
3075                    zero padding insertion point being at pad_ptr.  */
3076                 if (has_width && p - tmp < width)
3077                   {
3078                     size_t pad = width - (p - tmp);
3079                     DCHAR_T *end = p + pad;
3080
3081                     if (flags & FLAG_LEFT)
3082                       {
3083                         /* Pad with spaces on the right.  */
3084                         for (; pad > 0; pad--)
3085                           *p++ = ' ';
3086                       }
3087                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3088                       {
3089                         /* Pad with zeroes.  */
3090                         DCHAR_T *q = end;
3091
3092                         while (p > pad_ptr)
3093                           *--q = *--p;
3094                         for (; pad > 0; pad--)
3095                           *p++ = '0';
3096                       }
3097                     else
3098                       {
3099                         /* Pad with spaces on the left.  */
3100                         DCHAR_T *q = end;
3101
3102                         while (p > tmp)
3103                           *--q = *--p;
3104                         for (; pad > 0; pad--)
3105                           *p++ = ' ';
3106                       }
3107
3108                     p = end;
3109                   }
3110
3111                 {
3112                   size_t count = p - tmp;
3113
3114                   if (count >= tmp_length)
3115                     /* tmp_length was incorrectly calculated - fix the
3116                        code above!  */
3117                     abort ();
3118
3119                   /* Make room for the result.  */
3120                   if (count >= allocated - length)
3121                     {
3122                       size_t n = xsum (length, count);
3123
3124                       ENSURE_ALLOCATION (n);
3125                     }
3126
3127                   /* Append the result.  */
3128                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3129                   if (tmp != tmpbuf)
3130                     free (tmp);
3131                   length += count;
3132                 }
3133               }
3134 #endif
3135 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3136             else if ((dp->conversion == 'f' || dp->conversion == 'F'
3137                       || dp->conversion == 'e' || dp->conversion == 'E'
3138                       || dp->conversion == 'g' || dp->conversion == 'G'
3139                       || dp->conversion == 'a' || dp->conversion == 'A')
3140                      && (0
3141 # if NEED_PRINTF_DOUBLE
3142                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
3143 # elif NEED_PRINTF_INFINITE_DOUBLE
3144                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3145                              /* The systems (mingw) which produce wrong output
3146                                 for Inf, -Inf, and NaN also do so for -0.0.
3147                                 Therefore we treat this case here as well.  */
3148                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3149 # endif
3150 # if NEED_PRINTF_LONG_DOUBLE
3151                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3152 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3153                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3154                              /* Some systems produce wrong output for Inf,
3155                                 -Inf, and NaN.  Some systems in this category
3156                                 (IRIX 5.3) also do so for -0.0.  Therefore we
3157                                 treat this case here as well.  */
3158                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3159 # endif
3160                         ))
3161               {
3162 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3163                 arg_type type = a.arg[dp->arg_index].type;
3164 # endif
3165                 int flags = dp->flags;
3166                 int has_width;
3167                 size_t width;
3168                 int has_precision;
3169                 size_t precision;
3170                 size_t tmp_length;
3171                 DCHAR_T tmpbuf[700];
3172                 DCHAR_T *tmp;
3173                 DCHAR_T *pad_ptr;
3174                 DCHAR_T *p;
3175
3176                 has_width = 0;
3177                 width = 0;
3178                 if (dp->width_start != dp->width_end)
3179                   {
3180                     if (dp->width_arg_index != ARG_NONE)
3181                       {
3182                         int arg;
3183
3184                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3185                           abort ();
3186                         arg = a.arg[dp->width_arg_index].a.a_int;
3187                         if (arg < 0)
3188                           {
3189                             /* "A negative field width is taken as a '-' flag
3190                                 followed by a positive field width."  */
3191                             flags |= FLAG_LEFT;
3192                             width = (unsigned int) (-arg);
3193                           }
3194                         else
3195                           width = arg;
3196                       }
3197                     else
3198                       {
3199                         const FCHAR_T *digitp = dp->width_start;
3200
3201                         do
3202                           width = xsum (xtimes (width, 10), *digitp++ - '0');
3203                         while (digitp != dp->width_end);
3204                       }
3205                     has_width = 1;
3206                   }
3207
3208                 has_precision = 0;
3209                 precision = 0;
3210                 if (dp->precision_start != dp->precision_end)
3211                   {
3212                     if (dp->precision_arg_index != ARG_NONE)
3213                       {
3214                         int arg;
3215
3216                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3217                           abort ();
3218                         arg = a.arg[dp->precision_arg_index].a.a_int;
3219                         /* "A negative precision is taken as if the precision
3220                             were omitted."  */
3221                         if (arg >= 0)
3222                           {
3223                             precision = arg;
3224                             has_precision = 1;
3225                           }
3226                       }
3227                     else
3228                       {
3229                         const FCHAR_T *digitp = dp->precision_start + 1;
3230
3231                         precision = 0;
3232                         while (digitp != dp->precision_end)
3233                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3234                         has_precision = 1;
3235                       }
3236                   }
3237
3238                 /* POSIX specifies the default precision to be 6 for %f, %F,
3239                    %e, %E, but not for %g, %G.  Implementations appear to use
3240                    the same default precision also for %g, %G.  But for %a, %A,
3241                    the default precision is 0.  */
3242                 if (!has_precision)
3243                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3244                     precision = 6;
3245
3246                 /* Allocate a temporary buffer of sufficient size.  */
3247 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3248                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3249 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3250                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3251 # elif NEED_PRINTF_LONG_DOUBLE
3252                 tmp_length = LDBL_DIG + 1;
3253 # elif NEED_PRINTF_DOUBLE
3254                 tmp_length = DBL_DIG + 1;
3255 # else
3256                 tmp_length = 0;
3257 # endif
3258                 if (tmp_length < precision)
3259                   tmp_length = precision;
3260 # if NEED_PRINTF_LONG_DOUBLE
3261 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3262                 if (type == TYPE_LONGDOUBLE)
3263 #  endif
3264                   if (dp->conversion == 'f' || dp->conversion == 'F')
3265                     {
3266                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
3267                       if (!(isnanl (arg) || arg + arg == arg))
3268                         {
3269                           /* arg is finite and nonzero.  */
3270                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
3271                           if (exponent >= 0 && tmp_length < exponent + precision)
3272                             tmp_length = exponent + precision;
3273                         }
3274                     }
3275 # endif
3276 # if NEED_PRINTF_DOUBLE
3277 #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3278                 if (type == TYPE_DOUBLE)
3279 #  endif
3280                   if (dp->conversion == 'f' || dp->conversion == 'F')
3281                     {
3282                       double arg = a.arg[dp->arg_index].a.a_double;
3283                       if (!(isnand (arg) || arg + arg == arg))
3284                         {
3285                           /* arg is finite and nonzero.  */
3286                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
3287                           if (exponent >= 0 && tmp_length < exponent + precision)
3288                             tmp_length = exponent + precision;
3289                         }
3290                     }
3291 # endif
3292                 /* Account for sign, decimal point etc. */
3293                 tmp_length = xsum (tmp_length, 12);
3294
3295                 if (tmp_length < width)
3296                   tmp_length = width;
3297
3298                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3299
3300                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3301                   tmp = tmpbuf;
3302                 else
3303                   {
3304                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3305
3306                     if (size_overflow_p (tmp_memsize))
3307                       /* Overflow, would lead to out of memory.  */
3308                       goto out_of_memory;
3309                     tmp = (DCHAR_T *) malloc (tmp_memsize);
3310                     if (tmp == NULL)
3311                       /* Out of memory.  */
3312                       goto out_of_memory;
3313                   }
3314
3315                 pad_ptr = NULL;
3316                 p = tmp;
3317
3318 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3319 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3320                 if (type == TYPE_LONGDOUBLE)
3321 #  endif
3322                   {
3323                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
3324
3325                     if (isnanl (arg))
3326                       {
3327                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3328                           {
3329                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3330                           }
3331                         else
3332                           {
3333                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3334                           }
3335                       }
3336                     else
3337                       {
3338                         int sign = 0;
3339                         DECL_LONG_DOUBLE_ROUNDING
3340
3341                         BEGIN_LONG_DOUBLE_ROUNDING ();
3342
3343                         if (signbit (arg)) /* arg < 0.0L or negative zero */
3344                           {
3345                             sign = -1;
3346                             arg = -arg;
3347                           }
3348
3349                         if (sign < 0)
3350                           *p++ = '-';
3351                         else if (flags & FLAG_SHOWSIGN)
3352                           *p++ = '+';
3353                         else if (flags & FLAG_SPACE)
3354                           *p++ = ' ';
3355
3356                         if (arg > 0.0L && arg + arg == arg)
3357                           {
3358                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3359                               {
3360                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3361                               }
3362                             else
3363                               {
3364                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3365                               }
3366                           }
3367                         else
3368                           {
3369 #  if NEED_PRINTF_LONG_DOUBLE
3370                             pad_ptr = p;
3371
3372                             if (dp->conversion == 'f' || dp->conversion == 'F')
3373                               {
3374                                 char *digits;
3375                                 size_t ndigits;
3376
3377                                 digits =
3378                                   scale10_round_decimal_long_double (arg, precision);
3379                                 if (digits == NULL)
3380                                   {
3381                                     END_LONG_DOUBLE_ROUNDING ();
3382                                     goto out_of_memory;
3383                                   }
3384                                 ndigits = strlen (digits);
3385
3386                                 if (ndigits > precision)
3387                                   do
3388                                     {
3389                                       --ndigits;
3390                                       *p++ = digits[ndigits];
3391                                     }
3392                                   while (ndigits > precision);
3393                                 else
3394                                   *p++ = '0';
3395                                 /* Here ndigits <= precision.  */
3396                                 if ((flags & FLAG_ALT) || precision > 0)
3397                                   {
3398                                     *p++ = decimal_point_char ();
3399                                     for (; precision > ndigits; precision--)
3400                                       *p++ = '0';
3401                                     while (ndigits > 0)
3402                                       {
3403                                         --ndigits;
3404                                         *p++ = digits[ndigits];
3405                                       }
3406                                   }
3407
3408                                 free (digits);
3409                               }
3410                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3411                               {
3412                                 int exponent;
3413
3414                                 if (arg == 0.0L)
3415                                   {
3416                                     exponent = 0;
3417                                     *p++ = '0';
3418                                     if ((flags & FLAG_ALT) || precision > 0)
3419                                       {
3420                                         *p++ = decimal_point_char ();
3421                                         for (; precision > 0; precision--)
3422                                           *p++ = '0';
3423                                       }
3424                                   }
3425                                 else
3426                                   {
3427                                     /* arg > 0.0L.  */
3428                                     int adjusted;
3429                                     char *digits;
3430                                     size_t ndigits;
3431
3432                                     exponent = floorlog10l (arg);
3433                                     adjusted = 0;
3434                                     for (;;)
3435                                       {
3436                                         digits =
3437                                           scale10_round_decimal_long_double (arg,
3438                                                                              (int)precision - exponent);
3439                                         if (digits == NULL)
3440                                           {
3441                                             END_LONG_DOUBLE_ROUNDING ();
3442                                             goto out_of_memory;
3443                                           }
3444                                         ndigits = strlen (digits);
3445
3446                                         if (ndigits == precision + 1)
3447                                           break;
3448                                         if (ndigits < precision
3449                                             || ndigits > precision + 2)
3450                                           /* The exponent was not guessed
3451                                              precisely enough.  */
3452                                           abort ();
3453                                         if (adjusted)
3454                                           /* None of two values of exponent is
3455                                              the right one.  Prevent an endless
3456                                              loop.  */
3457                                           abort ();
3458                                         free (digits);
3459                                         if (ndigits == precision)
3460                                           exponent -= 1;
3461                                         else
3462                                           exponent += 1;
3463                                         adjusted = 1;
3464                                       }
3465                                     /* Here ndigits = precision+1.  */
3466                                     if (is_borderline (digits, precision))
3467                                       {
3468                                         /* Maybe the exponent guess was too high
3469                                            and a smaller exponent can be reached
3470                                            by turning a 10...0 into 9...9x.  */
3471                                         char *digits2 =
3472                                           scale10_round_decimal_long_double (arg,
3473                                                                              (int)precision - exponent + 1);
3474                                         if (digits2 == NULL)
3475                                           {
3476                                             free (digits);
3477                                             END_LONG_DOUBLE_ROUNDING ();
3478                                             goto out_of_memory;
3479                                           }
3480                                         if (strlen (digits2) == precision + 1)
3481                                           {
3482                                             free (digits);
3483                                             digits = digits2;
3484                                             exponent -= 1;
3485                                           }
3486                                         else
3487                                           free (digits2);
3488                                       }
3489                                     /* Here ndigits = precision+1.  */
3490
3491                                     *p++ = digits[--ndigits];
3492                                     if ((flags & FLAG_ALT) || precision > 0)
3493                                       {
3494                                         *p++ = decimal_point_char ();
3495                                         while (ndigits > 0)
3496                                           {
3497                                             --ndigits;
3498                                             *p++ = digits[ndigits];
3499                                           }
3500                                       }
3501
3502                                     free (digits);
3503                                   }
3504
3505                                 *p++ = dp->conversion; /* 'e' or 'E' */
3506 #   if WIDE_CHAR_VERSION
3507                                 {
3508                                   static const wchar_t decimal_format[] =
3509                                     { '%', '+', '.', '2', 'd', '\0' };
3510                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
3511                                 }
3512                                 while (*p != '\0')
3513                                   p++;
3514 #   else
3515                                 if (sizeof (DCHAR_T) == 1)
3516                                   {
3517                                     sprintf ((char *) p, "%+.2d", exponent);
3518                                     while (*p != '\0')
3519                                       p++;
3520                                   }
3521                                 else
3522                                   {
3523                                     char expbuf[6 + 1];
3524                                     const char *ep;
3525                                     sprintf (expbuf, "%+.2d", exponent);
3526                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3527                                       p++;
3528                                   }
3529 #   endif
3530                               }
3531                             else if (dp->conversion == 'g' || dp->conversion == 'G')
3532                               {
3533                                 if (precision == 0)
3534                                   precision = 1;
3535                                 /* precision >= 1.  */
3536
3537                                 if (arg == 0.0L)
3538                                   /* The exponent is 0, >= -4, < precision.
3539                                      Use fixed-point notation.  */
3540                                   {
3541                                     size_t ndigits = precision;
3542                                     /* Number of trailing zeroes that have to be
3543                                        dropped.  */
3544                                     size_t nzeroes =
3545                                       (flags & FLAG_ALT ? 0 : precision - 1);
3546
3547                                     --ndigits;
3548                                     *p++ = '0';
3549                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
3550                                       {
3551                                         *p++ = decimal_point_char ();
3552                                         while (ndigits > nzeroes)
3553                                           {
3554                                             --ndigits;
3555                                             *p++ = '0';
3556                                           }
3557                                       }
3558                                   }
3559                                 else
3560                                   {
3561                                     /* arg > 0.0L.  */
3562                                     int exponent;
3563                                     int adjusted;
3564                                     char *digits;
3565                                     size_t ndigits;
3566                                     size_t nzeroes;
3567
3568                                     exponent = floorlog10l (arg);
3569                                     adjusted = 0;
3570                                     for (;;)
3571                                       {
3572                                         digits =
3573                                           scale10_round_decimal_long_double (arg,
3574                                                                              (int)(precision - 1) - exponent);
3575                                         if (digits == NULL)
3576                                           {
3577                                             END_LONG_DOUBLE_ROUNDING ();
3578                                             goto out_of_memory;
3579                                           }
3580                                         ndigits = strlen (digits);
3581
3582                                         if (ndigits == precision)
3583                                           break;
3584                                         if (ndigits < precision - 1
3585                                             || ndigits > precision + 1)
3586                                           /* The exponent was not guessed
3587                                              precisely enough.  */
3588                                           abort ();
3589                                         if (adjusted)
3590                                           /* None of two values of exponent is
3591                                              the right one.  Prevent an endless
3592                                              loop.  */
3593                                           abort ();
3594                                         free (digits);
3595                                         if (ndigits < precision)
3596                                           exponent -= 1;
3597                                         else
3598                                           exponent += 1;
3599                                         adjusted = 1;
3600                                       }
3601                                     /* Here ndigits = precision.  */
3602                                     if (is_borderline (digits, precision - 1))
3603                                       {
3604                                         /* Maybe the exponent guess was too high
3605                                            and a smaller exponent can be reached
3606                                            by turning a 10...0 into 9...9x.  */
3607                                         char *digits2 =
3608                                           scale10_round_decimal_long_double (arg,
3609                                                                              (int)(precision - 1) - exponent + 1);
3610                                         if (digits2 == NULL)
3611                                           {
3612                                             free (digits);
3613                                             END_LONG_DOUBLE_ROUNDING ();
3614                                             goto out_of_memory;
3615                                           }
3616                                         if (strlen (digits2) == precision)
3617                                           {
3618                                             free (digits);
3619                                             digits = digits2;
3620                                             exponent -= 1;
3621                                           }
3622                                         else
3623                                           free (digits2);
3624                                       }
3625                                     /* Here ndigits = precision.  */
3626
3627                                     /* Determine the number of trailing zeroes
3628                                        that have to be dropped.  */
3629                                     nzeroes = 0;
3630                                     if ((flags & FLAG_ALT) == 0)
3631                                       while (nzeroes < ndigits
3632                                              && digits[nzeroes] == '0')
3633                                         nzeroes++;
3634
3635                                     /* The exponent is now determined.  */
3636                                     if (exponent >= -4
3637                                         && exponent < (long)precision)
3638                                       {
3639                                         /* Fixed-point notation:
3640                                            max(exponent,0)+1 digits, then the
3641                                            decimal point, then the remaining
3642                                            digits without trailing zeroes.  */
3643                                         if (exponent >= 0)
3644                                           {
3645                                             size_t count = exponent + 1;
3646                                             /* Note: count <= precision = ndigits.  */
3647                                             for (; count > 0; count--)
3648                                               *p++ = digits[--ndigits];
3649                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
3650                                               {
3651                                                 *p++ = decimal_point_char ();
3652                                                 while (ndigits > nzeroes)
3653                                                   {
3654                                                     --ndigits;
3655                                                     *p++ = digits[ndigits];
3656                                                   }
3657                                               }
3658                                           }
3659                                         else
3660                                           {
3661                                             size_t count = -exponent - 1;
3662                                             *p++ = '0';
3663                                             *p++ = decimal_point_char ();
3664                                             for (; count > 0; count--)
3665                                               *p++ = '0';
3666                                             while (ndigits > nzeroes)
3667                                               {
3668                                                 --ndigits;
3669                                                 *p++ = digits[ndigits];
3670                                               }
3671                                           }
3672                                       }
3673                                     else
3674                                       {
3675                                         /* Exponential notation.  */
3676                                         *p++ = digits[--ndigits];
3677                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
3678                                           {
3679                                             *p++ = decimal_point_char ();
3680                                             while (ndigits > nzeroes)
3681                                               {
3682                                                 --ndigits;
3683                                                 *p++ = digits[ndigits];
3684                                               }
3685                                           }
3686                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3687 #   if WIDE_CHAR_VERSION
3688                                         {
3689                                           static const wchar_t decimal_format[] =
3690                                             { '%', '+', '.', '2', 'd', '\0' };
3691                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
3692                                         }
3693                                         while (*p != '\0')
3694                                           p++;
3695 #   else
3696                                         if (sizeof (DCHAR_T) == 1)
3697                                           {
3698                                             sprintf ((char *) p, "%+.2d", exponent);
3699                                             while (*p != '\0')
3700                                               p++;
3701                                           }
3702                                         else
3703                                           {
3704                                             char expbuf[6 + 1];
3705                                             const char *ep;
3706                                             sprintf (expbuf, "%+.2d", exponent);
3707                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3708                                               p++;
3709                                           }
3710 #   endif
3711                                       }
3712
3713                                     free (digits);
3714                                   }
3715                               }
3716                             else
3717                               abort ();
3718 #  else
3719                             /* arg is finite.  */
3720                             if (!(arg == 0.0L))
3721                               abort ();
3722
3723                             pad_ptr = p;
3724
3725                             if (dp->conversion == 'f' || dp->conversion == 'F')
3726                               {
3727                                 *p++ = '0';
3728                                 if ((flags & FLAG_ALT) || precision > 0)
3729                                   {
3730                                     *p++ = decimal_point_char ();
3731                                     for (; precision > 0; precision--)
3732                                       *p++ = '0';
3733                                   }
3734                               }
3735                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3736                               {
3737                                 *p++ = '0';
3738                                 if ((flags & FLAG_ALT) || precision > 0)
3739                                   {
3740                                     *p++ = decimal_point_char ();
3741                                     for (; precision > 0; precision--)
3742                                       *p++ = '0';
3743                                   }
3744                                 *p++ = dp->conversion; /* 'e' or 'E' */
3745                                 *p++ = '+';
3746                                 *p++ = '0';
3747                                 *p++ = '0';
3748                               }
3749                             else if (dp->conversion == 'g' || dp->conversion == 'G')
3750                               {
3751                                 *p++ = '0';
3752                                 if (flags & FLAG_ALT)
3753                                   {
3754                                     size_t ndigits =
3755                                       (precision > 0 ? precision - 1 : 0);
3756                                     *p++ = decimal_point_char ();
3757                                     for (; ndigits > 0; --ndigits)
3758                                       *p++ = '0';
3759                                   }
3760                               }
3761                             else if (dp->conversion == 'a' || dp->conversion == 'A')
3762                               {
3763                                 *p++ = '0';
3764                                 *p++ = dp->conversion - 'A' + 'X';
3765                                 pad_ptr = p;
3766                                 *p++ = '0';
3767                                 if ((flags & FLAG_ALT) || precision > 0)
3768                                   {
3769                                     *p++ = decimal_point_char ();
3770                                     for (; precision > 0; precision--)
3771                                       *p++ = '0';
3772                                   }
3773                                 *p++ = dp->conversion - 'A' + 'P';
3774                                 *p++ = '+';
3775                                 *p++ = '0';
3776                               }
3777                             else
3778                               abort ();
3779 #  endif
3780                           }
3781
3782                         END_LONG_DOUBLE_ROUNDING ();
3783                       }
3784                   }
3785 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3786                 else
3787 #  endif
3788 # endif
3789 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3790                   {
3791                     double arg = a.arg[dp->arg_index].a.a_double;
3792
3793                     if (isnand (arg))
3794                       {
3795                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3796                           {
3797                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3798                           }
3799                         else
3800                           {
3801                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3802                           }
3803                       }
3804                     else
3805                       {
3806                         int sign = 0;
3807
3808                         if (signbit (arg)) /* arg < 0.0 or negative zero */
3809                           {
3810                             sign = -1;
3811                             arg = -arg;
3812                           }
3813
3814                         if (sign < 0)
3815                           *p++ = '-';
3816                         else if (flags & FLAG_SHOWSIGN)
3817                           *p++ = '+';
3818                         else if (flags & FLAG_SPACE)
3819                           *p++ = ' ';
3820
3821                         if (arg > 0.0 && arg + arg == arg)
3822                           {
3823                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3824                               {
3825                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3826                               }
3827                             else
3828                               {
3829                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3830                               }
3831                           }
3832                         else
3833                           {
3834 #  if NEED_PRINTF_DOUBLE
3835                             pad_ptr = p;
3836
3837                             if (dp->conversion == 'f' || dp->conversion == 'F')
3838                               {
3839                                 char *digits;
3840                                 size_t ndigits;
3841
3842                                 digits =
3843                                   scale10_round_decimal_double (arg, precision);
3844                                 if (digits == NULL)
3845                                   goto out_of_memory;
3846                                 ndigits = strlen (digits);
3847
3848                                 if (ndigits > precision)
3849                                   do
3850                                     {
3851                                       --ndigits;
3852                                       *p++ = digits[ndigits];
3853                                     }
3854                                   while (ndigits > precision);
3855                                 else
3856                                   *p++ = '0';
3857                                 /* Here ndigits <= precision.  */
3858                                 if ((flags & FLAG_ALT) || precision > 0)
3859                                   {
3860                                     *p++ = decimal_point_char ();
3861                                     for (; precision > ndigits; precision--)
3862                                       *p++ = '0';
3863                                     while (ndigits > 0)
3864                                       {
3865                                         --ndigits;
3866                                         *p++ = digits[ndigits];
3867                                       }
3868                                   }
3869
3870                                 free (digits);
3871                               }
3872                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3873                               {
3874                                 int exponent;
3875
3876                                 if (arg == 0.0)
3877                                   {
3878                                     exponent = 0;
3879                                     *p++ = '0';
3880                                     if ((flags & FLAG_ALT) || precision > 0)
3881                                       {
3882                                         *p++ = decimal_point_char ();
3883                                         for (; precision > 0; precision--)
3884                                           *p++ = '0';
3885                                       }
3886                                   }
3887                                 else
3888                                   {
3889                                     /* arg > 0.0.  */
3890                                     int adjusted;
3891                                     char *digits;
3892                                     size_t ndigits;
3893
3894                                     exponent = floorlog10 (arg);
3895                                     adjusted = 0;
3896                                     for (;;)
3897                                       {
3898                                         digits =
3899                                           scale10_round_decimal_double (arg,
3900                                                                         (int)precision - exponent);
3901                                         if (digits == NULL)
3902                                           goto out_of_memory;
3903                                         ndigits = strlen (digits);
3904
3905                                         if (ndigits == precision + 1)
3906                                           break;
3907                                         if (ndigits < precision
3908                                             || ndigits > precision + 2)
3909                                           /* The exponent was not guessed
3910                                              precisely enough.  */
3911                                           abort ();
3912                                         if (adjusted)
3913                                           /* None of two values of exponent is
3914                                              the right one.  Prevent an endless
3915                                              loop.  */
3916                                           abort ();
3917                                         free (digits);
3918                                         if (ndigits == precision)
3919                                           exponent -= 1;
3920                                         else
3921                                           exponent += 1;
3922                                         adjusted = 1;
3923                                       }
3924                                     /* Here ndigits = precision+1.  */
3925                                     if (is_borderline (digits, precision))
3926                                       {
3927                                         /* Maybe the exponent guess was too high
3928                                            and a smaller exponent can be reached
3929                                            by turning a 10...0 into 9...9x.  */
3930                                         char *digits2 =
3931                                           scale10_round_decimal_double (arg,
3932                                                                         (int)precision - exponent + 1);
3933                                         if (digits2 == NULL)
3934                                           {
3935                                             free (digits);
3936                                             goto out_of_memory;
3937                                           }
3938                                         if (strlen (digits2) == precision + 1)
3939                                           {
3940                                             free (digits);
3941                                             digits = digits2;
3942                                             exponent -= 1;
3943                                           }
3944                                         else
3945                                           free (digits2);
3946                                       }
3947                                     /* Here ndigits = precision+1.  */
3948
3949                                     *p++ = digits[--ndigits];
3950                                     if ((flags & FLAG_ALT) || precision > 0)
3951                                       {
3952                                         *p++ = decimal_point_char ();
3953                                         while (ndigits > 0)
3954                                           {
3955                                             --ndigits;
3956                                             *p++ = digits[ndigits];
3957                                           }
3958                                       }
3959
3960                                     free (digits);
3961                                   }
3962
3963                                 *p++ = dp->conversion; /* 'e' or 'E' */
3964 #   if WIDE_CHAR_VERSION
3965                                 {
3966                                   static const wchar_t decimal_format[] =
3967                                     /* Produce the same number of exponent digits
3968                                        as the native printf implementation.  */
3969 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3970                                     { '%', '+', '.', '3', 'd', '\0' };
3971 #    else
3972                                     { '%', '+', '.', '2', 'd', '\0' };
3973 #    endif
3974                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
3975                                 }
3976                                 while (*p != '\0')
3977                                   p++;
3978 #   else
3979                                 {
3980                                   static const char decimal_format[] =
3981                                     /* Produce the same number of exponent digits
3982                                        as the native printf implementation.  */
3983 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3984                                     "%+.3d";
3985 #    else
3986                                     "%+.2d";
3987 #    endif
3988                                   if (sizeof (DCHAR_T) == 1)
3989                                     {
3990                                       sprintf ((char *) p, decimal_format, exponent);
3991                                       while (*p != '\0')
3992                                         p++;
3993                                     }
3994                                   else
3995                                     {
3996                                       char expbuf[6 + 1];
3997                                       const char *ep;
3998                                       sprintf (expbuf, decimal_format, exponent);
3999                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4000                                         p++;
4001                                     }
4002                                 }
4003 #   endif
4004                               }
4005                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4006                               {
4007                                 if (precision == 0)
4008                                   precision = 1;
4009                                 /* precision >= 1.  */
4010
4011                                 if (arg == 0.0)
4012                                   /* The exponent is 0, >= -4, < precision.
4013                                      Use fixed-point notation.  */
4014                                   {
4015                                     size_t ndigits = precision;
4016                                     /* Number of trailing zeroes that have to be
4017                                        dropped.  */
4018                                     size_t nzeroes =
4019                                       (flags & FLAG_ALT ? 0 : precision - 1);
4020
4021                                     --ndigits;
4022                                     *p++ = '0';
4023                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
4024                                       {
4025                                         *p++ = decimal_point_char ();
4026                                         while (ndigits > nzeroes)
4027                                           {
4028                                             --ndigits;
4029                                             *p++ = '0';
4030                                           }
4031                                       }
4032                                   }
4033                                 else
4034                                   {
4035                                     /* arg > 0.0.  */
4036                                     int exponent;
4037                                     int adjusted;
4038                                     char *digits;
4039                                     size_t ndigits;
4040                                     size_t nzeroes;
4041
4042                                     exponent = floorlog10 (arg);
4043                                     adjusted = 0;
4044                                     for (;;)
4045                                       {
4046                                         digits =
4047                                           scale10_round_decimal_double (arg,
4048                                                                         (int)(precision - 1) - exponent);
4049                                         if (digits == NULL)
4050                                           goto out_of_memory;
4051                                         ndigits = strlen (digits);
4052
4053                                         if (ndigits == precision)
4054                                           break;
4055                                         if (ndigits < precision - 1
4056                                             || ndigits > precision + 1)
4057                                           /* The exponent was not guessed
4058                                              precisely enough.  */
4059                                           abort ();
4060                                         if (adjusted)
4061                                           /* None of two values of exponent is
4062                                              the right one.  Prevent an endless
4063                                              loop.  */
4064                                           abort ();
4065                                         free (digits);
4066                                         if (ndigits < precision)
4067                                           exponent -= 1;
4068                                         else
4069                                           exponent += 1;
4070                                         adjusted = 1;
4071                                       }
4072                                     /* Here ndigits = precision.  */
4073                                     if (is_borderline (digits, precision - 1))
4074                                       {
4075                                         /* Maybe the exponent guess was too high
4076                                            and a smaller exponent can be reached
4077                                            by turning a 10...0 into 9...9x.  */
4078                                         char *digits2 =
4079                                           scale10_round_decimal_double (arg,
4080                                                                         (int)(precision - 1) - exponent + 1);
4081                                         if (digits2 == NULL)
4082                                           {
4083                                             free (digits);
4084                                             goto out_of_memory;
4085                                           }
4086                                         if (strlen (digits2) == precision)
4087                                           {
4088                                             free (digits);
4089                                             digits = digits2;
4090                                             exponent -= 1;
4091                                           }
4092                                         else
4093                                           free (digits2);
4094                                       }
4095                                     /* Here ndigits = precision.  */
4096
4097                                     /* Determine the number of trailing zeroes
4098                                        that have to be dropped.  */
4099                                     nzeroes = 0;
4100                                     if ((flags & FLAG_ALT) == 0)
4101                                       while (nzeroes < ndigits
4102                                              && digits[nzeroes] == '0')
4103                                         nzeroes++;
4104
4105                                     /* The exponent is now determined.  */
4106                                     if (exponent >= -4
4107                                         && exponent < (long)precision)
4108                                       {
4109                                         /* Fixed-point notation:
4110                                            max(exponent,0)+1 digits, then the
4111                                            decimal point, then the remaining
4112                                            digits without trailing zeroes.  */
4113                                         if (exponent >= 0)
4114                                           {
4115                                             size_t count = exponent + 1;
4116                                             /* Note: count <= precision = ndigits.  */
4117                                             for (; count > 0; count--)
4118                                               *p++ = digits[--ndigits];
4119                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
4120                                               {
4121                                                 *p++ = decimal_point_char ();
4122                                                 while (ndigits > nzeroes)
4123                                                   {
4124                                                     --ndigits;
4125                                                     *p++ = digits[ndigits];
4126                                                   }
4127                                               }
4128                                           }
4129                                         else
4130                                           {
4131                                             size_t count = -exponent - 1;
4132                                             *p++ = '0';
4133                                             *p++ = decimal_point_char ();
4134                                             for (; count > 0; count--)
4135                                               *p++ = '0';
4136                                             while (ndigits > nzeroes)
4137                                               {
4138                                                 --ndigits;
4139                                                 *p++ = digits[ndigits];
4140                                               }
4141                                           }
4142                                       }
4143                                     else
4144                                       {
4145                                         /* Exponential notation.  */
4146                                         *p++ = digits[--ndigits];
4147                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
4148                                           {
4149                                             *p++ = decimal_point_char ();
4150                                             while (ndigits > nzeroes)
4151                                               {
4152                                                 --ndigits;
4153                                                 *p++ = digits[ndigits];
4154                                               }
4155                                           }
4156                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4157 #   if WIDE_CHAR_VERSION
4158                                         {
4159                                           static const wchar_t decimal_format[] =
4160                                             /* Produce the same number of exponent digits
4161                                                as the native printf implementation.  */
4162 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4163                                             { '%', '+', '.', '3', 'd', '\0' };
4164 #    else
4165                                             { '%', '+', '.', '2', 'd', '\0' };
4166 #    endif
4167                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
4168                                         }
4169                                         while (*p != '\0')
4170                                           p++;
4171 #   else
4172                                         {
4173                                           static const char decimal_format[] =
4174                                             /* Produce the same number of exponent digits
4175                                                as the native printf implementation.  */
4176 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4177                                             "%+.3d";
4178 #    else
4179                                             "%+.2d";
4180 #    endif
4181                                           if (sizeof (DCHAR_T) == 1)
4182                                             {
4183                                               sprintf ((char *) p, decimal_format, exponent);
4184                                               while (*p != '\0')
4185                                                 p++;
4186                                             }
4187                                           else
4188                                             {
4189                                               char expbuf[6 + 1];
4190                                               const char *ep;
4191                                               sprintf (expbuf, decimal_format, exponent);
4192                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4193                                                 p++;
4194                                             }
4195                                         }
4196 #   endif
4197                                       }
4198
4199                                     free (digits);
4200                                   }
4201                               }
4202                             else
4203                               abort ();
4204 #  else
4205                             /* arg is finite.  */
4206                             if (!(arg == 0.0))
4207                               abort ();
4208
4209                             pad_ptr = p;
4210
4211                             if (dp->conversion == 'f' || dp->conversion == 'F')
4212                               {
4213                                 *p++ = '0';
4214                                 if ((flags & FLAG_ALT) || precision > 0)
4215                                   {
4216                                     *p++ = decimal_point_char ();
4217                                     for (; precision > 0; precision--)
4218                                       *p++ = '0';
4219                                   }
4220                               }
4221                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4222                               {
4223                                 *p++ = '0';
4224                                 if ((flags & FLAG_ALT) || precision > 0)
4225                                   {
4226                                     *p++ = decimal_point_char ();
4227                                     for (; precision > 0; precision--)
4228                                       *p++ = '0';
4229                                   }
4230                                 *p++ = dp->conversion; /* 'e' or 'E' */
4231                                 *p++ = '+';
4232                                 /* Produce the same number of exponent digits as
4233                                    the native printf implementation.  */
4234 #   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4235                                 *p++ = '0';
4236 #   endif
4237                                 *p++ = '0';
4238                                 *p++ = '0';
4239                               }
4240                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4241                               {
4242                                 *p++ = '0';
4243                                 if (flags & FLAG_ALT)
4244                                   {
4245                                     size_t ndigits =
4246                                       (precision > 0 ? precision - 1 : 0);
4247                                     *p++ = decimal_point_char ();
4248                                     for (; ndigits > 0; --ndigits)
4249                                       *p++ = '0';
4250                                   }
4251                               }
4252                             else
4253                               abort ();
4254 #  endif
4255                           }
4256                       }
4257                   }
4258 # endif
4259
4260                 /* The generated string now extends from tmp to p, with the
4261                    zero padding insertion point being at pad_ptr.  */
4262                 if (has_width && p - tmp < width)
4263                   {
4264                     size_t pad = width - (p - tmp);
4265                     DCHAR_T *end = p + pad;
4266
4267                     if (flags & FLAG_LEFT)
4268                       {
4269                         /* Pad with spaces on the right.  */
4270                         for (; pad > 0; pad--)
4271                           *p++ = ' ';
4272                       }
4273                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4274                       {
4275                         /* Pad with zeroes.  */
4276                         DCHAR_T *q = end;
4277
4278                         while (p > pad_ptr)
4279                           *--q = *--p;
4280                         for (; pad > 0; pad--)
4281                           *p++ = '0';
4282                       }
4283                     else
4284                       {
4285                         /* Pad with spaces on the left.  */
4286                         DCHAR_T *q = end;
4287
4288                         while (p > tmp)
4289                           *--q = *--p;
4290                         for (; pad > 0; pad--)
4291                           *p++ = ' ';
4292                       }
4293
4294                     p = end;
4295                   }
4296
4297                 {
4298                   size_t count = p - tmp;
4299
4300                   if (count >= tmp_length)
4301                     /* tmp_length was incorrectly calculated - fix the
4302                        code above!  */
4303                     abort ();
4304
4305                   /* Make room for the result.  */
4306                   if (count >= allocated - length)
4307                     {
4308                       size_t n = xsum (length, count);
4309
4310                       ENSURE_ALLOCATION (n);
4311                     }
4312
4313                   /* Append the result.  */
4314                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4315                   if (tmp != tmpbuf)
4316                     free (tmp);
4317                   length += count;
4318                 }
4319               }
4320 #endif
4321             else
4322               {
4323                 arg_type type = a.arg[dp->arg_index].type;
4324                 int flags = dp->flags;
4325 #if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4326                 int has_width;
4327                 size_t width;
4328 #endif
4329 #if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4330                 int has_precision;
4331                 size_t precision;
4332 #endif
4333 #if NEED_PRINTF_UNBOUNDED_PRECISION
4334                 int prec_ourselves;
4335 #else
4336 #               define prec_ourselves 0
4337 #endif
4338 #if NEED_PRINTF_FLAG_LEFTADJUST
4339 #               define pad_ourselves 1
4340 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4341                 int pad_ourselves;
4342 #else
4343 #               define pad_ourselves 0
4344 #endif
4345                 TCHAR_T *fbp;
4346                 unsigned int prefix_count;
4347                 int prefixes[2] IF_LINT (= { 0 });
4348 #if !USE_SNPRINTF
4349                 size_t tmp_length;
4350                 TCHAR_T tmpbuf[700];
4351                 TCHAR_T *tmp;
4352 #endif
4353
4354 #if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4355                 has_width = 0;
4356                 width = 0;
4357                 if (dp->width_start != dp->width_end)
4358                   {
4359                     if (dp->width_arg_index != ARG_NONE)
4360                       {
4361                         int arg;
4362
4363                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4364                           abort ();
4365                         arg = a.arg[dp->width_arg_index].a.a_int;
4366                         if (arg < 0)
4367                           {
4368                             /* "A negative field width is taken as a '-' flag
4369                                 followed by a positive field width."  */
4370                             flags |= FLAG_LEFT;
4371                             width = (unsigned int) (-arg);
4372                           }
4373                         else
4374                           width = arg;
4375                       }
4376                     else
4377                       {
4378                         const FCHAR_T *digitp = dp->width_start;
4379
4380                         do
4381                           width = xsum (xtimes (width, 10), *digitp++ - '0');
4382                         while (digitp != dp->width_end);
4383                       }
4384                     has_width = 1;
4385                   }
4386 #endif
4387
4388 #if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4389                 has_precision = 0;
4390                 precision = 6;
4391                 if (dp->precision_start != dp->precision_end)
4392                   {
4393                     if (dp->precision_arg_index != ARG_NONE)
4394                       {
4395                         int arg;
4396
4397                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4398                           abort ();
4399                         arg = a.arg[dp->precision_arg_index].a.a_int;
4400                         /* "A negative precision is taken as if the precision
4401                             were omitted."  */
4402                         if (arg >= 0)
4403                           {
4404                             precision = arg;
4405                             has_precision = 1;
4406                           }
4407                       }
4408                     else
4409                       {
4410                         const FCHAR_T *digitp = dp->precision_start + 1;
4411
4412                         precision = 0;
4413                         while (digitp != dp->precision_end)
4414                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4415                         has_precision = 1;
4416                       }
4417                   }
4418 #endif
4419
4420                 /* Decide whether to handle the precision ourselves.  */
4421 #if NEED_PRINTF_UNBOUNDED_PRECISION
4422                 switch (dp->conversion)
4423                   {
4424                   case 'd': case 'i': case 'u':
4425                   case 'o':
4426                   case 'x': case 'X': case 'p':
4427                     prec_ourselves = has_precision && (precision > 0);
4428                     break;
4429                   default:
4430                     prec_ourselves = 0;
4431                     break;
4432                   }
4433 #endif
4434
4435                 /* Decide whether to perform the padding ourselves.  */
4436 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4437                 switch (dp->conversion)
4438                   {
4439 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4440                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4441                      to perform the padding after this conversion.  Functions
4442                      with unistdio extensions perform the padding based on
4443                      character count rather than element count.  */
4444                   case 'c': case 's':
4445 # endif
4446 # if NEED_PRINTF_FLAG_ZERO
4447                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4448                   case 'a': case 'A':
4449 # endif
4450                     pad_ourselves = 1;
4451                     break;
4452                   default:
4453                     pad_ourselves = prec_ourselves;
4454                     break;
4455                   }
4456 #endif
4457
4458 #if !USE_SNPRINTF
4459                 /* Allocate a temporary buffer of sufficient size for calling
4460                    sprintf.  */
4461                 {
4462                   switch (dp->conversion)
4463                     {
4464
4465                     case 'd': case 'i': case 'u':
4466 # if HAVE_LONG_LONG_INT
4467                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
4468                         tmp_length =
4469                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
4470                                           * 0.30103 /* binary -> decimal */
4471                                          )
4472                           + 1; /* turn floor into ceil */
4473                       else
4474 # endif
4475                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
4476                         tmp_length =
4477                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
4478                                           * 0.30103 /* binary -> decimal */
4479                                          )
4480                           + 1; /* turn floor into ceil */
4481                       else
4482                         tmp_length =
4483                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
4484                                           * 0.30103 /* binary -> decimal */
4485                                          )
4486                           + 1; /* turn floor into ceil */
4487                       if (tmp_length < precision)
4488                         tmp_length = precision;
4489                       /* Multiply by 2, as an estimate for FLAG_GROUP.  */
4490                       tmp_length = xsum (tmp_length, tmp_length);
4491                       /* Add 1, to account for a leading sign.  */
4492                       tmp_length = xsum (tmp_length, 1);
4493                       break;
4494
4495                     case 'o':
4496 # if HAVE_LONG_LONG_INT
4497                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
4498                         tmp_length =
4499                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
4500                                           * 0.333334 /* binary -> octal */
4501                                          )
4502                           + 1; /* turn floor into ceil */
4503                       else
4504 # endif
4505                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
4506                         tmp_length =
4507                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
4508                                           * 0.333334 /* binary -> octal */
4509                                          )
4510                           + 1; /* turn floor into ceil */
4511                       else
4512                         tmp_length =
4513                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
4514                                           * 0.333334 /* binary -> octal */
4515                                          )
4516                           + 1; /* turn floor into ceil */
4517                       if (tmp_length < precision)
4518                         tmp_length = precision;
4519                       /* Add 1, to account for a leading sign.  */
4520                       tmp_length = xsum (tmp_length, 1);
4521                       break;
4522
4523                     case 'x': case 'X':
4524 # if HAVE_LONG_LONG_INT
4525                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
4526                         tmp_length =
4527                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
4528                                           * 0.25 /* binary -> hexadecimal */
4529                                          )
4530                           + 1; /* turn floor into ceil */
4531                       else
4532 # endif
4533                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
4534                         tmp_length =
4535                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
4536                                           * 0.25 /* binary -> hexadecimal */
4537                                          )
4538                           + 1; /* turn floor into ceil */
4539                       else
4540                         tmp_length =
4541                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
4542                                           * 0.25 /* binary -> hexadecimal */
4543                                          )
4544                           + 1; /* turn floor into ceil */
4545                       if (tmp_length < precision)
4546                         tmp_length = precision;
4547                       /* Add 2, to account for a leading sign or alternate form.  */
4548                       tmp_length = xsum (tmp_length, 2);
4549                       break;
4550
4551                     case 'f': case 'F':
4552                       if (type == TYPE_LONGDOUBLE)
4553                         tmp_length =
4554                           (unsigned int) (LDBL_MAX_EXP
4555                                           * 0.30103 /* binary -> decimal */
4556                                           * 2 /* estimate for FLAG_GROUP */
4557                                          )
4558                           + 1 /* turn floor into ceil */
4559                           + 10; /* sign, decimal point etc. */
4560                       else
4561                         tmp_length =
4562                           (unsigned int) (DBL_MAX_EXP
4563                                           * 0.30103 /* binary -> decimal */
4564                                           * 2 /* estimate for FLAG_GROUP */
4565                                          )
4566                           + 1 /* turn floor into ceil */
4567                           + 10; /* sign, decimal point etc. */
4568                       tmp_length = xsum (tmp_length, precision);
4569                       break;
4570
4571                     case 'e': case 'E': case 'g': case 'G':
4572                       tmp_length =
4573                         12; /* sign, decimal point, exponent etc. */
4574                       tmp_length = xsum (tmp_length, precision);
4575                       break;
4576
4577                     case 'a': case 'A':
4578                       if (type == TYPE_LONGDOUBLE)
4579                         tmp_length =
4580                           (unsigned int) (LDBL_DIG
4581                                           * 0.831 /* decimal -> hexadecimal */
4582                                          )
4583                           + 1; /* turn floor into ceil */
4584                       else
4585                         tmp_length =
4586                           (unsigned int) (DBL_DIG
4587                                           * 0.831 /* decimal -> hexadecimal */
4588                                          )
4589                           + 1; /* turn floor into ceil */
4590                       if (tmp_length < precision)
4591                         tmp_length = precision;
4592                       /* Account for sign, decimal point etc. */
4593                       tmp_length = xsum (tmp_length, 12);
4594                       break;
4595
4596                     case 'c':
4597 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
4598                       if (type == TYPE_WIDE_CHAR)
4599                         tmp_length = MB_CUR_MAX;
4600                       else
4601 # endif
4602                         tmp_length = 1;
4603                       break;
4604
4605                     case 's':
4606 # if HAVE_WCHAR_T
4607                       if (type == TYPE_WIDE_STRING)
4608                         {
4609 #  if WIDE_CHAR_VERSION
4610                           /* ISO C says about %ls in fwprintf:
4611                                "If the precision is not specified or is greater
4612                                 than the size of the array, the array shall
4613                                 contain a null wide character."
4614                              So if there is a precision, we must not use
4615                              wcslen.  */
4616                           const wchar_t *arg =
4617                             a.arg[dp->arg_index].a.a_wide_string;
4618
4619                           if (has_precision)
4620                             tmp_length = local_wcsnlen (arg, precision);
4621                           else
4622                             tmp_length = local_wcslen (arg);
4623 #  else
4624                           /* ISO C says about %ls in fprintf:
4625                                "If a precision is specified, no more than that
4626                                 many bytes are written (including shift
4627                                 sequences, if any), and the array shall contain
4628                                 a null wide character if, to equal the
4629                                 multibyte character sequence length given by
4630                                 the precision, the function would need to
4631                                 access a wide character one past the end of the
4632                                 array."
4633                              So if there is a precision, we must not use
4634                              wcslen.  */
4635                           /* This case has already been handled above.  */
4636                           abort ();
4637 #  endif
4638                         }
4639                       else
4640 # endif
4641                         {
4642 # if WIDE_CHAR_VERSION
4643                           /* ISO C says about %s in fwprintf:
4644                                "If the precision is not specified or is greater
4645                                 than the size of the converted array, the
4646                                 converted array shall contain a null wide
4647                                 character."
4648                              So if there is a precision, we must not use
4649                              strlen.  */
4650                           /* This case has already been handled above.  */
4651                           abort ();
4652 # else
4653                           /* ISO C says about %s in fprintf:
4654                                "If the precision is not specified or greater
4655                                 than the size of the array, the array shall
4656                                 contain a null character."
4657                              So if there is a precision, we must not use
4658                              strlen.  */
4659                           const char *arg = a.arg[dp->arg_index].a.a_string;
4660
4661                           if (has_precision)
4662                             tmp_length = local_strnlen (arg, precision);
4663                           else
4664                             tmp_length = strlen (arg);
4665 # endif
4666                         }
4667                       break;
4668
4669                     case 'p':
4670                       tmp_length =
4671                         (unsigned int) (sizeof (void *) * CHAR_BIT
4672                                         * 0.25 /* binary -> hexadecimal */
4673                                        )
4674                           + 1 /* turn floor into ceil */
4675                           + 2; /* account for leading 0x */
4676                       break;
4677
4678                     default:
4679                       abort ();
4680                     }
4681
4682                   if (!pad_ourselves)
4683                     {
4684 # if ENABLE_UNISTDIO
4685                       /* Padding considers the number of characters, therefore
4686                          the number of elements after padding may be
4687                            > max (tmp_length, width)
4688                          but is certainly
4689                            <= tmp_length + width.  */
4690                       tmp_length = xsum (tmp_length, width);
4691 # else
4692                       /* Padding considers the number of elements,
4693                          says POSIX.  */
4694                       if (tmp_length < width)
4695                         tmp_length = width;
4696 # endif
4697                     }
4698
4699                   tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
4700                 }
4701
4702                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4703                   tmp = tmpbuf;
4704                 else
4705                   {
4706                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4707
4708                     if (size_overflow_p (tmp_memsize))
4709                       /* Overflow, would lead to out of memory.  */
4710                       goto out_of_memory;
4711                     tmp = (TCHAR_T *) malloc (tmp_memsize);
4712                     if (tmp == NULL)
4713                       /* Out of memory.  */
4714                       goto out_of_memory;
4715                   }
4716 #endif
4717
4718                 /* Construct the format string for calling snprintf or
4719                    sprintf.  */
4720                 fbp = buf;
4721                 *fbp++ = '%';
4722 #if NEED_PRINTF_FLAG_GROUPING
4723                 /* The underlying implementation doesn't support the ' flag.
4724                    Produce no grouping characters in this case; this is
4725                    acceptable because the grouping is locale dependent.  */
4726 #else
4727                 if (flags & FLAG_GROUP)
4728                   *fbp++ = '\'';
4729 #endif
4730                 if (flags & FLAG_LEFT)
4731                   *fbp++ = '-';
4732                 if (flags & FLAG_SHOWSIGN)
4733                   *fbp++ = '+';
4734                 if (flags & FLAG_SPACE)
4735                   *fbp++ = ' ';
4736                 if (flags & FLAG_ALT)
4737                   *fbp++ = '#';
4738                 if (!pad_ourselves)
4739                   {
4740                     if (flags & FLAG_ZERO)
4741                       *fbp++ = '0';
4742                     if (dp->width_start != dp->width_end)
4743                       {
4744                         size_t n = dp->width_end - dp->width_start;
4745                         /* The width specification is known to consist only
4746                            of standard ASCII characters.  */
4747                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4748                           {
4749                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4750                             fbp += n;
4751                           }
4752                         else
4753                           {
4754                             const FCHAR_T *mp = dp->width_start;
4755                             do
4756                               *fbp++ = (unsigned char) *mp++;
4757                             while (--n > 0);
4758                           }
4759                       }
4760                   }
4761                 if (!prec_ourselves)
4762                   {
4763                     if (dp->precision_start != dp->precision_end)
4764                       {
4765                         size_t n = dp->precision_end - dp->precision_start;
4766                         /* The precision specification is known to consist only
4767                            of standard ASCII characters.  */
4768                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4769                           {
4770                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4771                             fbp += n;
4772                           }
4773                         else
4774                           {
4775                             const FCHAR_T *mp = dp->precision_start;
4776                             do
4777                               *fbp++ = (unsigned char) *mp++;
4778                             while (--n > 0);
4779                           }
4780                       }
4781                   }
4782
4783                 switch (type)
4784                   {
4785 #if HAVE_LONG_LONG_INT
4786                   case TYPE_LONGLONGINT:
4787                   case TYPE_ULONGLONGINT:
4788 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4789                     *fbp++ = 'I';
4790                     *fbp++ = '6';
4791                     *fbp++ = '4';
4792                     break;
4793 # else
4794                     *fbp++ = 'l';
4795                     /*FALLTHROUGH*/
4796 # endif
4797 #endif
4798                   case TYPE_LONGINT:
4799                   case TYPE_ULONGINT:
4800 #if HAVE_WINT_T
4801                   case TYPE_WIDE_CHAR:
4802 #endif
4803 #if HAVE_WCHAR_T
4804                   case TYPE_WIDE_STRING:
4805 #endif
4806                     *fbp++ = 'l';
4807                     break;
4808                   case TYPE_LONGDOUBLE:
4809                     *fbp++ = 'L';
4810                     break;
4811                   default:
4812                     break;
4813                   }
4814 #if NEED_PRINTF_DIRECTIVE_F
4815                 if (dp->conversion == 'F')
4816                   *fbp = 'f';
4817                 else
4818 #endif
4819                   *fbp = dp->conversion;
4820 #if USE_SNPRINTF
4821 # if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4822                 fbp[1] = '%';
4823                 fbp[2] = 'n';
4824                 fbp[3] = '\0';
4825 # else
4826                 /* On glibc2 systems from glibc >= 2.3 - probably also older
4827                    ones - we know that snprintf's returns value conforms to
4828                    ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
4829                    Therefore we can avoid using %n in this situation.
4830                    On glibc2 systems from 2004-10-18 or newer, the use of %n
4831                    in format strings in writable memory may crash the program
4832                    (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4833                    in this situation.  */
4834                 /* On native Win32 systems (such as mingw), we can avoid using
4835                    %n because:
4836                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4837                        snprintf does not write more than the specified number
4838                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4839                        '4', '5', '6' into buf, not '4', '5', '\0'.)
4840                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4841                        allows us to recognize the case of an insufficient
4842                        buffer size: it returns -1 in this case.
4843                    On native Win32 systems (such as mingw) where the OS is
4844                    Windows Vista, the use of %n in format strings by default
4845                    crashes the program. See
4846                      <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4847                      <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4848                    So we should avoid %n in this situation.  */
4849                 fbp[1] = '\0';
4850 # endif
4851 #else
4852                 fbp[1] = '\0';
4853 #endif
4854
4855                 /* Construct the arguments for calling snprintf or sprintf.  */
4856                 prefix_count = 0;
4857                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4858                   {
4859                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4860                       abort ();
4861                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4862                   }
4863                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4864                   {
4865                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4866                       abort ();
4867                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4868                   }
4869
4870 #if USE_SNPRINTF
4871                 /* The SNPRINTF result is appended after result[0..length].
4872                    The latter is an array of DCHAR_T; SNPRINTF appends an
4873                    array of TCHAR_T to it.  This is possible because
4874                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4875                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
4876 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4877                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
4878                    where an snprintf() with maxlen==1 acts like sprintf().  */
4879                 ENSURE_ALLOCATION (xsum (length,
4880                                          (2 + TCHARS_PER_DCHAR - 1)
4881                                          / TCHARS_PER_DCHAR));
4882                 /* Prepare checking whether snprintf returns the count
4883                    via %n.  */
4884                 *(TCHAR_T *) (result + length) = '\0';
4885 #endif
4886
4887                 for (;;)
4888                   {
4889                     int count = -1;
4890
4891 #if USE_SNPRINTF
4892                     int retcount = 0;
4893                     size_t maxlen = allocated - length;
4894                     /* SNPRINTF can fail if its second argument is
4895                        > INT_MAX.  */
4896                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4897                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
4898                     maxlen = maxlen * TCHARS_PER_DCHAR;
4899 # define SNPRINTF_BUF(arg) \
4900                     switch (prefix_count)                                   \
4901                       {                                                     \
4902                       case 0:                                               \
4903                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4904                                              maxlen, buf,                   \
4905                                              arg, &count);                  \
4906                         break;                                              \
4907                       case 1:                                               \
4908                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4909                                              maxlen, buf,                   \
4910                                              prefixes[0], arg, &count);     \
4911                         break;                                              \
4912                       case 2:                                               \
4913                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4914                                              maxlen, buf,                   \
4915                                              prefixes[0], prefixes[1], arg, \
4916                                              &count);                       \
4917                         break;                                              \
4918                       default:                                              \
4919                         abort ();                                           \
4920                       }
4921 #else
4922 # define SNPRINTF_BUF(arg) \
4923                     switch (prefix_count)                                   \
4924                       {                                                     \
4925                       case 0:                                               \
4926                         count = sprintf (tmp, buf, arg);                    \
4927                         break;                                              \
4928                       case 1:                                               \
4929                         count = sprintf (tmp, buf, prefixes[0], arg);       \
4930                         break;                                              \
4931                       case 2:                                               \
4932                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4933                                          arg);                              \
4934                         break;                                              \
4935                       default:                                              \
4936                         abort ();                                           \
4937                       }
4938 #endif
4939
4940                     switch (type)
4941                       {
4942                       case TYPE_SCHAR:
4943                         {
4944                           int arg = a.arg[dp->arg_index].a.a_schar;
4945                           SNPRINTF_BUF (arg);
4946                         }
4947                         break;
4948                       case TYPE_UCHAR:
4949                         {
4950                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4951                           SNPRINTF_BUF (arg);
4952                         }
4953                         break;
4954                       case TYPE_SHORT:
4955                         {
4956                           int arg = a.arg[dp->arg_index].a.a_short;
4957                           SNPRINTF_BUF (arg);
4958                         }
4959                         break;
4960                       case TYPE_USHORT:
4961                         {
4962                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
4963                           SNPRINTF_BUF (arg);
4964                         }
4965                         break;
4966                       case TYPE_INT:
4967                         {
4968                           int arg = a.arg[dp->arg_index].a.a_int;
4969                           SNPRINTF_BUF (arg);
4970                         }
4971                         break;
4972                       case TYPE_UINT:
4973                         {
4974                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
4975                           SNPRINTF_BUF (arg);
4976                         }
4977                         break;
4978                       case TYPE_LONGINT:
4979                         {
4980                           long int arg = a.arg[dp->arg_index].a.a_longint;
4981                           SNPRINTF_BUF (arg);
4982                         }
4983                         break;
4984                       case TYPE_ULONGINT:
4985                         {
4986                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
4987                           SNPRINTF_BUF (arg);
4988                         }
4989                         break;
4990 #if HAVE_LONG_LONG_INT
4991                       case TYPE_LONGLONGINT:
4992                         {
4993                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
4994                           SNPRINTF_BUF (arg);
4995                         }
4996                         break;
4997                       case TYPE_ULONGLONGINT:
4998                         {
4999                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5000                           SNPRINTF_BUF (arg);
5001                         }
5002                         break;
5003 #endif
5004                       case TYPE_DOUBLE:
5005                         {
5006                           double arg = a.arg[dp->arg_index].a.a_double;
5007                           SNPRINTF_BUF (arg);
5008                         }
5009                         break;
5010                       case TYPE_LONGDOUBLE:
5011                         {
5012                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
5013                           SNPRINTF_BUF (arg);
5014                         }
5015                         break;
5016                       case TYPE_CHAR:
5017                         {
5018                           int arg = a.arg[dp->arg_index].a.a_char;
5019                           SNPRINTF_BUF (arg);
5020                         }
5021                         break;
5022 #if HAVE_WINT_T
5023                       case TYPE_WIDE_CHAR:
5024                         {
5025                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5026                           SNPRINTF_BUF (arg);
5027                         }
5028                         break;
5029 #endif
5030                       case TYPE_STRING:
5031                         {
5032                           const char *arg = a.arg[dp->arg_index].a.a_string;
5033                           SNPRINTF_BUF (arg);
5034                         }
5035                         break;
5036 #if HAVE_WCHAR_T
5037                       case TYPE_WIDE_STRING:
5038                         {
5039                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5040                           SNPRINTF_BUF (arg);
5041                         }
5042                         break;
5043 #endif
5044                       case TYPE_POINTER:
5045                         {
5046                           void *arg = a.arg[dp->arg_index].a.a_pointer;
5047                           SNPRINTF_BUF (arg);
5048                         }
5049                         break;
5050                       default:
5051                         abort ();
5052                       }
5053
5054 #if USE_SNPRINTF
5055                     /* Portability: Not all implementations of snprintf()
5056                        are ISO C 99 compliant.  Determine the number of
5057                        bytes that snprintf() has produced or would have
5058                        produced.  */
5059                     if (count >= 0)
5060                       {
5061                         /* Verify that snprintf() has NUL-terminated its
5062                            result.  */
5063                         if (count < maxlen
5064                             && ((TCHAR_T *) (result + length)) [count] != '\0')
5065                           abort ();
5066                         /* Portability hack.  */
5067                         if (retcount > count)
5068                           count = retcount;
5069                       }
5070                     else
5071                       {
5072                         /* snprintf() doesn't understand the '%n'
5073                            directive.  */
5074                         if (fbp[1] != '\0')
5075                           {
5076                             /* Don't use the '%n' directive; instead, look
5077                                at the snprintf() return value.  */
5078                             fbp[1] = '\0';
5079                             continue;
5080                           }
5081                         else
5082                           {
5083                             /* Look at the snprintf() return value.  */
5084                             if (retcount < 0)
5085                               {
5086                                 /* HP-UX 10.20 snprintf() is doubly deficient:
5087                                    It doesn't understand the '%n' directive,
5088                                    *and* it returns -1 (rather than the length
5089                                    that would have been required) when the
5090                                    buffer is too small.  */
5091                                 size_t bigger_need =
5092                                   xsum (xtimes (allocated, 2), 12);
5093                                 ENSURE_ALLOCATION (bigger_need);
5094                                 continue;
5095                               }
5096                             else
5097                               count = retcount;
5098                           }
5099                       }
5100 #endif
5101
5102                     /* Attempt to handle failure.  */
5103                     if (count < 0)
5104                       {
5105                         if (!(result == resultbuf || result == NULL))
5106                           free (result);
5107                         if (buf_malloced != NULL)
5108                           free (buf_malloced);
5109                         CLEANUP ();
5110                         errno = EINVAL;
5111                         return NULL;
5112                       }
5113
5114 #if USE_SNPRINTF
5115                     /* Handle overflow of the allocated buffer.
5116                        If such an overflow occurs, a C99 compliant snprintf()
5117                        returns a count >= maxlen.  However, a non-compliant
5118                        snprintf() function returns only count = maxlen - 1.  To
5119                        cover both cases, test whether count >= maxlen - 1.  */
5120                     if ((unsigned int) count + 1 >= maxlen)
5121                       {
5122                         /* If maxlen already has attained its allowed maximum,
5123                            allocating more memory will not increase maxlen.
5124                            Instead of looping, bail out.  */
5125                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5126                           goto overflow;
5127                         else
5128                           {
5129                             /* Need at least (count + 1) * sizeof (TCHAR_T)
5130                                bytes.  (The +1 is for the trailing NUL.)
5131                                But ask for (count + 2) * sizeof (TCHAR_T)
5132                                bytes, so that in the next round, we likely get
5133                                  maxlen > (unsigned int) count + 1
5134                                and so we don't get here again.
5135                                And allocate proportionally, to avoid looping
5136                                eternally if snprintf() reports a too small
5137                                count.  */
5138                             size_t n =
5139                               xmax (xsum (length,
5140                                           ((unsigned int) count + 2
5141                                            + TCHARS_PER_DCHAR - 1)
5142                                           / TCHARS_PER_DCHAR),
5143                                     xtimes (allocated, 2));
5144
5145                             ENSURE_ALLOCATION (n);
5146                             continue;
5147                           }
5148                       }
5149 #endif
5150
5151 #if NEED_PRINTF_UNBOUNDED_PRECISION
5152                     if (prec_ourselves)
5153                       {
5154                         /* Handle the precision.  */
5155                         TCHAR_T *prec_ptr =
5156 # if USE_SNPRINTF
5157                           (TCHAR_T *) (result + length);
5158 # else
5159                           tmp;
5160 # endif
5161                         size_t prefix_count;
5162                         size_t move;
5163
5164                         prefix_count = 0;
5165                         /* Put the additional zeroes after the sign.  */
5166                         if (count >= 1
5167                             && (*prec_ptr == '-' || *prec_ptr == '+'
5168                                 || *prec_ptr == ' '))
5169                           prefix_count = 1;
5170                         /* Put the additional zeroes after the 0x prefix if
5171                            (flags & FLAG_ALT) || (dp->conversion == 'p').  */
5172                         else if (count >= 2
5173                                  && prec_ptr[0] == '0'
5174                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5175                           prefix_count = 2;
5176
5177                         move = count - prefix_count;
5178                         if (precision > move)
5179                           {
5180                             /* Insert zeroes.  */
5181                             size_t insert = precision - move;
5182                             TCHAR_T *prec_end;
5183
5184 # if USE_SNPRINTF
5185                             size_t n =
5186                               xsum (length,
5187                                     (count + insert + TCHARS_PER_DCHAR - 1)
5188                                     / TCHARS_PER_DCHAR);
5189                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5190                             ENSURE_ALLOCATION (n);
5191                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5192                             prec_ptr = (TCHAR_T *) (result + length);
5193 # endif
5194
5195                             prec_end = prec_ptr + count;
5196                             prec_ptr += prefix_count;
5197
5198                             while (prec_end > prec_ptr)
5199                               {
5200                                 prec_end--;
5201                                 prec_end[insert] = prec_end[0];
5202                               }
5203
5204                             prec_end += insert;
5205                             do
5206                               *--prec_end = '0';
5207                             while (prec_end > prec_ptr);
5208
5209                             count += insert;
5210                           }
5211                       }
5212 #endif
5213
5214 #if !USE_SNPRINTF
5215                     if (count >= tmp_length)
5216                       /* tmp_length was incorrectly calculated - fix the
5217                          code above!  */
5218                       abort ();
5219 #endif
5220
5221 #if !DCHAR_IS_TCHAR
5222                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
5223                     if (dp->conversion == 'c' || dp->conversion == 's')
5224                       {
5225                         /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5226                            TYPE_WIDE_STRING.
5227                            The result string is not certainly ASCII.  */
5228                         const TCHAR_T *tmpsrc;
5229                         DCHAR_T *tmpdst;
5230                         size_t tmpdst_len;
5231                         /* This code assumes that TCHAR_T is 'char'.  */
5232                         typedef int TCHAR_T_verify
5233                                     [2 * (sizeof (TCHAR_T) == 1) - 1];
5234 # if USE_SNPRINTF
5235                         tmpsrc = (TCHAR_T *) (result + length);
5236 # else
5237                         tmpsrc = tmp;
5238 # endif
5239                         tmpdst =
5240                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
5241                                                     iconveh_question_mark,
5242                                                     tmpsrc, count,
5243                                                     NULL,
5244                                                     NULL, &tmpdst_len);
5245                         if (tmpdst == NULL)
5246                           {
5247                             int saved_errno = errno;
5248                             if (!(result == resultbuf || result == NULL))
5249                               free (result);
5250                             if (buf_malloced != NULL)
5251                               free (buf_malloced);
5252                             CLEANUP ();
5253                             errno = saved_errno;
5254                             return NULL;
5255                           }
5256                         ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5257                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5258                         free (tmpdst);
5259                         count = tmpdst_len;
5260                       }
5261                     else
5262                       {
5263                         /* The result string is ASCII.
5264                            Simple 1:1 conversion.  */
5265 # if USE_SNPRINTF
5266                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5267                            no-op conversion, in-place on the array starting
5268                            at (result + length).  */
5269                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5270 # endif
5271                           {
5272                             const TCHAR_T *tmpsrc;
5273                             DCHAR_T *tmpdst;
5274                             size_t n;
5275
5276 # if USE_SNPRINTF
5277                             if (result == resultbuf)
5278                               {
5279                                 tmpsrc = (TCHAR_T *) (result + length);
5280                                 /* ENSURE_ALLOCATION will not move tmpsrc
5281                                    (because it's part of resultbuf).  */
5282                                 ENSURE_ALLOCATION (xsum (length, count));
5283                               }
5284                             else
5285                               {
5286                                 /* ENSURE_ALLOCATION will move the array
5287                                    (because it uses realloc().  */
5288                                 ENSURE_ALLOCATION (xsum (length, count));
5289                                 tmpsrc = (TCHAR_T *) (result + length);
5290                               }
5291 # else
5292                             tmpsrc = tmp;
5293                             ENSURE_ALLOCATION (xsum (length, count));
5294 # endif
5295                             tmpdst = result + length;
5296                             /* Copy backwards, because of overlapping.  */
5297                             tmpsrc += count;
5298                             tmpdst += count;
5299                             for (n = count; n > 0; n--)
5300                               *--tmpdst = (unsigned char) *--tmpsrc;
5301                           }
5302                       }
5303 #endif
5304
5305 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5306                     /* Make room for the result.  */
5307                     if (count > allocated - length)
5308                       {
5309                         /* Need at least count elements.  But allocate
5310                            proportionally.  */
5311                         size_t n =
5312                           xmax (xsum (length, count), xtimes (allocated, 2));
5313
5314                         ENSURE_ALLOCATION (n);
5315                       }
5316 #endif
5317
5318                     /* Here count <= allocated - length.  */
5319
5320                     /* Perform padding.  */
5321 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5322                     if (pad_ourselves && has_width)
5323                       {
5324                         size_t w;
5325 # if ENABLE_UNISTDIO
5326                         /* Outside POSIX, it's preferrable to compare the width
5327                            against the number of _characters_ of the converted
5328                            value.  */
5329                         w = DCHAR_MBSNLEN (result + length, count);
5330 # else
5331                         /* The width is compared against the number of _bytes_
5332                            of the converted value, says POSIX.  */
5333                         w = count;
5334 # endif
5335                         if (w < width)
5336                           {
5337                             size_t pad = width - w;
5338
5339                             /* Make room for the result.  */
5340                             if (xsum (count, pad) > allocated - length)
5341                               {
5342                                 /* Need at least count + pad elements.  But
5343                                    allocate proportionally.  */
5344                                 size_t n =
5345                                   xmax (xsum3 (length, count, pad),
5346                                         xtimes (allocated, 2));
5347
5348 # if USE_SNPRINTF
5349                                 length += count;
5350                                 ENSURE_ALLOCATION (n);
5351                                 length -= count;
5352 # else
5353                                 ENSURE_ALLOCATION (n);
5354 # endif
5355                               }
5356                             /* Here count + pad <= allocated - length.  */
5357
5358                             {
5359 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5360                               DCHAR_T * const rp = result + length;
5361 # else
5362                               DCHAR_T * const rp = tmp;
5363 # endif
5364                               DCHAR_T *p = rp + count;
5365                               DCHAR_T *end = p + pad;
5366                               DCHAR_T *pad_ptr;
5367 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5368                               if (dp->conversion == 'c'
5369                                   || dp->conversion == 's')
5370                                 /* No zero-padding for string directives.  */
5371                                 pad_ptr = NULL;
5372                               else
5373 # endif
5374                                 {
5375                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
5376                                   /* No zero-padding of "inf" and "nan".  */
5377                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5378                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5379                                     pad_ptr = NULL;
5380                                 }
5381                               /* The generated string now extends from rp to p,
5382                                  with the zero padding insertion point being at
5383                                  pad_ptr.  */
5384
5385                               count = count + pad; /* = end - rp */
5386
5387                               if (flags & FLAG_LEFT)
5388                                 {
5389                                   /* Pad with spaces on the right.  */
5390                                   for (; pad > 0; pad--)
5391                                     *p++ = ' ';
5392                                 }
5393                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5394                                 {
5395                                   /* Pad with zeroes.  */
5396                                   DCHAR_T *q = end;
5397
5398                                   while (p > pad_ptr)
5399                                     *--q = *--p;
5400                                   for (; pad > 0; pad--)
5401                                     *p++ = '0';
5402                                 }
5403                               else
5404                                 {
5405                                   /* Pad with spaces on the left.  */
5406                                   DCHAR_T *q = end;
5407
5408                                   while (p > rp)
5409                                     *--q = *--p;
5410                                   for (; pad > 0; pad--)
5411                                     *p++ = ' ';
5412                                 }
5413                             }
5414                           }
5415                       }
5416 #endif
5417
5418                     /* Here still count <= allocated - length.  */
5419
5420 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5421                     /* The snprintf() result did fit.  */
5422 #else
5423                     /* Append the sprintf() result.  */
5424                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5425 #endif
5426 #if !USE_SNPRINTF
5427                     if (tmp != tmpbuf)
5428                       free (tmp);
5429 #endif
5430
5431 #if NEED_PRINTF_DIRECTIVE_F
5432                     if (dp->conversion == 'F')
5433                       {
5434                         /* Convert the %f result to upper case for %F.  */
5435                         DCHAR_T *rp = result + length;
5436                         size_t rc;
5437                         for (rc = count; rc > 0; rc--, rp++)
5438                           if (*rp >= 'a' && *rp <= 'z')
5439                             *rp = *rp - 'a' + 'A';
5440                       }
5441 #endif
5442
5443                     length += count;
5444                     break;
5445                   }
5446               }
5447           }
5448       }
5449
5450     /* Add the final NUL.  */
5451     ENSURE_ALLOCATION (xsum (length, 1));
5452     result[length] = '\0';
5453
5454     if (result != resultbuf && length + 1 < allocated)
5455       {
5456         /* Shrink the allocated memory if possible.  */
5457         DCHAR_T *memory;
5458
5459         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5460         if (memory != NULL)
5461           result = memory;
5462       }
5463
5464     if (buf_malloced != NULL)
5465       free (buf_malloced);
5466     CLEANUP ();
5467     *lengthp = length;
5468     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
5469        says that snprintf() fails with errno = EOVERFLOW in this case, but
5470        that's only because snprintf() returns an 'int'.  This function does
5471        not have this limitation.  */
5472     return result;
5473
5474 #if USE_SNPRINTF
5475   overflow:
5476     if (!(result == resultbuf || result == NULL))
5477       free (result);
5478     if (buf_malloced != NULL)
5479       free (buf_malloced);
5480     CLEANUP ();
5481     errno = EOVERFLOW;
5482     return NULL;
5483 #endif
5484
5485   out_of_memory:
5486     if (!(result == resultbuf || result == NULL))
5487       free (result);
5488     if (buf_malloced != NULL)
5489       free (buf_malloced);
5490   out_of_memory_1:
5491     CLEANUP ();
5492     errno = ENOMEM;
5493     return NULL;
5494   }
5495 }
5496
5497 #undef TCHARS_PER_DCHAR
5498 #undef SNPRINTF
5499 #undef USE_SNPRINTF
5500 #undef DCHAR_SET
5501 #undef DCHAR_CPY
5502 #undef PRINTF_PARSE
5503 #undef DIRECTIVES
5504 #undef DIRECTIVE
5505 #undef DCHAR_IS_TCHAR
5506 #undef TCHAR_T
5507 #undef DCHAR_T
5508 #undef FCHAR_T
5509 #undef VASNPRINTF