vasnprintf: Fix multiple test failures on mingw.
[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                             /* Inconsistency.  */
2609                             abort ();
2610                           ENSURE_ALLOCATION (xsum (length, count));
2611                           memcpy (result + length, cbuf, count);
2612                           length += count;
2613                           arg++;
2614                         }
2615                     }
2616 #  else
2617                   ENSURE_ALLOCATION (xsum (length, tmpdst_len));
2618                   DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2619                   free (tmpdst);
2620                   length += tmpdst_len;
2621 #  endif
2622
2623                   if (has_width && width > w
2624                       && (dp->flags & FLAG_LEFT))
2625                     {
2626                       size_t n = width - w;
2627                       ENSURE_ALLOCATION (xsum (length, n));
2628                       DCHAR_SET (result + length, ' ', n);
2629                       length += n;
2630                     }
2631                 }
2632               }
2633 # endif
2634 #endif
2635 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2636             else if ((dp->conversion == 'a' || dp->conversion == 'A')
2637 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2638                      && (0
2639 #  if NEED_PRINTF_DOUBLE
2640                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
2641 #  endif
2642 #  if NEED_PRINTF_LONG_DOUBLE
2643                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2644 #  endif
2645                         )
2646 # endif
2647                     )
2648               {
2649                 arg_type type = a.arg[dp->arg_index].type;
2650                 int flags = dp->flags;
2651                 int has_width;
2652                 size_t width;
2653                 int has_precision;
2654                 size_t precision;
2655                 size_t tmp_length;
2656                 DCHAR_T tmpbuf[700];
2657                 DCHAR_T *tmp;
2658                 DCHAR_T *pad_ptr;
2659                 DCHAR_T *p;
2660
2661                 has_width = 0;
2662                 width = 0;
2663                 if (dp->width_start != dp->width_end)
2664                   {
2665                     if (dp->width_arg_index != ARG_NONE)
2666                       {
2667                         int arg;
2668
2669                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2670                           abort ();
2671                         arg = a.arg[dp->width_arg_index].a.a_int;
2672                         if (arg < 0)
2673                           {
2674                             /* "A negative field width is taken as a '-' flag
2675                                 followed by a positive field width."  */
2676                             flags |= FLAG_LEFT;
2677                             width = (unsigned int) (-arg);
2678                           }
2679                         else
2680                           width = arg;
2681                       }
2682                     else
2683                       {
2684                         const FCHAR_T *digitp = dp->width_start;
2685
2686                         do
2687                           width = xsum (xtimes (width, 10), *digitp++ - '0');
2688                         while (digitp != dp->width_end);
2689                       }
2690                     has_width = 1;
2691                   }
2692
2693                 has_precision = 0;
2694                 precision = 0;
2695                 if (dp->precision_start != dp->precision_end)
2696                   {
2697                     if (dp->precision_arg_index != ARG_NONE)
2698                       {
2699                         int arg;
2700
2701                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2702                           abort ();
2703                         arg = a.arg[dp->precision_arg_index].a.a_int;
2704                         /* "A negative precision is taken as if the precision
2705                             were omitted."  */
2706                         if (arg >= 0)
2707                           {
2708                             precision = arg;
2709                             has_precision = 1;
2710                           }
2711                       }
2712                     else
2713                       {
2714                         const FCHAR_T *digitp = dp->precision_start + 1;
2715
2716                         precision = 0;
2717                         while (digitp != dp->precision_end)
2718                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2719                         has_precision = 1;
2720                       }
2721                   }
2722
2723                 /* Allocate a temporary buffer of sufficient size.  */
2724                 if (type == TYPE_LONGDOUBLE)
2725                   tmp_length =
2726                     (unsigned int) ((LDBL_DIG + 1)
2727                                     * 0.831 /* decimal -> hexadecimal */
2728                                    )
2729                     + 1; /* turn floor into ceil */
2730                 else
2731                   tmp_length =
2732                     (unsigned int) ((DBL_DIG + 1)
2733                                     * 0.831 /* decimal -> hexadecimal */
2734                                    )
2735                     + 1; /* turn floor into ceil */
2736                 if (tmp_length < precision)
2737                   tmp_length = precision;
2738                 /* Account for sign, decimal point etc. */
2739                 tmp_length = xsum (tmp_length, 12);
2740
2741                 if (tmp_length < width)
2742                   tmp_length = width;
2743
2744                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2745
2746                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
2747                   tmp = tmpbuf;
2748                 else
2749                   {
2750                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
2751
2752                     if (size_overflow_p (tmp_memsize))
2753                       /* Overflow, would lead to out of memory.  */
2754                       goto out_of_memory;
2755                     tmp = (DCHAR_T *) malloc (tmp_memsize);
2756                     if (tmp == NULL)
2757                       /* Out of memory.  */
2758                       goto out_of_memory;
2759                   }
2760
2761                 pad_ptr = NULL;
2762                 p = tmp;
2763                 if (type == TYPE_LONGDOUBLE)
2764                   {
2765 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
2766                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
2767
2768                     if (isnanl (arg))
2769                       {
2770                         if (dp->conversion == 'A')
2771                           {
2772                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2773                           }
2774                         else
2775                           {
2776                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2777                           }
2778                       }
2779                     else
2780                       {
2781                         int sign = 0;
2782                         DECL_LONG_DOUBLE_ROUNDING
2783
2784                         BEGIN_LONG_DOUBLE_ROUNDING ();
2785
2786                         if (signbit (arg)) /* arg < 0.0L or negative zero */
2787                           {
2788                             sign = -1;
2789                             arg = -arg;
2790                           }
2791
2792                         if (sign < 0)
2793                           *p++ = '-';
2794                         else if (flags & FLAG_SHOWSIGN)
2795                           *p++ = '+';
2796                         else if (flags & FLAG_SPACE)
2797                           *p++ = ' ';
2798
2799                         if (arg > 0.0L && arg + arg == arg)
2800                           {
2801                             if (dp->conversion == 'A')
2802                               {
2803                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2804                               }
2805                             else
2806                               {
2807                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2808                               }
2809                           }
2810                         else
2811                           {
2812                             int exponent;
2813                             long double mantissa;
2814
2815                             if (arg > 0.0L)
2816                               mantissa = printf_frexpl (arg, &exponent);
2817                             else
2818                               {
2819                                 exponent = 0;
2820                                 mantissa = 0.0L;
2821                               }
2822
2823                             if (has_precision
2824                                 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
2825                               {
2826                                 /* Round the mantissa.  */
2827                                 long double tail = mantissa;
2828                                 size_t q;
2829
2830                                 for (q = precision; ; q--)
2831                                   {
2832                                     int digit = (int) tail;
2833                                     tail -= digit;
2834                                     if (q == 0)
2835                                       {
2836                                         if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
2837                                           tail = 1 - tail;
2838                                         else
2839                                           tail = - tail;
2840                                         break;
2841                                       }
2842                                     tail *= 16.0L;
2843                                   }
2844                                 if (tail != 0.0L)
2845                                   for (q = precision; q > 0; q--)
2846                                     tail *= 0.0625L;
2847                                 mantissa += tail;
2848                               }
2849
2850                             *p++ = '0';
2851                             *p++ = dp->conversion - 'A' + 'X';
2852                             pad_ptr = p;
2853                             {
2854                               int digit;
2855
2856                               digit = (int) mantissa;
2857                               mantissa -= digit;
2858                               *p++ = '0' + digit;
2859                               if ((flags & FLAG_ALT)
2860                                   || mantissa > 0.0L || precision > 0)
2861                                 {
2862                                   *p++ = decimal_point_char ();
2863                                   /* This loop terminates because we assume
2864                                      that FLT_RADIX is a power of 2.  */
2865                                   while (mantissa > 0.0L)
2866                                     {
2867                                       mantissa *= 16.0L;
2868                                       digit = (int) mantissa;
2869                                       mantissa -= digit;
2870                                       *p++ = digit
2871                                              + (digit < 10
2872                                                 ? '0'
2873                                                 : dp->conversion - 10);
2874                                       if (precision > 0)
2875                                         precision--;
2876                                     }
2877                                   while (precision > 0)
2878                                     {
2879                                       *p++ = '0';
2880                                       precision--;
2881                                     }
2882                                 }
2883                               }
2884                               *p++ = dp->conversion - 'A' + 'P';
2885 #  if WIDE_CHAR_VERSION
2886                               {
2887                                 static const wchar_t decimal_format[] =
2888                                   { '%', '+', 'd', '\0' };
2889                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
2890                               }
2891                               while (*p != '\0')
2892                                 p++;
2893 #  else
2894                               if (sizeof (DCHAR_T) == 1)
2895                                 {
2896                                   sprintf ((char *) p, "%+d", exponent);
2897                                   while (*p != '\0')
2898                                     p++;
2899                                 }
2900                               else
2901                                 {
2902                                   char expbuf[6 + 1];
2903                                   const char *ep;
2904                                   sprintf (expbuf, "%+d", exponent);
2905                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2906                                     p++;
2907                                 }
2908 #  endif
2909                           }
2910
2911                         END_LONG_DOUBLE_ROUNDING ();
2912                       }
2913 # else
2914                     abort ();
2915 # endif
2916                   }
2917                 else
2918                   {
2919 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
2920                     double arg = a.arg[dp->arg_index].a.a_double;
2921
2922                     if (isnand (arg))
2923                       {
2924                         if (dp->conversion == 'A')
2925                           {
2926                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
2927                           }
2928                         else
2929                           {
2930                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
2931                           }
2932                       }
2933                     else
2934                       {
2935                         int sign = 0;
2936
2937                         if (signbit (arg)) /* arg < 0.0 or negative zero */
2938                           {
2939                             sign = -1;
2940                             arg = -arg;
2941                           }
2942
2943                         if (sign < 0)
2944                           *p++ = '-';
2945                         else if (flags & FLAG_SHOWSIGN)
2946                           *p++ = '+';
2947                         else if (flags & FLAG_SPACE)
2948                           *p++ = ' ';
2949
2950                         if (arg > 0.0 && arg + arg == arg)
2951                           {
2952                             if (dp->conversion == 'A')
2953                               {
2954                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
2955                               }
2956                             else
2957                               {
2958                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
2959                               }
2960                           }
2961                         else
2962                           {
2963                             int exponent;
2964                             double mantissa;
2965
2966                             if (arg > 0.0)
2967                               mantissa = printf_frexp (arg, &exponent);
2968                             else
2969                               {
2970                                 exponent = 0;
2971                                 mantissa = 0.0;
2972                               }
2973
2974                             if (has_precision
2975                                 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
2976                               {
2977                                 /* Round the mantissa.  */
2978                                 double tail = mantissa;
2979                                 size_t q;
2980
2981                                 for (q = precision; ; q--)
2982                                   {
2983                                     int digit = (int) tail;
2984                                     tail -= digit;
2985                                     if (q == 0)
2986                                       {
2987                                         if (digit & 1 ? tail >= 0.5 : tail > 0.5)
2988                                           tail = 1 - tail;
2989                                         else
2990                                           tail = - tail;
2991                                         break;
2992                                       }
2993                                     tail *= 16.0;
2994                                   }
2995                                 if (tail != 0.0)
2996                                   for (q = precision; q > 0; q--)
2997                                     tail *= 0.0625;
2998                                 mantissa += tail;
2999                               }
3000
3001                             *p++ = '0';
3002                             *p++ = dp->conversion - 'A' + 'X';
3003                             pad_ptr = p;
3004                             {
3005                               int digit;
3006
3007                               digit = (int) mantissa;
3008                               mantissa -= digit;
3009                               *p++ = '0' + digit;
3010                               if ((flags & FLAG_ALT)
3011                                   || mantissa > 0.0 || precision > 0)
3012                                 {
3013                                   *p++ = decimal_point_char ();
3014                                   /* This loop terminates because we assume
3015                                      that FLT_RADIX is a power of 2.  */
3016                                   while (mantissa > 0.0)
3017                                     {
3018                                       mantissa *= 16.0;
3019                                       digit = (int) mantissa;
3020                                       mantissa -= digit;
3021                                       *p++ = digit
3022                                              + (digit < 10
3023                                                 ? '0'
3024                                                 : dp->conversion - 10);
3025                                       if (precision > 0)
3026                                         precision--;
3027                                     }
3028                                   while (precision > 0)
3029                                     {
3030                                       *p++ = '0';
3031                                       precision--;
3032                                     }
3033                                 }
3034                               }
3035                               *p++ = dp->conversion - 'A' + 'P';
3036 #  if WIDE_CHAR_VERSION
3037                               {
3038                                 static const wchar_t decimal_format[] =
3039                                   { '%', '+', 'd', '\0' };
3040                                 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3041                               }
3042                               while (*p != '\0')
3043                                 p++;
3044 #  else
3045                               if (sizeof (DCHAR_T) == 1)
3046                                 {
3047                                   sprintf ((char *) p, "%+d", exponent);
3048                                   while (*p != '\0')
3049                                     p++;
3050                                 }
3051                               else
3052                                 {
3053                                   char expbuf[6 + 1];
3054                                   const char *ep;
3055                                   sprintf (expbuf, "%+d", exponent);
3056                                   for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3057                                     p++;
3058                                 }
3059 #  endif
3060                           }
3061                       }
3062 # else
3063                     abort ();
3064 # endif
3065                   }
3066                 /* The generated string now extends from tmp to p, with the
3067                    zero padding insertion point being at pad_ptr.  */
3068                 if (has_width && p - tmp < width)
3069                   {
3070                     size_t pad = width - (p - tmp);
3071                     DCHAR_T *end = p + pad;
3072
3073                     if (flags & FLAG_LEFT)
3074                       {
3075                         /* Pad with spaces on the right.  */
3076                         for (; pad > 0; pad--)
3077                           *p++ = ' ';
3078                       }
3079                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3080                       {
3081                         /* Pad with zeroes.  */
3082                         DCHAR_T *q = end;
3083
3084                         while (p > pad_ptr)
3085                           *--q = *--p;
3086                         for (; pad > 0; pad--)
3087                           *p++ = '0';
3088                       }
3089                     else
3090                       {
3091                         /* Pad with spaces on the left.  */
3092                         DCHAR_T *q = end;
3093
3094                         while (p > tmp)
3095                           *--q = *--p;
3096                         for (; pad > 0; pad--)
3097                           *p++ = ' ';
3098                       }
3099
3100                     p = end;
3101                   }
3102
3103                 {
3104                   size_t count = p - tmp;
3105
3106                   if (count >= tmp_length)
3107                     /* tmp_length was incorrectly calculated - fix the
3108                        code above!  */
3109                     abort ();
3110
3111                   /* Make room for the result.  */
3112                   if (count >= allocated - length)
3113                     {
3114                       size_t n = xsum (length, count);
3115
3116                       ENSURE_ALLOCATION (n);
3117                     }
3118
3119                   /* Append the result.  */
3120                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3121                   if (tmp != tmpbuf)
3122                     free (tmp);
3123                   length += count;
3124                 }
3125               }
3126 #endif
3127 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3128             else if ((dp->conversion == 'f' || dp->conversion == 'F'
3129                       || dp->conversion == 'e' || dp->conversion == 'E'
3130                       || dp->conversion == 'g' || dp->conversion == 'G'
3131                       || dp->conversion == 'a' || dp->conversion == 'A')
3132                      && (0
3133 # if NEED_PRINTF_DOUBLE
3134                          || a.arg[dp->arg_index].type == TYPE_DOUBLE
3135 # elif NEED_PRINTF_INFINITE_DOUBLE
3136                          || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3137                              /* The systems (mingw) which produce wrong output
3138                                 for Inf, -Inf, and NaN also do so for -0.0.
3139                                 Therefore we treat this case here as well.  */
3140                              && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3141 # endif
3142 # if NEED_PRINTF_LONG_DOUBLE
3143                          || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3144 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3145                          || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3146                              /* Some systems produce wrong output for Inf,
3147                                 -Inf, and NaN.  Some systems in this category
3148                                 (IRIX 5.3) also do so for -0.0.  Therefore we
3149                                 treat this case here as well.  */
3150                              && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3151 # endif
3152                         ))
3153               {
3154 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3155                 arg_type type = a.arg[dp->arg_index].type;
3156 # endif
3157                 int flags = dp->flags;
3158                 int has_width;
3159                 size_t width;
3160                 int has_precision;
3161                 size_t precision;
3162                 size_t tmp_length;
3163                 DCHAR_T tmpbuf[700];
3164                 DCHAR_T *tmp;
3165                 DCHAR_T *pad_ptr;
3166                 DCHAR_T *p;
3167
3168                 has_width = 0;
3169                 width = 0;
3170                 if (dp->width_start != dp->width_end)
3171                   {
3172                     if (dp->width_arg_index != ARG_NONE)
3173                       {
3174                         int arg;
3175
3176                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3177                           abort ();
3178                         arg = a.arg[dp->width_arg_index].a.a_int;
3179                         if (arg < 0)
3180                           {
3181                             /* "A negative field width is taken as a '-' flag
3182                                 followed by a positive field width."  */
3183                             flags |= FLAG_LEFT;
3184                             width = (unsigned int) (-arg);
3185                           }
3186                         else
3187                           width = arg;
3188                       }
3189                     else
3190                       {
3191                         const FCHAR_T *digitp = dp->width_start;
3192
3193                         do
3194                           width = xsum (xtimes (width, 10), *digitp++ - '0');
3195                         while (digitp != dp->width_end);
3196                       }
3197                     has_width = 1;
3198                   }
3199
3200                 has_precision = 0;
3201                 precision = 0;
3202                 if (dp->precision_start != dp->precision_end)
3203                   {
3204                     if (dp->precision_arg_index != ARG_NONE)
3205                       {
3206                         int arg;
3207
3208                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3209                           abort ();
3210                         arg = a.arg[dp->precision_arg_index].a.a_int;
3211                         /* "A negative precision is taken as if the precision
3212                             were omitted."  */
3213                         if (arg >= 0)
3214                           {
3215                             precision = arg;
3216                             has_precision = 1;
3217                           }
3218                       }
3219                     else
3220                       {
3221                         const FCHAR_T *digitp = dp->precision_start + 1;
3222
3223                         precision = 0;
3224                         while (digitp != dp->precision_end)
3225                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3226                         has_precision = 1;
3227                       }
3228                   }
3229
3230                 /* POSIX specifies the default precision to be 6 for %f, %F,
3231                    %e, %E, but not for %g, %G.  Implementations appear to use
3232                    the same default precision also for %g, %G.  But for %a, %A,
3233                    the default precision is 0.  */
3234                 if (!has_precision)
3235                   if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3236                     precision = 6;
3237
3238                 /* Allocate a temporary buffer of sufficient size.  */
3239 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3240                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3241 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3242                 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3243 # elif NEED_PRINTF_LONG_DOUBLE
3244                 tmp_length = LDBL_DIG + 1;
3245 # elif NEED_PRINTF_DOUBLE
3246                 tmp_length = DBL_DIG + 1;
3247 # else
3248                 tmp_length = 0;
3249 # endif
3250                 if (tmp_length < precision)
3251                   tmp_length = precision;
3252 # if NEED_PRINTF_LONG_DOUBLE
3253 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3254                 if (type == TYPE_LONGDOUBLE)
3255 #  endif
3256                   if (dp->conversion == 'f' || dp->conversion == 'F')
3257                     {
3258                       long double arg = a.arg[dp->arg_index].a.a_longdouble;
3259                       if (!(isnanl (arg) || arg + arg == arg))
3260                         {
3261                           /* arg is finite and nonzero.  */
3262                           int exponent = floorlog10l (arg < 0 ? -arg : arg);
3263                           if (exponent >= 0 && tmp_length < exponent + precision)
3264                             tmp_length = exponent + precision;
3265                         }
3266                     }
3267 # endif
3268 # if NEED_PRINTF_DOUBLE
3269 #  if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3270                 if (type == TYPE_DOUBLE)
3271 #  endif
3272                   if (dp->conversion == 'f' || dp->conversion == 'F')
3273                     {
3274                       double arg = a.arg[dp->arg_index].a.a_double;
3275                       if (!(isnand (arg) || arg + arg == arg))
3276                         {
3277                           /* arg is finite and nonzero.  */
3278                           int exponent = floorlog10 (arg < 0 ? -arg : arg);
3279                           if (exponent >= 0 && tmp_length < exponent + precision)
3280                             tmp_length = exponent + precision;
3281                         }
3282                     }
3283 # endif
3284                 /* Account for sign, decimal point etc. */
3285                 tmp_length = xsum (tmp_length, 12);
3286
3287                 if (tmp_length < width)
3288                   tmp_length = width;
3289
3290                 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3291
3292                 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3293                   tmp = tmpbuf;
3294                 else
3295                   {
3296                     size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3297
3298                     if (size_overflow_p (tmp_memsize))
3299                       /* Overflow, would lead to out of memory.  */
3300                       goto out_of_memory;
3301                     tmp = (DCHAR_T *) malloc (tmp_memsize);
3302                     if (tmp == NULL)
3303                       /* Out of memory.  */
3304                       goto out_of_memory;
3305                   }
3306
3307                 pad_ptr = NULL;
3308                 p = tmp;
3309
3310 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3311 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3312                 if (type == TYPE_LONGDOUBLE)
3313 #  endif
3314                   {
3315                     long double arg = a.arg[dp->arg_index].a.a_longdouble;
3316
3317                     if (isnanl (arg))
3318                       {
3319                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3320                           {
3321                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3322                           }
3323                         else
3324                           {
3325                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3326                           }
3327                       }
3328                     else
3329                       {
3330                         int sign = 0;
3331                         DECL_LONG_DOUBLE_ROUNDING
3332
3333                         BEGIN_LONG_DOUBLE_ROUNDING ();
3334
3335                         if (signbit (arg)) /* arg < 0.0L or negative zero */
3336                           {
3337                             sign = -1;
3338                             arg = -arg;
3339                           }
3340
3341                         if (sign < 0)
3342                           *p++ = '-';
3343                         else if (flags & FLAG_SHOWSIGN)
3344                           *p++ = '+';
3345                         else if (flags & FLAG_SPACE)
3346                           *p++ = ' ';
3347
3348                         if (arg > 0.0L && arg + arg == arg)
3349                           {
3350                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3351                               {
3352                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3353                               }
3354                             else
3355                               {
3356                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3357                               }
3358                           }
3359                         else
3360                           {
3361 #  if NEED_PRINTF_LONG_DOUBLE
3362                             pad_ptr = p;
3363
3364                             if (dp->conversion == 'f' || dp->conversion == 'F')
3365                               {
3366                                 char *digits;
3367                                 size_t ndigits;
3368
3369                                 digits =
3370                                   scale10_round_decimal_long_double (arg, precision);
3371                                 if (digits == NULL)
3372                                   {
3373                                     END_LONG_DOUBLE_ROUNDING ();
3374                                     goto out_of_memory;
3375                                   }
3376                                 ndigits = strlen (digits);
3377
3378                                 if (ndigits > precision)
3379                                   do
3380                                     {
3381                                       --ndigits;
3382                                       *p++ = digits[ndigits];
3383                                     }
3384                                   while (ndigits > precision);
3385                                 else
3386                                   *p++ = '0';
3387                                 /* Here ndigits <= precision.  */
3388                                 if ((flags & FLAG_ALT) || precision > 0)
3389                                   {
3390                                     *p++ = decimal_point_char ();
3391                                     for (; precision > ndigits; precision--)
3392                                       *p++ = '0';
3393                                     while (ndigits > 0)
3394                                       {
3395                                         --ndigits;
3396                                         *p++ = digits[ndigits];
3397                                       }
3398                                   }
3399
3400                                 free (digits);
3401                               }
3402                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3403                               {
3404                                 int exponent;
3405
3406                                 if (arg == 0.0L)
3407                                   {
3408                                     exponent = 0;
3409                                     *p++ = '0';
3410                                     if ((flags & FLAG_ALT) || precision > 0)
3411                                       {
3412                                         *p++ = decimal_point_char ();
3413                                         for (; precision > 0; precision--)
3414                                           *p++ = '0';
3415                                       }
3416                                   }
3417                                 else
3418                                   {
3419                                     /* arg > 0.0L.  */
3420                                     int adjusted;
3421                                     char *digits;
3422                                     size_t ndigits;
3423
3424                                     exponent = floorlog10l (arg);
3425                                     adjusted = 0;
3426                                     for (;;)
3427                                       {
3428                                         digits =
3429                                           scale10_round_decimal_long_double (arg,
3430                                                                              (int)precision - exponent);
3431                                         if (digits == NULL)
3432                                           {
3433                                             END_LONG_DOUBLE_ROUNDING ();
3434                                             goto out_of_memory;
3435                                           }
3436                                         ndigits = strlen (digits);
3437
3438                                         if (ndigits == precision + 1)
3439                                           break;
3440                                         if (ndigits < precision
3441                                             || ndigits > precision + 2)
3442                                           /* The exponent was not guessed
3443                                              precisely enough.  */
3444                                           abort ();
3445                                         if (adjusted)
3446                                           /* None of two values of exponent is
3447                                              the right one.  Prevent an endless
3448                                              loop.  */
3449                                           abort ();
3450                                         free (digits);
3451                                         if (ndigits == precision)
3452                                           exponent -= 1;
3453                                         else
3454                                           exponent += 1;
3455                                         adjusted = 1;
3456                                       }
3457                                     /* Here ndigits = precision+1.  */
3458                                     if (is_borderline (digits, precision))
3459                                       {
3460                                         /* Maybe the exponent guess was too high
3461                                            and a smaller exponent can be reached
3462                                            by turning a 10...0 into 9...9x.  */
3463                                         char *digits2 =
3464                                           scale10_round_decimal_long_double (arg,
3465                                                                              (int)precision - exponent + 1);
3466                                         if (digits2 == NULL)
3467                                           {
3468                                             free (digits);
3469                                             END_LONG_DOUBLE_ROUNDING ();
3470                                             goto out_of_memory;
3471                                           }
3472                                         if (strlen (digits2) == precision + 1)
3473                                           {
3474                                             free (digits);
3475                                             digits = digits2;
3476                                             exponent -= 1;
3477                                           }
3478                                         else
3479                                           free (digits2);
3480                                       }
3481                                     /* Here ndigits = precision+1.  */
3482
3483                                     *p++ = digits[--ndigits];
3484                                     if ((flags & FLAG_ALT) || precision > 0)
3485                                       {
3486                                         *p++ = decimal_point_char ();
3487                                         while (ndigits > 0)
3488                                           {
3489                                             --ndigits;
3490                                             *p++ = digits[ndigits];
3491                                           }
3492                                       }
3493
3494                                     free (digits);
3495                                   }
3496
3497                                 *p++ = dp->conversion; /* 'e' or 'E' */
3498 #   if WIDE_CHAR_VERSION
3499                                 {
3500                                   static const wchar_t decimal_format[] =
3501                                     { '%', '+', '.', '2', 'd', '\0' };
3502                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
3503                                 }
3504                                 while (*p != '\0')
3505                                   p++;
3506 #   else
3507                                 if (sizeof (DCHAR_T) == 1)
3508                                   {
3509                                     sprintf ((char *) p, "%+.2d", exponent);
3510                                     while (*p != '\0')
3511                                       p++;
3512                                   }
3513                                 else
3514                                   {
3515                                     char expbuf[6 + 1];
3516                                     const char *ep;
3517                                     sprintf (expbuf, "%+.2d", exponent);
3518                                     for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3519                                       p++;
3520                                   }
3521 #   endif
3522                               }
3523                             else if (dp->conversion == 'g' || dp->conversion == 'G')
3524                               {
3525                                 if (precision == 0)
3526                                   precision = 1;
3527                                 /* precision >= 1.  */
3528
3529                                 if (arg == 0.0L)
3530                                   /* The exponent is 0, >= -4, < precision.
3531                                      Use fixed-point notation.  */
3532                                   {
3533                                     size_t ndigits = precision;
3534                                     /* Number of trailing zeroes that have to be
3535                                        dropped.  */
3536                                     size_t nzeroes =
3537                                       (flags & FLAG_ALT ? 0 : precision - 1);
3538
3539                                     --ndigits;
3540                                     *p++ = '0';
3541                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
3542                                       {
3543                                         *p++ = decimal_point_char ();
3544                                         while (ndigits > nzeroes)
3545                                           {
3546                                             --ndigits;
3547                                             *p++ = '0';
3548                                           }
3549                                       }
3550                                   }
3551                                 else
3552                                   {
3553                                     /* arg > 0.0L.  */
3554                                     int exponent;
3555                                     int adjusted;
3556                                     char *digits;
3557                                     size_t ndigits;
3558                                     size_t nzeroes;
3559
3560                                     exponent = floorlog10l (arg);
3561                                     adjusted = 0;
3562                                     for (;;)
3563                                       {
3564                                         digits =
3565                                           scale10_round_decimal_long_double (arg,
3566                                                                              (int)(precision - 1) - exponent);
3567                                         if (digits == NULL)
3568                                           {
3569                                             END_LONG_DOUBLE_ROUNDING ();
3570                                             goto out_of_memory;
3571                                           }
3572                                         ndigits = strlen (digits);
3573
3574                                         if (ndigits == precision)
3575                                           break;
3576                                         if (ndigits < precision - 1
3577                                             || ndigits > precision + 1)
3578                                           /* The exponent was not guessed
3579                                              precisely enough.  */
3580                                           abort ();
3581                                         if (adjusted)
3582                                           /* None of two values of exponent is
3583                                              the right one.  Prevent an endless
3584                                              loop.  */
3585                                           abort ();
3586                                         free (digits);
3587                                         if (ndigits < precision)
3588                                           exponent -= 1;
3589                                         else
3590                                           exponent += 1;
3591                                         adjusted = 1;
3592                                       }
3593                                     /* Here ndigits = precision.  */
3594                                     if (is_borderline (digits, precision - 1))
3595                                       {
3596                                         /* Maybe the exponent guess was too high
3597                                            and a smaller exponent can be reached
3598                                            by turning a 10...0 into 9...9x.  */
3599                                         char *digits2 =
3600                                           scale10_round_decimal_long_double (arg,
3601                                                                              (int)(precision - 1) - exponent + 1);
3602                                         if (digits2 == NULL)
3603                                           {
3604                                             free (digits);
3605                                             END_LONG_DOUBLE_ROUNDING ();
3606                                             goto out_of_memory;
3607                                           }
3608                                         if (strlen (digits2) == precision)
3609                                           {
3610                                             free (digits);
3611                                             digits = digits2;
3612                                             exponent -= 1;
3613                                           }
3614                                         else
3615                                           free (digits2);
3616                                       }
3617                                     /* Here ndigits = precision.  */
3618
3619                                     /* Determine the number of trailing zeroes
3620                                        that have to be dropped.  */
3621                                     nzeroes = 0;
3622                                     if ((flags & FLAG_ALT) == 0)
3623                                       while (nzeroes < ndigits
3624                                              && digits[nzeroes] == '0')
3625                                         nzeroes++;
3626
3627                                     /* The exponent is now determined.  */
3628                                     if (exponent >= -4
3629                                         && exponent < (long)precision)
3630                                       {
3631                                         /* Fixed-point notation:
3632                                            max(exponent,0)+1 digits, then the
3633                                            decimal point, then the remaining
3634                                            digits without trailing zeroes.  */
3635                                         if (exponent >= 0)
3636                                           {
3637                                             size_t count = exponent + 1;
3638                                             /* Note: count <= precision = ndigits.  */
3639                                             for (; count > 0; count--)
3640                                               *p++ = digits[--ndigits];
3641                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
3642                                               {
3643                                                 *p++ = decimal_point_char ();
3644                                                 while (ndigits > nzeroes)
3645                                                   {
3646                                                     --ndigits;
3647                                                     *p++ = digits[ndigits];
3648                                                   }
3649                                               }
3650                                           }
3651                                         else
3652                                           {
3653                                             size_t count = -exponent - 1;
3654                                             *p++ = '0';
3655                                             *p++ = decimal_point_char ();
3656                                             for (; count > 0; count--)
3657                                               *p++ = '0';
3658                                             while (ndigits > nzeroes)
3659                                               {
3660                                                 --ndigits;
3661                                                 *p++ = digits[ndigits];
3662                                               }
3663                                           }
3664                                       }
3665                                     else
3666                                       {
3667                                         /* Exponential notation.  */
3668                                         *p++ = digits[--ndigits];
3669                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
3670                                           {
3671                                             *p++ = decimal_point_char ();
3672                                             while (ndigits > nzeroes)
3673                                               {
3674                                                 --ndigits;
3675                                                 *p++ = digits[ndigits];
3676                                               }
3677                                           }
3678                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3679 #   if WIDE_CHAR_VERSION
3680                                         {
3681                                           static const wchar_t decimal_format[] =
3682                                             { '%', '+', '.', '2', 'd', '\0' };
3683                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
3684                                         }
3685                                         while (*p != '\0')
3686                                           p++;
3687 #   else
3688                                         if (sizeof (DCHAR_T) == 1)
3689                                           {
3690                                             sprintf ((char *) p, "%+.2d", exponent);
3691                                             while (*p != '\0')
3692                                               p++;
3693                                           }
3694                                         else
3695                                           {
3696                                             char expbuf[6 + 1];
3697                                             const char *ep;
3698                                             sprintf (expbuf, "%+.2d", exponent);
3699                                             for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3700                                               p++;
3701                                           }
3702 #   endif
3703                                       }
3704
3705                                     free (digits);
3706                                   }
3707                               }
3708                             else
3709                               abort ();
3710 #  else
3711                             /* arg is finite.  */
3712                             if (!(arg == 0.0L))
3713                               abort ();
3714
3715                             pad_ptr = p;
3716
3717                             if (dp->conversion == 'f' || dp->conversion == 'F')
3718                               {
3719                                 *p++ = '0';
3720                                 if ((flags & FLAG_ALT) || precision > 0)
3721                                   {
3722                                     *p++ = decimal_point_char ();
3723                                     for (; precision > 0; precision--)
3724                                       *p++ = '0';
3725                                   }
3726                               }
3727                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3728                               {
3729                                 *p++ = '0';
3730                                 if ((flags & FLAG_ALT) || precision > 0)
3731                                   {
3732                                     *p++ = decimal_point_char ();
3733                                     for (; precision > 0; precision--)
3734                                       *p++ = '0';
3735                                   }
3736                                 *p++ = dp->conversion; /* 'e' or 'E' */
3737                                 *p++ = '+';
3738                                 *p++ = '0';
3739                                 *p++ = '0';
3740                               }
3741                             else if (dp->conversion == 'g' || dp->conversion == 'G')
3742                               {
3743                                 *p++ = '0';
3744                                 if (flags & FLAG_ALT)
3745                                   {
3746                                     size_t ndigits =
3747                                       (precision > 0 ? precision - 1 : 0);
3748                                     *p++ = decimal_point_char ();
3749                                     for (; ndigits > 0; --ndigits)
3750                                       *p++ = '0';
3751                                   }
3752                               }
3753                             else if (dp->conversion == 'a' || dp->conversion == 'A')
3754                               {
3755                                 *p++ = '0';
3756                                 *p++ = dp->conversion - 'A' + 'X';
3757                                 pad_ptr = p;
3758                                 *p++ = '0';
3759                                 if ((flags & FLAG_ALT) || precision > 0)
3760                                   {
3761                                     *p++ = decimal_point_char ();
3762                                     for (; precision > 0; precision--)
3763                                       *p++ = '0';
3764                                   }
3765                                 *p++ = dp->conversion - 'A' + 'P';
3766                                 *p++ = '+';
3767                                 *p++ = '0';
3768                               }
3769                             else
3770                               abort ();
3771 #  endif
3772                           }
3773
3774                         END_LONG_DOUBLE_ROUNDING ();
3775                       }
3776                   }
3777 #  if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3778                 else
3779 #  endif
3780 # endif
3781 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3782                   {
3783                     double arg = a.arg[dp->arg_index].a.a_double;
3784
3785                     if (isnand (arg))
3786                       {
3787                         if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3788                           {
3789                             *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3790                           }
3791                         else
3792                           {
3793                             *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3794                           }
3795                       }
3796                     else
3797                       {
3798                         int sign = 0;
3799
3800                         if (signbit (arg)) /* arg < 0.0 or negative zero */
3801                           {
3802                             sign = -1;
3803                             arg = -arg;
3804                           }
3805
3806                         if (sign < 0)
3807                           *p++ = '-';
3808                         else if (flags & FLAG_SHOWSIGN)
3809                           *p++ = '+';
3810                         else if (flags & FLAG_SPACE)
3811                           *p++ = ' ';
3812
3813                         if (arg > 0.0 && arg + arg == arg)
3814                           {
3815                             if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3816                               {
3817                                 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3818                               }
3819                             else
3820                               {
3821                                 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3822                               }
3823                           }
3824                         else
3825                           {
3826 #  if NEED_PRINTF_DOUBLE
3827                             pad_ptr = p;
3828
3829                             if (dp->conversion == 'f' || dp->conversion == 'F')
3830                               {
3831                                 char *digits;
3832                                 size_t ndigits;
3833
3834                                 digits =
3835                                   scale10_round_decimal_double (arg, precision);
3836                                 if (digits == NULL)
3837                                   goto out_of_memory;
3838                                 ndigits = strlen (digits);
3839
3840                                 if (ndigits > precision)
3841                                   do
3842                                     {
3843                                       --ndigits;
3844                                       *p++ = digits[ndigits];
3845                                     }
3846                                   while (ndigits > precision);
3847                                 else
3848                                   *p++ = '0';
3849                                 /* Here ndigits <= precision.  */
3850                                 if ((flags & FLAG_ALT) || precision > 0)
3851                                   {
3852                                     *p++ = decimal_point_char ();
3853                                     for (; precision > ndigits; precision--)
3854                                       *p++ = '0';
3855                                     while (ndigits > 0)
3856                                       {
3857                                         --ndigits;
3858                                         *p++ = digits[ndigits];
3859                                       }
3860                                   }
3861
3862                                 free (digits);
3863                               }
3864                             else if (dp->conversion == 'e' || dp->conversion == 'E')
3865                               {
3866                                 int exponent;
3867
3868                                 if (arg == 0.0)
3869                                   {
3870                                     exponent = 0;
3871                                     *p++ = '0';
3872                                     if ((flags & FLAG_ALT) || precision > 0)
3873                                       {
3874                                         *p++ = decimal_point_char ();
3875                                         for (; precision > 0; precision--)
3876                                           *p++ = '0';
3877                                       }
3878                                   }
3879                                 else
3880                                   {
3881                                     /* arg > 0.0.  */
3882                                     int adjusted;
3883                                     char *digits;
3884                                     size_t ndigits;
3885
3886                                     exponent = floorlog10 (arg);
3887                                     adjusted = 0;
3888                                     for (;;)
3889                                       {
3890                                         digits =
3891                                           scale10_round_decimal_double (arg,
3892                                                                         (int)precision - exponent);
3893                                         if (digits == NULL)
3894                                           goto out_of_memory;
3895                                         ndigits = strlen (digits);
3896
3897                                         if (ndigits == precision + 1)
3898                                           break;
3899                                         if (ndigits < precision
3900                                             || ndigits > precision + 2)
3901                                           /* The exponent was not guessed
3902                                              precisely enough.  */
3903                                           abort ();
3904                                         if (adjusted)
3905                                           /* None of two values of exponent is
3906                                              the right one.  Prevent an endless
3907                                              loop.  */
3908                                           abort ();
3909                                         free (digits);
3910                                         if (ndigits == precision)
3911                                           exponent -= 1;
3912                                         else
3913                                           exponent += 1;
3914                                         adjusted = 1;
3915                                       }
3916                                     /* Here ndigits = precision+1.  */
3917                                     if (is_borderline (digits, precision))
3918                                       {
3919                                         /* Maybe the exponent guess was too high
3920                                            and a smaller exponent can be reached
3921                                            by turning a 10...0 into 9...9x.  */
3922                                         char *digits2 =
3923                                           scale10_round_decimal_double (arg,
3924                                                                         (int)precision - exponent + 1);
3925                                         if (digits2 == NULL)
3926                                           {
3927                                             free (digits);
3928                                             goto out_of_memory;
3929                                           }
3930                                         if (strlen (digits2) == precision + 1)
3931                                           {
3932                                             free (digits);
3933                                             digits = digits2;
3934                                             exponent -= 1;
3935                                           }
3936                                         else
3937                                           free (digits2);
3938                                       }
3939                                     /* Here ndigits = precision+1.  */
3940
3941                                     *p++ = digits[--ndigits];
3942                                     if ((flags & FLAG_ALT) || precision > 0)
3943                                       {
3944                                         *p++ = decimal_point_char ();
3945                                         while (ndigits > 0)
3946                                           {
3947                                             --ndigits;
3948                                             *p++ = digits[ndigits];
3949                                           }
3950                                       }
3951
3952                                     free (digits);
3953                                   }
3954
3955                                 *p++ = dp->conversion; /* 'e' or 'E' */
3956 #   if WIDE_CHAR_VERSION
3957                                 {
3958                                   static const wchar_t decimal_format[] =
3959                                     /* Produce the same number of exponent digits
3960                                        as the native printf implementation.  */
3961 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3962                                     { '%', '+', '.', '3', 'd', '\0' };
3963 #    else
3964                                     { '%', '+', '.', '2', 'd', '\0' };
3965 #    endif
3966                                   SNPRINTF (p, 6 + 1, decimal_format, exponent);
3967                                 }
3968                                 while (*p != '\0')
3969                                   p++;
3970 #   else
3971                                 {
3972                                   static const char decimal_format[] =
3973                                     /* Produce the same number of exponent digits
3974                                        as the native printf implementation.  */
3975 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3976                                     "%+.3d";
3977 #    else
3978                                     "%+.2d";
3979 #    endif
3980                                   if (sizeof (DCHAR_T) == 1)
3981                                     {
3982                                       sprintf ((char *) p, decimal_format, exponent);
3983                                       while (*p != '\0')
3984                                         p++;
3985                                     }
3986                                   else
3987                                     {
3988                                       char expbuf[6 + 1];
3989                                       const char *ep;
3990                                       sprintf (expbuf, decimal_format, exponent);
3991                                       for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3992                                         p++;
3993                                     }
3994                                 }
3995 #   endif
3996                               }
3997                             else if (dp->conversion == 'g' || dp->conversion == 'G')
3998                               {
3999                                 if (precision == 0)
4000                                   precision = 1;
4001                                 /* precision >= 1.  */
4002
4003                                 if (arg == 0.0)
4004                                   /* The exponent is 0, >= -4, < precision.
4005                                      Use fixed-point notation.  */
4006                                   {
4007                                     size_t ndigits = precision;
4008                                     /* Number of trailing zeroes that have to be
4009                                        dropped.  */
4010                                     size_t nzeroes =
4011                                       (flags & FLAG_ALT ? 0 : precision - 1);
4012
4013                                     --ndigits;
4014                                     *p++ = '0';
4015                                     if ((flags & FLAG_ALT) || ndigits > nzeroes)
4016                                       {
4017                                         *p++ = decimal_point_char ();
4018                                         while (ndigits > nzeroes)
4019                                           {
4020                                             --ndigits;
4021                                             *p++ = '0';
4022                                           }
4023                                       }
4024                                   }
4025                                 else
4026                                   {
4027                                     /* arg > 0.0.  */
4028                                     int exponent;
4029                                     int adjusted;
4030                                     char *digits;
4031                                     size_t ndigits;
4032                                     size_t nzeroes;
4033
4034                                     exponent = floorlog10 (arg);
4035                                     adjusted = 0;
4036                                     for (;;)
4037                                       {
4038                                         digits =
4039                                           scale10_round_decimal_double (arg,
4040                                                                         (int)(precision - 1) - exponent);
4041                                         if (digits == NULL)
4042                                           goto out_of_memory;
4043                                         ndigits = strlen (digits);
4044
4045                                         if (ndigits == precision)
4046                                           break;
4047                                         if (ndigits < precision - 1
4048                                             || ndigits > precision + 1)
4049                                           /* The exponent was not guessed
4050                                              precisely enough.  */
4051                                           abort ();
4052                                         if (adjusted)
4053                                           /* None of two values of exponent is
4054                                              the right one.  Prevent an endless
4055                                              loop.  */
4056                                           abort ();
4057                                         free (digits);
4058                                         if (ndigits < precision)
4059                                           exponent -= 1;
4060                                         else
4061                                           exponent += 1;
4062                                         adjusted = 1;
4063                                       }
4064                                     /* Here ndigits = precision.  */
4065                                     if (is_borderline (digits, precision - 1))
4066                                       {
4067                                         /* Maybe the exponent guess was too high
4068                                            and a smaller exponent can be reached
4069                                            by turning a 10...0 into 9...9x.  */
4070                                         char *digits2 =
4071                                           scale10_round_decimal_double (arg,
4072                                                                         (int)(precision - 1) - exponent + 1);
4073                                         if (digits2 == NULL)
4074                                           {
4075                                             free (digits);
4076                                             goto out_of_memory;
4077                                           }
4078                                         if (strlen (digits2) == precision)
4079                                           {
4080                                             free (digits);
4081                                             digits = digits2;
4082                                             exponent -= 1;
4083                                           }
4084                                         else
4085                                           free (digits2);
4086                                       }
4087                                     /* Here ndigits = precision.  */
4088
4089                                     /* Determine the number of trailing zeroes
4090                                        that have to be dropped.  */
4091                                     nzeroes = 0;
4092                                     if ((flags & FLAG_ALT) == 0)
4093                                       while (nzeroes < ndigits
4094                                              && digits[nzeroes] == '0')
4095                                         nzeroes++;
4096
4097                                     /* The exponent is now determined.  */
4098                                     if (exponent >= -4
4099                                         && exponent < (long)precision)
4100                                       {
4101                                         /* Fixed-point notation:
4102                                            max(exponent,0)+1 digits, then the
4103                                            decimal point, then the remaining
4104                                            digits without trailing zeroes.  */
4105                                         if (exponent >= 0)
4106                                           {
4107                                             size_t count = exponent + 1;
4108                                             /* Note: count <= precision = ndigits.  */
4109                                             for (; count > 0; count--)
4110                                               *p++ = digits[--ndigits];
4111                                             if ((flags & FLAG_ALT) || ndigits > nzeroes)
4112                                               {
4113                                                 *p++ = decimal_point_char ();
4114                                                 while (ndigits > nzeroes)
4115                                                   {
4116                                                     --ndigits;
4117                                                     *p++ = digits[ndigits];
4118                                                   }
4119                                               }
4120                                           }
4121                                         else
4122                                           {
4123                                             size_t count = -exponent - 1;
4124                                             *p++ = '0';
4125                                             *p++ = decimal_point_char ();
4126                                             for (; count > 0; count--)
4127                                               *p++ = '0';
4128                                             while (ndigits > nzeroes)
4129                                               {
4130                                                 --ndigits;
4131                                                 *p++ = digits[ndigits];
4132                                               }
4133                                           }
4134                                       }
4135                                     else
4136                                       {
4137                                         /* Exponential notation.  */
4138                                         *p++ = digits[--ndigits];
4139                                         if ((flags & FLAG_ALT) || ndigits > nzeroes)
4140                                           {
4141                                             *p++ = decimal_point_char ();
4142                                             while (ndigits > nzeroes)
4143                                               {
4144                                                 --ndigits;
4145                                                 *p++ = digits[ndigits];
4146                                               }
4147                                           }
4148                                         *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4149 #   if WIDE_CHAR_VERSION
4150                                         {
4151                                           static const wchar_t decimal_format[] =
4152                                             /* Produce the same number of exponent digits
4153                                                as the native printf implementation.  */
4154 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4155                                             { '%', '+', '.', '3', 'd', '\0' };
4156 #    else
4157                                             { '%', '+', '.', '2', 'd', '\0' };
4158 #    endif
4159                                           SNPRINTF (p, 6 + 1, decimal_format, exponent);
4160                                         }
4161                                         while (*p != '\0')
4162                                           p++;
4163 #   else
4164                                         {
4165                                           static const char decimal_format[] =
4166                                             /* Produce the same number of exponent digits
4167                                                as the native printf implementation.  */
4168 #    if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4169                                             "%+.3d";
4170 #    else
4171                                             "%+.2d";
4172 #    endif
4173                                           if (sizeof (DCHAR_T) == 1)
4174                                             {
4175                                               sprintf ((char *) p, decimal_format, exponent);
4176                                               while (*p != '\0')
4177                                                 p++;
4178                                             }
4179                                           else
4180                                             {
4181                                               char expbuf[6 + 1];
4182                                               const char *ep;
4183                                               sprintf (expbuf, decimal_format, exponent);
4184                                               for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4185                                                 p++;
4186                                             }
4187                                         }
4188 #   endif
4189                                       }
4190
4191                                     free (digits);
4192                                   }
4193                               }
4194                             else
4195                               abort ();
4196 #  else
4197                             /* arg is finite.  */
4198                             if (!(arg == 0.0))
4199                               abort ();
4200
4201                             pad_ptr = p;
4202
4203                             if (dp->conversion == 'f' || dp->conversion == 'F')
4204                               {
4205                                 *p++ = '0';
4206                                 if ((flags & FLAG_ALT) || precision > 0)
4207                                   {
4208                                     *p++ = decimal_point_char ();
4209                                     for (; precision > 0; precision--)
4210                                       *p++ = '0';
4211                                   }
4212                               }
4213                             else if (dp->conversion == 'e' || dp->conversion == 'E')
4214                               {
4215                                 *p++ = '0';
4216                                 if ((flags & FLAG_ALT) || precision > 0)
4217                                   {
4218                                     *p++ = decimal_point_char ();
4219                                     for (; precision > 0; precision--)
4220                                       *p++ = '0';
4221                                   }
4222                                 *p++ = dp->conversion; /* 'e' or 'E' */
4223                                 *p++ = '+';
4224                                 /* Produce the same number of exponent digits as
4225                                    the native printf implementation.  */
4226 #   if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4227                                 *p++ = '0';
4228 #   endif
4229                                 *p++ = '0';
4230                                 *p++ = '0';
4231                               }
4232                             else if (dp->conversion == 'g' || dp->conversion == 'G')
4233                               {
4234                                 *p++ = '0';
4235                                 if (flags & FLAG_ALT)
4236                                   {
4237                                     size_t ndigits =
4238                                       (precision > 0 ? precision - 1 : 0);
4239                                     *p++ = decimal_point_char ();
4240                                     for (; ndigits > 0; --ndigits)
4241                                       *p++ = '0';
4242                                   }
4243                               }
4244                             else
4245                               abort ();
4246 #  endif
4247                           }
4248                       }
4249                   }
4250 # endif
4251
4252                 /* The generated string now extends from tmp to p, with the
4253                    zero padding insertion point being at pad_ptr.  */
4254                 if (has_width && p - tmp < width)
4255                   {
4256                     size_t pad = width - (p - tmp);
4257                     DCHAR_T *end = p + pad;
4258
4259                     if (flags & FLAG_LEFT)
4260                       {
4261                         /* Pad with spaces on the right.  */
4262                         for (; pad > 0; pad--)
4263                           *p++ = ' ';
4264                       }
4265                     else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4266                       {
4267                         /* Pad with zeroes.  */
4268                         DCHAR_T *q = end;
4269
4270                         while (p > pad_ptr)
4271                           *--q = *--p;
4272                         for (; pad > 0; pad--)
4273                           *p++ = '0';
4274                       }
4275                     else
4276                       {
4277                         /* Pad with spaces on the left.  */
4278                         DCHAR_T *q = end;
4279
4280                         while (p > tmp)
4281                           *--q = *--p;
4282                         for (; pad > 0; pad--)
4283                           *p++ = ' ';
4284                       }
4285
4286                     p = end;
4287                   }
4288
4289                 {
4290                   size_t count = p - tmp;
4291
4292                   if (count >= tmp_length)
4293                     /* tmp_length was incorrectly calculated - fix the
4294                        code above!  */
4295                     abort ();
4296
4297                   /* Make room for the result.  */
4298                   if (count >= allocated - length)
4299                     {
4300                       size_t n = xsum (length, count);
4301
4302                       ENSURE_ALLOCATION (n);
4303                     }
4304
4305                   /* Append the result.  */
4306                   memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4307                   if (tmp != tmpbuf)
4308                     free (tmp);
4309                   length += count;
4310                 }
4311               }
4312 #endif
4313             else
4314               {
4315                 arg_type type = a.arg[dp->arg_index].type;
4316                 int flags = dp->flags;
4317 #if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4318                 int has_width;
4319                 size_t width;
4320 #endif
4321 #if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4322                 int has_precision;
4323                 size_t precision;
4324 #endif
4325 #if NEED_PRINTF_UNBOUNDED_PRECISION
4326                 int prec_ourselves;
4327 #else
4328 #               define prec_ourselves 0
4329 #endif
4330 #if NEED_PRINTF_FLAG_LEFTADJUST
4331 #               define pad_ourselves 1
4332 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4333                 int pad_ourselves;
4334 #else
4335 #               define pad_ourselves 0
4336 #endif
4337                 TCHAR_T *fbp;
4338                 unsigned int prefix_count;
4339                 int prefixes[2] IF_LINT (= { 0 });
4340 #if !USE_SNPRINTF
4341                 size_t tmp_length;
4342                 TCHAR_T tmpbuf[700];
4343                 TCHAR_T *tmp;
4344 #endif
4345
4346 #if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4347                 has_width = 0;
4348                 width = 0;
4349                 if (dp->width_start != dp->width_end)
4350                   {
4351                     if (dp->width_arg_index != ARG_NONE)
4352                       {
4353                         int arg;
4354
4355                         if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4356                           abort ();
4357                         arg = a.arg[dp->width_arg_index].a.a_int;
4358                         if (arg < 0)
4359                           {
4360                             /* "A negative field width is taken as a '-' flag
4361                                 followed by a positive field width."  */
4362                             flags |= FLAG_LEFT;
4363                             width = (unsigned int) (-arg);
4364                           }
4365                         else
4366                           width = arg;
4367                       }
4368                     else
4369                       {
4370                         const FCHAR_T *digitp = dp->width_start;
4371
4372                         do
4373                           width = xsum (xtimes (width, 10), *digitp++ - '0');
4374                         while (digitp != dp->width_end);
4375                       }
4376                     has_width = 1;
4377                   }
4378 #endif
4379
4380 #if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4381                 has_precision = 0;
4382                 precision = 6;
4383                 if (dp->precision_start != dp->precision_end)
4384                   {
4385                     if (dp->precision_arg_index != ARG_NONE)
4386                       {
4387                         int arg;
4388
4389                         if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4390                           abort ();
4391                         arg = a.arg[dp->precision_arg_index].a.a_int;
4392                         /* "A negative precision is taken as if the precision
4393                             were omitted."  */
4394                         if (arg >= 0)
4395                           {
4396                             precision = arg;
4397                             has_precision = 1;
4398                           }
4399                       }
4400                     else
4401                       {
4402                         const FCHAR_T *digitp = dp->precision_start + 1;
4403
4404                         precision = 0;
4405                         while (digitp != dp->precision_end)
4406                           precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4407                         has_precision = 1;
4408                       }
4409                   }
4410 #endif
4411
4412                 /* Decide whether to handle the precision ourselves.  */
4413 #if NEED_PRINTF_UNBOUNDED_PRECISION
4414                 switch (dp->conversion)
4415                   {
4416                   case 'd': case 'i': case 'u':
4417                   case 'o':
4418                   case 'x': case 'X': case 'p':
4419                     prec_ourselves = has_precision && (precision > 0);
4420                     break;
4421                   default:
4422                     prec_ourselves = 0;
4423                     break;
4424                   }
4425 #endif
4426
4427                 /* Decide whether to perform the padding ourselves.  */
4428 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4429                 switch (dp->conversion)
4430                   {
4431 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4432                   /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4433                      to perform the padding after this conversion.  Functions
4434                      with unistdio extensions perform the padding based on
4435                      character count rather than element count.  */
4436                   case 'c': case 's':
4437 # endif
4438 # if NEED_PRINTF_FLAG_ZERO
4439                   case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4440                   case 'a': case 'A':
4441 # endif
4442                     pad_ourselves = 1;
4443                     break;
4444                   default:
4445                     pad_ourselves = prec_ourselves;
4446                     break;
4447                   }
4448 #endif
4449
4450 #if !USE_SNPRINTF
4451                 /* Allocate a temporary buffer of sufficient size for calling
4452                    sprintf.  */
4453                 {
4454                   switch (dp->conversion)
4455                     {
4456
4457                     case 'd': case 'i': case 'u':
4458 # if HAVE_LONG_LONG_INT
4459                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
4460                         tmp_length =
4461                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
4462                                           * 0.30103 /* binary -> decimal */
4463                                          )
4464                           + 1; /* turn floor into ceil */
4465                       else
4466 # endif
4467                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
4468                         tmp_length =
4469                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
4470                                           * 0.30103 /* binary -> decimal */
4471                                          )
4472                           + 1; /* turn floor into ceil */
4473                       else
4474                         tmp_length =
4475                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
4476                                           * 0.30103 /* binary -> decimal */
4477                                          )
4478                           + 1; /* turn floor into ceil */
4479                       if (tmp_length < precision)
4480                         tmp_length = precision;
4481                       /* Multiply by 2, as an estimate for FLAG_GROUP.  */
4482                       tmp_length = xsum (tmp_length, tmp_length);
4483                       /* Add 1, to account for a leading sign.  */
4484                       tmp_length = xsum (tmp_length, 1);
4485                       break;
4486
4487                     case 'o':
4488 # if HAVE_LONG_LONG_INT
4489                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
4490                         tmp_length =
4491                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
4492                                           * 0.333334 /* binary -> octal */
4493                                          )
4494                           + 1; /* turn floor into ceil */
4495                       else
4496 # endif
4497                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
4498                         tmp_length =
4499                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
4500                                           * 0.333334 /* binary -> octal */
4501                                          )
4502                           + 1; /* turn floor into ceil */
4503                       else
4504                         tmp_length =
4505                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
4506                                           * 0.333334 /* binary -> octal */
4507                                          )
4508                           + 1; /* turn floor into ceil */
4509                       if (tmp_length < precision)
4510                         tmp_length = precision;
4511                       /* Add 1, to account for a leading sign.  */
4512                       tmp_length = xsum (tmp_length, 1);
4513                       break;
4514
4515                     case 'x': case 'X':
4516 # if HAVE_LONG_LONG_INT
4517                       if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
4518                         tmp_length =
4519                           (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
4520                                           * 0.25 /* binary -> hexadecimal */
4521                                          )
4522                           + 1; /* turn floor into ceil */
4523                       else
4524 # endif
4525                       if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
4526                         tmp_length =
4527                           (unsigned int) (sizeof (unsigned long) * CHAR_BIT
4528                                           * 0.25 /* binary -> hexadecimal */
4529                                          )
4530                           + 1; /* turn floor into ceil */
4531                       else
4532                         tmp_length =
4533                           (unsigned int) (sizeof (unsigned int) * CHAR_BIT
4534                                           * 0.25 /* binary -> hexadecimal */
4535                                          )
4536                           + 1; /* turn floor into ceil */
4537                       if (tmp_length < precision)
4538                         tmp_length = precision;
4539                       /* Add 2, to account for a leading sign or alternate form.  */
4540                       tmp_length = xsum (tmp_length, 2);
4541                       break;
4542
4543                     case 'f': case 'F':
4544                       if (type == TYPE_LONGDOUBLE)
4545                         tmp_length =
4546                           (unsigned int) (LDBL_MAX_EXP
4547                                           * 0.30103 /* binary -> decimal */
4548                                           * 2 /* estimate for FLAG_GROUP */
4549                                          )
4550                           + 1 /* turn floor into ceil */
4551                           + 10; /* sign, decimal point etc. */
4552                       else
4553                         tmp_length =
4554                           (unsigned int) (DBL_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                       tmp_length = xsum (tmp_length, precision);
4561                       break;
4562
4563                     case 'e': case 'E': case 'g': case 'G':
4564                       tmp_length =
4565                         12; /* sign, decimal point, exponent etc. */
4566                       tmp_length = xsum (tmp_length, precision);
4567                       break;
4568
4569                     case 'a': case 'A':
4570                       if (type == TYPE_LONGDOUBLE)
4571                         tmp_length =
4572                           (unsigned int) (LDBL_DIG
4573                                           * 0.831 /* decimal -> hexadecimal */
4574                                          )
4575                           + 1; /* turn floor into ceil */
4576                       else
4577                         tmp_length =
4578                           (unsigned int) (DBL_DIG
4579                                           * 0.831 /* decimal -> hexadecimal */
4580                                          )
4581                           + 1; /* turn floor into ceil */
4582                       if (tmp_length < precision)
4583                         tmp_length = precision;
4584                       /* Account for sign, decimal point etc. */
4585                       tmp_length = xsum (tmp_length, 12);
4586                       break;
4587
4588                     case 'c':
4589 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
4590                       if (type == TYPE_WIDE_CHAR)
4591                         tmp_length = MB_CUR_MAX;
4592                       else
4593 # endif
4594                         tmp_length = 1;
4595                       break;
4596
4597                     case 's':
4598 # if HAVE_WCHAR_T
4599                       if (type == TYPE_WIDE_STRING)
4600                         {
4601 #  if WIDE_CHAR_VERSION
4602                           /* ISO C says about %ls in fwprintf:
4603                                "If the precision is not specified or is greater
4604                                 than the size of the array, the array shall
4605                                 contain a null wide character."
4606                              So if there is a precision, we must not use
4607                              wcslen.  */
4608                           const wchar_t *arg =
4609                             a.arg[dp->arg_index].a.a_wide_string;
4610
4611                           if (has_precision)
4612                             tmp_length = local_wcsnlen (arg, precision);
4613                           else
4614                             tmp_length = local_wcslen (arg);
4615 #  else
4616                           /* ISO C says about %ls in fprintf:
4617                                "If a precision is specified, no more than that
4618                                 many bytes are written (including shift
4619                                 sequences, if any), and the array shall contain
4620                                 a null wide character if, to equal the
4621                                 multibyte character sequence length given by
4622                                 the precision, the function would need to
4623                                 access a wide character one past the end of the
4624                                 array."
4625                              So if there is a precision, we must not use
4626                              wcslen.  */
4627                           /* This case has already been handled above.  */
4628                           abort ();
4629 #  endif
4630                         }
4631                       else
4632 # endif
4633                         {
4634 # if WIDE_CHAR_VERSION
4635                           /* ISO C says about %s in fwprintf:
4636                                "If the precision is not specified or is greater
4637                                 than the size of the converted array, the
4638                                 converted array shall contain a null wide
4639                                 character."
4640                              So if there is a precision, we must not use
4641                              strlen.  */
4642                           /* This case has already been handled above.  */
4643                           abort ();
4644 # else
4645                           /* ISO C says about %s in fprintf:
4646                                "If the precision is not specified or greater
4647                                 than the size of the array, the array shall
4648                                 contain a null character."
4649                              So if there is a precision, we must not use
4650                              strlen.  */
4651                           const char *arg = a.arg[dp->arg_index].a.a_string;
4652
4653                           if (has_precision)
4654                             tmp_length = local_strnlen (arg, precision);
4655                           else
4656                             tmp_length = strlen (arg);
4657 # endif
4658                         }
4659                       break;
4660
4661                     case 'p':
4662                       tmp_length =
4663                         (unsigned int) (sizeof (void *) * CHAR_BIT
4664                                         * 0.25 /* binary -> hexadecimal */
4665                                        )
4666                           + 1 /* turn floor into ceil */
4667                           + 2; /* account for leading 0x */
4668                       break;
4669
4670                     default:
4671                       abort ();
4672                     }
4673
4674                   if (!pad_ourselves)
4675                     {
4676 # if ENABLE_UNISTDIO
4677                       /* Padding considers the number of characters, therefore
4678                          the number of elements after padding may be
4679                            > max (tmp_length, width)
4680                          but is certainly
4681                            <= tmp_length + width.  */
4682                       tmp_length = xsum (tmp_length, width);
4683 # else
4684                       /* Padding considers the number of elements,
4685                          says POSIX.  */
4686                       if (tmp_length < width)
4687                         tmp_length = width;
4688 # endif
4689                     }
4690
4691                   tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
4692                 }
4693
4694                 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4695                   tmp = tmpbuf;
4696                 else
4697                   {
4698                     size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4699
4700                     if (size_overflow_p (tmp_memsize))
4701                       /* Overflow, would lead to out of memory.  */
4702                       goto out_of_memory;
4703                     tmp = (TCHAR_T *) malloc (tmp_memsize);
4704                     if (tmp == NULL)
4705                       /* Out of memory.  */
4706                       goto out_of_memory;
4707                   }
4708 #endif
4709
4710                 /* Construct the format string for calling snprintf or
4711                    sprintf.  */
4712                 fbp = buf;
4713                 *fbp++ = '%';
4714 #if NEED_PRINTF_FLAG_GROUPING
4715                 /* The underlying implementation doesn't support the ' flag.
4716                    Produce no grouping characters in this case; this is
4717                    acceptable because the grouping is locale dependent.  */
4718 #else
4719                 if (flags & FLAG_GROUP)
4720                   *fbp++ = '\'';
4721 #endif
4722                 if (flags & FLAG_LEFT)
4723                   *fbp++ = '-';
4724                 if (flags & FLAG_SHOWSIGN)
4725                   *fbp++ = '+';
4726                 if (flags & FLAG_SPACE)
4727                   *fbp++ = ' ';
4728                 if (flags & FLAG_ALT)
4729                   *fbp++ = '#';
4730                 if (!pad_ourselves)
4731                   {
4732                     if (flags & FLAG_ZERO)
4733                       *fbp++ = '0';
4734                     if (dp->width_start != dp->width_end)
4735                       {
4736                         size_t n = dp->width_end - dp->width_start;
4737                         /* The width specification is known to consist only
4738                            of standard ASCII characters.  */
4739                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4740                           {
4741                             memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4742                             fbp += n;
4743                           }
4744                         else
4745                           {
4746                             const FCHAR_T *mp = dp->width_start;
4747                             do
4748                               *fbp++ = (unsigned char) *mp++;
4749                             while (--n > 0);
4750                           }
4751                       }
4752                   }
4753                 if (!prec_ourselves)
4754                   {
4755                     if (dp->precision_start != dp->precision_end)
4756                       {
4757                         size_t n = dp->precision_end - dp->precision_start;
4758                         /* The precision specification is known to consist only
4759                            of standard ASCII characters.  */
4760                         if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4761                           {
4762                             memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4763                             fbp += n;
4764                           }
4765                         else
4766                           {
4767                             const FCHAR_T *mp = dp->precision_start;
4768                             do
4769                               *fbp++ = (unsigned char) *mp++;
4770                             while (--n > 0);
4771                           }
4772                       }
4773                   }
4774
4775                 switch (type)
4776                   {
4777 #if HAVE_LONG_LONG_INT
4778                   case TYPE_LONGLONGINT:
4779                   case TYPE_ULONGLONGINT:
4780 # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4781                     *fbp++ = 'I';
4782                     *fbp++ = '6';
4783                     *fbp++ = '4';
4784                     break;
4785 # else
4786                     *fbp++ = 'l';
4787                     /*FALLTHROUGH*/
4788 # endif
4789 #endif
4790                   case TYPE_LONGINT:
4791                   case TYPE_ULONGINT:
4792 #if HAVE_WINT_T
4793                   case TYPE_WIDE_CHAR:
4794 #endif
4795 #if HAVE_WCHAR_T
4796                   case TYPE_WIDE_STRING:
4797 #endif
4798                     *fbp++ = 'l';
4799                     break;
4800                   case TYPE_LONGDOUBLE:
4801                     *fbp++ = 'L';
4802                     break;
4803                   default:
4804                     break;
4805                   }
4806 #if NEED_PRINTF_DIRECTIVE_F
4807                 if (dp->conversion == 'F')
4808                   *fbp = 'f';
4809                 else
4810 #endif
4811                   *fbp = dp->conversion;
4812 #if USE_SNPRINTF
4813 # if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
4814                 fbp[1] = '%';
4815                 fbp[2] = 'n';
4816                 fbp[3] = '\0';
4817 # else
4818                 /* On glibc2 systems from glibc >= 2.3 - probably also older
4819                    ones - we know that snprintf's returns value conforms to
4820                    ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
4821                    Therefore we can avoid using %n in this situation.
4822                    On glibc2 systems from 2004-10-18 or newer, the use of %n
4823                    in format strings in writable memory may crash the program
4824                    (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4825                    in this situation.  */
4826                 /* On native Win32 systems (such as mingw), we can avoid using
4827                    %n because:
4828                      - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
4829                        snprintf does not write more than the specified number
4830                        of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
4831                        '4', '5', '6' into buf, not '4', '5', '\0'.)
4832                      - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
4833                        allows us to recognize the case of an insufficient
4834                        buffer size: it returns -1 in this case.
4835                    On native Win32 systems (such as mingw) where the OS is
4836                    Windows Vista, the use of %n in format strings by default
4837                    crashes the program. See
4838                      <http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
4839                      <http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
4840                    So we should avoid %n in this situation.  */
4841                 fbp[1] = '\0';
4842 # endif
4843 #else
4844                 fbp[1] = '\0';
4845 #endif
4846
4847                 /* Construct the arguments for calling snprintf or sprintf.  */
4848                 prefix_count = 0;
4849                 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4850                   {
4851                     if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4852                       abort ();
4853                     prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
4854                   }
4855                 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
4856                   {
4857                     if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4858                       abort ();
4859                     prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
4860                   }
4861
4862 #if USE_SNPRINTF
4863                 /* The SNPRINTF result is appended after result[0..length].
4864                    The latter is an array of DCHAR_T; SNPRINTF appends an
4865                    array of TCHAR_T to it.  This is possible because
4866                    sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4867                    alignof (TCHAR_T) <= alignof (DCHAR_T).  */
4868 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4869                 /* Ensure that maxlen below will be >= 2.  Needed on BeOS,
4870                    where an snprintf() with maxlen==1 acts like sprintf().  */
4871                 ENSURE_ALLOCATION (xsum (length,
4872                                          (2 + TCHARS_PER_DCHAR - 1)
4873                                          / TCHARS_PER_DCHAR));
4874                 /* Prepare checking whether snprintf returns the count
4875                    via %n.  */
4876                 *(TCHAR_T *) (result + length) = '\0';
4877 #endif
4878
4879                 for (;;)
4880                   {
4881                     int count = -1;
4882
4883 #if USE_SNPRINTF
4884                     int retcount = 0;
4885                     size_t maxlen = allocated - length;
4886                     /* SNPRINTF can fail if its second argument is
4887                        > INT_MAX.  */
4888                     if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4889                       maxlen = INT_MAX / TCHARS_PER_DCHAR;
4890                     maxlen = maxlen * TCHARS_PER_DCHAR;
4891 # define SNPRINTF_BUF(arg) \
4892                     switch (prefix_count)                                   \
4893                       {                                                     \
4894                       case 0:                                               \
4895                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4896                                              maxlen, buf,                   \
4897                                              arg, &count);                  \
4898                         break;                                              \
4899                       case 1:                                               \
4900                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4901                                              maxlen, buf,                   \
4902                                              prefixes[0], arg, &count);     \
4903                         break;                                              \
4904                       case 2:                                               \
4905                         retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4906                                              maxlen, buf,                   \
4907                                              prefixes[0], prefixes[1], arg, \
4908                                              &count);                       \
4909                         break;                                              \
4910                       default:                                              \
4911                         abort ();                                           \
4912                       }
4913 #else
4914 # define SNPRINTF_BUF(arg) \
4915                     switch (prefix_count)                                   \
4916                       {                                                     \
4917                       case 0:                                               \
4918                         count = sprintf (tmp, buf, arg);                    \
4919                         break;                                              \
4920                       case 1:                                               \
4921                         count = sprintf (tmp, buf, prefixes[0], arg);       \
4922                         break;                                              \
4923                       case 2:                                               \
4924                         count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4925                                          arg);                              \
4926                         break;                                              \
4927                       default:                                              \
4928                         abort ();                                           \
4929                       }
4930 #endif
4931
4932                     switch (type)
4933                       {
4934                       case TYPE_SCHAR:
4935                         {
4936                           int arg = a.arg[dp->arg_index].a.a_schar;
4937                           SNPRINTF_BUF (arg);
4938                         }
4939                         break;
4940                       case TYPE_UCHAR:
4941                         {
4942                           unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4943                           SNPRINTF_BUF (arg);
4944                         }
4945                         break;
4946                       case TYPE_SHORT:
4947                         {
4948                           int arg = a.arg[dp->arg_index].a.a_short;
4949                           SNPRINTF_BUF (arg);
4950                         }
4951                         break;
4952                       case TYPE_USHORT:
4953                         {
4954                           unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
4955                           SNPRINTF_BUF (arg);
4956                         }
4957                         break;
4958                       case TYPE_INT:
4959                         {
4960                           int arg = a.arg[dp->arg_index].a.a_int;
4961                           SNPRINTF_BUF (arg);
4962                         }
4963                         break;
4964                       case TYPE_UINT:
4965                         {
4966                           unsigned int arg = a.arg[dp->arg_index].a.a_uint;
4967                           SNPRINTF_BUF (arg);
4968                         }
4969                         break;
4970                       case TYPE_LONGINT:
4971                         {
4972                           long int arg = a.arg[dp->arg_index].a.a_longint;
4973                           SNPRINTF_BUF (arg);
4974                         }
4975                         break;
4976                       case TYPE_ULONGINT:
4977                         {
4978                           unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
4979                           SNPRINTF_BUF (arg);
4980                         }
4981                         break;
4982 #if HAVE_LONG_LONG_INT
4983                       case TYPE_LONGLONGINT:
4984                         {
4985                           long long int arg = a.arg[dp->arg_index].a.a_longlongint;
4986                           SNPRINTF_BUF (arg);
4987                         }
4988                         break;
4989                       case TYPE_ULONGLONGINT:
4990                         {
4991                           unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
4992                           SNPRINTF_BUF (arg);
4993                         }
4994                         break;
4995 #endif
4996                       case TYPE_DOUBLE:
4997                         {
4998                           double arg = a.arg[dp->arg_index].a.a_double;
4999                           SNPRINTF_BUF (arg);
5000                         }
5001                         break;
5002                       case TYPE_LONGDOUBLE:
5003                         {
5004                           long double arg = a.arg[dp->arg_index].a.a_longdouble;
5005                           SNPRINTF_BUF (arg);
5006                         }
5007                         break;
5008                       case TYPE_CHAR:
5009                         {
5010                           int arg = a.arg[dp->arg_index].a.a_char;
5011                           SNPRINTF_BUF (arg);
5012                         }
5013                         break;
5014 #if HAVE_WINT_T
5015                       case TYPE_WIDE_CHAR:
5016                         {
5017                           wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5018                           SNPRINTF_BUF (arg);
5019                         }
5020                         break;
5021 #endif
5022                       case TYPE_STRING:
5023                         {
5024                           const char *arg = a.arg[dp->arg_index].a.a_string;
5025                           SNPRINTF_BUF (arg);
5026                         }
5027                         break;
5028 #if HAVE_WCHAR_T
5029                       case TYPE_WIDE_STRING:
5030                         {
5031                           const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5032                           SNPRINTF_BUF (arg);
5033                         }
5034                         break;
5035 #endif
5036                       case TYPE_POINTER:
5037                         {
5038                           void *arg = a.arg[dp->arg_index].a.a_pointer;
5039                           SNPRINTF_BUF (arg);
5040                         }
5041                         break;
5042                       default:
5043                         abort ();
5044                       }
5045
5046 #if USE_SNPRINTF
5047                     /* Portability: Not all implementations of snprintf()
5048                        are ISO C 99 compliant.  Determine the number of
5049                        bytes that snprintf() has produced or would have
5050                        produced.  */
5051                     if (count >= 0)
5052                       {
5053                         /* Verify that snprintf() has NUL-terminated its
5054                            result.  */
5055                         if (count < maxlen
5056                             && ((TCHAR_T *) (result + length)) [count] != '\0')
5057                           abort ();
5058                         /* Portability hack.  */
5059                         if (retcount > count)
5060                           count = retcount;
5061                       }
5062                     else
5063                       {
5064                         /* snprintf() doesn't understand the '%n'
5065                            directive.  */
5066                         if (fbp[1] != '\0')
5067                           {
5068                             /* Don't use the '%n' directive; instead, look
5069                                at the snprintf() return value.  */
5070                             fbp[1] = '\0';
5071                             continue;
5072                           }
5073                         else
5074                           {
5075                             /* Look at the snprintf() return value.  */
5076                             if (retcount < 0)
5077                               {
5078                                 /* HP-UX 10.20 snprintf() is doubly deficient:
5079                                    It doesn't understand the '%n' directive,
5080                                    *and* it returns -1 (rather than the length
5081                                    that would have been required) when the
5082                                    buffer is too small.  */
5083                                 size_t bigger_need =
5084                                   xsum (xtimes (allocated, 2), 12);
5085                                 ENSURE_ALLOCATION (bigger_need);
5086                                 continue;
5087                               }
5088                             else
5089                               count = retcount;
5090                           }
5091                       }
5092 #endif
5093
5094                     /* Attempt to handle failure.  */
5095                     if (count < 0)
5096                       {
5097                         if (!(result == resultbuf || result == NULL))
5098                           free (result);
5099                         if (buf_malloced != NULL)
5100                           free (buf_malloced);
5101                         CLEANUP ();
5102                         errno = EINVAL;
5103                         return NULL;
5104                       }
5105
5106 #if USE_SNPRINTF
5107                     /* Handle overflow of the allocated buffer.
5108                        If such an overflow occurs, a C99 compliant snprintf()
5109                        returns a count >= maxlen.  However, a non-compliant
5110                        snprintf() function returns only count = maxlen - 1.  To
5111                        cover both cases, test whether count >= maxlen - 1.  */
5112                     if ((unsigned int) count + 1 >= maxlen)
5113                       {
5114                         /* If maxlen already has attained its allowed maximum,
5115                            allocating more memory will not increase maxlen.
5116                            Instead of looping, bail out.  */
5117                         if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5118                           goto overflow;
5119                         else
5120                           {
5121                             /* Need at least (count + 1) * sizeof (TCHAR_T)
5122                                bytes.  (The +1 is for the trailing NUL.)
5123                                But ask for (count + 2) * sizeof (TCHAR_T)
5124                                bytes, so that in the next round, we likely get
5125                                  maxlen > (unsigned int) count + 1
5126                                and so we don't get here again.
5127                                And allocate proportionally, to avoid looping
5128                                eternally if snprintf() reports a too small
5129                                count.  */
5130                             size_t n =
5131                               xmax (xsum (length,
5132                                           ((unsigned int) count + 2
5133                                            + TCHARS_PER_DCHAR - 1)
5134                                           / TCHARS_PER_DCHAR),
5135                                     xtimes (allocated, 2));
5136
5137                             ENSURE_ALLOCATION (n);
5138                             continue;
5139                           }
5140                       }
5141 #endif
5142
5143 #if NEED_PRINTF_UNBOUNDED_PRECISION
5144                     if (prec_ourselves)
5145                       {
5146                         /* Handle the precision.  */
5147                         TCHAR_T *prec_ptr =
5148 # if USE_SNPRINTF
5149                           (TCHAR_T *) (result + length);
5150 # else
5151                           tmp;
5152 # endif
5153                         size_t prefix_count;
5154                         size_t move;
5155
5156                         prefix_count = 0;
5157                         /* Put the additional zeroes after the sign.  */
5158                         if (count >= 1
5159                             && (*prec_ptr == '-' || *prec_ptr == '+'
5160                                 || *prec_ptr == ' '))
5161                           prefix_count = 1;
5162                         /* Put the additional zeroes after the 0x prefix if
5163                            (flags & FLAG_ALT) || (dp->conversion == 'p').  */
5164                         else if (count >= 2
5165                                  && prec_ptr[0] == '0'
5166                                  && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5167                           prefix_count = 2;
5168
5169                         move = count - prefix_count;
5170                         if (precision > move)
5171                           {
5172                             /* Insert zeroes.  */
5173                             size_t insert = precision - move;
5174                             TCHAR_T *prec_end;
5175
5176 # if USE_SNPRINTF
5177                             size_t n =
5178                               xsum (length,
5179                                     (count + insert + TCHARS_PER_DCHAR - 1)
5180                                     / TCHARS_PER_DCHAR);
5181                             length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5182                             ENSURE_ALLOCATION (n);
5183                             length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5184                             prec_ptr = (TCHAR_T *) (result + length);
5185 # endif
5186
5187                             prec_end = prec_ptr + count;
5188                             prec_ptr += prefix_count;
5189
5190                             while (prec_end > prec_ptr)
5191                               {
5192                                 prec_end--;
5193                                 prec_end[insert] = prec_end[0];
5194                               }
5195
5196                             prec_end += insert;
5197                             do
5198                               *--prec_end = '0';
5199                             while (prec_end > prec_ptr);
5200
5201                             count += insert;
5202                           }
5203                       }
5204 #endif
5205
5206 #if !USE_SNPRINTF
5207                     if (count >= tmp_length)
5208                       /* tmp_length was incorrectly calculated - fix the
5209                          code above!  */
5210                       abort ();
5211 #endif
5212
5213 #if !DCHAR_IS_TCHAR
5214                     /* Convert from TCHAR_T[] to DCHAR_T[].  */
5215                     if (dp->conversion == 'c' || dp->conversion == 's')
5216                       {
5217                         /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5218                            TYPE_WIDE_STRING.
5219                            The result string is not certainly ASCII.  */
5220                         const TCHAR_T *tmpsrc;
5221                         DCHAR_T *tmpdst;
5222                         size_t tmpdst_len;
5223                         /* This code assumes that TCHAR_T is 'char'.  */
5224                         typedef int TCHAR_T_verify
5225                                     [2 * (sizeof (TCHAR_T) == 1) - 1];
5226 # if USE_SNPRINTF
5227                         tmpsrc = (TCHAR_T *) (result + length);
5228 # else
5229                         tmpsrc = tmp;
5230 # endif
5231                         tmpdst =
5232                           DCHAR_CONV_FROM_ENCODING (locale_charset (),
5233                                                     iconveh_question_mark,
5234                                                     tmpsrc, count,
5235                                                     NULL,
5236                                                     NULL, &tmpdst_len);
5237                         if (tmpdst == NULL)
5238                           {
5239                             int saved_errno = errno;
5240                             if (!(result == resultbuf || result == NULL))
5241                               free (result);
5242                             if (buf_malloced != NULL)
5243                               free (buf_malloced);
5244                             CLEANUP ();
5245                             errno = saved_errno;
5246                             return NULL;
5247                           }
5248                         ENSURE_ALLOCATION (xsum (length, tmpdst_len));
5249                         DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5250                         free (tmpdst);
5251                         count = tmpdst_len;
5252                       }
5253                     else
5254                       {
5255                         /* The result string is ASCII.
5256                            Simple 1:1 conversion.  */
5257 # if USE_SNPRINTF
5258                         /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5259                            no-op conversion, in-place on the array starting
5260                            at (result + length).  */
5261                         if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5262 # endif
5263                           {
5264                             const TCHAR_T *tmpsrc;
5265                             DCHAR_T *tmpdst;
5266                             size_t n;
5267
5268 # if USE_SNPRINTF
5269                             if (result == resultbuf)
5270                               {
5271                                 tmpsrc = (TCHAR_T *) (result + length);
5272                                 /* ENSURE_ALLOCATION will not move tmpsrc
5273                                    (because it's part of resultbuf).  */
5274                                 ENSURE_ALLOCATION (xsum (length, count));
5275                               }
5276                             else
5277                               {
5278                                 /* ENSURE_ALLOCATION will move the array
5279                                    (because it uses realloc().  */
5280                                 ENSURE_ALLOCATION (xsum (length, count));
5281                                 tmpsrc = (TCHAR_T *) (result + length);
5282                               }
5283 # else
5284                             tmpsrc = tmp;
5285                             ENSURE_ALLOCATION (xsum (length, count));
5286 # endif
5287                             tmpdst = result + length;
5288                             /* Copy backwards, because of overlapping.  */
5289                             tmpsrc += count;
5290                             tmpdst += count;
5291                             for (n = count; n > 0; n--)
5292                               *--tmpdst = (unsigned char) *--tmpsrc;
5293                           }
5294                       }
5295 #endif
5296
5297 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5298                     /* Make room for the result.  */
5299                     if (count > allocated - length)
5300                       {
5301                         /* Need at least count elements.  But allocate
5302                            proportionally.  */
5303                         size_t n =
5304                           xmax (xsum (length, count), xtimes (allocated, 2));
5305
5306                         ENSURE_ALLOCATION (n);
5307                       }
5308 #endif
5309
5310                     /* Here count <= allocated - length.  */
5311
5312                     /* Perform padding.  */
5313 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5314                     if (pad_ourselves && has_width)
5315                       {
5316                         size_t w;
5317 # if ENABLE_UNISTDIO
5318                         /* Outside POSIX, it's preferrable to compare the width
5319                            against the number of _characters_ of the converted
5320                            value.  */
5321                         w = DCHAR_MBSNLEN (result + length, count);
5322 # else
5323                         /* The width is compared against the number of _bytes_
5324                            of the converted value, says POSIX.  */
5325                         w = count;
5326 # endif
5327                         if (w < width)
5328                           {
5329                             size_t pad = width - w;
5330
5331                             /* Make room for the result.  */
5332                             if (xsum (count, pad) > allocated - length)
5333                               {
5334                                 /* Need at least count + pad elements.  But
5335                                    allocate proportionally.  */
5336                                 size_t n =
5337                                   xmax (xsum3 (length, count, pad),
5338                                         xtimes (allocated, 2));
5339
5340 # if USE_SNPRINTF
5341                                 length += count;
5342                                 ENSURE_ALLOCATION (n);
5343                                 length -= count;
5344 # else
5345                                 ENSURE_ALLOCATION (n);
5346 # endif
5347                               }
5348                             /* Here count + pad <= allocated - length.  */
5349
5350                             {
5351 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5352                               DCHAR_T * const rp = result + length;
5353 # else
5354                               DCHAR_T * const rp = tmp;
5355 # endif
5356                               DCHAR_T *p = rp + count;
5357                               DCHAR_T *end = p + pad;
5358                               DCHAR_T *pad_ptr;
5359 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5360                               if (dp->conversion == 'c'
5361                                   || dp->conversion == 's')
5362                                 /* No zero-padding for string directives.  */
5363                                 pad_ptr = NULL;
5364                               else
5365 # endif
5366                                 {
5367                                   pad_ptr = (*rp == '-' ? rp + 1 : rp);
5368                                   /* No zero-padding of "inf" and "nan".  */
5369                                   if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5370                                       || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5371                                     pad_ptr = NULL;
5372                                 }
5373                               /* The generated string now extends from rp to p,
5374                                  with the zero padding insertion point being at
5375                                  pad_ptr.  */
5376
5377                               count = count + pad; /* = end - rp */
5378
5379                               if (flags & FLAG_LEFT)
5380                                 {
5381                                   /* Pad with spaces on the right.  */
5382                                   for (; pad > 0; pad--)
5383                                     *p++ = ' ';
5384                                 }
5385                               else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5386                                 {
5387                                   /* Pad with zeroes.  */
5388                                   DCHAR_T *q = end;
5389
5390                                   while (p > pad_ptr)
5391                                     *--q = *--p;
5392                                   for (; pad > 0; pad--)
5393                                     *p++ = '0';
5394                                 }
5395                               else
5396                                 {
5397                                   /* Pad with spaces on the left.  */
5398                                   DCHAR_T *q = end;
5399
5400                                   while (p > rp)
5401                                     *--q = *--p;
5402                                   for (; pad > 0; pad--)
5403                                     *p++ = ' ';
5404                                 }
5405                             }
5406                           }
5407                       }
5408 #endif
5409
5410                     /* Here still count <= allocated - length.  */
5411
5412 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5413                     /* The snprintf() result did fit.  */
5414 #else
5415                     /* Append the sprintf() result.  */
5416                     memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5417 #endif
5418 #if !USE_SNPRINTF
5419                     if (tmp != tmpbuf)
5420                       free (tmp);
5421 #endif
5422
5423 #if NEED_PRINTF_DIRECTIVE_F
5424                     if (dp->conversion == 'F')
5425                       {
5426                         /* Convert the %f result to upper case for %F.  */
5427                         DCHAR_T *rp = result + length;
5428                         size_t rc;
5429                         for (rc = count; rc > 0; rc--, rp++)
5430                           if (*rp >= 'a' && *rp <= 'z')
5431                             *rp = *rp - 'a' + 'A';
5432                       }
5433 #endif
5434
5435                     length += count;
5436                     break;
5437                   }
5438               }
5439           }
5440       }
5441
5442     /* Add the final NUL.  */
5443     ENSURE_ALLOCATION (xsum (length, 1));
5444     result[length] = '\0';
5445
5446     if (result != resultbuf && length + 1 < allocated)
5447       {
5448         /* Shrink the allocated memory if possible.  */
5449         DCHAR_T *memory;
5450
5451         memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5452         if (memory != NULL)
5453           result = memory;
5454       }
5455
5456     if (buf_malloced != NULL)
5457       free (buf_malloced);
5458     CLEANUP ();
5459     *lengthp = length;
5460     /* Note that we can produce a big string of a length > INT_MAX.  POSIX
5461        says that snprintf() fails with errno = EOVERFLOW in this case, but
5462        that's only because snprintf() returns an 'int'.  This function does
5463        not have this limitation.  */
5464     return result;
5465
5466 #if USE_SNPRINTF
5467   overflow:
5468     if (!(result == resultbuf || result == NULL))
5469       free (result);
5470     if (buf_malloced != NULL)
5471       free (buf_malloced);
5472     CLEANUP ();
5473     errno = EOVERFLOW;
5474     return NULL;
5475 #endif
5476
5477   out_of_memory:
5478     if (!(result == resultbuf || result == NULL))
5479       free (result);
5480     if (buf_malloced != NULL)
5481       free (buf_malloced);
5482   out_of_memory_1:
5483     CLEANUP ();
5484     errno = ENOMEM;
5485     return NULL;
5486   }
5487 }
5488
5489 #undef TCHARS_PER_DCHAR
5490 #undef SNPRINTF
5491 #undef USE_SNPRINTF
5492 #undef DCHAR_SET
5493 #undef DCHAR_CPY
5494 #undef PRINTF_PARSE
5495 #undef DIRECTIVES
5496 #undef DIRECTIVE
5497 #undef DCHAR_IS_TCHAR
5498 #undef TCHAR_T
5499 #undef DCHAR_T
5500 #undef FCHAR_T
5501 #undef VASNPRINTF