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