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