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