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