1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 2002-2024 Free Software Foundation, Inc.
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
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.
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.
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.
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. */
57 # define _GNU_SOURCE 1
64 /* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's
65 use of CHECK macros expands to code that is too complicated for gcc
66 -fanalyzer. Suppress the resulting bogus warnings. */
68 # pragma GCC diagnostic ignored "-Wanalyzer-null-argument"
75 # if WIDE_CHAR_VERSION
76 # include "vasnwprintf.h"
78 # include "vasnprintf.h"
82 #include <locale.h> /* localeconv() */
83 #include <stdio.h> /* snprintf(), sprintf() */
84 #include <stdlib.h> /* abort(), malloc(), realloc(), free() */
85 #include <string.h> /* memcpy(), strlen() */
86 #include <wchar.h> /* mbstate_t, mbrtowc(), mbrlen(), wcrtomb(), mbszero() */
87 #include <errno.h> /* errno */
88 #include <limits.h> /* CHAR_BIT, INT_WIDTH, LONG_WIDTH */
89 #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
91 # include <langinfo.h>
94 # if WIDE_CHAR_VERSION
95 # include "wprintf-parse.h"
97 # include "printf-parse.h"
101 /* Checked size_t computations. */
104 #include "attribute.h"
106 #if NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
111 #if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
113 # include "isnand-nolibm.h"
116 #if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
118 # include "isnanl-nolibm.h"
122 #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
124 # include "isnand-nolibm.h"
125 # include "printf-frexp.h"
128 #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
130 # include "isnanl-nolibm.h"
131 # include "printf-frexpl.h"
135 /* Default parameters. */
137 # if WIDE_CHAR_VERSION
138 # define VASNPRINTF vasnwprintf
139 # define FCHAR_T wchar_t
140 # define DCHAR_T wchar_t
141 # define DIRECTIVE wchar_t_directive
142 # define DIRECTIVES wchar_t_directives
143 # define PRINTF_PARSE wprintf_parse
144 # define DCHAR_CPY wmemcpy
145 # define DCHAR_SET wmemset
147 # define VASNPRINTF vasnprintf
148 # define FCHAR_T char
149 # define DCHAR_T char
150 # define TCHAR_T char
151 # define DCHAR_IS_TCHAR 1
152 # define DIRECTIVE char_directive
153 # define DIRECTIVES char_directives
154 # define PRINTF_PARSE printf_parse
155 # define DCHAR_CPY memcpy
156 # define DCHAR_SET memset
159 #if WIDE_CHAR_VERSION
160 /* DCHAR_T is wchar_t. */
161 # if HAVE_DECL__SNWPRINTF || (HAVE_SWPRINTF && HAVE_WORKING_SWPRINTF)
162 # define TCHAR_T wchar_t
163 # define DCHAR_IS_TCHAR 1
164 # define USE_SNPRINTF 1
165 # if HAVE_DECL__SNWPRINTF
166 /* On Windows, the function swprintf() has a different signature than
167 on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
168 instead. The mingw function snwprintf() has fewer bugs than the
169 MSVCRT function _snwprintf(), so prefer that. */
170 # if defined __MINGW32__
171 # define SNPRINTF snwprintf
173 # define SNPRINTF _snwprintf
174 # define USE_MSVC__SNPRINTF 1
178 # define SNPRINTF swprintf
181 /* Old platforms such as NetBSD 3.0, OpenBSD 3.8, HP-UX 11.00, IRIX 6.5. */
182 # define TCHAR_T char
185 #if !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR
186 /* TCHAR_T is char. */
187 /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
188 But don't use it on BeOS, since BeOS snprintf produces no output if the
189 size argument is >= 0x3000000.
190 Also don't use it on Linux libc5, since there snprintf with size = 1
191 writes any output without bounds, like sprintf. */
192 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
193 # define USE_SNPRINTF 1
195 # define USE_SNPRINTF 0
197 # if HAVE_DECL__SNPRINTF
198 /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT
199 function _snprintf(), so prefer that. */
200 # if defined __MINGW32__
201 # define SNPRINTF snprintf
202 /* Here we need to call the native snprintf, not rpl_snprintf. */
205 /* MSVC versions < 14 did not have snprintf, only _snprintf. */
206 # define SNPRINTF _snprintf
207 # define USE_MSVC__SNPRINTF 1
211 # define SNPRINTF snprintf
212 /* Here we need to call the native snprintf, not rpl_snprintf. */
216 /* Here we need to call the native sprintf, not rpl_sprintf. */
219 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
220 warnings in this file. Use -Dlint to suppress them. */
221 #if defined GCC_LINT || defined lint
222 # define IF_LINT(Code) Code
224 # define IF_LINT(Code) /* empty */
227 /* Avoid some warnings from "gcc -Wshadow".
228 This file doesn't use the exp() and remainder() functions. */
232 #define remainder rem
234 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION
235 # if (HAVE_STRNLEN && !defined _AIX)
236 # define local_strnlen strnlen
238 # ifndef local_strnlen_defined
239 # define local_strnlen_defined 1
241 local_strnlen (const char *string
, size_t maxlen
)
243 const char *end
= memchr (string
, '\0', maxlen
);
244 return end
? (size_t) (end
- string
) : maxlen
;
250 #if (((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_WPRINTF_DIRECTIVE_LC) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
252 # define local_wcslen wcslen
254 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
255 a dependency towards this library, here is a local substitute.
256 Define this substitute only once, even if this file is included
257 twice in the same compilation unit. */
258 # ifndef local_wcslen_defined
259 # define local_wcslen_defined 1
261 local_wcslen (const wchar_t *s
)
265 for (ptr
= s
; *ptr
!= (wchar_t) 0; ptr
++)
273 #if (!USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
274 # if HAVE_WCSNLEN && HAVE_DECL_WCSNLEN
275 # define local_wcsnlen wcsnlen
277 # ifndef local_wcsnlen_defined
278 # define local_wcsnlen_defined 1
280 local_wcsnlen (const wchar_t *s
, size_t maxlen
)
284 for (ptr
= s
; maxlen
> 0 && *ptr
!= (wchar_t) 0; ptr
++, maxlen
--)
292 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T)) && !WIDE_CHAR_VERSION
293 # if ENABLE_WCHAR_FALLBACK
295 wctomb_fallback (char *s
, wchar_t wc
)
297 static char const hex
[16] = "0123456789ABCDEF";
300 if (sizeof (wchar_t) > 2 && wc
> 0xffff)
302 # if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
307 s
[2] = hex
[(wc
& 0xf0000000U
) >> 28];
308 s
[3] = hex
[(wc
& 0xf000000U
) >> 24];
309 s
[4] = hex
[(wc
& 0xf00000U
) >> 20];
310 s
[5] = hex
[(wc
& 0xf0000U
) >> 16];
311 s
[6] = hex
[(wc
& 0xf000U
) >> 12];
312 s
[7] = hex
[(wc
& 0xf00U
) >> 8];
313 s
[8] = hex
[(wc
& 0xf0U
) >> 4];
314 s
[9] = hex
[wc
& 0xfU
];
319 # if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
324 s
[2] = hex
[(wc
& 0xf000U
) >> 12];
325 s
[3] = hex
[(wc
& 0xf00U
) >> 8];
326 s
[4] = hex
[(wc
& 0xf0U
) >> 4];
327 s
[5] = hex
[wc
& 0xfU
];
331 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
333 local_wcrtomb (char *s
, wchar_t wc
, mbstate_t *ps
)
335 size_t count
= wcrtomb (s
, wc
, ps
);
336 if (count
== (size_t)(-1))
337 count
= wctomb_fallback (s
, wc
);
342 local_wctomb (char *s
, wchar_t wc
)
344 int count
= wctomb (s
, wc
);
346 count
= wctomb_fallback (s
, wc
);
349 # define local_wcrtomb(S, WC, PS) local_wctomb ((S), (WC))
352 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
353 # define local_wcrtomb(S, WC, PS) wcrtomb ((S), (WC), (PS))
355 # define local_wcrtomb(S, WC, PS) wctomb ((S), (WC))
360 #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
361 /* Determine the decimal-point character according to the current locale. */
362 # ifndef decimal_point_char_defined
363 # define decimal_point_char_defined 1
365 decimal_point_char (void)
368 /* Determine it in a multithread-safe way. We know nl_langinfo is
369 multithread-safe on glibc systems and Mac OS X systems, but is not required
370 to be multithread-safe by POSIX. sprintf(), however, is multithread-safe.
371 localeconv() is rarely multithread-safe. */
372 # if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
373 point
= nl_langinfo (RADIXCHAR
);
376 sprintf (pointbuf
, "%#.0f", 1.0);
377 point
= &pointbuf
[1];
379 point
= localeconv () -> decimal_point
;
381 /* The decimal point is always a single byte: either '.' or ','. */
382 return (point
[0] != '\0' ? point
[0] : '.');
387 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE
389 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
391 is_infinite_or_zero (double x
)
393 return isnand (x
) || x
+ x
== x
;
398 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE
400 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
402 is_infinite_or_zerol (long double x
)
404 return isnanl (x
) || x
+ x
== x
;
409 #if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE
411 /* Converting 'long double' to decimal without rare rounding bugs requires
412 real bignums. We use the naming conventions of GNU gmp, but vastly simpler
413 (and slower) algorithms. */
415 typedef unsigned int mp_limb_t
;
416 # define GMP_LIMB_BITS 32
417 static_assert (sizeof (mp_limb_t
) * CHAR_BIT
== GMP_LIMB_BITS
);
419 typedef unsigned long long mp_twolimb_t
;
420 # define GMP_TWOLIMB_BITS 64
421 static_assert (sizeof (mp_twolimb_t
) * CHAR_BIT
== GMP_TWOLIMB_BITS
);
423 /* Representation of a bignum >= 0. */
427 mp_limb_t
*limbs
; /* Bits in little-endian order, allocated with malloc(). */
430 /* Compute the product of two bignums >= 0.
431 Return the allocated memory in case of success, NULL in case of memory
432 allocation failure. */
434 multiply (mpn_t src1
, mpn_t src2
, mpn_t
*dest
)
441 if (src1
.nlimbs
<= src2
.nlimbs
)
455 /* Now 0 <= len1 <= len2. */
458 /* src1 or src2 is zero. */
460 dest
->limbs
= (mp_limb_t
*) malloc (1);
464 /* Here 1 <= len1 <= len2. */
470 dp
= (mp_limb_t
*) malloc (dlen
* sizeof (mp_limb_t
));
473 for (k
= len2
; k
> 0; )
475 for (i
= 0; i
< len1
; i
++)
477 mp_limb_t digit1
= p1
[i
];
478 mp_twolimb_t carry
= 0;
479 for (j
= 0; j
< len2
; j
++)
481 mp_limb_t digit2
= p2
[j
];
482 carry
+= (mp_twolimb_t
) digit1
* (mp_twolimb_t
) digit2
;
484 dp
[i
+ j
] = (mp_limb_t
) carry
;
485 carry
= carry
>> GMP_LIMB_BITS
;
487 dp
[i
+ len2
] = (mp_limb_t
) carry
;
490 while (dlen
> 0 && dp
[dlen
- 1] == 0)
498 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
499 a is written as a = q * b + r with 0 <= r < b. q is the quotient, r
501 Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
503 Return the allocated memory in case of success, NULL in case of memory
504 allocation failure. */
506 divide (mpn_t a
, mpn_t b
, mpn_t
*q
)
509 First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
510 with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
511 If m<n, then q:=0 and r:=a.
512 If m>=n=1, perform a single-precision division:
515 {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
516 = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
517 j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
518 Normalise [q[m-1],...,q[0]], yields q.
519 If m>=n>1, perform a multiple-precision division:
520 We have a/b < beta^(m-n+1).
521 s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
522 Shift a and b left by s bits, copying them. r:=a.
523 r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
524 For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
526 q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
527 In case of overflow (q* >= beta) set q* := beta-1.
528 Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
529 and c3 := b[n-2] * q*.
530 {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
531 occurred. Furthermore 0 <= c3 < beta^2.
532 If there was overflow and
533 r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
534 the next test can be skipped.}
535 While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
536 Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
538 Put r := r - b * q* * beta^j. In detail:
539 [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
540 hence: u:=0, for i:=0 to n-1 do
542 r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
543 u:=u div beta (+ 1, if carry in subtraction)
545 {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
547 the carry u does not overflow.}
548 If a negative carry occurs, put q* := q* - 1
549 and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
551 Normalise [q[m-n],..,q[0]]; this yields the quotient q.
552 Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
554 The room for q[j] can be allocated at the memory location of r[n+j].
555 Finally, round-to-even:
556 Shift r left by 1 bit.
557 If r > b or if r = b and q[0] is odd, q := q+1.
559 const mp_limb_t
*a_ptr
= a
.limbs
;
560 size_t a_len
= a
.nlimbs
;
561 const mp_limb_t
*b_ptr
= b
.limbs
;
562 size_t b_len
= b
.nlimbs
;
564 mp_limb_t
*tmp_roomptr
= NULL
;
570 /* Allocate room for a_len+2 digits.
571 (Need a_len+1 digits for the real division and 1 more digit for the
572 final rounding of q.) */
573 roomptr
= (mp_limb_t
*) malloc ((a_len
+ 2) * sizeof (mp_limb_t
));
578 while (a_len
> 0 && a_ptr
[a_len
- 1] == 0)
585 /* Division by zero. */
587 if (b_ptr
[b_len
- 1] == 0)
593 /* Here m = a_len >= 0 and n = b_len > 0. */
597 /* m<n: trivial case. q=0, r := copy of a. */
600 memcpy (r_ptr
, a_ptr
, a_len
* sizeof (mp_limb_t
));
601 q_ptr
= roomptr
+ a_len
;
606 /* n=1: single precision division.
607 beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
611 mp_limb_t den
= b_ptr
[0];
612 mp_limb_t remainder
= 0;
613 const mp_limb_t
*sourceptr
= a_ptr
+ a_len
;
614 mp_limb_t
*destptr
= q_ptr
+ a_len
;
616 for (count
= a_len
; count
> 0; count
--)
619 ((mp_twolimb_t
) remainder
<< GMP_LIMB_BITS
) | *--sourceptr
;
620 *--destptr
= num
/ den
;
621 remainder
= num
% den
;
623 /* Normalise and store r. */
626 r_ptr
[0] = remainder
;
633 if (q_ptr
[q_len
- 1] == 0)
639 /* n>1: multiple precision division.
640 beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==>
641 beta^(m-n-1) <= a/b < beta^(m-n+1). */
645 mp_limb_t msd
= b_ptr
[b_len
- 1]; /* = b[n-1], > 0 */
646 /* Determine s = GMP_LIMB_BITS - integer_length (msd).
647 Code copied from gnulib's integer_length.c. */
648 # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
649 || (__clang_major__ >= 4)
650 s
= __builtin_clz (msd
);
652 # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
653 if (GMP_LIMB_BITS
<= DBL_MANT_BIT
)
655 /* Use 'double' operations.
656 Assumes an IEEE 754 'double' implementation. */
657 # define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
658 # define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
660 ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
661 union { double value
; unsigned int word
[NWORDS
]; } m
;
663 /* Use a single integer to floating-point conversion. */
667 - (((m
.word
[DBL_EXPBIT0_WORD
] >> DBL_EXPBIT0_BIT
) & DBL_EXP_MASK
)
703 /* 0 <= s < GMP_LIMB_BITS.
704 Copy b, shifting it left by s bits. */
707 tmp_roomptr
= (mp_limb_t
*) malloc (b_len
* sizeof (mp_limb_t
));
708 if (tmp_roomptr
== NULL
)
714 const mp_limb_t
*sourceptr
= b_ptr
;
715 mp_limb_t
*destptr
= tmp_roomptr
;
716 mp_twolimb_t accu
= 0;
718 for (count
= b_len
; count
> 0; count
--)
720 accu
+= (mp_twolimb_t
) *sourceptr
++ << s
;
721 *destptr
++ = (mp_limb_t
) accu
;
722 accu
= accu
>> GMP_LIMB_BITS
;
724 /* accu must be zero, since that was how s was determined. */
730 /* Copy a, shifting it left by s bits, yields r.
732 At the beginning: r = roomptr[0..a_len],
733 at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */
737 memcpy (r_ptr
, a_ptr
, a_len
* sizeof (mp_limb_t
));
742 const mp_limb_t
*sourceptr
= a_ptr
;
743 mp_limb_t
*destptr
= r_ptr
;
744 mp_twolimb_t accu
= 0;
746 for (count
= a_len
; count
> 0; count
--)
748 accu
+= (mp_twolimb_t
) *sourceptr
++ << s
;
749 *destptr
++ = (mp_limb_t
) accu
;
750 accu
= accu
>> GMP_LIMB_BITS
;
752 *destptr
++ = (mp_limb_t
) accu
;
754 q_ptr
= roomptr
+ b_len
;
755 q_len
= a_len
- b_len
+ 1; /* q will have m-n+1 limbs */
757 size_t j
= a_len
- b_len
; /* m-n */
758 mp_limb_t b_msd
= b_ptr
[b_len
- 1]; /* b[n-1] */
759 mp_limb_t b_2msd
= b_ptr
[b_len
- 2]; /* b[n-2] */
760 mp_twolimb_t b_msdd
= /* b[n-1]*beta+b[n-2] */
761 ((mp_twolimb_t
) b_msd
<< GMP_LIMB_BITS
) | b_2msd
;
762 /* Division loop, traversed m-n+1 times.
763 j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */
768 if (r_ptr
[j
+ b_len
] < b_msd
) /* r[j+n] < b[n-1] ? */
770 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */
772 ((mp_twolimb_t
) r_ptr
[j
+ b_len
] << GMP_LIMB_BITS
)
773 | r_ptr
[j
+ b_len
- 1];
774 q_star
= num
/ b_msd
;
779 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */
780 q_star
= (mp_limb_t
)~(mp_limb_t
)0; /* q* = beta-1 */
781 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
782 <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
783 <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
785 If yes, jump directly to the subtraction loop.
786 (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
787 <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
788 if (r_ptr
[j
+ b_len
] > b_msd
789 || (c1
= r_ptr
[j
+ b_len
- 1] + b_msd
) < b_msd
)
790 /* r[j+n] >= b[n-1]+1 or
791 r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
796 c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
798 mp_twolimb_t c2
= /* c1*beta+r[j+n-2] */
799 ((mp_twolimb_t
) c1
<< GMP_LIMB_BITS
) | r_ptr
[j
+ b_len
- 2];
800 mp_twolimb_t c3
= /* b[n-2] * q* */
801 (mp_twolimb_t
) b_2msd
* (mp_twolimb_t
) q_star
;
802 /* While c2 < c3, increase c2 and decrease c3.
803 Consider c3-c2. While it is > 0, decrease it by
804 b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2
805 this can happen only twice. */
808 q_star
= q_star
- 1; /* q* := q* - 1 */
809 if (c3
- c2
> b_msdd
)
810 q_star
= q_star
- 1; /* q* := q* - 1 */
816 /* Subtract r := r - b * q* * beta^j. */
819 const mp_limb_t
*sourceptr
= b_ptr
;
820 mp_limb_t
*destptr
= r_ptr
+ j
;
821 mp_twolimb_t carry
= 0;
823 for (count
= b_len
; count
> 0; count
--)
825 /* Here 0 <= carry <= q*. */
828 + (mp_twolimb_t
) q_star
* (mp_twolimb_t
) *sourceptr
++
829 + (mp_limb_t
) ~(*destptr
);
830 /* Here 0 <= carry <= beta*q* + beta-1. */
831 *destptr
++ = ~(mp_limb_t
) carry
;
832 carry
= carry
>> GMP_LIMB_BITS
; /* <= q* */
834 cr
= (mp_limb_t
) carry
;
836 /* Subtract cr from r_ptr[j + b_len], then forget about
838 if (cr
> r_ptr
[j
+ b_len
])
840 /* Subtraction gave a carry. */
841 q_star
= q_star
- 1; /* q* := q* - 1 */
844 const mp_limb_t
*sourceptr
= b_ptr
;
845 mp_limb_t
*destptr
= r_ptr
+ j
;
848 for (count
= b_len
; count
> 0; count
--)
850 mp_limb_t source1
= *sourceptr
++;
851 mp_limb_t source2
= *destptr
;
852 *destptr
++ = source1
+ source2
+ carry
;
855 ? source1
>= (mp_limb_t
) ~source2
856 : source1
> (mp_limb_t
) ~source2
);
859 /* Forget about the carry and about r[j+n]. */
862 /* q* is determined. Store it as q[j]. */
871 if (q_ptr
[q_len
- 1] == 0)
873 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
874 b is shifted left by s bits. */
875 /* Shift r right by s bits. */
878 mp_limb_t ptr
= r_ptr
+ r_len
;
879 mp_twolimb_t accu
= 0;
881 for (count
= r_len
; count
> 0; count
--)
883 accu
= (mp_twolimb_t
) (mp_limb_t
) accu
<< GMP_LIMB_BITS
;
884 accu
+= (mp_twolimb_t
) *--ptr
<< (GMP_LIMB_BITS
- s
);
885 *ptr
= (mp_limb_t
) (accu
>> GMP_LIMB_BITS
);
890 while (r_len
> 0 && r_ptr
[r_len
- 1] == 0)
893 /* Compare r << 1 with b. */
901 (i
<= r_len
&& i
> 0 ? r_ptr
[i
- 1] >> (GMP_LIMB_BITS
- 1) : 0)
902 | (i
< r_len
? r_ptr
[i
] << 1 : 0);
903 mp_limb_t b_i
= (i
< b_len
? b_ptr
[i
] : 0);
913 if (q_len
> 0 && ((q_ptr
[0] & 1) != 0))
918 for (i
= 0; i
< q_len
; i
++)
919 if (++(q_ptr
[i
]) != 0)
930 /* Avoid pointless GCC warning "argument 1 value '18446744073709551615' exceeds
931 maximum object size 9223372036854775807", triggered by the use of xsum as
932 argument of malloc. */
934 # pragma GCC diagnostic push
935 # pragma GCC diagnostic ignored "-Walloc-size-larger-than="
938 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
940 Destroys the contents of a.
941 Return the allocated memory - containing the decimal digits in low-to-high
942 order, terminated with a NUL character - in case of success, NULL in case
943 of memory allocation failure. */
945 convert_to_decimal (mpn_t a
, size_t extra_zeroes
)
947 mp_limb_t
*a_ptr
= a
.limbs
;
948 size_t a_len
= a
.nlimbs
;
949 /* 0.03345 is slightly larger than log(2)/(9*log(10)). */
950 size_t c_len
= 9 * ((size_t)(a_len
* (GMP_LIMB_BITS
* 0.03345f
)) + 1);
951 /* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the
952 digits of a, followed by 1 byte for the terminating NUL. */
953 char *c_ptr
= (char *) malloc (xsum (xsum (extra_zeroes
, c_len
), 1));
957 for (; extra_zeroes
> 0; extra_zeroes
--)
961 /* Divide a by 10^9, in-place. */
962 mp_limb_t remainder
= 0;
963 mp_limb_t
*ptr
= a_ptr
+ a_len
;
965 for (count
= a_len
; count
> 0; count
--)
968 ((mp_twolimb_t
) remainder
<< GMP_LIMB_BITS
) | *--ptr
;
969 *ptr
= num
/ 1000000000;
970 remainder
= num
% 1000000000;
972 /* Store the remainder as 9 decimal digits. */
973 for (count
= 9; count
> 0; count
--)
975 *d_ptr
++ = '0' + (remainder
% 10);
976 remainder
= remainder
/ 10;
979 if (a_ptr
[a_len
- 1] == 0)
982 /* Remove leading zeroes. */
983 while (d_ptr
> c_ptr
&& d_ptr
[-1] == '0')
985 /* But keep at least one zero. */
988 /* Terminate the string. */
995 # pragma GCC diagnostic pop
998 # if NEED_PRINTF_LONG_DOUBLE
1000 /* Assuming x is finite and >= 0:
1001 write x as x = 2^e * m, where m is a bignum.
1002 Return the allocated memory in case of success, NULL in case of memory
1003 allocation failure. */
1005 decode_long_double (long double x
, int *ep
, mpn_t
*mp
)
1012 /* Allocate memory for result. */
1013 m
.nlimbs
= (LDBL_MANT_BIT
+ GMP_LIMB_BITS
- 1) / GMP_LIMB_BITS
;
1014 m
.limbs
= (mp_limb_t
*) malloc (m
.nlimbs
* sizeof (mp_limb_t
));
1015 if (m
.limbs
== NULL
)
1017 /* Split into exponential part and mantissa. */
1018 y
= frexpl (x
, &exp
);
1019 if (!(y
>= 0.0L && y
< 1.0L))
1021 /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
1022 latter is an integer. */
1023 /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
1024 I'm not sure whether it's safe to cast a 'long double' value between
1025 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1026 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1028 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
1029 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1032 y
*= (mp_limb_t
) 1 << (LDBL_MANT_BIT
% (GMP_LIMB_BITS
/ 2));
1035 if (!(y
>= 0.0L && y
< 1.0L))
1037 y
*= (mp_limb_t
) 1 << (GMP_LIMB_BITS
/ 2);
1040 if (!(y
>= 0.0L && y
< 1.0L))
1042 m
.limbs
[LDBL_MANT_BIT
/ GMP_LIMB_BITS
] = (hi
<< (GMP_LIMB_BITS
/ 2)) | lo
;
1047 y
*= (mp_limb_t
) 1 << (LDBL_MANT_BIT
% GMP_LIMB_BITS
);
1050 if (!(y
>= 0.0L && y
< 1.0L))
1052 m
.limbs
[LDBL_MANT_BIT
/ GMP_LIMB_BITS
] = d
;
1056 for (i
= LDBL_MANT_BIT
/ GMP_LIMB_BITS
; i
> 0; )
1059 y
*= (mp_limb_t
) 1 << (GMP_LIMB_BITS
/ 2);
1062 if (!(y
>= 0.0L && y
< 1.0L))
1064 y
*= (mp_limb_t
) 1 << (GMP_LIMB_BITS
/ 2);
1067 if (!(y
>= 0.0L && y
< 1.0L))
1069 m
.limbs
[--i
] = (hi
<< (GMP_LIMB_BITS
/ 2)) | lo
;
1071 # if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
1077 while (m
.nlimbs
> 0 && m
.limbs
[m
.nlimbs
- 1] == 0)
1080 *ep
= exp
- LDBL_MANT_BIT
;
1086 # if NEED_PRINTF_DOUBLE
1088 /* Assuming x is finite and >= 0:
1089 write x as x = 2^e * m, where m is a bignum.
1090 Return the allocated memory in case of success, NULL in case of memory
1091 allocation failure. */
1093 decode_double (double x
, int *ep
, mpn_t
*mp
)
1100 /* Allocate memory for result. */
1101 m
.nlimbs
= (DBL_MANT_BIT
+ GMP_LIMB_BITS
- 1) / GMP_LIMB_BITS
;
1102 m
.limbs
= (mp_limb_t
*) malloc (m
.nlimbs
* sizeof (mp_limb_t
));
1103 if (m
.limbs
== NULL
)
1105 /* Split into exponential part and mantissa. */
1106 y
= frexp (x
, &exp
);
1107 if (!(y
>= 0.0 && y
< 1.0))
1109 /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
1110 latter is an integer. */
1111 /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
1112 I'm not sure whether it's safe to cast a 'double' value between
1113 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1114 'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1116 # if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
1117 # if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1120 y
*= (mp_limb_t
) 1 << (DBL_MANT_BIT
% (GMP_LIMB_BITS
/ 2));
1123 if (!(y
>= 0.0 && y
< 1.0))
1125 y
*= (mp_limb_t
) 1 << (GMP_LIMB_BITS
/ 2);
1128 if (!(y
>= 0.0 && y
< 1.0))
1130 m
.limbs
[DBL_MANT_BIT
/ GMP_LIMB_BITS
] = (hi
<< (GMP_LIMB_BITS
/ 2)) | lo
;
1135 y
*= (mp_limb_t
) 1 << (DBL_MANT_BIT
% GMP_LIMB_BITS
);
1138 if (!(y
>= 0.0 && y
< 1.0))
1140 m
.limbs
[DBL_MANT_BIT
/ GMP_LIMB_BITS
] = d
;
1144 for (i
= DBL_MANT_BIT
/ GMP_LIMB_BITS
; i
> 0; )
1147 y
*= (mp_limb_t
) 1 << (GMP_LIMB_BITS
/ 2);
1150 if (!(y
>= 0.0 && y
< 1.0))
1152 y
*= (mp_limb_t
) 1 << (GMP_LIMB_BITS
/ 2);
1155 if (!(y
>= 0.0 && y
< 1.0))
1157 m
.limbs
[--i
] = (hi
<< (GMP_LIMB_BITS
/ 2)) | lo
;
1162 while (m
.nlimbs
> 0 && m
.limbs
[m
.nlimbs
- 1] == 0)
1165 *ep
= exp
- DBL_MANT_BIT
;
1171 /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
1172 Returns the decimal representation of round (x * 10^n).
1173 Return the allocated memory - containing the decimal digits in low-to-high
1174 order, terminated with a NUL character - in case of success, NULL in case
1175 of memory allocation failure. */
1177 scale10_round_decimal_decoded (int e
, mpn_t m
, void *memory
, int n
)
1180 size_t extra_zeroes
;
1183 mp_limb_t
*pow5_ptr
;
1185 unsigned int s_limbs
;
1186 unsigned int s_bits
;
1192 /* x = 2^e * m, hence
1193 y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1194 = round (2^s * 5^n * m). */
1197 /* Factor out a common power of 10 if possible. */
1200 extra_zeroes
= (s
< n
? s
: n
);
1204 /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1205 Before converting to decimal, we need to compute
1206 z = round (2^s * 5^n * m). */
1207 /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1208 sign. 2.322 is slightly larger than log(5)/log(2). */
1209 abs_n
= (n
>= 0 ? n
: -n
);
1210 abs_s
= (s
>= 0 ? s
: -s
);
1211 pow5_ptr
= (mp_limb_t
*) malloc (((int)(abs_n
* (2.322f
/ GMP_LIMB_BITS
)) + 1
1212 + abs_s
/ GMP_LIMB_BITS
+ 1)
1213 * sizeof (mp_limb_t
));
1214 if (pow5_ptr
== NULL
)
1219 /* Initialize with 1. */
1222 /* Multiply with 5^|n|. */
1225 static mp_limb_t
const small_pow5
[13 + 1] =
1227 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1228 48828125, 244140625, 1220703125
1231 for (n13
= 0; n13
<= abs_n
; n13
+= 13)
1233 mp_limb_t digit1
= small_pow5
[n13
+ 13 <= abs_n
? 13 : abs_n
- n13
];
1235 mp_twolimb_t carry
= 0;
1236 for (j
= 0; j
< pow5_len
; j
++)
1238 mp_limb_t digit2
= pow5_ptr
[j
];
1239 carry
+= (mp_twolimb_t
) digit1
* (mp_twolimb_t
) digit2
;
1240 pow5_ptr
[j
] = (mp_limb_t
) carry
;
1241 carry
= carry
>> GMP_LIMB_BITS
;
1244 pow5_ptr
[pow5_len
++] = (mp_limb_t
) carry
;
1247 s_limbs
= abs_s
/ GMP_LIMB_BITS
;
1248 s_bits
= abs_s
% GMP_LIMB_BITS
;
1249 if (n
>= 0 ? s
>= 0 : s
<= 0)
1251 /* Multiply with 2^|s|. */
1254 mp_limb_t
*ptr
= pow5_ptr
;
1255 mp_twolimb_t accu
= 0;
1257 for (count
= pow5_len
; count
> 0; count
--)
1259 accu
+= (mp_twolimb_t
) *ptr
<< s_bits
;
1260 *ptr
++ = (mp_limb_t
) accu
;
1261 accu
= accu
>> GMP_LIMB_BITS
;
1265 *ptr
= (mp_limb_t
) accu
;
1272 for (count
= pow5_len
; count
> 0;)
1275 pow5_ptr
[s_limbs
+ count
] = pow5_ptr
[count
];
1277 for (count
= s_limbs
; count
> 0;)
1280 pow5_ptr
[count
] = 0;
1282 pow5_len
+= s_limbs
;
1284 pow5
.limbs
= pow5_ptr
;
1285 pow5
.nlimbs
= pow5_len
;
1288 /* Multiply m with pow5. No division needed. */
1289 z_memory
= multiply (m
, pow5
, &z
);
1293 /* Divide m by pow5 and round. */
1294 z_memory
= divide (m
, pow5
, &z
);
1299 pow5
.limbs
= pow5_ptr
;
1300 pow5
.nlimbs
= pow5_len
;
1304 Multiply m with pow5, then divide by 2^|s|. */
1308 tmp_memory
= multiply (m
, pow5
, &numerator
);
1309 if (tmp_memory
== NULL
)
1315 /* Construct 2^|s|. */
1317 mp_limb_t
*ptr
= pow5_ptr
+ pow5_len
;
1319 for (i
= 0; i
< s_limbs
; i
++)
1321 ptr
[s_limbs
] = (mp_limb_t
) 1 << s_bits
;
1322 denominator
.limbs
= ptr
;
1323 denominator
.nlimbs
= s_limbs
+ 1;
1325 z_memory
= divide (numerator
, denominator
, &z
);
1331 Multiply m with 2^s, then divide by pow5. */
1334 num_ptr
= (mp_limb_t
*) malloc ((m
.nlimbs
+ s_limbs
+ 1)
1335 * sizeof (mp_limb_t
));
1336 if (num_ptr
== NULL
)
1343 mp_limb_t
*destptr
= num_ptr
;
1346 for (i
= 0; i
< s_limbs
; i
++)
1351 const mp_limb_t
*sourceptr
= m
.limbs
;
1352 mp_twolimb_t accu
= 0;
1354 for (count
= m
.nlimbs
; count
> 0; count
--)
1356 accu
+= (mp_twolimb_t
) *sourceptr
++ << s_bits
;
1357 *destptr
++ = (mp_limb_t
) accu
;
1358 accu
= accu
>> GMP_LIMB_BITS
;
1361 *destptr
++ = (mp_limb_t
) accu
;
1365 const mp_limb_t
*sourceptr
= m
.limbs
;
1367 for (count
= m
.nlimbs
; count
> 0; count
--)
1368 *destptr
++ = *sourceptr
++;
1370 numerator
.limbs
= num_ptr
;
1371 numerator
.nlimbs
= destptr
- num_ptr
;
1373 z_memory
= divide (numerator
, pow5
, &z
);
1380 /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1382 if (z_memory
== NULL
)
1384 digits
= convert_to_decimal (z
, extra_zeroes
);
1389 # if NEED_PRINTF_LONG_DOUBLE
1391 /* Assuming x is finite and >= 0, and n is an integer:
1392 Returns the decimal representation of round (x * 10^n).
1393 Return the allocated memory - containing the decimal digits in low-to-high
1394 order, terminated with a NUL character - in case of success, NULL in case
1395 of memory allocation failure. */
1397 scale10_round_decimal_long_double (long double x
, int n
)
1401 void *memory
= decode_long_double (x
, &e
, &m
);
1403 return scale10_round_decimal_decoded (e
, m
, memory
, n
);
1410 # if NEED_PRINTF_DOUBLE
1412 /* Assuming x is finite and >= 0, and n is an integer:
1413 Returns the decimal representation of round (x * 10^n).
1414 Return the allocated memory - containing the decimal digits in low-to-high
1415 order, terminated with a NUL character - in case of success, NULL in case
1416 of memory allocation failure. */
1418 scale10_round_decimal_double (double x
, int n
)
1422 void *memory
= decode_double (x
, &e
, &m
);
1424 return scale10_round_decimal_decoded (e
, m
, memory
, n
);
1431 # if NEED_PRINTF_LONG_DOUBLE
1433 /* Assuming x is finite and > 0:
1434 Return an approximation for n with 10^n <= x < 10^(n+1).
1435 The approximation is usually the right n, but may be off by 1 sometimes. */
1437 floorlog10l (long double x
)
1444 /* Split into exponential part and mantissa. */
1445 y
= frexpl (x
, &exp
);
1446 if (!(y
>= 0.0L && y
< 1.0L))
1452 while (y
< (1.0L / (1 << (GMP_LIMB_BITS
/ 2)) / (1 << (GMP_LIMB_BITS
/ 2))))
1454 y
*= 1.0L * (1 << (GMP_LIMB_BITS
/ 2)) * (1 << (GMP_LIMB_BITS
/ 2));
1455 exp
-= GMP_LIMB_BITS
;
1457 if (y
< (1.0L / (1 << 16)))
1459 y
*= 1.0L * (1 << 16);
1462 if (y
< (1.0L / (1 << 8)))
1464 y
*= 1.0L * (1 << 8);
1467 if (y
< (1.0L / (1 << 4)))
1469 y
*= 1.0L * (1 << 4);
1472 if (y
< (1.0L / (1 << 2)))
1474 y
*= 1.0L * (1 << 2);
1477 if (y
< (1.0L / (1 << 1)))
1479 y
*= 1.0L * (1 << 1);
1483 if (!(y
>= 0.5L && y
< 1.0L))
1485 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1488 if (z
< 0.70710678118654752444)
1490 z
*= 1.4142135623730950488;
1493 if (z
< 0.8408964152537145431)
1495 z
*= 1.1892071150027210667;
1498 if (z
< 0.91700404320467123175)
1500 z
*= 1.0905077326652576592;
1503 if (z
< 0.9576032806985736469)
1505 z
*= 1.0442737824274138403;
1508 /* Now 0.95 <= z <= 1.01. */
1510 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1511 Four terms are enough to get an approximation with error < 10^-7. */
1512 l
-= 1.4426950408889634074 * z
* (1.0 + z
* (0.5 + z
* ((1.0 / 3) + z
* 0.25)));
1513 /* Finally multiply with log(2)/log(10), yields an approximation for
1515 l
*= 0.30102999566398119523;
1516 /* Round down to the next integer. */
1517 return (int) l
+ (l
< 0 ? -1 : 0);
1522 # if NEED_PRINTF_DOUBLE
1524 /* Assuming x is finite and > 0:
1525 Return an approximation for n with 10^n <= x < 10^(n+1).
1526 The approximation is usually the right n, but may be off by 1 sometimes. */
1528 floorlog10 (double x
)
1535 /* Split into exponential part and mantissa. */
1536 y
= frexp (x
, &exp
);
1537 if (!(y
>= 0.0 && y
< 1.0))
1543 while (y
< (1.0 / (1 << (GMP_LIMB_BITS
/ 2)) / (1 << (GMP_LIMB_BITS
/ 2))))
1545 y
*= 1.0 * (1 << (GMP_LIMB_BITS
/ 2)) * (1 << (GMP_LIMB_BITS
/ 2));
1546 exp
-= GMP_LIMB_BITS
;
1548 if (y
< (1.0 / (1 << 16)))
1550 y
*= 1.0 * (1 << 16);
1553 if (y
< (1.0 / (1 << 8)))
1555 y
*= 1.0 * (1 << 8);
1558 if (y
< (1.0 / (1 << 4)))
1560 y
*= 1.0 * (1 << 4);
1563 if (y
< (1.0 / (1 << 2)))
1565 y
*= 1.0 * (1 << 2);
1568 if (y
< (1.0 / (1 << 1)))
1570 y
*= 1.0 * (1 << 1);
1574 if (!(y
>= 0.5 && y
< 1.0))
1576 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1579 if (z
< 0.70710678118654752444)
1581 z
*= 1.4142135623730950488;
1584 if (z
< 0.8408964152537145431)
1586 z
*= 1.1892071150027210667;
1589 if (z
< 0.91700404320467123175)
1591 z
*= 1.0905077326652576592;
1594 if (z
< 0.9576032806985736469)
1596 z
*= 1.0442737824274138403;
1599 /* Now 0.95 <= z <= 1.01. */
1601 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1602 Four terms are enough to get an approximation with error < 10^-7. */
1603 l
-= 1.4426950408889634074 * z
* (1.0 + z
* (0.5 + z
* ((1.0 / 3) + z
* 0.25)));
1604 /* Finally multiply with log(2)/log(10), yields an approximation for
1606 l
*= 0.30102999566398119523;
1607 /* Round down to the next integer. */
1608 return (int) l
+ (l
< 0 ? -1 : 0);
1613 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
1614 a single '1' digit. */
1616 is_borderline (const char *digits
, size_t precision
)
1618 for (; precision
> 0; precision
--, digits
++)
1624 return *digits
== '\0';
1629 #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
1631 /* Use a different function name, to make it possible that the 'wchar_t'
1632 parametrization and the 'char' parametrization get compiled in the same
1633 translation unit. */
1634 # if WIDE_CHAR_VERSION
1635 # define MAX_ROOM_NEEDED wmax_room_needed
1637 # define MAX_ROOM_NEEDED max_room_needed
1640 /* Returns the number of TCHAR_T units needed as temporary space for the result
1641 of sprintf or SNPRINTF of a single conversion directive. */
1643 MAX_ROOM_NEEDED (const arguments
*ap
, size_t arg_index
, FCHAR_T conversion
,
1644 arg_type type
, int flags
, size_t width
, int has_precision
,
1645 size_t precision
, int pad_ourselves
)
1651 case 'd': case 'i': case 'u':
1656 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1657 * 0.30103 /* binary -> decimal */
1659 + 1; /* turn floor into ceil */
1663 (unsigned int) (sizeof (long int) * CHAR_BIT
1664 * 0.30103 /* binary -> decimal */
1666 + 1; /* turn floor into ceil */
1670 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
1671 * 0.30103 /* binary -> decimal */
1673 + 1; /* turn floor into ceil */
1675 case TYPE_LONGLONGINT
:
1677 (unsigned int) (sizeof (long long int) * CHAR_BIT
1678 * 0.30103 /* binary -> decimal */
1680 + 1; /* turn floor into ceil */
1682 case TYPE_ULONGLONGINT
:
1684 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
1685 * 0.30103 /* binary -> decimal */
1687 + 1; /* turn floor into ceil */
1691 (unsigned int) (sizeof (int8_t) * CHAR_BIT
1692 * 0.30103 /* binary -> decimal */
1694 + 1; /* turn floor into ceil */
1698 (unsigned int) (sizeof (uint8_t) * CHAR_BIT
1699 * 0.30103 /* binary -> decimal */
1701 + 1; /* turn floor into ceil */
1705 (unsigned int) (sizeof (int16_t) * CHAR_BIT
1706 * 0.30103 /* binary -> decimal */
1708 + 1; /* turn floor into ceil */
1712 (unsigned int) (sizeof (uint16_t) * CHAR_BIT
1713 * 0.30103 /* binary -> decimal */
1715 + 1; /* turn floor into ceil */
1719 (unsigned int) (sizeof (int32_t) * CHAR_BIT
1720 * 0.30103 /* binary -> decimal */
1722 + 1; /* turn floor into ceil */
1726 (unsigned int) (sizeof (uint32_t) * CHAR_BIT
1727 * 0.30103 /* binary -> decimal */
1729 + 1; /* turn floor into ceil */
1733 (unsigned int) (sizeof (int64_t) * CHAR_BIT
1734 * 0.30103 /* binary -> decimal */
1736 + 1; /* turn floor into ceil */
1740 (unsigned int) (sizeof (uint64_t) * CHAR_BIT
1741 * 0.30103 /* binary -> decimal */
1743 + 1; /* turn floor into ceil */
1745 case TYPE_INT_FAST8_T
:
1747 (unsigned int) (sizeof (int_fast8_t) * CHAR_BIT
1748 * 0.30103 /* binary -> decimal */
1750 + 1; /* turn floor into ceil */
1752 case TYPE_UINT_FAST8_T
:
1754 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
1755 * 0.30103 /* binary -> decimal */
1757 + 1; /* turn floor into ceil */
1759 case TYPE_INT_FAST16_T
:
1761 (unsigned int) (sizeof (int_fast16_t) * CHAR_BIT
1762 * 0.30103 /* binary -> decimal */
1764 + 1; /* turn floor into ceil */
1766 case TYPE_UINT_FAST16_T
:
1768 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
1769 * 0.30103 /* binary -> decimal */
1771 + 1; /* turn floor into ceil */
1773 case TYPE_INT_FAST32_T
:
1775 (unsigned int) (sizeof (int_fast32_t) * CHAR_BIT
1776 * 0.30103 /* binary -> decimal */
1778 + 1; /* turn floor into ceil */
1780 case TYPE_UINT_FAST32_T
:
1782 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
1783 * 0.30103 /* binary -> decimal */
1785 + 1; /* turn floor into ceil */
1787 case TYPE_INT_FAST64_T
:
1789 (unsigned int) (sizeof (int_fast64_t) * CHAR_BIT
1790 * 0.30103 /* binary -> decimal */
1792 + 1; /* turn floor into ceil */
1794 case TYPE_UINT_FAST64_T
:
1796 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
1797 * 0.30103 /* binary -> decimal */
1799 + 1; /* turn floor into ceil */
1802 if (tmp_length
< precision
)
1803 tmp_length
= precision
;
1804 /* Multiply by 2, as an estimate for FLAG_GROUP. */
1805 tmp_length
= xsum (tmp_length
, tmp_length
);
1806 /* Add 1, to account for a leading sign. */
1807 tmp_length
= xsum (tmp_length
, 1);
1811 #if SUPPORT_GNU_PRINTF_DIRECTIVES \
1812 || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
1819 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
)
1820 + 1; /* turn floor into ceil */
1824 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
)
1825 + 1; /* turn floor into ceil */
1827 case TYPE_ULONGLONGINT
:
1829 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
)
1830 + 1; /* turn floor into ceil */
1834 (unsigned int) (sizeof (uint8_t) * CHAR_BIT
)
1835 + 1; /* turn floor into ceil */
1839 (unsigned int) (sizeof (uint16_t) * CHAR_BIT
)
1840 + 1; /* turn floor into ceil */
1844 (unsigned int) (sizeof (uint32_t) * CHAR_BIT
)
1845 + 1; /* turn floor into ceil */
1849 (unsigned int) (sizeof (uint64_t) * CHAR_BIT
)
1850 + 1; /* turn floor into ceil */
1852 case TYPE_UINT_FAST8_T
:
1854 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
)
1855 + 1; /* turn floor into ceil */
1857 case TYPE_UINT_FAST16_T
:
1859 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
)
1860 + 1; /* turn floor into ceil */
1862 case TYPE_UINT_FAST32_T
:
1864 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
)
1865 + 1; /* turn floor into ceil */
1867 case TYPE_UINT_FAST64_T
:
1869 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
)
1870 + 1; /* turn floor into ceil */
1873 if (tmp_length
< precision
)
1874 tmp_length
= precision
;
1875 /* Add 2, to account for a prefix from the alternate form. */
1876 tmp_length
= xsum (tmp_length
, 2);
1884 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1885 * 0.333334 /* binary -> octal */
1887 + 1; /* turn floor into ceil */
1891 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
1892 * 0.333334 /* binary -> octal */
1894 + 1; /* turn floor into ceil */
1896 case TYPE_ULONGLONGINT
:
1898 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
1899 * 0.333334 /* binary -> octal */
1901 + 1; /* turn floor into ceil */
1905 (unsigned int) (sizeof (uint8_t) * CHAR_BIT
1906 * 0.333334 /* binary -> octal */
1908 + 1; /* turn floor into ceil */
1912 (unsigned int) (sizeof (uint16_t) * CHAR_BIT
1913 * 0.333334 /* binary -> octal */
1915 + 1; /* turn floor into ceil */
1919 (unsigned int) (sizeof (uint32_t) * CHAR_BIT
1920 * 0.333334 /* binary -> octal */
1922 + 1; /* turn floor into ceil */
1926 (unsigned int) (sizeof (uint64_t) * CHAR_BIT
1927 * 0.333334 /* binary -> octal */
1929 + 1; /* turn floor into ceil */
1931 case TYPE_UINT_FAST8_T
:
1933 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
1934 * 0.333334 /* binary -> octal */
1936 + 1; /* turn floor into ceil */
1938 case TYPE_UINT_FAST16_T
:
1940 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
1941 * 0.333334 /* binary -> octal */
1943 + 1; /* turn floor into ceil */
1945 case TYPE_UINT_FAST32_T
:
1947 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
1948 * 0.333334 /* binary -> octal */
1950 + 1; /* turn floor into ceil */
1952 case TYPE_UINT_FAST64_T
:
1954 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
1955 * 0.333334 /* binary -> octal */
1957 + 1; /* turn floor into ceil */
1960 if (tmp_length
< precision
)
1961 tmp_length
= precision
;
1962 /* Add 1, to account for a leading sign. */
1963 tmp_length
= xsum (tmp_length
, 1);
1971 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1972 * 0.25 /* binary -> hexadecimal */
1974 + 1; /* turn floor into ceil */
1978 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
1979 * 0.25 /* binary -> hexadecimal */
1981 + 1; /* turn floor into ceil */
1983 case TYPE_ULONGLONGINT
:
1985 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
1986 * 0.25 /* binary -> hexadecimal */
1988 + 1; /* turn floor into ceil */
1992 (unsigned int) (sizeof (uint8_t) * CHAR_BIT
1993 * 0.25 /* binary -> hexadecimal */
1995 + 1; /* turn floor into ceil */
1999 (unsigned int) (sizeof (uint16_t) * CHAR_BIT
2000 * 0.25 /* binary -> hexadecimal */
2002 + 1; /* turn floor into ceil */
2006 (unsigned int) (sizeof (uint32_t) * CHAR_BIT
2007 * 0.25 /* binary -> hexadecimal */
2009 + 1; /* turn floor into ceil */
2013 (unsigned int) (sizeof (uint64_t) * CHAR_BIT
2014 * 0.25 /* binary -> hexadecimal */
2016 + 1; /* turn floor into ceil */
2018 case TYPE_UINT_FAST8_T
:
2020 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
2021 * 0.25 /* binary -> hexadecimal */
2023 + 1; /* turn floor into ceil */
2025 case TYPE_UINT_FAST16_T
:
2027 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
2028 * 0.25 /* binary -> hexadecimal */
2030 + 1; /* turn floor into ceil */
2032 case TYPE_UINT_FAST32_T
:
2034 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
2035 * 0.25 /* binary -> hexadecimal */
2037 + 1; /* turn floor into ceil */
2039 case TYPE_UINT_FAST64_T
:
2041 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
2042 * 0.25 /* binary -> hexadecimal */
2044 + 1; /* turn floor into ceil */
2047 if (tmp_length
< precision
)
2048 tmp_length
= precision
;
2049 /* Add 2, to account for a prefix from the alternate form. */
2050 tmp_length
= xsum (tmp_length
, 2);
2054 if (type
== TYPE_LONGDOUBLE
)
2056 (unsigned int) (LDBL_MAX_EXP
2057 * 0.30103 /* binary -> decimal */
2058 * 2 /* estimate for FLAG_GROUP */
2060 + 1 /* turn floor into ceil */
2061 + 10; /* sign, decimal point etc. */
2064 (unsigned int) (DBL_MAX_EXP
2065 * 0.30103 /* binary -> decimal */
2066 * 2 /* estimate for FLAG_GROUP */
2068 + 1 /* turn floor into ceil */
2069 + 10; /* sign, decimal point etc. */
2070 tmp_length
= xsum (tmp_length
, precision
);
2073 case 'e': case 'E': case 'g': case 'G':
2075 12; /* sign, decimal point, exponent etc. */
2076 tmp_length
= xsum (tmp_length
, precision
);
2080 if (type
== TYPE_LONGDOUBLE
)
2082 (unsigned int) (LDBL_DIG
2083 * 0.831 /* decimal -> hexadecimal */
2085 + 1; /* turn floor into ceil */
2088 (unsigned int) (DBL_DIG
2089 * 0.831 /* decimal -> hexadecimal */
2091 + 1; /* turn floor into ceil */
2092 if (tmp_length
< precision
)
2093 tmp_length
= precision
;
2094 /* Account for sign, decimal point etc. */
2095 tmp_length
= xsum (tmp_length
, 12);
2099 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
2100 if (type
== TYPE_WIDE_CHAR
)
2102 tmp_length
= MB_CUR_MAX
;
2103 # if ENABLE_WCHAR_FALLBACK
2104 if (tmp_length
< (sizeof (wchar_t) > 2 ? 10 : 6))
2105 tmp_length
= (sizeof (wchar_t) > 2 ? 10 : 6);
2115 if (type
== TYPE_WIDE_STRING
)
2117 # if WIDE_CHAR_VERSION
2118 /* ISO C says about %ls in fwprintf:
2119 "If the precision is not specified or is greater than the size
2120 of the array, the array shall contain a null wide character."
2121 So if there is a precision, we must not use wcslen. */
2122 const wchar_t *arg
= ap
->arg
[arg_index
].a
.a_wide_string
;
2125 tmp_length
= local_wcsnlen (arg
, precision
);
2127 tmp_length
= local_wcslen (arg
);
2129 /* ISO C says about %ls in fprintf:
2130 "If a precision is specified, no more than that many bytes are
2131 written (including shift sequences, if any), and the array
2132 shall contain a null wide character if, to equal the multibyte
2133 character sequence length given by the precision, the function
2134 would need to access a wide character one past the end of the
2136 So if there is a precision, we must not use wcslen. */
2137 /* This case has already been handled separately in VASNPRINTF. */
2144 # if WIDE_CHAR_VERSION
2145 /* ISO C says about %s in fwprintf:
2146 "If the precision is not specified or is greater than the size
2147 of the converted array, the converted array shall contain a
2148 null wide character."
2149 So if there is a precision, we must not use strlen. */
2150 /* This case has already been handled separately in VASNPRINTF. */
2153 /* ISO C says about %s in fprintf:
2154 "If the precision is not specified or greater than the size of
2155 the array, the array shall contain a null character."
2156 So if there is a precision, we must not use strlen. */
2157 const char *arg
= ap
->arg
[arg_index
].a
.a_string
;
2160 tmp_length
= local_strnlen (arg
, precision
);
2162 tmp_length
= strlen (arg
);
2169 (unsigned int) (sizeof (void *) * CHAR_BIT
2170 * 0.25 /* binary -> hexadecimal */
2172 + 1 /* turn floor into ceil */
2173 + 2; /* account for leading 0x */
2182 # if ENABLE_UNISTDIO
2183 /* Padding considers the number of characters, therefore the number of
2184 elements after padding may be
2185 > max (tmp_length, width)
2187 <= tmp_length + width. */
2188 tmp_length
= xsum (tmp_length
, width
);
2190 /* Padding considers the number of elements, says POSIX. */
2191 if (tmp_length
< width
)
2196 tmp_length
= xsum (tmp_length
, 1); /* account for trailing NUL */
2204 VASNPRINTF (DCHAR_T
*resultbuf
, size_t *lengthp
,
2205 const FCHAR_T
*format
, va_list args
)
2210 if (PRINTF_PARSE (format
, &d
, &a
) < 0)
2211 /* errno is already set. */
2214 /* Frees the memory allocated by this function. Preserves errno. */
2216 if (d.dir != d.direct_alloc_dir) \
2218 if (a.arg != a.direct_alloc_arg) \
2221 if (PRINTF_FETCHARGS (args
, &a
) < 0)
2222 goto fail_1_with_EINVAL
;
2225 size_t buf_neededlength
;
2227 TCHAR_T
*buf_malloced
;
2231 /* Output string accumulator. */
2236 /* Allocate a small buffer that will hold a directive passed to
2237 sprintf or snprintf. */
2239 xsum4 (7, d
.max_width_length
, d
.max_precision_length
, 6);
2241 if (buf_neededlength
< 4000 / sizeof (TCHAR_T
))
2243 buf
= (TCHAR_T
*) alloca (buf_neededlength
* sizeof (TCHAR_T
));
2244 buf_malloced
= NULL
;
2249 size_t buf_memsize
= xtimes (buf_neededlength
, sizeof (TCHAR_T
));
2250 if (size_overflow_p (buf_memsize
))
2251 goto out_of_memory_1
;
2252 buf
= (TCHAR_T
*) malloc (buf_memsize
);
2254 goto out_of_memory_1
;
2259 allocated
= (resultbuf
!= NULL
? *lengthp
: 0);
2262 result is either == resultbuf or malloc-allocated.
2263 If result == NULL, resultbuf is == NULL as well.
2264 If length > 0, then result != NULL. */
2266 /* Ensures that allocated >= needed. Aborts through a jump to
2267 out_of_memory if needed is SIZE_MAX or otherwise too big. */
2268 #define ENSURE_ALLOCATION_ELSE(needed, oom_statement) \
2269 if ((needed) > allocated) \
2271 size_t memory_size; \
2274 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
2275 if ((needed) > allocated) \
2276 allocated = (needed); \
2277 memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
2278 if (size_overflow_p (memory_size)) \
2280 if (result == resultbuf) \
2281 memory = (DCHAR_T *) malloc (memory_size); \
2283 memory = (DCHAR_T *) realloc (result, memory_size); \
2284 if (memory == NULL) \
2286 if (result == resultbuf && length > 0) \
2287 DCHAR_CPY (memory, result, length); \
2290 #define ENSURE_ALLOCATION(needed) \
2291 ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; )
2293 for (cp
= format
, i
= 0, dp
= &d
.dir
[0]; ; cp
= dp
->dir_end
, i
++, dp
++)
2295 if (cp
!= dp
->dir_start
)
2297 size_t n
= dp
->dir_start
- cp
;
2298 size_t augmented_length
= xsum (length
, n
);
2300 ENSURE_ALLOCATION (augmented_length
);
2301 /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we
2302 need that the format string contains only ASCII characters
2303 if FCHAR_T and DCHAR_T are not the same type. */
2304 if (sizeof (FCHAR_T
) == sizeof (DCHAR_T
))
2306 DCHAR_CPY (result
+ length
, (const DCHAR_T
*) cp
, n
);
2307 length
= augmented_length
;
2312 result
[length
++] = *cp
++;
2319 /* Execute a single directive. */
2320 if (dp
->conversion
== '%')
2322 size_t augmented_length
;
2324 if (!(dp
->arg_index
== ARG_NONE
))
2326 augmented_length
= xsum (length
, 1);
2327 ENSURE_ALLOCATION (augmented_length
);
2328 result
[length
] = '%';
2329 length
= augmented_length
;
2333 if (!(dp
->arg_index
!= ARG_NONE
))
2336 if (dp
->conversion
== 'n')
2338 #if NEED_PRINTF_WITH_N_DIRECTIVE
2339 switch (a
.arg
[dp
->arg_index
].type
)
2341 case TYPE_COUNT_SCHAR_POINTER
:
2342 *a
.arg
[dp
->arg_index
].a
.a_count_schar_pointer
= length
;
2344 case TYPE_COUNT_SHORT_POINTER
:
2345 *a
.arg
[dp
->arg_index
].a
.a_count_short_pointer
= length
;
2347 case TYPE_COUNT_INT_POINTER
:
2348 *a
.arg
[dp
->arg_index
].a
.a_count_int_pointer
= length
;
2350 case TYPE_COUNT_LONGINT_POINTER
:
2351 *a
.arg
[dp
->arg_index
].a
.a_count_longint_pointer
= length
;
2353 case TYPE_COUNT_LONGLONGINT_POINTER
:
2354 *a
.arg
[dp
->arg_index
].a
.a_count_longlongint_pointer
= length
;
2356 case TYPE_COUNT_INT8_T_POINTER
:
2357 *a
.arg
[dp
->arg_index
].a
.a_count_int8_t_pointer
= length
;
2359 case TYPE_COUNT_INT16_T_POINTER
:
2360 *a
.arg
[dp
->arg_index
].a
.a_count_int16_t_pointer
= length
;
2362 case TYPE_COUNT_INT32_T_POINTER
:
2363 *a
.arg
[dp
->arg_index
].a
.a_count_int32_t_pointer
= length
;
2365 case TYPE_COUNT_INT64_T_POINTER
:
2366 *a
.arg
[dp
->arg_index
].a
.a_count_int64_t_pointer
= length
;
2368 case TYPE_COUNT_INT_FAST8_T_POINTER
:
2369 *a
.arg
[dp
->arg_index
].a
.a_count_int_fast8_t_pointer
= length
;
2371 case TYPE_COUNT_INT_FAST16_T_POINTER
:
2372 *a
.arg
[dp
->arg_index
].a
.a_count_int_fast16_t_pointer
= length
;
2374 case TYPE_COUNT_INT_FAST32_T_POINTER
:
2375 *a
.arg
[dp
->arg_index
].a
.a_count_int_fast32_t_pointer
= length
;
2377 case TYPE_COUNT_INT_FAST64_T_POINTER
:
2378 *a
.arg
[dp
->arg_index
].a
.a_count_int_fast64_t_pointer
= length
;
2388 /* The unistdio extensions. */
2389 else if (dp
->conversion
== 'U')
2391 arg_type type
= a
.arg
[dp
->arg_index
].type
;
2392 int flags
= dp
->flags
;
2400 if (dp
->width_start
!= dp
->width_end
)
2402 if (dp
->width_arg_index
!= ARG_NONE
)
2406 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
2408 arg
= a
.arg
[dp
->width_arg_index
].a
.a_int
;
2412 /* "A negative field width is taken as a '-' flag
2413 followed by a positive field width." */
2420 const FCHAR_T
*digitp
= dp
->width_start
;
2423 width
= xsum (xtimes (width
, 10), *digitp
++ - '0');
2424 while (digitp
!= dp
->width_end
);
2431 if (dp
->precision_start
!= dp
->precision_end
)
2433 if (dp
->precision_arg_index
!= ARG_NONE
)
2437 if (!(a
.arg
[dp
->precision_arg_index
].type
== TYPE_INT
))
2439 arg
= a
.arg
[dp
->precision_arg_index
].a
.a_int
;
2440 /* "A negative precision is taken as if the precision
2450 const FCHAR_T
*digitp
= dp
->precision_start
+ 1;
2453 while (digitp
!= dp
->precision_end
)
2454 precision
= xsum (xtimes (precision
, 10), *digitp
++ - '0');
2461 case TYPE_U8_STRING
:
2463 const uint8_t *arg
= a
.arg
[dp
->arg_index
].a
.a_u8_string
;
2464 const uint8_t *arg_end
;
2469 /* Use only PRECISION characters, from the left. */
2472 for (; precision
> 0; precision
--)
2474 int count
= u8_strmblen (arg_end
);
2478 goto fail_with_EILSEQ
;
2485 /* Use the entire string, and count the number of
2491 int count
= u8_strmblen (arg_end
);
2495 goto fail_with_EILSEQ
;
2502 /* Use the entire string. */
2503 arg_end
= arg
+ u8_strlen (arg
);
2504 /* The number of characters doesn't matter. */
2508 if (characters
< width
&& !(flags
& FLAG_LEFT
))
2510 size_t n
= width
- characters
;
2511 ENSURE_ALLOCATION (xsum (length
, n
));
2512 DCHAR_SET (result
+ length
, ' ', n
);
2516 # if DCHAR_IS_UINT8_T
2518 size_t n
= arg_end
- arg
;
2519 ENSURE_ALLOCATION (xsum (length
, n
));
2520 DCHAR_CPY (result
+ length
, arg
, n
);
2525 DCHAR_T
*converted
= result
+ length
;
2526 size_t converted_len
= allocated
- length
;
2528 /* Convert from UTF-8 to locale encoding. */
2530 u8_conv_to_encoding (locale_charset (),
2531 iconveh_question_mark
,
2532 arg
, arg_end
- arg
, NULL
,
2533 converted
, &converted_len
);
2535 /* Convert from UTF-8 to UTF-16/UTF-32. */
2537 U8_TO_DCHAR (arg
, arg_end
- arg
,
2538 converted
, &converted_len
);
2540 if (converted
== NULL
)
2541 goto fail_with_errno
;
2542 if (converted
!= result
+ length
)
2544 ENSURE_ALLOCATION_ELSE (xsum (length
, converted_len
),
2545 { free (converted
); goto out_of_memory
; });
2546 DCHAR_CPY (result
+ length
, converted
, converted_len
);
2549 length
+= converted_len
;
2553 if (characters
< width
&& (flags
& FLAG_LEFT
))
2555 size_t n
= width
- characters
;
2556 ENSURE_ALLOCATION (xsum (length
, n
));
2557 DCHAR_SET (result
+ length
, ' ', n
);
2563 case TYPE_U16_STRING
:
2565 const uint16_t *arg
= a
.arg
[dp
->arg_index
].a
.a_u16_string
;
2566 const uint16_t *arg_end
;
2571 /* Use only PRECISION characters, from the left. */
2574 for (; precision
> 0; precision
--)
2576 int count
= u16_strmblen (arg_end
);
2580 goto fail_with_EILSEQ
;
2587 /* Use the entire string, and count the number of
2593 int count
= u16_strmblen (arg_end
);
2597 goto fail_with_EILSEQ
;
2604 /* Use the entire string. */
2605 arg_end
= arg
+ u16_strlen (arg
);
2606 /* The number of characters doesn't matter. */
2610 if (characters
< width
&& !(flags
& FLAG_LEFT
))
2612 size_t n
= width
- characters
;
2613 ENSURE_ALLOCATION (xsum (length
, n
));
2614 DCHAR_SET (result
+ length
, ' ', n
);
2618 # if DCHAR_IS_UINT16_T
2620 size_t n
= arg_end
- arg
;
2621 ENSURE_ALLOCATION (xsum (length
, n
));
2622 DCHAR_CPY (result
+ length
, arg
, n
);
2627 DCHAR_T
*converted
= result
+ length
;
2628 size_t converted_len
= allocated
- length
;
2630 /* Convert from UTF-16 to locale encoding. */
2632 u16_conv_to_encoding (locale_charset (),
2633 iconveh_question_mark
,
2634 arg
, arg_end
- arg
, NULL
,
2635 converted
, &converted_len
);
2637 /* Convert from UTF-16 to UTF-8/UTF-32. */
2639 U16_TO_DCHAR (arg
, arg_end
- arg
,
2640 converted
, &converted_len
);
2642 if (converted
== NULL
)
2643 goto fail_with_errno
;
2644 if (converted
!= result
+ length
)
2646 ENSURE_ALLOCATION_ELSE (xsum (length
, converted_len
),
2647 { free (converted
); goto out_of_memory
; });
2648 DCHAR_CPY (result
+ length
, converted
, converted_len
);
2651 length
+= converted_len
;
2655 if (characters
< width
&& (flags
& FLAG_LEFT
))
2657 size_t n
= width
- characters
;
2658 ENSURE_ALLOCATION (xsum (length
, n
));
2659 DCHAR_SET (result
+ length
, ' ', n
);
2665 case TYPE_U32_STRING
:
2667 const uint32_t *arg
= a
.arg
[dp
->arg_index
].a
.a_u32_string
;
2668 const uint32_t *arg_end
;
2673 /* Use only PRECISION characters, from the left. */
2676 for (; precision
> 0; precision
--)
2678 int count
= u32_strmblen (arg_end
);
2682 goto fail_with_EILSEQ
;
2689 /* Use the entire string, and count the number of
2695 int count
= u32_strmblen (arg_end
);
2699 goto fail_with_EILSEQ
;
2706 /* Use the entire string. */
2707 arg_end
= arg
+ u32_strlen (arg
);
2708 /* The number of characters doesn't matter. */
2712 if (characters
< width
&& !(flags
& FLAG_LEFT
))
2714 size_t n
= width
- characters
;
2715 ENSURE_ALLOCATION (xsum (length
, n
));
2716 DCHAR_SET (result
+ length
, ' ', n
);
2720 # if DCHAR_IS_UINT32_T
2722 size_t n
= arg_end
- arg
;
2723 ENSURE_ALLOCATION (xsum (length
, n
));
2724 DCHAR_CPY (result
+ length
, arg
, n
);
2729 DCHAR_T
*converted
= result
+ length
;
2730 size_t converted_len
= allocated
- length
;
2732 /* Convert from UTF-32 to locale encoding. */
2734 u32_conv_to_encoding (locale_charset (),
2735 iconveh_question_mark
,
2736 arg
, arg_end
- arg
, NULL
,
2737 converted
, &converted_len
);
2739 /* Convert from UTF-32 to UTF-8/UTF-16. */
2741 U32_TO_DCHAR (arg
, arg_end
- arg
,
2742 converted
, &converted_len
);
2744 if (converted
== NULL
)
2745 goto fail_with_errno
;
2746 if (converted
!= result
+ length
)
2748 ENSURE_ALLOCATION_ELSE (xsum (length
, converted_len
),
2749 { free (converted
); goto out_of_memory
; });
2750 DCHAR_CPY (result
+ length
, converted
, converted_len
);
2753 length
+= converted_len
;
2757 if (characters
< width
&& (flags
& FLAG_LEFT
))
2759 size_t n
= width
- characters
;
2760 ENSURE_ALLOCATION (xsum (length
, n
));
2761 DCHAR_SET (result
+ length
, ' ', n
);
2772 #if WIDE_CHAR_VERSION && (!DCHAR_IS_TCHAR || NEED_WPRINTF_DIRECTIVE_LC)
2773 else if ((dp
->conversion
== 's'
2774 && a
.arg
[dp
->arg_index
].type
== TYPE_WIDE_STRING
)
2775 || (dp
->conversion
== 'c'
2776 && a
.arg
[dp
->arg_index
].type
== TYPE_WIDE_CHAR
))
2778 /* %ls or %lc in vasnwprintf. See the specification of
2780 /* It would be silly to use snprintf ("%ls", ...) and then
2781 convert back the result from a char[] to a wchar_t[].
2782 Instead, just copy the argument wchar_t[] to the result. */
2783 int flags
= dp
->flags
;
2787 if (dp
->width_start
!= dp
->width_end
)
2789 if (dp
->width_arg_index
!= ARG_NONE
)
2793 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
2795 arg
= a
.arg
[dp
->width_arg_index
].a
.a_int
;
2799 /* "A negative field width is taken as a '-' flag
2800 followed by a positive field width." */
2807 const FCHAR_T
*digitp
= dp
->width_start
;
2810 width
= xsum (xtimes (width
, 10), *digitp
++ - '0');
2811 while (digitp
!= dp
->width_end
);
2816 const wchar_t *ls_arg
;
2820 if (dp
->conversion
== 's')
2827 if (dp
->precision_start
!= dp
->precision_end
)
2829 if (dp
->precision_arg_index
!= ARG_NONE
)
2833 if (!(a
.arg
[dp
->precision_arg_index
].type
== TYPE_INT
))
2835 arg
= a
.arg
[dp
->precision_arg_index
].a
.a_int
;
2836 /* "A negative precision is taken as if the precision
2846 const FCHAR_T
*digitp
= dp
->precision_start
+ 1;
2849 while (digitp
!= dp
->precision_end
)
2850 precision
= xsum (xtimes (precision
, 10), *digitp
++ - '0');
2855 ls_arg
= a
.arg
[dp
->arg_index
].a
.a_wide_string
;
2859 /* Use only at most PRECISION wide characters, from
2861 const wchar_t *ls_arg_end
;
2863 ls_arg_end
= ls_arg
;
2865 for (; precision
> 0; precision
--)
2867 if (*ls_arg_end
== 0)
2868 /* Found the terminating null wide character. */
2876 /* Use the entire string, and count the number of wide
2878 characters
= local_wcslen (ls_arg
);
2881 else /* dp->conversion == 'c' */
2883 lc_arg
[0] = (wchar_t) a
.arg
[dp
->arg_index
].a
.a_wide_char
;
2889 size_t total
= (characters
< width
? width
: characters
);
2890 ENSURE_ALLOCATION (xsum (length
, total
));
2892 if (characters
< width
&& !(flags
& FLAG_LEFT
))
2894 size_t n
= width
- characters
;
2895 DCHAR_SET (result
+ length
, ' ', n
);
2901 DCHAR_CPY (result
+ length
, ls_arg
, characters
);
2902 length
+= characters
;
2905 if (characters
< width
&& (flags
& FLAG_LEFT
))
2907 size_t n
= width
- characters
;
2908 DCHAR_SET (result
+ length
, ' ', n
);
2915 #if (!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T
2916 else if (dp
->conversion
== 's'
2917 # if WIDE_CHAR_VERSION
2918 && a
.arg
[dp
->arg_index
].type
!= TYPE_WIDE_STRING
2920 && a
.arg
[dp
->arg_index
].type
== TYPE_WIDE_STRING
2924 /* The normal handling of the 's' directive below requires
2925 allocating a temporary buffer. The determination of its
2926 length (tmp_length), in the case when a precision is
2927 specified, below requires a conversion between a char[]
2928 string and a wchar_t[] wide string. It could be done, but
2929 we have no guarantee that the implementation of sprintf will
2930 use the exactly same algorithm. Without this guarantee, it
2931 is possible to have buffer overrun bugs. In order to avoid
2932 such bugs, we implement the entire processing of the 's'
2933 directive ourselves. */
2934 int flags
= dp
->flags
;
2942 if (dp
->width_start
!= dp
->width_end
)
2944 if (dp
->width_arg_index
!= ARG_NONE
)
2948 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
2950 arg
= a
.arg
[dp
->width_arg_index
].a
.a_int
;
2954 /* "A negative field width is taken as a '-' flag
2955 followed by a positive field width." */
2962 const FCHAR_T
*digitp
= dp
->width_start
;
2965 width
= xsum (xtimes (width
, 10), *digitp
++ - '0');
2966 while (digitp
!= dp
->width_end
);
2973 if (dp
->precision_start
!= dp
->precision_end
)
2975 if (dp
->precision_arg_index
!= ARG_NONE
)
2979 if (!(a
.arg
[dp
->precision_arg_index
].type
== TYPE_INT
))
2981 arg
= a
.arg
[dp
->precision_arg_index
].a
.a_int
;
2982 /* "A negative precision is taken as if the precision
2992 const FCHAR_T
*digitp
= dp
->precision_start
+ 1;
2995 while (digitp
!= dp
->precision_end
)
2996 precision
= xsum (xtimes (precision
, 10), *digitp
++ - '0');
3001 # if WIDE_CHAR_VERSION
3002 /* %s in vasnwprintf. See the specification of fwprintf. */
3004 const char *arg
= a
.arg
[dp
->arg_index
].a
.a_string
;
3005 const char *arg_end
;
3010 /* Use only as many bytes as needed to produce PRECISION
3011 wide characters, from the left. */
3018 for (; precision
> 0; precision
--)
3022 count
= mbrlen (arg_end
, MB_CUR_MAX
, &state
);
3024 count
= mblen (arg_end
, MB_CUR_MAX
);
3027 /* Found the terminating NUL. */
3030 /* Invalid or incomplete multibyte character. */
3031 goto fail_with_EILSEQ
;
3038 /* Use the entire string, and count the number of wide
3050 count
= mbrlen (arg_end
, MB_CUR_MAX
, &state
);
3052 count
= mblen (arg_end
, MB_CUR_MAX
);
3055 /* Found the terminating NUL. */
3058 /* Invalid or incomplete multibyte character. */
3059 goto fail_with_EILSEQ
;
3066 /* Use the entire string. */
3067 arg_end
= arg
+ strlen (arg
);
3068 /* The number of characters doesn't matter. */
3072 if (characters
< width
&& !(flags
& FLAG_LEFT
))
3074 size_t n
= width
- characters
;
3075 ENSURE_ALLOCATION (xsum (length
, n
));
3076 DCHAR_SET (result
+ length
, ' ', n
);
3080 if (has_precision
|| has_width
)
3082 /* We know the number of wide characters in advance. */
3088 ENSURE_ALLOCATION (xsum (length
, characters
));
3089 for (remaining
= characters
; remaining
> 0; remaining
--)
3094 count
= mbrtowc (&wc
, arg
, arg_end
- arg
, &state
);
3096 count
= mbtowc (&wc
, arg
, arg_end
- arg
);
3099 /* mbrtowc not consistent with mbrlen, or mbtowc
3100 not consistent with mblen. */
3102 result
[length
++] = wc
;
3105 if (!(arg
== arg_end
))
3114 while (arg
< arg_end
)
3119 count
= mbrtowc (&wc
, arg
, arg_end
- arg
, &state
);
3121 count
= mbtowc (&wc
, arg
, arg_end
- arg
);
3124 /* mbrtowc not consistent with strlen. */
3127 /* Invalid or incomplete multibyte character. */
3128 goto fail_with_EILSEQ
;
3129 ENSURE_ALLOCATION (xsum (length
, 1));
3130 result
[length
++] = wc
;
3135 if (characters
< width
&& (flags
& FLAG_LEFT
))
3137 size_t n
= width
- characters
;
3138 ENSURE_ALLOCATION (xsum (length
, n
));
3139 DCHAR_SET (result
+ length
, ' ', n
);
3144 /* %ls in vasnprintf. See the specification of fprintf. */
3146 const wchar_t *arg
= a
.arg
[dp
->arg_index
].a
.a_wide_string
;
3147 const wchar_t *arg_end
;
3149 # if !DCHAR_IS_TCHAR
3150 /* This code assumes that TCHAR_T is 'char'. */
3151 static_assert (sizeof (TCHAR_T
) == 1);
3160 /* Use only as many wide characters as needed to produce
3161 at most PRECISION bytes, from the left. */
3162 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3168 while (precision
> 0)
3170 char cbuf
[64]; /* Assume MB_CUR_MAX <= 64. */
3174 /* Found the terminating null wide character. */
3176 count
= local_wcrtomb (cbuf
, *arg_end
, &state
);
3178 /* Cannot convert. */
3179 goto fail_with_EILSEQ
;
3180 if (precision
< (unsigned int) count
)
3183 characters
+= count
;
3193 /* Use the entire string, and count the number of
3195 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3203 char cbuf
[64]; /* Assume MB_CUR_MAX <= 64. */
3207 /* Found the terminating null wide character. */
3209 count
= local_wcrtomb (cbuf
, *arg_end
, &state
);
3211 /* Cannot convert. */
3212 goto fail_with_EILSEQ
;
3214 characters
+= count
;
3220 /* Use the entire string. */
3221 arg_end
= arg
+ local_wcslen (arg
);
3222 /* The number of bytes doesn't matter. */
3227 # if !DCHAR_IS_TCHAR
3228 /* Convert the string into a piece of temporary memory. */
3229 tmpsrc
= (TCHAR_T
*) malloc (characters
* sizeof (TCHAR_T
));
3233 TCHAR_T
*tmpptr
= tmpsrc
;
3235 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3239 for (remaining
= characters
; remaining
> 0; )
3241 char cbuf
[64]; /* Assume MB_CUR_MAX <= 64. */
3246 count
= local_wcrtomb (cbuf
, *arg
, &state
);
3248 /* Inconsistency. */
3250 memcpy (tmpptr
, cbuf
, count
);
3255 if (!(arg
== arg_end
))
3259 /* Convert from TCHAR_T[] to DCHAR_T[]. */
3261 DCHAR_CONV_FROM_ENCODING (locale_charset (),
3262 iconveh_question_mark
,
3269 goto fail_with_errno
;
3276 # if ENABLE_UNISTDIO
3277 /* Outside POSIX, it's preferable to compare the width
3278 against the number of _characters_ of the converted
3280 w
= DCHAR_MBSNLEN (result
+ length
, characters
);
3282 /* The width is compared against the number of _bytes_
3283 of the converted value, says POSIX. */
3288 /* w doesn't matter. */
3291 if (w
< width
&& !(flags
& FLAG_LEFT
))
3293 size_t n
= width
- w
;
3294 ENSURE_ALLOCATION (xsum (length
, n
));
3295 DCHAR_SET (result
+ length
, ' ', n
);
3300 if (has_precision
|| has_width
)
3302 /* We know the number of bytes in advance. */
3304 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3308 ENSURE_ALLOCATION (xsum (length
, characters
));
3309 for (remaining
= characters
; remaining
> 0; )
3311 char cbuf
[64]; /* Assume MB_CUR_MAX <= 64. */
3316 count
= local_wcrtomb (cbuf
, *arg
, &state
);
3318 /* Inconsistency. */
3320 memcpy (result
+ length
, cbuf
, count
);
3325 if (!(arg
== arg_end
))
3330 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3334 while (arg
< arg_end
)
3336 char cbuf
[64]; /* Assume MB_CUR_MAX <= 64. */
3341 count
= local_wcrtomb (cbuf
, *arg
, &state
);
3343 /* Cannot convert. */
3344 goto fail_with_EILSEQ
;
3345 ENSURE_ALLOCATION (xsum (length
, count
));
3346 memcpy (result
+ length
, cbuf
, count
);
3352 ENSURE_ALLOCATION_ELSE (xsum (length
, tmpdst_len
),
3353 { free (tmpdst
); goto out_of_memory
; });
3354 DCHAR_CPY (result
+ length
, tmpdst
, tmpdst_len
);
3356 length
+= tmpdst_len
;
3359 if (w
< width
&& (flags
& FLAG_LEFT
))
3361 size_t n
= width
- w
;
3362 ENSURE_ALLOCATION (xsum (length
, n
));
3363 DCHAR_SET (result
+ length
, ' ', n
);
3370 #if (NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION
3371 else if (dp
->conversion
== 'c'
3372 && a
.arg
[dp
->arg_index
].type
== TYPE_WIDE_CHAR
)
3374 /* Implement the 'lc' directive ourselves, in order to provide
3375 a correct behaviour for the null wint_t argument and/or the
3376 fallback that avoids EILSEQ. */
3377 int flags
= dp
->flags
;
3383 if (dp
->width_start
!= dp
->width_end
)
3385 if (dp
->width_arg_index
!= ARG_NONE
)
3389 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
3391 arg
= a
.arg
[dp
->width_arg_index
].a
.a_int
;
3395 /* "A negative field width is taken as a '-' flag
3396 followed by a positive field width." */
3403 const FCHAR_T
*digitp
= dp
->width_start
;
3406 width
= xsum (xtimes (width
, 10), *digitp
++ - '0');
3407 while (digitp
!= dp
->width_end
);
3412 /* %lc in vasnprintf. See the specification of fprintf. */
3414 wchar_t arg
= (wchar_t) a
.arg
[dp
->arg_index
].a
.a_wide_char
;
3416 # if !DCHAR_IS_TCHAR
3417 /* This code assumes that TCHAR_T is 'char'. */
3418 static_assert (sizeof (TCHAR_T
) == 1);
3419 TCHAR_T tmpsrc
[64]; /* Assume MB_CUR_MAX <= 64. */
3429 /* Count the number of bytes. */
3431 char cbuf
[64]; /* Assume MB_CUR_MAX <= 64. */
3433 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3438 count
= local_wcrtomb (cbuf
, arg
, &state
);
3440 /* Cannot convert. */
3441 goto fail_with_EILSEQ
;
3447 /* The number of bytes doesn't matter. */
3452 # if !DCHAR_IS_TCHAR
3453 /* Convert the string into a piece of temporary memory. */
3456 char cbuf
[64]; /* Assume MB_CUR_MAX <= 64. */
3458 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3463 count
= local_wcrtomb (cbuf
, arg
, &state
);
3465 /* Inconsistency. */
3467 memcpy (tmpsrc
, cbuf
, count
);
3470 /* Convert from TCHAR_T[] to DCHAR_T[]. */
3472 DCHAR_CONV_FROM_ENCODING (locale_charset (),
3473 iconveh_question_mark
,
3478 goto fail_with_errno
;
3483 # if ENABLE_UNISTDIO
3484 /* Outside POSIX, it's preferable to compare the width
3485 against the number of _characters_ of the converted
3487 w
= DCHAR_MBSNLEN (result
+ length
, characters
);
3489 /* The width is compared against the number of _bytes_
3490 of the converted value, says POSIX. */
3495 /* w doesn't matter. */
3498 if (w
< width
&& !(flags
& FLAG_LEFT
))
3500 size_t n
= width
- w
;
3501 ENSURE_ALLOCATION (xsum (length
, n
));
3502 DCHAR_SET (result
+ length
, ' ', n
);
3509 /* We know the number of bytes in advance. */
3510 ENSURE_ALLOCATION (xsum (length
, characters
));
3514 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3519 count
= local_wcrtomb (result
+ length
, arg
, &state
);
3521 /* Inconsistency. */
3528 char cbuf
[64]; /* Assume MB_CUR_MAX <= 64. */
3530 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3535 count
= local_wcrtomb (cbuf
, arg
, &state
);
3537 /* Cannot convert. */
3538 goto fail_with_EILSEQ
;
3539 ENSURE_ALLOCATION (xsum (length
, count
));
3540 memcpy (result
+ length
, cbuf
, count
);
3544 ENSURE_ALLOCATION_ELSE (xsum (length
, tmpdst_len
),
3545 { free (tmpdst
); goto out_of_memory
; });
3546 DCHAR_CPY (result
+ length
, tmpdst
, tmpdst_len
);
3548 length
+= tmpdst_len
;
3551 if (w
< width
&& (flags
& FLAG_LEFT
))
3553 size_t n
= width
- w
;
3554 ENSURE_ALLOCATION (xsum (length
, n
));
3555 DCHAR_SET (result
+ length
, ' ', n
);
3561 #if NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION
3562 else if (dp
->conversion
== 'c'
3563 && a
.arg
[dp
->arg_index
].type
!= TYPE_WIDE_CHAR
)
3565 /* Implement the 'c' directive ourselves, in order to avoid
3566 EILSEQ in the "C" locale. */
3567 int flags
= dp
->flags
;
3571 if (dp
->width_start
!= dp
->width_end
)
3573 if (dp
->width_arg_index
!= ARG_NONE
)
3577 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
3579 arg
= a
.arg
[dp
->width_arg_index
].a
.a_int
;
3583 /* "A negative field width is taken as a '-' flag
3584 followed by a positive field width." */
3591 const FCHAR_T
*digitp
= dp
->width_start
;
3594 width
= xsum (xtimes (width
, 10), *digitp
++ - '0');
3595 while (digitp
!= dp
->width_end
);
3599 /* %c in vasnwprintf. See the specification of fwprintf. */
3601 char arg
= (char) a
.arg
[dp
->arg_index
].a
.a_char
;
3606 int count
= mbrtowc (&wc
, &arg
, 1, &state
);
3608 /* Invalid or incomplete multibyte character. */
3609 goto fail_with_EILSEQ
;
3611 if (1 < width
&& !(flags
& FLAG_LEFT
))
3613 size_t n
= width
- 1;
3614 ENSURE_ALLOCATION (xsum (length
, n
));
3615 DCHAR_SET (result
+ length
, ' ', n
);
3619 ENSURE_ALLOCATION (xsum (length
, 1));
3620 result
[length
++] = wc
;
3622 if (1 < width
&& (flags
& FLAG_LEFT
))
3624 size_t n
= width
- 1;
3625 ENSURE_ALLOCATION (xsum (length
, n
));
3626 DCHAR_SET (result
+ length
, ' ', n
);
3632 #if NEED_PRINTF_DIRECTIVE_B || NEED_PRINTF_DIRECTIVE_UPPERCASE_B
3634 # if NEED_PRINTF_DIRECTIVE_B
3635 || (dp
->conversion
== 'b')
3637 # if NEED_PRINTF_DIRECTIVE_UPPERCASE_B
3638 || (dp
->conversion
== 'B')
3642 arg_type type
= a
.arg
[dp
->arg_index
].type
;
3643 int flags
= dp
->flags
;
3650 DCHAR_T tmpbuf
[700];
3659 if (dp
->width_start
!= dp
->width_end
)
3661 if (dp
->width_arg_index
!= ARG_NONE
)
3665 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
3667 arg
= a
.arg
[dp
->width_arg_index
].a
.a_int
;
3671 /* "A negative field width is taken as a '-' flag
3672 followed by a positive field width." */
3679 const FCHAR_T
*digitp
= dp
->width_start
;
3682 width
= xsum (xtimes (width
, 10), *digitp
++ - '0');
3683 while (digitp
!= dp
->width_end
);
3690 if (dp
->precision_start
!= dp
->precision_end
)
3692 if (dp
->precision_arg_index
!= ARG_NONE
)
3696 if (!(a
.arg
[dp
->precision_arg_index
].type
== TYPE_INT
))
3698 arg
= a
.arg
[dp
->precision_arg_index
].a
.a_int
;
3699 /* "A negative precision is taken as if the precision
3709 const FCHAR_T
*digitp
= dp
->precision_start
+ 1;
3712 while (digitp
!= dp
->precision_end
)
3713 precision
= xsum (xtimes (precision
, 10), *digitp
++ - '0');
3718 /* Allocate a temporary buffer of sufficient size. */
3723 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
)
3724 + 1; /* turn floor into ceil */
3728 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
)
3729 + 1; /* turn floor into ceil */
3731 case TYPE_ULONGLONGINT
:
3733 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
)
3734 + 1; /* turn floor into ceil */
3738 (unsigned int) (sizeof (uint8_t) * CHAR_BIT
)
3739 + 1; /* turn floor into ceil */
3743 (unsigned int) (sizeof (uint16_t) * CHAR_BIT
)
3744 + 1; /* turn floor into ceil */
3748 (unsigned int) (sizeof (uint32_t) * CHAR_BIT
)
3749 + 1; /* turn floor into ceil */
3753 (unsigned int) (sizeof (uint64_t) * CHAR_BIT
)
3754 + 1; /* turn floor into ceil */
3756 case TYPE_UINT_FAST8_T
:
3758 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
)
3759 + 1; /* turn floor into ceil */
3761 case TYPE_UINT_FAST16_T
:
3763 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
)
3764 + 1; /* turn floor into ceil */
3766 case TYPE_UINT_FAST32_T
:
3768 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
)
3769 + 1; /* turn floor into ceil */
3771 case TYPE_UINT_FAST64_T
:
3773 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
)
3774 + 1; /* turn floor into ceil */
3777 if (tmp_length
< precision
)
3778 tmp_length
= precision
;
3779 /* Add 2, to account for a prefix from the alternate form. */
3780 tmp_length
= xsum (tmp_length
, 2);
3782 if (tmp_length
< width
)
3785 if (tmp_length
<= sizeof (tmpbuf
) / sizeof (DCHAR_T
))
3789 size_t tmp_memsize
= xtimes (tmp_length
, sizeof (DCHAR_T
));
3791 if (size_overflow_p (tmp_memsize
))
3792 /* Overflow, would lead to out of memory. */
3794 tmp
= (DCHAR_T
*) malloc (tmp_memsize
);
3796 /* Out of memory. */
3800 tmp_end
= tmp
+ tmp_length
;
3802 unsigned long long arg
;
3806 arg
= a
.arg
[dp
->arg_index
].a
.a_uchar
;
3809 arg
= a
.arg
[dp
->arg_index
].a
.a_ushort
;
3812 arg
= a
.arg
[dp
->arg_index
].a
.a_uint
;
3815 arg
= a
.arg
[dp
->arg_index
].a
.a_ulongint
;
3817 case TYPE_ULONGLONGINT
:
3818 arg
= a
.arg
[dp
->arg_index
].a
.a_ulonglongint
;
3821 arg
= a
.arg
[dp
->arg_index
].a
.a_uint8_t
;
3824 arg
= a
.arg
[dp
->arg_index
].a
.a_uint16_t
;
3827 arg
= a
.arg
[dp
->arg_index
].a
.a_uint32_t
;
3830 arg
= a
.arg
[dp
->arg_index
].a
.a_uint64_t
;
3832 case TYPE_UINT_FAST8_T
:
3833 arg
= a
.arg
[dp
->arg_index
].a
.a_uint_fast8_t
;
3835 case TYPE_UINT_FAST16_T
:
3836 arg
= a
.arg
[dp
->arg_index
].a
.a_uint_fast16_t
;
3838 case TYPE_UINT_FAST32_T
:
3839 arg
= a
.arg
[dp
->arg_index
].a
.a_uint_fast32_t
;
3841 case TYPE_UINT_FAST64_T
:
3842 arg
= a
.arg
[dp
->arg_index
].a
.a_uint_fast64_t
;
3847 int need_prefix
= ((flags
& FLAG_ALT
) && arg
!= 0);
3850 /* "The result of converting a zero value with a precision
3851 of zero is no characters." */
3852 if (!(has_precision
&& precision
== 0 && arg
== 0))
3856 *--p
= '0' + (arg
& 1);
3864 DCHAR_T
*digits_start
= tmp_end
- precision
;
3865 while (p
> digits_start
)
3873 # if NEED_PRINTF_DIRECTIVE_B && !NEED_PRINTF_DIRECTIVE_UPPERCASE_B
3875 # elif NEED_PRINTF_DIRECTIVE_UPPERCASE_B && !NEED_PRINTF_DIRECTIVE_B
3878 *--p
= dp
->conversion
;
3884 /* The generated string now extends from tmp_start to tmp_end,
3885 with the zero padding insertion point being at pad_ptr,
3886 tmp_start <= pad_ptr <= tmp_end. */
3887 count
= tmp_end
- tmp_start
;
3891 size_t pad
= width
- count
;
3893 if (flags
& FLAG_LEFT
)
3895 /* Pad with spaces on the right. */
3896 for (p
= tmp_start
; p
< tmp_end
; p
++)
3898 for (p
= tmp_end
- pad
; p
< tmp_end
; p
++)
3901 else if ((flags
& FLAG_ZERO
)
3902 /* Neither ISO C nor POSIX specify that the '0'
3903 flag is ignored when a width and a precision
3904 are both present. But most implementations
3906 && !(has_width
&& has_precision
))
3908 /* Pad with zeroes. */
3909 for (p
= tmp_start
; p
< pad_ptr
; p
++)
3911 for (p
= pad_ptr
- pad
; p
< pad_ptr
; p
++)
3916 /* Pad with spaces on the left. */
3917 for (p
= tmp_start
- pad
; p
< tmp_start
; p
++)
3921 tmp_start
= tmp_start
- pad
;
3924 count
= tmp_end
- tmp_start
;
3926 if (count
> tmp_length
)
3927 /* tmp_length was incorrectly calculated - fix the
3931 /* Make room for the result. */
3932 if (count
>= allocated
- length
)
3934 size_t n
= xsum (length
, count
);
3936 ENSURE_ALLOCATION (n
);
3939 /* Append the result. */
3940 memcpy (result
+ length
, tmp_start
, count
* sizeof (DCHAR_T
));
3946 #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
3947 else if ((dp
->conversion
== 'a' || dp
->conversion
== 'A')
3948 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
3950 # if NEED_PRINTF_DOUBLE
3951 || a
.arg
[dp
->arg_index
].type
== TYPE_DOUBLE
3953 # if NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
3954 || a
.arg
[dp
->arg_index
].type
== TYPE_LONGDOUBLE
3960 arg_type type
= a
.arg
[dp
->arg_index
].type
;
3961 int flags
= dp
->flags
;
3967 DCHAR_T tmpbuf
[700];
3973 if (dp
->width_start
!= dp
->width_end
)
3975 if (dp
->width_arg_index
!= ARG_NONE
)
3979 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
3981 arg
= a
.arg
[dp
->width_arg_index
].a
.a_int
;
3985 /* "A negative field width is taken as a '-' flag
3986 followed by a positive field width." */
3993 const FCHAR_T
*digitp
= dp
->width_start
;
3996 width
= xsum (xtimes (width
, 10), *digitp
++ - '0');
3997 while (digitp
!= dp
->width_end
);
4003 if (dp
->precision_start
!= dp
->precision_end
)
4005 if (dp
->precision_arg_index
!= ARG_NONE
)
4009 if (!(a
.arg
[dp
->precision_arg_index
].type
== TYPE_INT
))
4011 arg
= a
.arg
[dp
->precision_arg_index
].a
.a_int
;
4012 /* "A negative precision is taken as if the precision
4022 const FCHAR_T
*digitp
= dp
->precision_start
+ 1;
4025 while (digitp
!= dp
->precision_end
)
4026 precision
= xsum (xtimes (precision
, 10), *digitp
++ - '0');
4031 /* Allocate a temporary buffer of sufficient size. */
4032 if (type
== TYPE_LONGDOUBLE
)
4034 (unsigned int) ((LDBL_DIG
+ 1)
4035 * 0.831 /* decimal -> hexadecimal */
4037 + 1; /* turn floor into ceil */
4040 (unsigned int) ((DBL_DIG
+ 1)
4041 * 0.831 /* decimal -> hexadecimal */
4043 + 1; /* turn floor into ceil */
4044 if (tmp_length
< precision
)
4045 tmp_length
= precision
;
4046 /* Account for sign, decimal point etc. */
4047 tmp_length
= xsum (tmp_length
, 12);
4049 if (tmp_length
< width
)
4052 tmp_length
= xsum (tmp_length
, 1); /* account for trailing NUL */
4054 if (tmp_length
<= sizeof (tmpbuf
) / sizeof (DCHAR_T
))
4058 size_t tmp_memsize
= xtimes (tmp_length
, sizeof (DCHAR_T
));
4060 if (size_overflow_p (tmp_memsize
))
4061 /* Overflow, would lead to out of memory. */
4063 tmp
= (DCHAR_T
*) malloc (tmp_memsize
);
4065 /* Out of memory. */
4071 if (type
== TYPE_LONGDOUBLE
)
4073 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
4074 long double arg
= a
.arg
[dp
->arg_index
].a
.a_longdouble
;
4078 if (dp
->conversion
== 'A')
4080 *p
++ = 'N'; *p
++ = 'A'; *p
++ = 'N';
4084 *p
++ = 'n'; *p
++ = 'a'; *p
++ = 'n';
4090 DECL_LONG_DOUBLE_ROUNDING
4092 BEGIN_LONG_DOUBLE_ROUNDING ();
4094 if (signbit (arg
)) /* arg < 0.0L or negative zero */
4102 else if (flags
& FLAG_SHOWSIGN
)
4104 else if (flags
& FLAG_SPACE
)
4107 if (arg
> 0.0L && arg
+ arg
== arg
)
4109 if (dp
->conversion
== 'A')
4111 *p
++ = 'I'; *p
++ = 'N'; *p
++ = 'F';
4115 *p
++ = 'i'; *p
++ = 'n'; *p
++ = 'f';
4121 long double mantissa
;
4124 mantissa
= printf_frexpl (arg
, &exponent
);
4132 && precision
< (unsigned int) ((LDBL_DIG
+ 1) * 0.831) + 1)
4134 /* Round the mantissa. */
4135 long double tail
= mantissa
;
4138 for (q
= precision
; ; q
--)
4140 int digit
= (int) tail
;
4144 if (digit
& 1 ? tail
>= 0.5L : tail
> 0.5L)
4153 for (q
= precision
; q
> 0; q
--)
4159 *p
++ = dp
->conversion
- 'A' + 'X';
4164 digit
= (int) mantissa
;
4167 if ((flags
& FLAG_ALT
)
4168 || mantissa
> 0.0L || precision
> 0)
4170 *p
++ = decimal_point_char ();
4171 /* This loop terminates because we assume
4172 that FLT_RADIX is a power of 2. */
4173 while (mantissa
> 0.0L)
4176 digit
= (int) mantissa
;
4181 : dp
->conversion
- 10);
4185 while (precision
> 0)
4192 *p
++ = dp
->conversion
- 'A' + 'P';
4193 # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
4195 static const wchar_t decimal_format
[] =
4196 { '%', '+', 'd', '\0' };
4197 SNPRINTF (p
, 6 + 1, decimal_format
, exponent
);
4202 if (sizeof (DCHAR_T
) == 1)
4204 sprintf ((char *) p
, "%+d", exponent
);
4212 sprintf (expbuf
, "%+d", exponent
);
4213 for (ep
= expbuf
; (*p
= *ep
) != '\0'; ep
++)
4219 END_LONG_DOUBLE_ROUNDING ();
4227 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
4228 double arg
= a
.arg
[dp
->arg_index
].a
.a_double
;
4232 if (dp
->conversion
== 'A')
4234 *p
++ = 'N'; *p
++ = 'A'; *p
++ = 'N';
4238 *p
++ = 'n'; *p
++ = 'a'; *p
++ = 'n';
4245 if (signbit (arg
)) /* arg < 0.0 or negative zero */
4253 else if (flags
& FLAG_SHOWSIGN
)
4255 else if (flags
& FLAG_SPACE
)
4258 if (arg
> 0.0 && arg
+ arg
== arg
)
4260 if (dp
->conversion
== 'A')
4262 *p
++ = 'I'; *p
++ = 'N'; *p
++ = 'F';
4266 *p
++ = 'i'; *p
++ = 'n'; *p
++ = 'f';
4275 mantissa
= printf_frexp (arg
, &exponent
);
4283 && precision
< (unsigned int) ((DBL_DIG
+ 1) * 0.831) + 1)
4285 /* Round the mantissa. */
4286 double tail
= mantissa
;
4289 for (q
= precision
; ; q
--)
4291 int digit
= (int) tail
;
4295 if (digit
& 1 ? tail
>= 0.5 : tail
> 0.5)
4304 for (q
= precision
; q
> 0; q
--)
4310 *p
++ = dp
->conversion
- 'A' + 'X';
4315 digit
= (int) mantissa
;
4318 if ((flags
& FLAG_ALT
)
4319 || mantissa
> 0.0 || precision
> 0)
4321 *p
++ = decimal_point_char ();
4322 /* This loop terminates because we assume
4323 that FLT_RADIX is a power of 2. */
4324 while (mantissa
> 0.0)
4327 digit
= (int) mantissa
;
4332 : dp
->conversion
- 10);
4336 while (precision
> 0)
4343 *p
++ = dp
->conversion
- 'A' + 'P';
4344 # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
4346 static const wchar_t decimal_format
[] =
4347 { '%', '+', 'd', '\0' };
4348 SNPRINTF (p
, 6 + 1, decimal_format
, exponent
);
4353 if (sizeof (DCHAR_T
) == 1)
4355 sprintf ((char *) p
, "%+d", exponent
);
4363 sprintf (expbuf
, "%+d", exponent
);
4364 for (ep
= expbuf
; (*p
= *ep
) != '\0'; ep
++)
4375 /* The generated string now extends from tmp to p, with the
4376 zero padding insertion point being at pad_ptr. */
4381 size_t pad
= width
- count
;
4382 DCHAR_T
*end
= p
+ pad
;
4384 if (flags
& FLAG_LEFT
)
4386 /* Pad with spaces on the right. */
4387 for (; pad
> 0; pad
--)
4390 else if ((flags
& FLAG_ZERO
) && pad_ptr
!= NULL
)
4392 /* Pad with zeroes. */
4397 for (; pad
> 0; pad
--)
4402 /* Pad with spaces on the left. */
4407 for (; pad
> 0; pad
--)
4416 if (count
>= tmp_length
)
4417 /* tmp_length was incorrectly calculated - fix the
4421 /* Make room for the result. */
4422 if (count
>= allocated
- length
)
4424 size_t n
= xsum (length
, count
);
4426 ENSURE_ALLOCATION (n
);
4429 /* Append the result. */
4430 memcpy (result
+ length
, tmp
, count
* sizeof (DCHAR_T
));
4436 #if NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE
4437 else if ((dp
->conversion
== 'f' || dp
->conversion
== 'F'
4438 || dp
->conversion
== 'e' || dp
->conversion
== 'E'
4439 || dp
->conversion
== 'g' || dp
->conversion
== 'G'
4440 || dp
->conversion
== 'a' || dp
->conversion
== 'A')
4442 # if NEED_PRINTF_DOUBLE
4443 || a
.arg
[dp
->arg_index
].type
== TYPE_DOUBLE
4444 # elif NEED_PRINTF_INFINITE_DOUBLE
4445 || (a
.arg
[dp
->arg_index
].type
== TYPE_DOUBLE
4446 /* The systems (mingw) which produce wrong output
4447 for Inf, -Inf, and NaN also do so for -0.0.
4448 Therefore we treat this case here as well. */
4449 && is_infinite_or_zero (a
.arg
[dp
->arg_index
].a
.a_double
))
4451 # if NEED_PRINTF_LONG_DOUBLE
4452 || a
.arg
[dp
->arg_index
].type
== TYPE_LONGDOUBLE
4453 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
4454 || (a
.arg
[dp
->arg_index
].type
== TYPE_LONGDOUBLE
4455 /* Some systems produce wrong output for Inf,
4456 -Inf, and NaN. Some systems in this category
4457 (IRIX 5.3) also do so for -0.0. Therefore we
4458 treat this case here as well. */
4459 && is_infinite_or_zerol (a
.arg
[dp
->arg_index
].a
.a_longdouble
))
4463 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
4464 arg_type type
= a
.arg
[dp
->arg_index
].type
;
4466 int flags
= dp
->flags
;
4472 DCHAR_T tmpbuf
[700];
4478 if (dp
->width_start
!= dp
->width_end
)
4480 if (dp
->width_arg_index
!= ARG_NONE
)
4484 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
4486 arg
= a
.arg
[dp
->width_arg_index
].a
.a_int
;
4490 /* "A negative field width is taken as a '-' flag
4491 followed by a positive field width." */
4498 const FCHAR_T
*digitp
= dp
->width_start
;
4501 width
= xsum (xtimes (width
, 10), *digitp
++ - '0');
4502 while (digitp
!= dp
->width_end
);
4508 if (dp
->precision_start
!= dp
->precision_end
)
4510 if (dp
->precision_arg_index
!= ARG_NONE
)
4514 if (!(a
.arg
[dp
->precision_arg_index
].type
== TYPE_INT
))
4516 arg
= a
.arg
[dp
->precision_arg_index
].a
.a_int
;
4517 /* "A negative precision is taken as if the precision
4527 const FCHAR_T
*digitp
= dp
->precision_start
+ 1;
4530 while (digitp
!= dp
->precision_end
)
4531 precision
= xsum (xtimes (precision
, 10), *digitp
++ - '0');
4536 /* POSIX specifies the default precision to be 6 for %f, %F,
4537 %e, %E, but not for %g, %G. Implementations appear to use
4538 the same default precision also for %g, %G. But for %a, %A,
4539 the default precision is 0. */
4541 if (!(dp
->conversion
== 'a' || dp
->conversion
== 'A'))
4544 /* Allocate a temporary buffer of sufficient size. */
4545 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
4546 tmp_length
= (type
== TYPE_LONGDOUBLE
? LDBL_DIG
+ 1 : DBL_DIG
+ 1);
4547 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
4548 tmp_length
= (type
== TYPE_LONGDOUBLE
? LDBL_DIG
+ 1 : 0);
4549 # elif NEED_PRINTF_LONG_DOUBLE
4550 tmp_length
= LDBL_DIG
+ 1;
4551 # elif NEED_PRINTF_DOUBLE
4552 tmp_length
= DBL_DIG
+ 1;
4556 if (tmp_length
< precision
)
4557 tmp_length
= precision
;
4558 # if NEED_PRINTF_LONG_DOUBLE
4559 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4560 if (type
== TYPE_LONGDOUBLE
)
4562 if (dp
->conversion
== 'f' || dp
->conversion
== 'F')
4564 long double arg
= a
.arg
[dp
->arg_index
].a
.a_longdouble
;
4565 if (!(isnanl (arg
) || arg
+ arg
== arg
))
4567 /* arg is finite and nonzero. */
4568 int exponent
= floorlog10l (arg
< 0 ? -arg
: arg
);
4569 if (exponent
>= 0 && tmp_length
< exponent
+ precision
)
4570 tmp_length
= exponent
+ precision
;
4574 # if NEED_PRINTF_DOUBLE
4575 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
4576 if (type
== TYPE_DOUBLE
)
4578 if (dp
->conversion
== 'f' || dp
->conversion
== 'F')
4580 double arg
= a
.arg
[dp
->arg_index
].a
.a_double
;
4581 if (!(isnand (arg
) || arg
+ arg
== arg
))
4583 /* arg is finite and nonzero. */
4584 int exponent
= floorlog10 (arg
< 0 ? -arg
: arg
);
4585 if (exponent
>= 0 && tmp_length
< exponent
+ precision
)
4586 tmp_length
= exponent
+ precision
;
4590 /* Account for sign, decimal point etc. */
4591 tmp_length
= xsum (tmp_length
, 12);
4593 if (tmp_length
< width
)
4596 tmp_length
= xsum (tmp_length
, 1); /* account for trailing NUL */
4598 if (tmp_length
<= sizeof (tmpbuf
) / sizeof (DCHAR_T
))
4602 size_t tmp_memsize
= xtimes (tmp_length
, sizeof (DCHAR_T
));
4604 if (size_overflow_p (tmp_memsize
))
4605 /* Overflow, would lead to out of memory. */
4607 tmp
= (DCHAR_T
*) malloc (tmp_memsize
);
4609 /* Out of memory. */
4616 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
4617 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4618 if (type
== TYPE_LONGDOUBLE
)
4621 long double arg
= a
.arg
[dp
->arg_index
].a
.a_longdouble
;
4625 if (dp
->conversion
>= 'A' && dp
->conversion
<= 'Z')
4627 *p
++ = 'N'; *p
++ = 'A'; *p
++ = 'N';
4631 *p
++ = 'n'; *p
++ = 'a'; *p
++ = 'n';
4637 DECL_LONG_DOUBLE_ROUNDING
4639 BEGIN_LONG_DOUBLE_ROUNDING ();
4641 if (signbit (arg
)) /* arg < 0.0L or negative zero */
4649 else if (flags
& FLAG_SHOWSIGN
)
4651 else if (flags
& FLAG_SPACE
)
4654 if (arg
> 0.0L && arg
+ arg
== arg
)
4656 if (dp
->conversion
>= 'A' && dp
->conversion
<= 'Z')
4658 *p
++ = 'I'; *p
++ = 'N'; *p
++ = 'F';
4662 *p
++ = 'i'; *p
++ = 'n'; *p
++ = 'f';
4667 # if NEED_PRINTF_LONG_DOUBLE
4670 if (dp
->conversion
== 'f' || dp
->conversion
== 'F')
4676 scale10_round_decimal_long_double (arg
, precision
);
4679 END_LONG_DOUBLE_ROUNDING ();
4682 ndigits
= strlen (digits
);
4684 if (ndigits
> precision
)
4688 *p
++ = digits
[ndigits
];
4690 while (ndigits
> precision
);
4693 /* Here ndigits <= precision. */
4694 if ((flags
& FLAG_ALT
) || precision
> 0)
4696 *p
++ = decimal_point_char ();
4697 for (; precision
> ndigits
; precision
--)
4702 *p
++ = digits
[ndigits
];
4708 else if (dp
->conversion
== 'e' || dp
->conversion
== 'E')
4716 if ((flags
& FLAG_ALT
) || precision
> 0)
4718 *p
++ = decimal_point_char ();
4719 for (; precision
> 0; precision
--)
4730 exponent
= floorlog10l (arg
);
4735 scale10_round_decimal_long_double (arg
,
4736 (int)precision
- exponent
);
4739 END_LONG_DOUBLE_ROUNDING ();
4742 ndigits
= strlen (digits
);
4744 if (ndigits
== precision
+ 1)
4746 if (ndigits
< precision
4747 || ndigits
> precision
+ 2)
4748 /* The exponent was not guessed
4749 precisely enough. */
4752 /* None of two values of exponent is
4753 the right one. Prevent an endless
4757 if (ndigits
== precision
)
4763 /* Here ndigits = precision+1. */
4764 if (is_borderline (digits
, precision
))
4766 /* Maybe the exponent guess was too high
4767 and a smaller exponent can be reached
4768 by turning a 10...0 into 9...9x. */
4770 scale10_round_decimal_long_double (arg
,
4771 (int)precision
- exponent
+ 1);
4772 if (digits2
== NULL
)
4775 END_LONG_DOUBLE_ROUNDING ();
4778 if (strlen (digits2
) == precision
+ 1)
4787 /* Here ndigits = precision+1. */
4789 *p
++ = digits
[--ndigits
];
4790 if ((flags
& FLAG_ALT
) || precision
> 0)
4792 *p
++ = decimal_point_char ();
4796 *p
++ = digits
[ndigits
];
4803 *p
++ = dp
->conversion
; /* 'e' or 'E' */
4804 # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
4806 static const wchar_t decimal_format
[] =
4807 { '%', '+', '.', '2', 'd', '\0' };
4808 SNPRINTF (p
, 6 + 1, decimal_format
, exponent
);
4813 if (sizeof (DCHAR_T
) == 1)
4815 sprintf ((char *) p
, "%+.2d", exponent
);
4823 sprintf (expbuf
, "%+.2d", exponent
);
4824 for (ep
= expbuf
; (*p
= *ep
) != '\0'; ep
++)
4829 else if (dp
->conversion
== 'g' || dp
->conversion
== 'G')
4833 /* precision >= 1. */
4836 /* The exponent is 0, >= -4, < precision.
4837 Use fixed-point notation. */
4839 size_t ndigits
= precision
;
4840 /* Number of trailing zeroes that have to be
4843 (flags
& FLAG_ALT
? 0 : precision
- 1);
4847 if ((flags
& FLAG_ALT
) || ndigits
> nzeroes
)
4849 *p
++ = decimal_point_char ();
4850 while (ndigits
> nzeroes
)
4866 exponent
= floorlog10l (arg
);
4871 scale10_round_decimal_long_double (arg
,
4872 (int)(precision
- 1) - exponent
);
4875 END_LONG_DOUBLE_ROUNDING ();
4878 ndigits
= strlen (digits
);
4880 if (ndigits
== precision
)
4882 if (ndigits
< precision
- 1
4883 || ndigits
> precision
+ 1)
4884 /* The exponent was not guessed
4885 precisely enough. */
4888 /* None of two values of exponent is
4889 the right one. Prevent an endless
4893 if (ndigits
< precision
)
4899 /* Here ndigits = precision. */
4900 if (is_borderline (digits
, precision
- 1))
4902 /* Maybe the exponent guess was too high
4903 and a smaller exponent can be reached
4904 by turning a 10...0 into 9...9x. */
4906 scale10_round_decimal_long_double (arg
,
4907 (int)(precision
- 1) - exponent
+ 1);
4908 if (digits2
== NULL
)
4911 END_LONG_DOUBLE_ROUNDING ();
4914 if (strlen (digits2
) == precision
)
4923 /* Here ndigits = precision. */
4925 /* Determine the number of trailing zeroes
4926 that have to be dropped. */
4928 if ((flags
& FLAG_ALT
) == 0)
4929 while (nzeroes
< ndigits
4930 && digits
[nzeroes
] == '0')
4933 /* The exponent is now determined. */
4935 && exponent
< (long)precision
)
4937 /* Fixed-point notation:
4938 max(exponent,0)+1 digits, then the
4939 decimal point, then the remaining
4940 digits without trailing zeroes. */
4943 size_t ecount
= exponent
+ 1;
4944 /* Note: count <= precision = ndigits. */
4945 for (; ecount
> 0; ecount
--)
4946 *p
++ = digits
[--ndigits
];
4947 if ((flags
& FLAG_ALT
) || ndigits
> nzeroes
)
4949 *p
++ = decimal_point_char ();
4950 while (ndigits
> nzeroes
)
4953 *p
++ = digits
[ndigits
];
4959 size_t ecount
= -exponent
- 1;
4961 *p
++ = decimal_point_char ();
4962 for (; ecount
> 0; ecount
--)
4964 while (ndigits
> nzeroes
)
4967 *p
++ = digits
[ndigits
];
4973 /* Exponential notation. */
4974 *p
++ = digits
[--ndigits
];
4975 if ((flags
& FLAG_ALT
) || ndigits
> nzeroes
)
4977 *p
++ = decimal_point_char ();
4978 while (ndigits
> nzeroes
)
4981 *p
++ = digits
[ndigits
];
4984 *p
++ = dp
->conversion
- 'G' + 'E'; /* 'e' or 'E' */
4985 # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
4987 static const wchar_t decimal_format
[] =
4988 { '%', '+', '.', '2', 'd', '\0' };
4989 SNPRINTF (p
, 6 + 1, decimal_format
, exponent
);
4994 if (sizeof (DCHAR_T
) == 1)
4996 sprintf ((char *) p
, "%+.2d", exponent
);
5004 sprintf (expbuf
, "%+.2d", exponent
);
5005 for (ep
= expbuf
; (*p
= *ep
) != '\0'; ep
++)
5017 /* arg is finite. */
5023 if (dp
->conversion
== 'f' || dp
->conversion
== 'F')
5026 if ((flags
& FLAG_ALT
) || precision
> 0)
5028 *p
++ = decimal_point_char ();
5029 for (; precision
> 0; precision
--)
5033 else if (dp
->conversion
== 'e' || dp
->conversion
== 'E')
5036 if ((flags
& FLAG_ALT
) || precision
> 0)
5038 *p
++ = decimal_point_char ();
5039 for (; precision
> 0; precision
--)
5042 *p
++ = dp
->conversion
; /* 'e' or 'E' */
5047 else if (dp
->conversion
== 'g' || dp
->conversion
== 'G')
5050 if (flags
& FLAG_ALT
)
5053 (precision
> 0 ? precision
- 1 : 0);
5054 *p
++ = decimal_point_char ();
5055 for (; ndigits
> 0; --ndigits
)
5059 else if (dp
->conversion
== 'a' || dp
->conversion
== 'A')
5062 *p
++ = dp
->conversion
- 'A' + 'X';
5065 if ((flags
& FLAG_ALT
) || precision
> 0)
5067 *p
++ = decimal_point_char ();
5068 for (; precision
> 0; precision
--)
5071 *p
++ = dp
->conversion
- 'A' + 'P';
5080 END_LONG_DOUBLE_ROUNDING ();
5083 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
5087 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
5089 double arg
= a
.arg
[dp
->arg_index
].a
.a_double
;
5093 if (dp
->conversion
>= 'A' && dp
->conversion
<= 'Z')
5095 *p
++ = 'N'; *p
++ = 'A'; *p
++ = 'N';
5099 *p
++ = 'n'; *p
++ = 'a'; *p
++ = 'n';
5106 if (signbit (arg
)) /* arg < 0.0 or negative zero */
5114 else if (flags
& FLAG_SHOWSIGN
)
5116 else if (flags
& FLAG_SPACE
)
5119 if (arg
> 0.0 && arg
+ arg
== arg
)
5121 if (dp
->conversion
>= 'A' && dp
->conversion
<= 'Z')
5123 *p
++ = 'I'; *p
++ = 'N'; *p
++ = 'F';
5127 *p
++ = 'i'; *p
++ = 'n'; *p
++ = 'f';
5132 # if NEED_PRINTF_DOUBLE
5135 if (dp
->conversion
== 'f' || dp
->conversion
== 'F')
5141 scale10_round_decimal_double (arg
, precision
);
5144 ndigits
= strlen (digits
);
5146 if (ndigits
> precision
)
5150 *p
++ = digits
[ndigits
];
5152 while (ndigits
> precision
);
5155 /* Here ndigits <= precision. */
5156 if ((flags
& FLAG_ALT
) || precision
> 0)
5158 *p
++ = decimal_point_char ();
5159 for (; precision
> ndigits
; precision
--)
5164 *p
++ = digits
[ndigits
];
5170 else if (dp
->conversion
== 'e' || dp
->conversion
== 'E')
5178 if ((flags
& FLAG_ALT
) || precision
> 0)
5180 *p
++ = decimal_point_char ();
5181 for (; precision
> 0; precision
--)
5192 exponent
= floorlog10 (arg
);
5197 scale10_round_decimal_double (arg
,
5198 (int)precision
- exponent
);
5201 ndigits
= strlen (digits
);
5203 if (ndigits
== precision
+ 1)
5205 if (ndigits
< precision
5206 || ndigits
> precision
+ 2)
5207 /* The exponent was not guessed
5208 precisely enough. */
5211 /* None of two values of exponent is
5212 the right one. Prevent an endless
5216 if (ndigits
== precision
)
5222 /* Here ndigits = precision+1. */
5223 if (is_borderline (digits
, precision
))
5225 /* Maybe the exponent guess was too high
5226 and a smaller exponent can be reached
5227 by turning a 10...0 into 9...9x. */
5229 scale10_round_decimal_double (arg
,
5230 (int)precision
- exponent
+ 1);
5231 if (digits2
== NULL
)
5236 if (strlen (digits2
) == precision
+ 1)
5245 /* Here ndigits = precision+1. */
5247 *p
++ = digits
[--ndigits
];
5248 if ((flags
& FLAG_ALT
) || precision
> 0)
5250 *p
++ = decimal_point_char ();
5254 *p
++ = digits
[ndigits
];
5261 *p
++ = dp
->conversion
; /* 'e' or 'E' */
5262 # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
5264 static const wchar_t decimal_format
[] =
5265 /* Produce the same number of exponent digits
5266 as the native printf implementation. */
5267 # if defined _WIN32 && ! defined __CYGWIN__
5268 { '%', '+', '.', '3', 'd', '\0' };
5270 { '%', '+', '.', '2', 'd', '\0' };
5272 SNPRINTF (p
, 6 + 1, decimal_format
, exponent
);
5278 static const char decimal_format
[] =
5279 /* Produce the same number of exponent digits
5280 as the native printf implementation. */
5281 # if defined _WIN32 && ! defined __CYGWIN__
5286 if (sizeof (DCHAR_T
) == 1)
5288 sprintf ((char *) p
, decimal_format
, exponent
);
5296 sprintf (expbuf
, decimal_format
, exponent
);
5297 for (ep
= expbuf
; (*p
= *ep
) != '\0'; ep
++)
5303 else if (dp
->conversion
== 'g' || dp
->conversion
== 'G')
5307 /* precision >= 1. */
5310 /* The exponent is 0, >= -4, < precision.
5311 Use fixed-point notation. */
5313 size_t ndigits
= precision
;
5314 /* Number of trailing zeroes that have to be
5317 (flags
& FLAG_ALT
? 0 : precision
- 1);
5321 if ((flags
& FLAG_ALT
) || ndigits
> nzeroes
)
5323 *p
++ = decimal_point_char ();
5324 while (ndigits
> nzeroes
)
5340 exponent
= floorlog10 (arg
);
5345 scale10_round_decimal_double (arg
,
5346 (int)(precision
- 1) - exponent
);
5349 ndigits
= strlen (digits
);
5351 if (ndigits
== precision
)
5353 if (ndigits
< precision
- 1
5354 || ndigits
> precision
+ 1)
5355 /* The exponent was not guessed
5356 precisely enough. */
5359 /* None of two values of exponent is
5360 the right one. Prevent an endless
5364 if (ndigits
< precision
)
5370 /* Here ndigits = precision. */
5371 if (is_borderline (digits
, precision
- 1))
5373 /* Maybe the exponent guess was too high
5374 and a smaller exponent can be reached
5375 by turning a 10...0 into 9...9x. */
5377 scale10_round_decimal_double (arg
,
5378 (int)(precision
- 1) - exponent
+ 1);
5379 if (digits2
== NULL
)
5384 if (strlen (digits2
) == precision
)
5393 /* Here ndigits = precision. */
5395 /* Determine the number of trailing zeroes
5396 that have to be dropped. */
5398 if ((flags
& FLAG_ALT
) == 0)
5399 while (nzeroes
< ndigits
5400 && digits
[nzeroes
] == '0')
5403 /* The exponent is now determined. */
5405 && exponent
< (long)precision
)
5407 /* Fixed-point notation:
5408 max(exponent,0)+1 digits, then the
5409 decimal point, then the remaining
5410 digits without trailing zeroes. */
5413 size_t ecount
= exponent
+ 1;
5414 /* Note: ecount <= precision = ndigits. */
5415 for (; ecount
> 0; ecount
--)
5416 *p
++ = digits
[--ndigits
];
5417 if ((flags
& FLAG_ALT
) || ndigits
> nzeroes
)
5419 *p
++ = decimal_point_char ();
5420 while (ndigits
> nzeroes
)
5423 *p
++ = digits
[ndigits
];
5429 size_t ecount
= -exponent
- 1;
5431 *p
++ = decimal_point_char ();
5432 for (; ecount
> 0; ecount
--)
5434 while (ndigits
> nzeroes
)
5437 *p
++ = digits
[ndigits
];
5443 /* Exponential notation. */
5444 *p
++ = digits
[--ndigits
];
5445 if ((flags
& FLAG_ALT
) || ndigits
> nzeroes
)
5447 *p
++ = decimal_point_char ();
5448 while (ndigits
> nzeroes
)
5451 *p
++ = digits
[ndigits
];
5454 *p
++ = dp
->conversion
- 'G' + 'E'; /* 'e' or 'E' */
5455 # if WIDE_CHAR_VERSION && DCHAR_IS_TCHAR
5457 static const wchar_t decimal_format
[] =
5458 /* Produce the same number of exponent digits
5459 as the native printf implementation. */
5460 # if defined _WIN32 && ! defined __CYGWIN__
5461 { '%', '+', '.', '3', 'd', '\0' };
5463 { '%', '+', '.', '2', 'd', '\0' };
5465 SNPRINTF (p
, 6 + 1, decimal_format
, exponent
);
5471 static const char decimal_format
[] =
5472 /* Produce the same number of exponent digits
5473 as the native printf implementation. */
5474 # if defined _WIN32 && ! defined __CYGWIN__
5479 if (sizeof (DCHAR_T
) == 1)
5481 sprintf ((char *) p
, decimal_format
, exponent
);
5489 sprintf (expbuf
, decimal_format
, exponent
);
5490 for (ep
= expbuf
; (*p
= *ep
) != '\0'; ep
++)
5503 /* arg is finite. */
5509 if (dp
->conversion
== 'f' || dp
->conversion
== 'F')
5512 if ((flags
& FLAG_ALT
) || precision
> 0)
5514 *p
++ = decimal_point_char ();
5515 for (; precision
> 0; precision
--)
5519 else if (dp
->conversion
== 'e' || dp
->conversion
== 'E')
5522 if ((flags
& FLAG_ALT
) || precision
> 0)
5524 *p
++ = decimal_point_char ();
5525 for (; precision
> 0; precision
--)
5528 *p
++ = dp
->conversion
; /* 'e' or 'E' */
5530 /* Produce the same number of exponent digits as
5531 the native printf implementation. */
5532 # if defined _WIN32 && ! defined __CYGWIN__
5538 else if (dp
->conversion
== 'g' || dp
->conversion
== 'G')
5541 if (flags
& FLAG_ALT
)
5544 (precision
> 0 ? precision
- 1 : 0);
5545 *p
++ = decimal_point_char ();
5546 for (; ndigits
> 0; --ndigits
)
5558 /* The generated string now extends from tmp to p, with the
5559 zero padding insertion point being at pad_ptr. */
5564 size_t pad
= width
- count
;
5565 DCHAR_T
*end
= p
+ pad
;
5567 if (flags
& FLAG_LEFT
)
5569 /* Pad with spaces on the right. */
5570 for (; pad
> 0; pad
--)
5573 else if ((flags
& FLAG_ZERO
) && pad_ptr
!= NULL
)
5575 /* Pad with zeroes. */
5580 for (; pad
> 0; pad
--)
5585 /* Pad with spaces on the left. */
5590 for (; pad
> 0; pad
--)
5599 if (count
>= tmp_length
)
5600 /* tmp_length was incorrectly calculated - fix the
5604 /* Make room for the result. */
5605 if (count
>= allocated
- length
)
5607 size_t n
= xsum (length
, count
);
5609 ENSURE_ALLOCATION (n
);
5612 /* Append the result. */
5613 memcpy (result
+ length
, tmp
, count
* sizeof (DCHAR_T
));
5621 arg_type type
= a
.arg
[dp
->arg_index
].type
;
5622 int flags
= dp
->flags
;
5623 #if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5626 #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5629 #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5633 #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5636 # define prec_ourselves 0
5638 #if (WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST
5639 # define pad_ourselves 1
5640 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5643 # define pad_ourselves 0
5646 unsigned int prefix_count
;
5647 int prefixes
[2] IF_LINT (= { 0 });
5651 TCHAR_T tmpbuf
[700];
5655 #if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5658 #if !USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5660 if (dp
->width_start
!= dp
->width_end
)
5662 if (dp
->width_arg_index
!= ARG_NONE
)
5666 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
5668 arg
= a
.arg
[dp
->width_arg_index
].a
.a_int
;
5672 /* "A negative field width is taken as a '-' flag
5673 followed by a positive field width." */
5680 const FCHAR_T
*digitp
= dp
->width_start
;
5683 width
= xsum (xtimes (width
, 10), *digitp
++ - '0');
5684 while (digitp
!= dp
->width_end
);
5686 # if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5692 #if !USE_SNPRINTF || (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5695 if (dp
->precision_start
!= dp
->precision_end
)
5697 if (dp
->precision_arg_index
!= ARG_NONE
)
5701 if (!(a
.arg
[dp
->precision_arg_index
].type
== TYPE_INT
))
5703 arg
= a
.arg
[dp
->precision_arg_index
].a
.a_int
;
5704 /* "A negative precision is taken as if the precision
5714 const FCHAR_T
*digitp
= dp
->precision_start
+ 1;
5717 while (digitp
!= dp
->precision_end
)
5718 precision
= xsum (xtimes (precision
, 10), *digitp
++ - '0');
5724 /* Decide whether to handle the precision ourselves. */
5725 #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5726 switch (dp
->conversion
)
5728 # if NEED_PRINTF_UNBOUNDED_PRECISION
5729 case 'd': case 'i': case 'u':
5731 #if SUPPORT_GNU_PRINTF_DIRECTIVES \
5732 || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
5736 prec_ourselves
= has_precision
&& (precision
> 0);
5739 case 'x': case 'X': case 'p':
5743 # if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO
5746 # if NEED_PRINTF_UNBOUNDED_PRECISION
5757 /* Decide whether to perform the padding ourselves. */
5758 #if !((WIDE_CHAR_VERSION && MUSL_LIBC) || NEED_PRINTF_FLAG_LEFTADJUST) && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
5759 switch (dp
->conversion
)
5761 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5762 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
5763 to perform the padding after this conversion. Functions
5764 with unistdio extensions perform the padding based on
5765 character count rather than element count. */
5768 # if NEED_PRINTF_FLAG_ZERO
5769 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
5775 pad_ourselves
= prec_ourselves
;
5781 /* Allocate a temporary buffer of sufficient size for calling
5784 MAX_ROOM_NEEDED (&a
, dp
->arg_index
, dp
->conversion
, type
,
5785 flags
, width
, has_precision
, precision
,
5788 if (tmp_length
<= sizeof (tmpbuf
) / sizeof (TCHAR_T
))
5792 size_t tmp_memsize
= xtimes (tmp_length
, sizeof (TCHAR_T
));
5794 if (size_overflow_p (tmp_memsize
))
5795 /* Overflow, would lead to out of memory. */
5797 tmp
= (TCHAR_T
*) malloc (tmp_memsize
);
5799 /* Out of memory. */
5804 /* Construct the format string for calling snprintf or
5808 #if NEED_PRINTF_FLAG_GROUPING
5809 /* The underlying implementation doesn't support the ' flag.
5810 Produce no grouping characters in this case; this is
5811 acceptable because the grouping is locale dependent. */
5813 if (flags
& FLAG_GROUP
)
5816 if (flags
& FLAG_LEFT
)
5818 if (flags
& FLAG_SHOWSIGN
)
5820 if (flags
& FLAG_SPACE
)
5822 if (flags
& FLAG_ALT
)
5824 #if __GLIBC__ >= 2 && !defined __UCLIBC__
5825 if (flags
& FLAG_LOCALIZED
)
5830 if (flags
& FLAG_ZERO
)
5832 if (dp
->width_start
!= dp
->width_end
)
5834 size_t n
= dp
->width_end
- dp
->width_start
;
5835 /* The width specification is known to consist only
5836 of standard ASCII characters. */
5837 if (sizeof (FCHAR_T
) == sizeof (TCHAR_T
))
5839 memcpy (fbp
, dp
->width_start
, n
* sizeof (TCHAR_T
));
5844 const FCHAR_T
*mp
= dp
->width_start
;
5851 if (!prec_ourselves
)
5853 if (dp
->precision_start
!= dp
->precision_end
)
5855 size_t n
= dp
->precision_end
- dp
->precision_start
;
5856 /* The precision specification is known to consist only
5857 of standard ASCII characters. */
5858 if (sizeof (FCHAR_T
) == sizeof (TCHAR_T
))
5860 memcpy (fbp
, dp
->precision_start
, n
* sizeof (TCHAR_T
));
5865 const FCHAR_T
*mp
= dp
->precision_start
;
5875 case TYPE_LONGLONGINT
:
5876 case TYPE_ULONGLONGINT
:
5877 #if INT8_WIDTH > LONG_WIDTH
5880 #if UINT8_WIDTH > LONG_WIDTH
5883 #if INT16_WIDTH > LONG_WIDTH
5886 #if UINT16_WIDTH > LONG_WIDTH
5889 #if INT32_WIDTH > LONG_WIDTH
5892 #if UINT32_WIDTH > LONG_WIDTH
5895 #if INT64_WIDTH > LONG_WIDTH
5898 #if UINT64_WIDTH > LONG_WIDTH
5901 #if INT_FAST8_WIDTH > LONG_WIDTH
5902 case TYPE_INT_FAST8_T
:
5904 #if UINT_FAST8_WIDTH > LONG_WIDTH
5905 case TYPE_UINT_FAST8_T
:
5907 #if INT_FAST16_WIDTH > LONG_WIDTH
5908 case TYPE_INT_FAST16_T
:
5910 #if UINT_FAST16_WIDTH > LONG_WIDTH
5911 case TYPE_UINT_FAST16_T
:
5913 #if INT_FAST32_WIDTH > LONG_WIDTH
5914 case TYPE_INT3_FAST2_T
:
5916 #if UINT_FAST32_WIDTH > LONG_WIDTH
5917 case TYPE_UINT_FAST32_T
:
5919 #if INT_FAST64_WIDTH > LONG_WIDTH
5920 case TYPE_INT_FAST64_T
:
5922 #if UINT_FAST64_WIDTH > LONG_WIDTH
5923 case TYPE_UINT_FAST64_T
:
5925 #if defined _WIN32 && ! defined __CYGWIN__
5936 #if INT8_WIDTH > INT_WIDTH && INT8_WIDTH <= LONG_WIDTH
5939 #if UINT8_WIDTH > INT_WIDTH && UINT8_WIDTH <= LONG_WIDTH
5942 #if INT16_WIDTH > INT_WIDTH && INT16_WIDTH <= LONG_WIDTH
5945 #if UINT16_WIDTH > INT_WIDTH && UINT16_WIDTH <= LONG_WIDTH
5948 #if INT32_WIDTH > INT_WIDTH && INT32_WIDTH <= LONG_WIDTH
5951 #if UINT32_WIDTH > INT_WIDTH && UINT32_WIDTH <= LONG_WIDTH
5954 #if INT64_WIDTH > INT_WIDTH && INT64_WIDTH <= LONG_WIDTH
5957 #if UINT64_WIDTH > INT_WIDTH && UINT64_WIDTH <= LONG_WIDTH
5960 #if INT_FAST8_WIDTH > INT_WIDTH && INT_FAST8_WIDTH <= LONG_WIDTH
5961 case TYPE_INT_FAST8_T
:
5963 #if UINT_FAST8_WIDTH > INT_WIDTH && UINT_FAST8_WIDTH <= LONG_WIDTH
5964 case TYPE_UINT_FAST8_T
:
5966 #if INT_FAST16_WIDTH > INT_WIDTH && INT_FAST16_WIDTH <= LONG_WIDTH
5967 case TYPE_INT_FAST16_T
:
5969 #if UINT_FAST16_WIDTH > INT_WIDTH && UINT_FAST16_WIDTH <= LONG_WIDTH
5970 case TYPE_UINT_FAST16_T
:
5972 #if INT_FAST32_WIDTH > INT_WIDTH && INT_FAST32_WIDTH <= LONG_WIDTH
5973 case TYPE_INT_FAST32_T
:
5975 #if UINT_FAST32_WIDTH > INT_WIDTH && UINT_FAST32_WIDTH <= LONG_WIDTH
5976 case TYPE_UINT_FAST32_T
:
5978 #if INT_FAST64_WIDTH > INT_WIDTH && INT_FAST64_WIDTH <= LONG_WIDTH
5979 case TYPE_INT_FAST64_T
:
5981 #if UINT_FAST64_WIDTH > INT_WIDTH && UINT_FAST64_WIDTH <= LONG_WIDTH
5982 case TYPE_UINT_FAST64_T
:
5985 case TYPE_WIDE_CHAR
:
5988 case TYPE_WIDE_STRING
:
5992 case TYPE_LONGDOUBLE
:
5998 #if NEED_PRINTF_DIRECTIVE_F
5999 if (dp
->conversion
== 'F')
6003 *fbp
= dp
->conversion
;
6005 /* Decide whether to pass %n in the format string
6007 # if (((!WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR) \
6008 && (HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99)) \
6009 || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \
6010 && !defined __UCLIBC__) \
6011 || (defined __APPLE__ && defined __MACH__) \
6012 || defined __OpenBSD__ \
6013 || defined __ANDROID__ \
6014 || (defined _WIN32 && ! defined __CYGWIN__)) \
6015 || (WIDE_CHAR_VERSION && MUSL_LIBC)
6016 /* We can avoid passing %n and instead rely on SNPRINTF's
6018 - !WIDE_CHAR_VERSION || !DCHAR_IS_TCHAR, because otherwise,
6019 when WIDE_CHAR_VERSION && DCHAR_IS_TCHAR,
6020 snwprintf()/_snwprintf() (Windows) and swprintf() (Unix)
6021 don't return the needed buffer size,
6023 - we're compiling for a system where we know
6024 - that snprintf's return value conforms to ISO C 99
6025 (HAVE_SNPRINTF_RETVAL_C99) and
6026 - that snprintf always produces NUL-terminated strings
6027 (HAVE_SNPRINTF_TRUNCATION_C99).
6028 And it is desirable to do so, because more and more platforms
6029 no longer support %n, for "security reasons". */
6030 /* On specific platforms, listed below, we *must* avoid %n.
6032 !WIDE_CHAR_VERSION && HAVE_SNPRINTF_RETVAL_C99 && !USE_MSVC__SNPRINTF
6033 we can rely on the return value of snprintf instead. Whereas
6034 in the opposite case
6035 WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
6036 we need to make room based on an estimation, computed by
6038 /* The following platforms forbid %n:
6039 - On glibc2 systems from 2004-10-18 or newer, the use of
6040 %n in format strings in writable memory may crash the
6041 program (if compiled with _FORTIFY_SOURCE=2).
6042 - On macOS 10.13 or newer, the use of %n in format
6043 strings in writable memory by default crashes the
6045 - On OpenBSD, since 2021-08-30, the use of %n in format
6046 strings produces an abort (see
6047 <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfprintf.c.diff?r1=1.79&r2=1.80&f=h>,
6048 <https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/vfwprintf.c.diff?r1=1.20&r2=1.21&f=h>).
6049 - On Android, starting on 2018-03-07, the use of %n in
6050 format strings produces a fatal error (see
6051 <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>).
6052 - On native Windows systems (such as mingw) where the OS is
6053 Windows Vista, the use of %n in format strings by default
6054 crashes the program. See
6055 <https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
6056 <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output>
6057 On the first four of these platforms, if !WIDE_CHAR_VERSION,
6058 it is not a big deal to avoid %n, because on these platforms,
6059 HAVE_SNPRINTF_RETVAL_C99 and HAVE_SNPRINTF_TRUNCATION_C99 are
6061 On native Windows, if !WIDE_CHAR_VERSION, it's not a big deal
6063 - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
6064 snprintf does not write more than the specified number
6065 of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
6066 '4', '5', '6' into buf, not '4', '5', '\0'.)
6067 - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
6068 allows us to recognize the case of an insufficient
6069 buffer size: it returns -1 in this case. */
6070 /* Additionally, in the WIDE_CHAR_VERSION case, we cannot use %n
6071 on musl libc because we would run into an swprintf() bug.
6072 See <https://www.openwall.com/lists/musl/2023/03/19/1>. */
6074 # else /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */
6083 /* Construct the arguments for calling snprintf or sprintf. */
6085 if (!pad_ourselves
&& dp
->width_arg_index
!= ARG_NONE
)
6087 if (!(a
.arg
[dp
->width_arg_index
].type
== TYPE_INT
))
6089 prefixes
[prefix_count
++] = a
.arg
[dp
->width_arg_index
].a
.a_int
;
6091 if (!prec_ourselves
&& dp
->precision_arg_index
!= ARG_NONE
)
6093 if (!(a
.arg
[dp
->precision_arg_index
].type
== TYPE_INT
))
6095 prefixes
[prefix_count
++] = a
.arg
[dp
->precision_arg_index
].a
.a_int
;
6099 /* The SNPRINTF result is appended after result[0..length].
6100 The latter is an array of DCHAR_T; SNPRINTF appends an
6101 array of TCHAR_T to it. This is possible because
6102 sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
6103 alignof (TCHAR_T) <= alignof (DCHAR_T). */
6104 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
6105 /* Ensure that maxlen below will be >= 2. Needed on BeOS,
6106 where an snprintf() with maxlen==1 acts like sprintf(). */
6107 ENSURE_ALLOCATION (xsum (length
,
6108 (2 + TCHARS_PER_DCHAR
- 1)
6109 / TCHARS_PER_DCHAR
));
6110 /* Prepare checking whether snprintf returns the count
6112 *(TCHAR_T
*) (result
+ length
) = '\0';
6123 size_t maxlen
= allocated
- length
;
6124 /* SNPRINTF can fail if its second argument is
6126 if (maxlen
> INT_MAX
/ TCHARS_PER_DCHAR
)
6127 maxlen
= INT_MAX
/ TCHARS_PER_DCHAR
;
6128 maxlen
= maxlen
* TCHARS_PER_DCHAR
;
6129 # define SNPRINTF_BUF(arg) \
6130 switch (prefix_count) \
6133 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
6138 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
6140 prefixes[0], arg, &count); \
6143 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
6145 prefixes[0], prefixes[1], arg, \
6152 # define SNPRINTF_BUF(arg) \
6153 switch (prefix_count) \
6156 count = sprintf (tmp, buf, arg); \
6159 count = sprintf (tmp, buf, prefixes[0], arg); \
6162 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
6175 int arg
= a
.arg
[dp
->arg_index
].a
.a_schar
;
6181 unsigned int arg
= a
.arg
[dp
->arg_index
].a
.a_uchar
;
6187 int arg
= a
.arg
[dp
->arg_index
].a
.a_short
;
6193 unsigned int arg
= a
.arg
[dp
->arg_index
].a
.a_ushort
;
6199 int arg
= a
.arg
[dp
->arg_index
].a
.a_int
;
6205 unsigned int arg
= a
.arg
[dp
->arg_index
].a
.a_uint
;
6211 long int arg
= a
.arg
[dp
->arg_index
].a
.a_longint
;
6217 unsigned long int arg
= a
.arg
[dp
->arg_index
].a
.a_ulongint
;
6221 case TYPE_LONGLONGINT
:
6223 long long int arg
= a
.arg
[dp
->arg_index
].a
.a_longlongint
;
6227 case TYPE_ULONGLONGINT
:
6229 unsigned long long int arg
= a
.arg
[dp
->arg_index
].a
.a_ulonglongint
;
6235 int8_t arg
= a
.arg
[dp
->arg_index
].a
.a_int8_t
;
6241 uint8_t arg
= a
.arg
[dp
->arg_index
].a
.a_uint8_t
;
6247 int16_t arg
= a
.arg
[dp
->arg_index
].a
.a_int16_t
;
6253 uint16_t arg
= a
.arg
[dp
->arg_index
].a
.a_uint16_t
;
6259 int32_t arg
= a
.arg
[dp
->arg_index
].a
.a_int32_t
;
6265 uint32_t arg
= a
.arg
[dp
->arg_index
].a
.a_uint32_t
;
6271 int64_t arg
= a
.arg
[dp
->arg_index
].a
.a_int64_t
;
6277 uint64_t arg
= a
.arg
[dp
->arg_index
].a
.a_uint64_t
;
6281 case TYPE_INT_FAST8_T
:
6283 int_fast8_t arg
= a
.arg
[dp
->arg_index
].a
.a_int_fast8_t
;
6287 case TYPE_UINT_FAST8_T
:
6289 uint_fast8_t arg
= a
.arg
[dp
->arg_index
].a
.a_uint_fast8_t
;
6293 case TYPE_INT_FAST16_T
:
6295 int_fast16_t arg
= a
.arg
[dp
->arg_index
].a
.a_int_fast16_t
;
6299 case TYPE_UINT_FAST16_T
:
6301 uint_fast16_t arg
= a
.arg
[dp
->arg_index
].a
.a_uint_fast16_t
;
6305 case TYPE_INT_FAST32_T
:
6307 int_fast32_t arg
= a
.arg
[dp
->arg_index
].a
.a_int_fast32_t
;
6311 case TYPE_UINT_FAST32_T
:
6313 uint_fast32_t arg
= a
.arg
[dp
->arg_index
].a
.a_uint_fast32_t
;
6317 case TYPE_INT_FAST64_T
:
6319 int_fast64_t arg
= a
.arg
[dp
->arg_index
].a
.a_int_fast64_t
;
6323 case TYPE_UINT_FAST64_T
:
6325 uint_fast64_t arg
= a
.arg
[dp
->arg_index
].a
.a_uint_fast64_t
;
6331 double arg
= a
.arg
[dp
->arg_index
].a
.a_double
;
6335 case TYPE_LONGDOUBLE
:
6337 long double arg
= a
.arg
[dp
->arg_index
].a
.a_longdouble
;
6343 int arg
= a
.arg
[dp
->arg_index
].a
.a_char
;
6348 case TYPE_WIDE_CHAR
:
6350 wint_t arg
= a
.arg
[dp
->arg_index
].a
.a_wide_char
;
6357 const char *arg
= a
.arg
[dp
->arg_index
].a
.a_string
;
6362 case TYPE_WIDE_STRING
:
6364 const wchar_t *arg
= a
.arg
[dp
->arg_index
].a
.a_wide_string
;
6371 void *arg
= a
.arg
[dp
->arg_index
].a
.a_pointer
;
6380 /* Portability: Not all implementations of snprintf()
6381 are ISO C 99 compliant. Determine the number of
6382 bytes that snprintf() has produced or would have
6386 /* Verify that snprintf() has NUL-terminated its
6388 if ((unsigned int) count
< maxlen
6389 && ((TCHAR_T
*) (result
+ length
)) [count
] != '\0')
6391 /* Portability hack. */
6392 if (retcount
> count
)
6397 /* snprintf() doesn't understand the '%n'
6401 /* Don't use the '%n' directive; instead, look
6402 at the snprintf() return value. */
6408 /* Look at the snprintf() return value. */
6411 # if (WIDE_CHAR_VERSION && DCHAR_IS_TCHAR) || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
6412 /* HP-UX 10.20 snprintf() is doubly deficient:
6413 It doesn't understand the '%n' directive,
6414 *and* it returns -1 (rather than the length
6415 that would have been required) when the
6416 buffer is too small.
6417 Likewise, in case of
6418 WIDE_CHAR_VERSION && DCHAR_IS_TCHAR, the
6419 functions snwprintf()/_snwprintf() (Windows)
6420 or swprintf() (Unix).
6421 But a failure at this point can also come
6422 from other reasons than a too small buffer,
6423 such as an invalid wide string argument to
6424 the %ls directive, or possibly an invalid
6425 floating-point argument. */
6427 MAX_ROOM_NEEDED (&a
, dp
->arg_index
,
6428 dp
->conversion
, type
, flags
,
6431 precision
, pad_ourselves
);
6433 if (maxlen
< tmp_length
)
6435 /* Make more room. But try to do through
6436 this reallocation only once. */
6437 size_t bigger_need
=
6440 TCHARS_PER_DCHAR
- 1)
6441 / TCHARS_PER_DCHAR
);
6442 /* And always grow proportionally.
6443 (There may be several arguments, each
6444 needing a little more room than the
6446 size_t bigger_need2
=
6447 xsum (xtimes (allocated
, 2), 12);
6448 if (bigger_need
< bigger_need2
)
6449 bigger_need
= bigger_need2
;
6450 ENSURE_ALLOCATION (bigger_need
);
6458 # if WIDE_CHAR_VERSION && defined __MINGW32__
6459 if (count
== 0 && dp
->conversion
== 'c')
6460 /* snwprintf returned 0 instead of 1. But it
6461 wrote a null wide character. */
6469 /* Attempt to handle failure. */
6472 /* SNPRINTF or sprintf failed. Use the errno that it
6476 if (dp
->conversion
== 'c' || dp
->conversion
== 's')
6482 goto fail_with_errno
;
6486 /* Handle overflow of the allocated buffer.
6487 If such an overflow occurs, a C99 compliant snprintf()
6488 returns a count >= maxlen. However, a non-compliant
6489 snprintf() function returns only count = maxlen - 1. To
6490 cover both cases, test whether count >= maxlen - 1. */
6491 if ((unsigned int) count
+ 1 >= maxlen
)
6493 /* If maxlen already has attained its allowed maximum,
6494 allocating more memory will not increase maxlen.
6495 Instead of looping, bail out. */
6496 if (maxlen
== INT_MAX
/ TCHARS_PER_DCHAR
)
6500 /* Need at least (count + 1) * sizeof (TCHAR_T)
6501 bytes. (The +1 is for the trailing NUL.)
6502 But ask for (count + 2) * sizeof (TCHAR_T)
6503 bytes, so that in the next round, we likely get
6504 maxlen > (unsigned int) count + 1
6505 and so we don't get here again.
6506 And allocate proportionally, to avoid looping
6507 eternally if snprintf() reports a too small
6511 ((unsigned int) count
+ 2
6512 + TCHARS_PER_DCHAR
- 1)
6513 / TCHARS_PER_DCHAR
),
6514 xtimes (allocated
, 2));
6516 ENSURE_ALLOCATION (n
);
6522 #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
6525 /* Handle the precision. */
6528 (TCHAR_T
*) (result
+ length
);
6532 size_t prefix_count
;
6536 /* Put the additional zeroes after the sign. */
6538 && (*prec_ptr
== '-' || *prec_ptr
== '+'
6539 || *prec_ptr
== ' '))
6541 /* Put the additional zeroes after the 0x prefix if
6542 (flags & FLAG_ALT) || (dp->conversion == 'p'). */
6544 && prec_ptr
[0] == '0'
6545 && (prec_ptr
[1] == 'x' || prec_ptr
[1] == 'X'))
6548 move
= count
- prefix_count
;
6549 if (precision
> move
)
6551 /* Insert zeroes. */
6552 size_t insert
= precision
- move
;
6558 (count
+ insert
+ TCHARS_PER_DCHAR
- 1)
6559 / TCHARS_PER_DCHAR
);
6560 length
+= (count
+ TCHARS_PER_DCHAR
- 1) / TCHARS_PER_DCHAR
;
6561 ENSURE_ALLOCATION (n
);
6562 length
-= (count
+ TCHARS_PER_DCHAR
- 1) / TCHARS_PER_DCHAR
;
6563 prec_ptr
= (TCHAR_T
*) (result
+ length
);
6566 prec_end
= prec_ptr
+ count
;
6567 prec_ptr
+= prefix_count
;
6569 while (prec_end
> prec_ptr
)
6572 prec_end
[insert
] = prec_end
[0];
6578 while (prec_end
> prec_ptr
);
6582 # if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO
6583 else if (precision
== 0
6585 && prec_ptr
[prefix_count
] == '0')
6587 /* Replace the "0" result with an empty string. */
6588 count
= prefix_count
;
6595 if (count
>= tmp_length
)
6596 /* tmp_length was incorrectly calculated - fix the
6602 /* Convert from TCHAR_T[] to DCHAR_T[]. */
6603 if (dp
->conversion
== 'c' || dp
->conversion
== 's'
6604 # if __GLIBC__ >= 2 && !defined __UCLIBC__
6605 || (flags
& FLAG_LOCALIZED
)
6609 /* The result string is not guaranteed to be ASCII. */
6610 const TCHAR_T
*tmpsrc
;
6613 /* This code assumes that TCHAR_T is 'char'. */
6614 static_assert (sizeof (TCHAR_T
) == 1);
6616 tmpsrc
= (TCHAR_T
*) (result
+ length
);
6620 # if WIDE_CHAR_VERSION
6621 /* Convert tmpsrc[0..count-1] to a freshly allocated
6622 wide character array. */
6628 const TCHAR_T
*src
= tmpsrc
;
6629 size_t srclen
= count
;
6631 for (; srclen
> 0; tmpdst_len
++)
6633 /* Parse the next multibyte character. */
6634 size_t ret
= mbrtowc (NULL
, src
, srclen
, &state
);
6635 if (ret
== (size_t)(-2) || ret
== (size_t)(-1))
6636 goto fail_with_EILSEQ
;
6645 (wchar_t *) malloc ((tmpdst_len
+ 1) * sizeof (wchar_t));
6651 DCHAR_T
*destptr
= tmpdst
;
6652 const TCHAR_T
*src
= tmpsrc
;
6653 size_t srclen
= count
;
6655 for (; srclen
> 0; destptr
++)
6657 /* Parse the next multibyte character. */
6658 size_t ret
= mbrtowc (destptr
, src
, srclen
, &state
);
6659 if (ret
== (size_t)(-2) || ret
== (size_t)(-1))
6660 /* Should already have been caught in the first
6671 DCHAR_CONV_FROM_ENCODING (locale_charset (),
6672 iconveh_question_mark
,
6677 goto fail_with_errno
;
6679 ENSURE_ALLOCATION_ELSE (xsum (length
, tmpdst_len
),
6680 { free (tmpdst
); goto out_of_memory
; });
6681 DCHAR_CPY (result
+ length
, tmpdst
, tmpdst_len
);
6687 /* The result string is ASCII.
6688 Simple 1:1 conversion. */
6690 /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
6691 no-op conversion, in-place on the array starting
6692 at (result + length). */
6693 if (sizeof (DCHAR_T
) != sizeof (TCHAR_T
))
6696 const TCHAR_T
*tmpsrc
;
6701 if (result
== resultbuf
)
6703 tmpsrc
= (TCHAR_T
*) (result
+ length
);
6704 /* ENSURE_ALLOCATION will not move tmpsrc
6705 (because it's part of resultbuf). */
6706 ENSURE_ALLOCATION (xsum (length
, count
));
6710 /* ENSURE_ALLOCATION will move the array
6711 (because it uses realloc(). */
6712 ENSURE_ALLOCATION (xsum (length
, count
));
6713 tmpsrc
= (TCHAR_T
*) (result
+ length
);
6717 ENSURE_ALLOCATION (xsum (length
, count
));
6719 tmpdst
= result
+ length
;
6720 /* Copy backwards, because of overlapping. */
6723 for (n
= count
; n
> 0; n
--)
6724 *--tmpdst
= *--tmpsrc
;
6729 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
6730 /* Make room for the result. */
6731 if (count
> allocated
- length
)
6733 /* Need at least count elements. But allocate
6736 xmax (xsum (length
, count
), xtimes (allocated
, 2));
6738 ENSURE_ALLOCATION (n
);
6742 /* Here count <= allocated - length. */
6744 /* Perform padding. */
6745 #if (WIDE_CHAR_VERSION && MUSL_LIBC) || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
6746 if (pad_ourselves
&& has_width
)
6749 # if ENABLE_UNISTDIO
6750 /* Outside POSIX, it's preferable to compare the width
6751 against the number of _characters_ of the converted
6753 w
= DCHAR_MBSNLEN (result
+ length
, count
);
6755 /* The width is compared against the number of _bytes_
6756 of the converted value, says POSIX. */
6761 size_t pad
= width
- w
;
6763 /* Make room for the result. */
6764 if (xsum (count
, pad
) > allocated
- length
)
6766 /* Need at least count + pad elements. But
6767 allocate proportionally. */
6769 xmax (xsum3 (length
, count
, pad
),
6770 xtimes (allocated
, 2));
6774 ENSURE_ALLOCATION (n
);
6777 ENSURE_ALLOCATION (n
);
6780 /* Here count + pad <= allocated - length. */
6783 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
6784 DCHAR_T
* const rp
= result
+ length
;
6786 DCHAR_T
* const rp
= tmp
;
6788 DCHAR_T
*p
= rp
+ count
;
6789 DCHAR_T
*end
= p
+ pad
;
6791 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
6792 if (dp
->conversion
== 'c'
6793 || dp
->conversion
== 's')
6794 /* No zero-padding for string directives. */
6799 pad_ptr
= (*rp
== '-' ? rp
+ 1 : rp
);
6800 /* No zero-padding of "inf" and "nan". */
6801 if ((*pad_ptr
>= 'A' && *pad_ptr
<= 'Z')
6802 || (*pad_ptr
>= 'a' && *pad_ptr
<= 'z'))
6805 /* Do the zero-padding after the "0x" or
6806 "0b" prefix, not before. */
6809 && (((dp
->conversion
== 'a'
6810 || dp
->conversion
== 'x')
6812 || ((dp
->conversion
== 'A'
6813 || dp
->conversion
== 'X')
6815 || (dp
->conversion
== 'b'
6817 || (dp
->conversion
== 'B'
6821 /* The generated string now extends from rp to p,
6822 with the zero padding insertion point being at
6825 count
= count
+ pad
; /* = end - rp */
6827 if (flags
& FLAG_LEFT
)
6829 /* Pad with spaces on the right. */
6830 for (; pad
> 0; pad
--)
6833 else if ((flags
& FLAG_ZERO
) && pad_ptr
!= NULL
6834 /* ISO C says: "For d, i, o, u, x, and X
6835 conversions, if a precision is
6836 specified, the 0 flag is ignored. */
6838 && (dp
->conversion
== 'd'
6839 || dp
->conversion
== 'i'
6840 || dp
->conversion
== 'o'
6841 || dp
->conversion
== 'u'
6842 || dp
->conversion
== 'x'
6843 || dp
->conversion
== 'X'
6844 /* Although ISO C does not
6845 require it, treat 'b' and 'B'
6846 like 'x' and 'X'. */
6847 || dp
->conversion
== 'b'
6848 || dp
->conversion
== 'B')))
6850 /* Pad with zeroes. */
6855 for (; pad
> 0; pad
--)
6860 /* Pad with spaces on the left. */
6865 for (; pad
> 0; pad
--)
6873 /* Here still count <= allocated - length. */
6875 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
6876 /* The snprintf() result did fit. */
6878 /* Append the sprintf() result. */
6879 memcpy (result
+ length
, tmp
, count
* sizeof (DCHAR_T
));
6886 #if NEED_PRINTF_DIRECTIVE_F
6887 if (dp
->conversion
== 'F')
6889 /* Convert the %f result to upper case for %F. */
6890 DCHAR_T
*rp
= result
+ length
;
6892 for (rc
= count
; rc
> 0; rc
--, rp
++)
6893 if (*rp
>= 'a' && *rp
<= 'z')
6894 *rp
= *rp
- 'a' + 'A';
6902 #undef pad_ourselves
6903 #undef prec_ourselves
6908 /* Add the final NUL. */
6909 ENSURE_ALLOCATION (xsum (length
, 1));
6910 result
[length
] = '\0';
6912 if (result
!= resultbuf
&& length
+ 1 < allocated
)
6914 /* Shrink the allocated memory if possible. */
6917 memory
= (DCHAR_T
*) realloc (result
, (length
+ 1) * sizeof (DCHAR_T
));
6922 if (buf_malloced
!= NULL
)
6923 free (buf_malloced
);
6926 /* Note that we can produce a big string of a length > INT_MAX. POSIX
6927 says that snprintf() fails with errno = EOVERFLOW in this case, but
6928 that's only because snprintf() returns an 'int'. This function does
6929 not have this limitation. */
6935 goto fail_with_errno
;
6940 goto fail_with_errno
;
6942 #if ENABLE_UNISTDIO || ((!USE_SNPRINTF || WIDE_CHAR_VERSION || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_DIRECTIVE_LS || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || ((NEED_PRINTF_DIRECTIVE_LC || ENABLE_WCHAR_FALLBACK) && HAVE_WINT_T && !WIDE_CHAR_VERSION) || (NEED_WPRINTF_DIRECTIVE_C && WIDE_CHAR_VERSION)
6945 goto fail_with_errno
;
6949 if (result
!= resultbuf
)
6951 if (buf_malloced
!= NULL
)
6952 free (buf_malloced
);
6959 goto fail_1_with_errno
;
6963 goto fail_1_with_errno
;
6970 #undef MAX_ROOM_NEEDED
6971 #undef TCHARS_PER_DCHAR
6979 #undef DCHAR_IS_TCHAR