Merge pull request #2043 from RincewindsHat/cleanup/leftovers
[monitoring-plugins.git] / gl / vasnprintf.c
blobde20445894aab9b512c7567ac820b96448e50943
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.
25 Depends on FCHAR_T.
26 DIRECTIVES Structure denoting the set of format directives of a
27 format string. Depends on FCHAR_T.
28 PRINTF_PARSE Function that parses a format string.
29 Depends on FCHAR_T.
30 DCHAR_CPY memcpy like function for DCHAR_T[] arrays.
31 DCHAR_SET memset like function for DCHAR_T[] arrays.
32 DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays.
33 SNPRINTF The system's snprintf (or similar) function.
34 This may be either snprintf or swprintf.
35 TCHAR_T The element type of the argument and result string
36 of the said SNPRINTF function. This may be either
37 char or wchar_t. The code exploits that
38 sizeof (TCHAR_T) | sizeof (DCHAR_T) and
39 alignof (TCHAR_T) <= alignof (DCHAR_T).
40 DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type.
41 DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
42 DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
43 DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
44 DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t.
45 ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
46 ENABLE_WCHAR_FALLBACK Set to 1 to avoid EILSEQ during conversion of wide
47 characters (wchar_t) and wide character strings
48 (wchar_t[]) to multibyte sequences. The fallback is the
49 hexadecimal escape syntax (\unnnn or \Unnnnnnnn) or,
50 if wchar_t is not Unicode encoded, \wnnnn or \Wnnnnnnnn.
53 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
54 This must come before <config.h> because <config.h> may include
55 <features.h>, and once <features.h> has been included, it's too late. */
56 #ifndef _GNU_SOURCE
57 # define _GNU_SOURCE 1
58 #endif
60 #ifndef VASNPRINTF
61 # include <config.h>
62 #endif
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. */
67 #if 10 <= __GNUC__
68 # pragma GCC diagnostic ignored "-Wanalyzer-null-argument"
69 #endif
71 #include <alloca.h>
73 /* Specification. */
74 #ifndef VASNPRINTF
75 # if WIDE_CHAR_VERSION
76 # include "vasnwprintf.h"
77 # else
78 # include "vasnprintf.h"
79 # endif
80 #endif
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 */
90 #if HAVE_NL_LANGINFO
91 # include <langinfo.h>
92 #endif
93 #ifndef VASNPRINTF
94 # if WIDE_CHAR_VERSION
95 # include "wprintf-parse.h"
96 # else
97 # include "printf-parse.h"
98 # endif
99 #endif
101 /* Checked size_t computations. */
102 #include "xsize.h"
104 #include "attribute.h"
106 #if NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
107 # include <math.h>
108 # include "float+.h"
109 #endif
111 #if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
112 # include <math.h>
113 # include "isnand-nolibm.h"
114 #endif
116 #if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
117 # include <math.h>
118 # include "isnanl-nolibm.h"
119 # include "fpucw.h"
120 #endif
122 #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
123 # include <math.h>
124 # include "isnand-nolibm.h"
125 # include "printf-frexp.h"
126 #endif
128 #if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
129 # include <math.h>
130 # include "isnanl-nolibm.h"
131 # include "printf-frexpl.h"
132 # include "fpucw.h"
133 #endif
135 /* Default parameters. */
136 #ifndef VASNPRINTF
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
146 # else
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
157 # endif
158 #endif
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
172 # else
173 # define SNPRINTF _snwprintf
174 # define USE_MSVC__SNPRINTF 1
175 # endif
176 # else
177 /* Unix. */
178 # define SNPRINTF swprintf
179 # endif
180 # else
181 /* Old platforms such as NetBSD 3.0, OpenBSD 3.8, HP-UX 11.00, IRIX 6.5. */
182 # define TCHAR_T char
183 # endif
184 #endif
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
194 # else
195 # define USE_SNPRINTF 0
196 # endif
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. */
203 # undef snprintf
204 # else
205 /* MSVC versions < 14 did not have snprintf, only _snprintf. */
206 # define SNPRINTF _snprintf
207 # define USE_MSVC__SNPRINTF 1
208 # endif
209 # else
210 /* Unix. */
211 # define SNPRINTF snprintf
212 /* Here we need to call the native snprintf, not rpl_snprintf. */
213 # undef snprintf
214 # endif
215 #endif
216 /* Here we need to call the native sprintf, not rpl_sprintf. */
217 #undef 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
223 #else
224 # define IF_LINT(Code) /* empty */
225 #endif
227 /* Avoid some warnings from "gcc -Wshadow".
228 This file doesn't use the exp() and remainder() functions. */
229 #undef exp
230 #define exp expo
231 #undef remainder
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
237 # else
238 # ifndef local_strnlen_defined
239 # define local_strnlen_defined 1
240 static size_t
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;
246 # endif
247 # endif
248 #endif
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
251 # if HAVE_WCSLEN
252 # define local_wcslen wcslen
253 # else
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
260 static size_t
261 local_wcslen (const wchar_t *s)
263 const wchar_t *ptr;
265 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
267 return ptr - s;
269 # endif
270 # endif
271 #endif
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
276 # else
277 # ifndef local_wcsnlen_defined
278 # define local_wcsnlen_defined 1
279 static size_t
280 local_wcsnlen (const wchar_t *s, size_t maxlen)
282 const wchar_t *ptr;
284 for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
286 return ptr - s;
288 # endif
289 # endif
290 #endif
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
294 static size_t
295 wctomb_fallback (char *s, wchar_t wc)
297 static char const hex[16] = "0123456789ABCDEF";
299 s[0] = '\\';
300 if (sizeof (wchar_t) > 2 && wc > 0xffff)
302 # if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
303 s[1] = 'U';
304 # else
305 s[1] = 'W';
306 # endif
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];
315 return 10;
317 else
319 # if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
320 s[1] = 'u';
321 # else
322 s[1] = 'w';
323 # endif
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];
328 return 6;
331 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
332 static size_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);
338 return count;
340 # else
341 static int
342 local_wctomb (char *s, wchar_t wc)
344 int count = wctomb (s, wc);
345 if (count < 0)
346 count = wctomb_fallback (s, wc);
347 return count;
349 # define local_wcrtomb(S, WC, PS) local_wctomb ((S), (WC))
350 # endif
351 # else
352 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
353 # define local_wcrtomb(S, WC, PS) wcrtomb ((S), (WC), (PS))
354 # else
355 # define local_wcrtomb(S, WC, PS) wctomb ((S), (WC))
356 # endif
357 # endif
358 #endif
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
364 static char
365 decimal_point_char (void)
367 const char *point;
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);
374 # elif 1
375 char pointbuf[5];
376 sprintf (pointbuf, "%#.0f", 1.0);
377 point = &pointbuf[1];
378 # else
379 point = localeconv () -> decimal_point;
380 # endif
381 /* The decimal point is always a single byte: either '.' or ','. */
382 return (point[0] != '\0' ? point[0] : '.');
384 # endif
385 #endif
387 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE
389 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
390 static int
391 is_infinite_or_zero (double x)
393 return isnand (x) || x + x == x;
396 #endif
398 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE
400 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
401 static int
402 is_infinite_or_zerol (long double x)
404 return isnanl (x) || x + x == x;
407 #endif
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. */
424 typedef struct
426 size_t nlimbs;
427 mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
428 } mpn_t;
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. */
433 static void *
434 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
436 const mp_limb_t *p1;
437 const mp_limb_t *p2;
438 size_t len1;
439 size_t len2;
441 if (src1.nlimbs <= src2.nlimbs)
443 len1 = src1.nlimbs;
444 p1 = src1.limbs;
445 len2 = src2.nlimbs;
446 p2 = src2.limbs;
448 else
450 len1 = src2.nlimbs;
451 p1 = src2.limbs;
452 len2 = src1.nlimbs;
453 p2 = src1.limbs;
455 /* Now 0 <= len1 <= len2. */
456 if (len1 == 0)
458 /* src1 or src2 is zero. */
459 dest->nlimbs = 0;
460 dest->limbs = (mp_limb_t *) malloc (1);
462 else
464 /* Here 1 <= len1 <= len2. */
465 size_t dlen;
466 mp_limb_t *dp;
467 size_t k, i, j;
469 dlen = len1 + len2;
470 dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
471 if (dp == NULL)
472 return NULL;
473 for (k = len2; k > 0; )
474 dp[--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;
483 carry += dp[i + j];
484 dp[i + j] = (mp_limb_t) carry;
485 carry = carry >> GMP_LIMB_BITS;
487 dp[i + len2] = (mp_limb_t) carry;
489 /* Normalise. */
490 while (dlen > 0 && dp[dlen - 1] == 0)
491 dlen--;
492 dest->nlimbs = dlen;
493 dest->limbs = dp;
495 return dest->limbs;
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
500 the remainder.
501 Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
502 q is incremented.
503 Return the allocated memory in case of success, NULL in case of memory
504 allocation failure. */
505 static void *
506 divide (mpn_t a, mpn_t b, mpn_t *q)
508 /* Algorithm:
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:
513 r:=0, j:=m,
514 while j>0 do
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).}
525 Compute q* :
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].
537 If q* > 0:
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
541 u := u + q* * b[i],
542 r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
543 u:=u div beta (+ 1, if carry in subtraction)
544 r[n+j]:=r[n+j]-u.
545 {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
546 < q* + 1 <= beta,
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]].
550 Set q[j] := q*.
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
553 rest r.
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;
563 mp_limb_t *roomptr;
564 mp_limb_t *tmp_roomptr = NULL;
565 mp_limb_t *q_ptr;
566 size_t q_len;
567 mp_limb_t *r_ptr;
568 size_t r_len;
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));
574 if (roomptr == NULL)
575 return NULL;
577 /* Normalise a. */
578 while (a_len > 0 && a_ptr[a_len - 1] == 0)
579 a_len--;
581 /* Normalise b. */
582 for (;;)
584 if (b_len == 0)
585 /* Division by zero. */
586 abort ();
587 if (b_ptr[b_len - 1] == 0)
588 b_len--;
589 else
590 break;
593 /* Here m = a_len >= 0 and n = b_len > 0. */
595 if (a_len < b_len)
597 /* m<n: trivial case. q=0, r := copy of a. */
598 r_ptr = roomptr;
599 r_len = a_len;
600 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
601 q_ptr = roomptr + a_len;
602 q_len = 0;
604 else if (b_len == 1)
606 /* n=1: single precision division.
607 beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
608 r_ptr = roomptr;
609 q_ptr = roomptr + 1;
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;
615 size_t count;
616 for (count = a_len; count > 0; count--)
618 mp_twolimb_t num =
619 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
620 *--destptr = num / den;
621 remainder = num % den;
623 /* Normalise and store r. */
624 if (remainder > 0)
626 r_ptr[0] = remainder;
627 r_len = 1;
629 else
630 r_len = 0;
631 /* Normalise q. */
632 q_len = a_len;
633 if (q_ptr[q_len - 1] == 0)
634 q_len--;
637 else
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). */
642 /* Determine s. */
643 size_t s;
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);
651 # else
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)
659 # define NWORDS \
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. */
664 m.value = msd;
666 s = GMP_LIMB_BITS
667 - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
668 - DBL_EXP_BIAS);
670 else
671 # undef NWORDS
672 # endif
674 s = 31;
675 if (msd >= 0x10000)
677 msd = msd >> 16;
678 s -= 16;
680 if (msd >= 0x100)
682 msd = msd >> 8;
683 s -= 8;
685 if (msd >= 0x10)
687 msd = msd >> 4;
688 s -= 4;
690 if (msd >= 0x4)
692 msd = msd >> 2;
693 s -= 2;
695 if (msd >= 0x2)
697 msd = msd >> 1;
698 s -= 1;
701 # endif
703 /* 0 <= s < GMP_LIMB_BITS.
704 Copy b, shifting it left by s bits. */
705 if (s > 0)
707 tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
708 if (tmp_roomptr == NULL)
710 free (roomptr);
711 return NULL;
714 const mp_limb_t *sourceptr = b_ptr;
715 mp_limb_t *destptr = tmp_roomptr;
716 mp_twolimb_t accu = 0;
717 size_t count;
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. */
725 if (accu != 0)
726 abort ();
728 b_ptr = tmp_roomptr;
730 /* Copy a, shifting it left by s bits, yields r.
731 Memory layout:
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] */
734 r_ptr = roomptr;
735 if (s == 0)
737 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
738 r_ptr[a_len] = 0;
740 else
742 const mp_limb_t *sourceptr = a_ptr;
743 mp_limb_t *destptr = r_ptr;
744 mp_twolimb_t accu = 0;
745 size_t count;
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. */
764 for (;;)
766 mp_limb_t q_star;
767 mp_limb_t c1;
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. */
771 mp_twolimb_t num =
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;
775 c1 = num % b_msd;
777 else
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)
784 {<= 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
792 carry. */
793 goto subtract;
795 /* q_star = q*,
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. */
806 if (c3 > c2)
808 q_star = q_star - 1; /* q* := q* - 1 */
809 if (c3 - c2 > b_msdd)
810 q_star = q_star - 1; /* q* := q* - 1 */
813 if (q_star > 0)
814 subtract:
816 /* Subtract r := r - b * q* * beta^j. */
817 mp_limb_t cr;
819 const mp_limb_t *sourceptr = b_ptr;
820 mp_limb_t *destptr = r_ptr + j;
821 mp_twolimb_t carry = 0;
822 size_t count;
823 for (count = b_len; count > 0; count--)
825 /* Here 0 <= carry <= q*. */
826 carry =
827 carry
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
837 r_ptr[j + b_len]. */
838 if (cr > r_ptr[j + b_len])
840 /* Subtraction gave a carry. */
841 q_star = q_star - 1; /* q* := q* - 1 */
842 /* Add b back. */
844 const mp_limb_t *sourceptr = b_ptr;
845 mp_limb_t *destptr = r_ptr + j;
846 mp_limb_t carry = 0;
847 size_t count;
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;
853 carry =
854 (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]. */
863 q_ptr[j] = q_star;
864 if (j == 0)
865 break;
866 j--;
869 r_len = b_len;
870 /* Normalise q. */
871 if (q_ptr[q_len - 1] == 0)
872 q_len--;
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. */
876 if (s > 0)
878 mp_limb_t ptr = r_ptr + r_len;
879 mp_twolimb_t accu = 0;
880 size_t count;
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);
888 # endif
889 /* Normalise r. */
890 while (r_len > 0 && r_ptr[r_len - 1] == 0)
891 r_len--;
893 /* Compare r << 1 with b. */
894 if (r_len > b_len)
895 goto increment_q;
897 size_t i;
898 for (i = b_len;;)
900 mp_limb_t r_i =
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);
904 if (r_i > b_i)
905 goto increment_q;
906 if (r_i < b_i)
907 goto keep_q;
908 if (i == 0)
909 break;
910 i--;
913 if (q_len > 0 && ((q_ptr[0] & 1) != 0))
914 /* q is odd. */
915 increment_q:
917 size_t i;
918 for (i = 0; i < q_len; i++)
919 if (++(q_ptr[i]) != 0)
920 goto keep_q;
921 q_ptr[q_len++] = 1;
923 keep_q:
924 free (tmp_roomptr);
925 q->limbs = q_ptr;
926 q->nlimbs = q_len;
927 return roomptr;
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. */
933 # if __GNUC__ >= 7
934 # pragma GCC diagnostic push
935 # pragma GCC diagnostic ignored "-Walloc-size-larger-than="
936 # endif
938 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
939 representation.
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. */
944 static char *
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));
954 if (c_ptr != NULL)
956 char *d_ptr = c_ptr;
957 for (; extra_zeroes > 0; extra_zeroes--)
958 *d_ptr++ = '0';
959 while (a_len > 0)
961 /* Divide a by 10^9, in-place. */
962 mp_limb_t remainder = 0;
963 mp_limb_t *ptr = a_ptr + a_len;
964 size_t count;
965 for (count = a_len; count > 0; count--)
967 mp_twolimb_t num =
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;
978 /* Normalize a. */
979 if (a_ptr[a_len - 1] == 0)
980 a_len--;
982 /* Remove leading zeroes. */
983 while (d_ptr > c_ptr && d_ptr[-1] == '0')
984 d_ptr--;
985 /* But keep at least one zero. */
986 if (d_ptr == c_ptr)
987 *d_ptr++ = '0';
988 /* Terminate the string. */
989 *d_ptr = '\0';
991 return c_ptr;
994 # if __GNUC__ >= 7
995 # pragma GCC diagnostic pop
996 # endif
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. */
1004 static void *
1005 decode_long_double (long double x, int *ep, mpn_t *mp)
1007 mpn_t m;
1008 int exp;
1009 long double y;
1010 size_t i;
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)
1016 return NULL;
1017 /* Split into exponential part and mantissa. */
1018 y = frexpl (x, &exp);
1019 if (!(y >= 0.0L && y < 1.0L))
1020 abort ();
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',
1027 doesn't matter). */
1028 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
1029 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1031 mp_limb_t hi, lo;
1032 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1033 hi = (int) y;
1034 y -= hi;
1035 if (!(y >= 0.0L && y < 1.0L))
1036 abort ();
1037 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1038 lo = (int) y;
1039 y -= lo;
1040 if (!(y >= 0.0L && y < 1.0L))
1041 abort ();
1042 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1044 # else
1046 mp_limb_t d;
1047 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
1048 d = (int) y;
1049 y -= d;
1050 if (!(y >= 0.0L && y < 1.0L))
1051 abort ();
1052 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
1054 # endif
1055 # endif
1056 for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1058 mp_limb_t hi, lo;
1059 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1060 hi = (int) y;
1061 y -= hi;
1062 if (!(y >= 0.0L && y < 1.0L))
1063 abort ();
1064 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1065 lo = (int) y;
1066 y -= lo;
1067 if (!(y >= 0.0L && y < 1.0L))
1068 abort ();
1069 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1071 # if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
1072 precision. */
1073 if (!(y == 0.0L))
1074 abort ();
1075 # endif
1076 /* Normalise. */
1077 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1078 m.nlimbs--;
1079 *mp = m;
1080 *ep = exp - LDBL_MANT_BIT;
1081 return m.limbs;
1084 # endif
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. */
1092 static void *
1093 decode_double (double x, int *ep, mpn_t *mp)
1095 mpn_t m;
1096 int exp;
1097 double y;
1098 size_t i;
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)
1104 return NULL;
1105 /* Split into exponential part and mantissa. */
1106 y = frexp (x, &exp);
1107 if (!(y >= 0.0 && y < 1.0))
1108 abort ();
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',
1115 doesn't matter). */
1116 # if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
1117 # if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1119 mp_limb_t hi, lo;
1120 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1121 hi = (int) y;
1122 y -= hi;
1123 if (!(y >= 0.0 && y < 1.0))
1124 abort ();
1125 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1126 lo = (int) y;
1127 y -= lo;
1128 if (!(y >= 0.0 && y < 1.0))
1129 abort ();
1130 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1132 # else
1134 mp_limb_t d;
1135 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
1136 d = (int) y;
1137 y -= d;
1138 if (!(y >= 0.0 && y < 1.0))
1139 abort ();
1140 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
1142 # endif
1143 # endif
1144 for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1146 mp_limb_t hi, lo;
1147 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1148 hi = (int) y;
1149 y -= hi;
1150 if (!(y >= 0.0 && y < 1.0))
1151 abort ();
1152 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1153 lo = (int) y;
1154 y -= lo;
1155 if (!(y >= 0.0 && y < 1.0))
1156 abort ();
1157 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1159 if (!(y == 0.0))
1160 abort ();
1161 /* Normalise. */
1162 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1163 m.nlimbs--;
1164 *mp = m;
1165 *ep = exp - DBL_MANT_BIT;
1166 return m.limbs;
1169 # endif
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. */
1176 static char *
1177 scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
1179 int s;
1180 size_t extra_zeroes;
1181 unsigned int abs_n;
1182 unsigned int abs_s;
1183 mp_limb_t *pow5_ptr;
1184 size_t pow5_len;
1185 unsigned int s_limbs;
1186 unsigned int s_bits;
1187 mpn_t pow5;
1188 mpn_t z;
1189 void *z_memory;
1190 char *digits;
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). */
1195 s = e + n;
1196 extra_zeroes = 0;
1197 /* Factor out a common power of 10 if possible. */
1198 if (s > 0 && n > 0)
1200 extra_zeroes = (s < n ? s : n);
1201 s -= extra_zeroes;
1202 n -= extra_zeroes;
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)
1216 free (memory);
1217 return NULL;
1219 /* Initialize with 1. */
1220 pow5_ptr[0] = 1;
1221 pow5_len = 1;
1222 /* Multiply with 5^|n|. */
1223 if (abs_n > 0)
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
1230 unsigned int n13;
1231 for (n13 = 0; n13 <= abs_n; n13 += 13)
1233 mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1234 size_t j;
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;
1243 if (carry > 0)
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|. */
1252 if (s_bits > 0)
1254 mp_limb_t *ptr = pow5_ptr;
1255 mp_twolimb_t accu = 0;
1256 size_t count;
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;
1263 if (accu > 0)
1265 *ptr = (mp_limb_t) accu;
1266 pow5_len++;
1269 if (s_limbs > 0)
1271 size_t count;
1272 for (count = pow5_len; count > 0;)
1274 count--;
1275 pow5_ptr[s_limbs + count] = pow5_ptr[count];
1277 for (count = s_limbs; count > 0;)
1279 count--;
1280 pow5_ptr[count] = 0;
1282 pow5_len += s_limbs;
1284 pow5.limbs = pow5_ptr;
1285 pow5.nlimbs = pow5_len;
1286 if (n >= 0)
1288 /* Multiply m with pow5. No division needed. */
1289 z_memory = multiply (m, pow5, &z);
1291 else
1293 /* Divide m by pow5 and round. */
1294 z_memory = divide (m, pow5, &z);
1297 else
1299 pow5.limbs = pow5_ptr;
1300 pow5.nlimbs = pow5_len;
1301 if (n >= 0)
1303 /* n >= 0, s < 0.
1304 Multiply m with pow5, then divide by 2^|s|. */
1305 mpn_t numerator;
1306 mpn_t denominator;
1307 void *tmp_memory;
1308 tmp_memory = multiply (m, pow5, &numerator);
1309 if (tmp_memory == NULL)
1311 free (pow5_ptr);
1312 free (memory);
1313 return NULL;
1315 /* Construct 2^|s|. */
1317 mp_limb_t *ptr = pow5_ptr + pow5_len;
1318 size_t i;
1319 for (i = 0; i < s_limbs; i++)
1320 ptr[i] = 0;
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);
1326 free (tmp_memory);
1328 else
1330 /* n < 0, s > 0.
1331 Multiply m with 2^s, then divide by pow5. */
1332 mpn_t numerator;
1333 mp_limb_t *num_ptr;
1334 num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1335 * sizeof (mp_limb_t));
1336 if (num_ptr == NULL)
1338 free (pow5_ptr);
1339 free (memory);
1340 return NULL;
1343 mp_limb_t *destptr = num_ptr;
1345 size_t i;
1346 for (i = 0; i < s_limbs; i++)
1347 *destptr++ = 0;
1349 if (s_bits > 0)
1351 const mp_limb_t *sourceptr = m.limbs;
1352 mp_twolimb_t accu = 0;
1353 size_t count;
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;
1360 if (accu > 0)
1361 *destptr++ = (mp_limb_t) accu;
1363 else
1365 const mp_limb_t *sourceptr = m.limbs;
1366 size_t count;
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);
1374 free (num_ptr);
1377 free (pow5_ptr);
1378 free (memory);
1380 /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1382 if (z_memory == NULL)
1383 return NULL;
1384 digits = convert_to_decimal (z, extra_zeroes);
1385 free (z_memory);
1386 return digits;
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. */
1396 static char *
1397 scale10_round_decimal_long_double (long double x, int n)
1399 int e;
1400 mpn_t m;
1401 void *memory = decode_long_double (x, &e, &m);
1402 if (memory != NULL)
1403 return scale10_round_decimal_decoded (e, m, memory, n);
1404 else
1405 return NULL;
1408 # endif
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. */
1417 static char *
1418 scale10_round_decimal_double (double x, int n)
1420 int e;
1421 mpn_t m;
1422 void *memory = decode_double (x, &e, &m);
1423 if (memory != NULL)
1424 return scale10_round_decimal_decoded (e, m, memory, n);
1425 else
1426 return NULL;
1429 # endif
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. */
1436 static int
1437 floorlog10l (long double x)
1439 int exp;
1440 long double y;
1441 double z;
1442 double l;
1444 /* Split into exponential part and mantissa. */
1445 y = frexpl (x, &exp);
1446 if (!(y >= 0.0L && y < 1.0L))
1447 abort ();
1448 if (y == 0.0L)
1449 return INT_MIN;
1450 if (y < 0.5L)
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);
1460 exp -= 16;
1462 if (y < (1.0L / (1 << 8)))
1464 y *= 1.0L * (1 << 8);
1465 exp -= 8;
1467 if (y < (1.0L / (1 << 4)))
1469 y *= 1.0L * (1 << 4);
1470 exp -= 4;
1472 if (y < (1.0L / (1 << 2)))
1474 y *= 1.0L * (1 << 2);
1475 exp -= 2;
1477 if (y < (1.0L / (1 << 1)))
1479 y *= 1.0L * (1 << 1);
1480 exp -= 1;
1483 if (!(y >= 0.5L && y < 1.0L))
1484 abort ();
1485 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1486 l = exp;
1487 z = y;
1488 if (z < 0.70710678118654752444)
1490 z *= 1.4142135623730950488;
1491 l -= 0.5;
1493 if (z < 0.8408964152537145431)
1495 z *= 1.1892071150027210667;
1496 l -= 0.25;
1498 if (z < 0.91700404320467123175)
1500 z *= 1.0905077326652576592;
1501 l -= 0.125;
1503 if (z < 0.9576032806985736469)
1505 z *= 1.0442737824274138403;
1506 l -= 0.0625;
1508 /* Now 0.95 <= z <= 1.01. */
1509 z = 1 - z;
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
1514 log10(x). */
1515 l *= 0.30102999566398119523;
1516 /* Round down to the next integer. */
1517 return (int) l + (l < 0 ? -1 : 0);
1520 # endif
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. */
1527 static int
1528 floorlog10 (double x)
1530 int exp;
1531 double y;
1532 double z;
1533 double l;
1535 /* Split into exponential part and mantissa. */
1536 y = frexp (x, &exp);
1537 if (!(y >= 0.0 && y < 1.0))
1538 abort ();
1539 if (y == 0.0)
1540 return INT_MIN;
1541 if (y < 0.5)
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);
1551 exp -= 16;
1553 if (y < (1.0 / (1 << 8)))
1555 y *= 1.0 * (1 << 8);
1556 exp -= 8;
1558 if (y < (1.0 / (1 << 4)))
1560 y *= 1.0 * (1 << 4);
1561 exp -= 4;
1563 if (y < (1.0 / (1 << 2)))
1565 y *= 1.0 * (1 << 2);
1566 exp -= 2;
1568 if (y < (1.0 / (1 << 1)))
1570 y *= 1.0 * (1 << 1);
1571 exp -= 1;
1574 if (!(y >= 0.5 && y < 1.0))
1575 abort ();
1576 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1577 l = exp;
1578 z = y;
1579 if (z < 0.70710678118654752444)
1581 z *= 1.4142135623730950488;
1582 l -= 0.5;
1584 if (z < 0.8408964152537145431)
1586 z *= 1.1892071150027210667;
1587 l -= 0.25;
1589 if (z < 0.91700404320467123175)
1591 z *= 1.0905077326652576592;
1592 l -= 0.125;
1594 if (z < 0.9576032806985736469)
1596 z *= 1.0442737824274138403;
1597 l -= 0.0625;
1599 /* Now 0.95 <= z <= 1.01. */
1600 z = 1 - z;
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
1605 log10(x). */
1606 l *= 0.30102999566398119523;
1607 /* Round down to the next integer. */
1608 return (int) l + (l < 0 ? -1 : 0);
1611 # endif
1613 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
1614 a single '1' digit. */
1615 static int
1616 is_borderline (const char *digits, size_t precision)
1618 for (; precision > 0; precision--, digits++)
1619 if (*digits != '0')
1620 return 0;
1621 if (*digits != '1')
1622 return 0;
1623 digits++;
1624 return *digits == '\0';
1627 #endif
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
1636 # else
1637 # define MAX_ROOM_NEEDED max_room_needed
1638 # endif
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. */
1642 static size_t
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)
1647 size_t tmp_length;
1649 switch (conversion)
1651 case 'd': case 'i': case 'u':
1652 switch (type)
1654 default:
1655 tmp_length =
1656 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1657 * 0.30103 /* binary -> decimal */
1659 + 1; /* turn floor into ceil */
1660 break;
1661 case TYPE_LONGINT:
1662 tmp_length =
1663 (unsigned int) (sizeof (long int) * CHAR_BIT
1664 * 0.30103 /* binary -> decimal */
1666 + 1; /* turn floor into ceil */
1667 break;
1668 case TYPE_ULONGINT:
1669 tmp_length =
1670 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
1671 * 0.30103 /* binary -> decimal */
1673 + 1; /* turn floor into ceil */
1674 break;
1675 case TYPE_LONGLONGINT:
1676 tmp_length =
1677 (unsigned int) (sizeof (long long int) * CHAR_BIT
1678 * 0.30103 /* binary -> decimal */
1680 + 1; /* turn floor into ceil */
1681 break;
1682 case TYPE_ULONGLONGINT:
1683 tmp_length =
1684 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
1685 * 0.30103 /* binary -> decimal */
1687 + 1; /* turn floor into ceil */
1688 break;
1689 case TYPE_INT8_T:
1690 tmp_length =
1691 (unsigned int) (sizeof (int8_t) * CHAR_BIT
1692 * 0.30103 /* binary -> decimal */
1694 + 1; /* turn floor into ceil */
1695 break;
1696 case TYPE_UINT8_T:
1697 tmp_length =
1698 (unsigned int) (sizeof (uint8_t) * CHAR_BIT
1699 * 0.30103 /* binary -> decimal */
1701 + 1; /* turn floor into ceil */
1702 break;
1703 case TYPE_INT16_T:
1704 tmp_length =
1705 (unsigned int) (sizeof (int16_t) * CHAR_BIT
1706 * 0.30103 /* binary -> decimal */
1708 + 1; /* turn floor into ceil */
1709 break;
1710 case TYPE_UINT16_T:
1711 tmp_length =
1712 (unsigned int) (sizeof (uint16_t) * CHAR_BIT
1713 * 0.30103 /* binary -> decimal */
1715 + 1; /* turn floor into ceil */
1716 break;
1717 case TYPE_INT32_T:
1718 tmp_length =
1719 (unsigned int) (sizeof (int32_t) * CHAR_BIT
1720 * 0.30103 /* binary -> decimal */
1722 + 1; /* turn floor into ceil */
1723 break;
1724 case TYPE_UINT32_T:
1725 tmp_length =
1726 (unsigned int) (sizeof (uint32_t) * CHAR_BIT
1727 * 0.30103 /* binary -> decimal */
1729 + 1; /* turn floor into ceil */
1730 break;
1731 case TYPE_INT64_T:
1732 tmp_length =
1733 (unsigned int) (sizeof (int64_t) * CHAR_BIT
1734 * 0.30103 /* binary -> decimal */
1736 + 1; /* turn floor into ceil */
1737 break;
1738 case TYPE_UINT64_T:
1739 tmp_length =
1740 (unsigned int) (sizeof (uint64_t) * CHAR_BIT
1741 * 0.30103 /* binary -> decimal */
1743 + 1; /* turn floor into ceil */
1744 break;
1745 case TYPE_INT_FAST8_T:
1746 tmp_length =
1747 (unsigned int) (sizeof (int_fast8_t) * CHAR_BIT
1748 * 0.30103 /* binary -> decimal */
1750 + 1; /* turn floor into ceil */
1751 break;
1752 case TYPE_UINT_FAST8_T:
1753 tmp_length =
1754 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
1755 * 0.30103 /* binary -> decimal */
1757 + 1; /* turn floor into ceil */
1758 break;
1759 case TYPE_INT_FAST16_T:
1760 tmp_length =
1761 (unsigned int) (sizeof (int_fast16_t) * CHAR_BIT
1762 * 0.30103 /* binary -> decimal */
1764 + 1; /* turn floor into ceil */
1765 break;
1766 case TYPE_UINT_FAST16_T:
1767 tmp_length =
1768 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
1769 * 0.30103 /* binary -> decimal */
1771 + 1; /* turn floor into ceil */
1772 break;
1773 case TYPE_INT_FAST32_T:
1774 tmp_length =
1775 (unsigned int) (sizeof (int_fast32_t) * CHAR_BIT
1776 * 0.30103 /* binary -> decimal */
1778 + 1; /* turn floor into ceil */
1779 break;
1780 case TYPE_UINT_FAST32_T:
1781 tmp_length =
1782 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
1783 * 0.30103 /* binary -> decimal */
1785 + 1; /* turn floor into ceil */
1786 break;
1787 case TYPE_INT_FAST64_T:
1788 tmp_length =
1789 (unsigned int) (sizeof (int_fast64_t) * CHAR_BIT
1790 * 0.30103 /* binary -> decimal */
1792 + 1; /* turn floor into ceil */
1793 break;
1794 case TYPE_UINT_FAST64_T:
1795 tmp_length =
1796 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
1797 * 0.30103 /* binary -> decimal */
1799 + 1; /* turn floor into ceil */
1800 break;
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);
1808 break;
1810 case 'b':
1811 #if SUPPORT_GNU_PRINTF_DIRECTIVES \
1812 || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
1813 case 'B':
1814 #endif
1815 switch (type)
1817 default:
1818 tmp_length =
1819 (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
1820 + 1; /* turn floor into ceil */
1821 break;
1822 case TYPE_ULONGINT:
1823 tmp_length =
1824 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT)
1825 + 1; /* turn floor into ceil */
1826 break;
1827 case TYPE_ULONGLONGINT:
1828 tmp_length =
1829 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT)
1830 + 1; /* turn floor into ceil */
1831 break;
1832 case TYPE_UINT8_T:
1833 tmp_length =
1834 (unsigned int) (sizeof (uint8_t) * CHAR_BIT)
1835 + 1; /* turn floor into ceil */
1836 break;
1837 case TYPE_UINT16_T:
1838 tmp_length =
1839 (unsigned int) (sizeof (uint16_t) * CHAR_BIT)
1840 + 1; /* turn floor into ceil */
1841 break;
1842 case TYPE_UINT32_T:
1843 tmp_length =
1844 (unsigned int) (sizeof (uint32_t) * CHAR_BIT)
1845 + 1; /* turn floor into ceil */
1846 break;
1847 case TYPE_UINT64_T:
1848 tmp_length =
1849 (unsigned int) (sizeof (uint64_t) * CHAR_BIT)
1850 + 1; /* turn floor into ceil */
1851 break;
1852 case TYPE_UINT_FAST8_T:
1853 tmp_length =
1854 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT)
1855 + 1; /* turn floor into ceil */
1856 break;
1857 case TYPE_UINT_FAST16_T:
1858 tmp_length =
1859 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT)
1860 + 1; /* turn floor into ceil */
1861 break;
1862 case TYPE_UINT_FAST32_T:
1863 tmp_length =
1864 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT)
1865 + 1; /* turn floor into ceil */
1866 break;
1867 case TYPE_UINT_FAST64_T:
1868 tmp_length =
1869 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT)
1870 + 1; /* turn floor into ceil */
1871 break;
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);
1877 break;
1879 case 'o':
1880 switch (type)
1882 default:
1883 tmp_length =
1884 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1885 * 0.333334 /* binary -> octal */
1887 + 1; /* turn floor into ceil */
1888 break;
1889 case TYPE_ULONGINT:
1890 tmp_length =
1891 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
1892 * 0.333334 /* binary -> octal */
1894 + 1; /* turn floor into ceil */
1895 break;
1896 case TYPE_ULONGLONGINT:
1897 tmp_length =
1898 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
1899 * 0.333334 /* binary -> octal */
1901 + 1; /* turn floor into ceil */
1902 break;
1903 case TYPE_UINT8_T:
1904 tmp_length =
1905 (unsigned int) (sizeof (uint8_t) * CHAR_BIT
1906 * 0.333334 /* binary -> octal */
1908 + 1; /* turn floor into ceil */
1909 break;
1910 case TYPE_UINT16_T:
1911 tmp_length =
1912 (unsigned int) (sizeof (uint16_t) * CHAR_BIT
1913 * 0.333334 /* binary -> octal */
1915 + 1; /* turn floor into ceil */
1916 break;
1917 case TYPE_UINT32_T:
1918 tmp_length =
1919 (unsigned int) (sizeof (uint32_t) * CHAR_BIT
1920 * 0.333334 /* binary -> octal */
1922 + 1; /* turn floor into ceil */
1923 break;
1924 case TYPE_UINT64_T:
1925 tmp_length =
1926 (unsigned int) (sizeof (uint64_t) * CHAR_BIT
1927 * 0.333334 /* binary -> octal */
1929 + 1; /* turn floor into ceil */
1930 break;
1931 case TYPE_UINT_FAST8_T:
1932 tmp_length =
1933 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
1934 * 0.333334 /* binary -> octal */
1936 + 1; /* turn floor into ceil */
1937 break;
1938 case TYPE_UINT_FAST16_T:
1939 tmp_length =
1940 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
1941 * 0.333334 /* binary -> octal */
1943 + 1; /* turn floor into ceil */
1944 break;
1945 case TYPE_UINT_FAST32_T:
1946 tmp_length =
1947 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
1948 * 0.333334 /* binary -> octal */
1950 + 1; /* turn floor into ceil */
1951 break;
1952 case TYPE_UINT_FAST64_T:
1953 tmp_length =
1954 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
1955 * 0.333334 /* binary -> octal */
1957 + 1; /* turn floor into ceil */
1958 break;
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);
1964 break;
1966 case 'x': case 'X':
1967 switch (type)
1969 default:
1970 tmp_length =
1971 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1972 * 0.25 /* binary -> hexadecimal */
1974 + 1; /* turn floor into ceil */
1975 break;
1976 case TYPE_ULONGINT:
1977 tmp_length =
1978 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT
1979 * 0.25 /* binary -> hexadecimal */
1981 + 1; /* turn floor into ceil */
1982 break;
1983 case TYPE_ULONGLONGINT:
1984 tmp_length =
1985 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT
1986 * 0.25 /* binary -> hexadecimal */
1988 + 1; /* turn floor into ceil */
1989 break;
1990 case TYPE_UINT8_T:
1991 tmp_length =
1992 (unsigned int) (sizeof (uint8_t) * CHAR_BIT
1993 * 0.25 /* binary -> hexadecimal */
1995 + 1; /* turn floor into ceil */
1996 break;
1997 case TYPE_UINT16_T:
1998 tmp_length =
1999 (unsigned int) (sizeof (uint16_t) * CHAR_BIT
2000 * 0.25 /* binary -> hexadecimal */
2002 + 1; /* turn floor into ceil */
2003 break;
2004 case TYPE_UINT32_T:
2005 tmp_length =
2006 (unsigned int) (sizeof (uint32_t) * CHAR_BIT
2007 * 0.25 /* binary -> hexadecimal */
2009 + 1; /* turn floor into ceil */
2010 break;
2011 case TYPE_UINT64_T:
2012 tmp_length =
2013 (unsigned int) (sizeof (uint64_t) * CHAR_BIT
2014 * 0.25 /* binary -> hexadecimal */
2016 + 1; /* turn floor into ceil */
2017 break;
2018 case TYPE_UINT_FAST8_T:
2019 tmp_length =
2020 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT
2021 * 0.25 /* binary -> hexadecimal */
2023 + 1; /* turn floor into ceil */
2024 break;
2025 case TYPE_UINT_FAST16_T:
2026 tmp_length =
2027 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT
2028 * 0.25 /* binary -> hexadecimal */
2030 + 1; /* turn floor into ceil */
2031 break;
2032 case TYPE_UINT_FAST32_T:
2033 tmp_length =
2034 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT
2035 * 0.25 /* binary -> hexadecimal */
2037 + 1; /* turn floor into ceil */
2038 break;
2039 case TYPE_UINT_FAST64_T:
2040 tmp_length =
2041 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT
2042 * 0.25 /* binary -> hexadecimal */
2044 + 1; /* turn floor into ceil */
2045 break;
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);
2051 break;
2053 case 'f': case 'F':
2054 if (type == TYPE_LONGDOUBLE)
2055 tmp_length =
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. */
2062 else
2063 tmp_length =
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);
2071 break;
2073 case 'e': case 'E': case 'g': case 'G':
2074 tmp_length =
2075 12; /* sign, decimal point, exponent etc. */
2076 tmp_length = xsum (tmp_length, precision);
2077 break;
2079 case 'a': case 'A':
2080 if (type == TYPE_LONGDOUBLE)
2081 tmp_length =
2082 (unsigned int) (LDBL_DIG
2083 * 0.831 /* decimal -> hexadecimal */
2085 + 1; /* turn floor into ceil */
2086 else
2087 tmp_length =
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);
2096 break;
2098 case 'c':
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);
2106 # endif
2108 else
2109 # endif
2110 tmp_length = 1;
2111 break;
2113 case 's':
2114 # if HAVE_WCHAR_T
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;
2124 if (has_precision)
2125 tmp_length = local_wcsnlen (arg, precision);
2126 else
2127 tmp_length = local_wcslen (arg);
2128 # else
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
2135 array."
2136 So if there is a precision, we must not use wcslen. */
2137 /* This case has already been handled separately in VASNPRINTF. */
2138 abort ();
2139 # endif
2141 else
2142 # endif
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. */
2151 abort ();
2152 # else
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;
2159 if (has_precision)
2160 tmp_length = local_strnlen (arg, precision);
2161 else
2162 tmp_length = strlen (arg);
2163 # endif
2165 break;
2167 case 'p':
2168 tmp_length =
2169 (unsigned int) (sizeof (void *) * CHAR_BIT
2170 * 0.25 /* binary -> hexadecimal */
2172 + 1 /* turn floor into ceil */
2173 + 2; /* account for leading 0x */
2174 break;
2176 default:
2177 abort ();
2180 if (!pad_ourselves)
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)
2186 but is certainly
2187 <= tmp_length + width. */
2188 tmp_length = xsum (tmp_length, width);
2189 # else
2190 /* Padding considers the number of elements, says POSIX. */
2191 if (tmp_length < width)
2192 tmp_length = width;
2193 # endif
2196 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2198 return tmp_length;
2201 #endif
2203 DCHAR_T *
2204 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
2205 const FCHAR_T *format, va_list args)
2207 DIRECTIVES d;
2208 arguments a;
2210 if (PRINTF_PARSE (format, &d, &a) < 0)
2211 /* errno is already set. */
2212 return NULL;
2214 /* Frees the memory allocated by this function. Preserves errno. */
2215 #define CLEANUP() \
2216 if (d.dir != d.direct_alloc_dir) \
2217 free (d.dir); \
2218 if (a.arg != a.direct_alloc_arg) \
2219 free (a.arg);
2221 if (PRINTF_FETCHARGS (args, &a) < 0)
2222 goto fail_1_with_EINVAL;
2225 size_t buf_neededlength;
2226 TCHAR_T *buf;
2227 TCHAR_T *buf_malloced;
2228 const FCHAR_T *cp;
2229 size_t i;
2230 DIRECTIVE *dp;
2231 /* Output string accumulator. */
2232 DCHAR_T *result;
2233 size_t allocated;
2234 size_t length;
2236 /* Allocate a small buffer that will hold a directive passed to
2237 sprintf or snprintf. */
2238 buf_neededlength =
2239 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
2240 #if HAVE_ALLOCA
2241 if (buf_neededlength < 4000 / sizeof (TCHAR_T))
2243 buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
2244 buf_malloced = NULL;
2246 else
2247 #endif
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);
2253 if (buf == NULL)
2254 goto out_of_memory_1;
2255 buf_malloced = buf;
2258 result = resultbuf;
2259 allocated = (resultbuf != NULL ? *lengthp : 0);
2260 length = 0;
2261 /* Invariants:
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; \
2272 DCHAR_T *memory; \
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)) \
2279 oom_statement \
2280 if (result == resultbuf) \
2281 memory = (DCHAR_T *) malloc (memory_size); \
2282 else \
2283 memory = (DCHAR_T *) realloc (result, memory_size); \
2284 if (memory == NULL) \
2285 oom_statement \
2286 if (result == resultbuf && length > 0) \
2287 DCHAR_CPY (memory, result, length); \
2288 result = memory; \
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;
2309 else
2312 result[length++] = *cp++;
2313 while (--n > 0);
2316 if (i == d.count)
2317 break;
2319 /* Execute a single directive. */
2320 if (dp->conversion == '%')
2322 size_t augmented_length;
2324 if (!(dp->arg_index == ARG_NONE))
2325 abort ();
2326 augmented_length = xsum (length, 1);
2327 ENSURE_ALLOCATION (augmented_length);
2328 result[length] = '%';
2329 length = augmented_length;
2331 else
2333 if (!(dp->arg_index != ARG_NONE))
2334 abort ();
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;
2343 break;
2344 case TYPE_COUNT_SHORT_POINTER:
2345 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
2346 break;
2347 case TYPE_COUNT_INT_POINTER:
2348 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
2349 break;
2350 case TYPE_COUNT_LONGINT_POINTER:
2351 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
2352 break;
2353 case TYPE_COUNT_LONGLONGINT_POINTER:
2354 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
2355 break;
2356 case TYPE_COUNT_INT8_T_POINTER:
2357 *a.arg[dp->arg_index].a.a_count_int8_t_pointer = length;
2358 break;
2359 case TYPE_COUNT_INT16_T_POINTER:
2360 *a.arg[dp->arg_index].a.a_count_int16_t_pointer = length;
2361 break;
2362 case TYPE_COUNT_INT32_T_POINTER:
2363 *a.arg[dp->arg_index].a.a_count_int32_t_pointer = length;
2364 break;
2365 case TYPE_COUNT_INT64_T_POINTER:
2366 *a.arg[dp->arg_index].a.a_count_int64_t_pointer = length;
2367 break;
2368 case TYPE_COUNT_INT_FAST8_T_POINTER:
2369 *a.arg[dp->arg_index].a.a_count_int_fast8_t_pointer = length;
2370 break;
2371 case TYPE_COUNT_INT_FAST16_T_POINTER:
2372 *a.arg[dp->arg_index].a.a_count_int_fast16_t_pointer = length;
2373 break;
2374 case TYPE_COUNT_INT_FAST32_T_POINTER:
2375 *a.arg[dp->arg_index].a.a_count_int_fast32_t_pointer = length;
2376 break;
2377 case TYPE_COUNT_INT_FAST64_T_POINTER:
2378 *a.arg[dp->arg_index].a.a_count_int_fast64_t_pointer = length;
2379 break;
2380 default:
2381 abort ();
2383 #else
2384 abort ();
2385 #endif
2387 #if ENABLE_UNISTDIO
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;
2393 int has_width;
2394 size_t width;
2395 int has_precision;
2396 size_t precision;
2398 has_width = 0;
2399 width = 0;
2400 if (dp->width_start != dp->width_end)
2402 if (dp->width_arg_index != ARG_NONE)
2404 int arg;
2406 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2407 abort ();
2408 arg = a.arg[dp->width_arg_index].a.a_int;
2409 width = arg;
2410 if (arg < 0)
2412 /* "A negative field width is taken as a '-' flag
2413 followed by a positive field width." */
2414 flags |= FLAG_LEFT;
2415 width = -width;
2418 else
2420 const FCHAR_T *digitp = dp->width_start;
2423 width = xsum (xtimes (width, 10), *digitp++ - '0');
2424 while (digitp != dp->width_end);
2426 has_width = 1;
2429 has_precision = 0;
2430 precision = 0;
2431 if (dp->precision_start != dp->precision_end)
2433 if (dp->precision_arg_index != ARG_NONE)
2435 int arg;
2437 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2438 abort ();
2439 arg = a.arg[dp->precision_arg_index].a.a_int;
2440 /* "A negative precision is taken as if the precision
2441 were omitted." */
2442 if (arg >= 0)
2444 precision = arg;
2445 has_precision = 1;
2448 else
2450 const FCHAR_T *digitp = dp->precision_start + 1;
2452 precision = 0;
2453 while (digitp != dp->precision_end)
2454 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2455 has_precision = 1;
2459 switch (type)
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;
2465 size_t characters;
2467 if (has_precision)
2469 /* Use only PRECISION characters, from the left. */
2470 arg_end = arg;
2471 characters = 0;
2472 for (; precision > 0; precision--)
2474 int count = u8_strmblen (arg_end);
2475 if (count == 0)
2476 break;
2477 if (count < 0)
2478 goto fail_with_EILSEQ;
2479 arg_end += count;
2480 characters++;
2483 else if (has_width)
2485 /* Use the entire string, and count the number of
2486 characters. */
2487 arg_end = arg;
2488 characters = 0;
2489 for (;;)
2491 int count = u8_strmblen (arg_end);
2492 if (count == 0)
2493 break;
2494 if (count < 0)
2495 goto fail_with_EILSEQ;
2496 arg_end += count;
2497 characters++;
2500 else
2502 /* Use the entire string. */
2503 arg_end = arg + u8_strlen (arg);
2504 /* The number of characters doesn't matter. */
2505 characters = 0;
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);
2513 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);
2521 length += n;
2523 # else
2524 { /* Convert. */
2525 DCHAR_T *converted = result + length;
2526 size_t converted_len = allocated - length;
2527 # if DCHAR_IS_TCHAR
2528 /* Convert from UTF-8 to locale encoding. */
2529 converted =
2530 u8_conv_to_encoding (locale_charset (),
2531 iconveh_question_mark,
2532 arg, arg_end - arg, NULL,
2533 converted, &converted_len);
2534 # else
2535 /* Convert from UTF-8 to UTF-16/UTF-32. */
2536 converted =
2537 U8_TO_DCHAR (arg, arg_end - arg,
2538 converted, &converted_len);
2539 # endif
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);
2547 free (converted);
2549 length += converted_len;
2551 # endif
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);
2558 length += n;
2561 break;
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;
2567 size_t characters;
2569 if (has_precision)
2571 /* Use only PRECISION characters, from the left. */
2572 arg_end = arg;
2573 characters = 0;
2574 for (; precision > 0; precision--)
2576 int count = u16_strmblen (arg_end);
2577 if (count == 0)
2578 break;
2579 if (count < 0)
2580 goto fail_with_EILSEQ;
2581 arg_end += count;
2582 characters++;
2585 else if (has_width)
2587 /* Use the entire string, and count the number of
2588 characters. */
2589 arg_end = arg;
2590 characters = 0;
2591 for (;;)
2593 int count = u16_strmblen (arg_end);
2594 if (count == 0)
2595 break;
2596 if (count < 0)
2597 goto fail_with_EILSEQ;
2598 arg_end += count;
2599 characters++;
2602 else
2604 /* Use the entire string. */
2605 arg_end = arg + u16_strlen (arg);
2606 /* The number of characters doesn't matter. */
2607 characters = 0;
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);
2615 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);
2623 length += n;
2625 # else
2626 { /* Convert. */
2627 DCHAR_T *converted = result + length;
2628 size_t converted_len = allocated - length;
2629 # if DCHAR_IS_TCHAR
2630 /* Convert from UTF-16 to locale encoding. */
2631 converted =
2632 u16_conv_to_encoding (locale_charset (),
2633 iconveh_question_mark,
2634 arg, arg_end - arg, NULL,
2635 converted, &converted_len);
2636 # else
2637 /* Convert from UTF-16 to UTF-8/UTF-32. */
2638 converted =
2639 U16_TO_DCHAR (arg, arg_end - arg,
2640 converted, &converted_len);
2641 # endif
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);
2649 free (converted);
2651 length += converted_len;
2653 # endif
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);
2660 length += n;
2663 break;
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;
2669 size_t characters;
2671 if (has_precision)
2673 /* Use only PRECISION characters, from the left. */
2674 arg_end = arg;
2675 characters = 0;
2676 for (; precision > 0; precision--)
2678 int count = u32_strmblen (arg_end);
2679 if (count == 0)
2680 break;
2681 if (count < 0)
2682 goto fail_with_EILSEQ;
2683 arg_end += count;
2684 characters++;
2687 else if (has_width)
2689 /* Use the entire string, and count the number of
2690 characters. */
2691 arg_end = arg;
2692 characters = 0;
2693 for (;;)
2695 int count = u32_strmblen (arg_end);
2696 if (count == 0)
2697 break;
2698 if (count < 0)
2699 goto fail_with_EILSEQ;
2700 arg_end += count;
2701 characters++;
2704 else
2706 /* Use the entire string. */
2707 arg_end = arg + u32_strlen (arg);
2708 /* The number of characters doesn't matter. */
2709 characters = 0;
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);
2717 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);
2725 length += n;
2727 # else
2728 { /* Convert. */
2729 DCHAR_T *converted = result + length;
2730 size_t converted_len = allocated - length;
2731 # if DCHAR_IS_TCHAR
2732 /* Convert from UTF-32 to locale encoding. */
2733 converted =
2734 u32_conv_to_encoding (locale_charset (),
2735 iconveh_question_mark,
2736 arg, arg_end - arg, NULL,
2737 converted, &converted_len);
2738 # else
2739 /* Convert from UTF-32 to UTF-8/UTF-16. */
2740 converted =
2741 U32_TO_DCHAR (arg, arg_end - arg,
2742 converted, &converted_len);
2743 # endif
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);
2751 free (converted);
2753 length += converted_len;
2755 # endif
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);
2762 length += n;
2765 break;
2767 default:
2768 abort ();
2771 #endif
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
2779 fwprintf. */
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;
2784 size_t width;
2786 width = 0;
2787 if (dp->width_start != dp->width_end)
2789 if (dp->width_arg_index != ARG_NONE)
2791 int arg;
2793 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2794 abort ();
2795 arg = a.arg[dp->width_arg_index].a.a_int;
2796 width = arg;
2797 if (arg < 0)
2799 /* "A negative field width is taken as a '-' flag
2800 followed by a positive field width." */
2801 flags |= FLAG_LEFT;
2802 width = -width;
2805 else
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;
2817 wchar_t lc_arg[1];
2818 size_t characters;
2820 if (dp->conversion == 's')
2822 int has_precision;
2823 size_t precision;
2825 has_precision = 0;
2826 precision = 6;
2827 if (dp->precision_start != dp->precision_end)
2829 if (dp->precision_arg_index != ARG_NONE)
2831 int arg;
2833 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2834 abort ();
2835 arg = a.arg[dp->precision_arg_index].a.a_int;
2836 /* "A negative precision is taken as if the precision
2837 were omitted." */
2838 if (arg >= 0)
2840 precision = arg;
2841 has_precision = 1;
2844 else
2846 const FCHAR_T *digitp = dp->precision_start + 1;
2848 precision = 0;
2849 while (digitp != dp->precision_end)
2850 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2851 has_precision = 1;
2855 ls_arg = a.arg[dp->arg_index].a.a_wide_string;
2857 if (has_precision)
2859 /* Use only at most PRECISION wide characters, from
2860 the left. */
2861 const wchar_t *ls_arg_end;
2863 ls_arg_end = ls_arg;
2864 characters = 0;
2865 for (; precision > 0; precision--)
2867 if (*ls_arg_end == 0)
2868 /* Found the terminating null wide character. */
2869 break;
2870 ls_arg_end++;
2871 characters++;
2874 else
2876 /* Use the entire string, and count the number of wide
2877 characters. */
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;
2884 ls_arg = lc_arg;
2885 characters = 1;
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);
2896 length += n;
2899 if (characters > 0)
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);
2909 length += n;
2914 #endif
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
2919 # else
2920 && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2921 # endif
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;
2935 int has_width;
2936 size_t width;
2937 int has_precision;
2938 size_t precision;
2940 has_width = 0;
2941 width = 0;
2942 if (dp->width_start != dp->width_end)
2944 if (dp->width_arg_index != ARG_NONE)
2946 int arg;
2948 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2949 abort ();
2950 arg = a.arg[dp->width_arg_index].a.a_int;
2951 width = arg;
2952 if (arg < 0)
2954 /* "A negative field width is taken as a '-' flag
2955 followed by a positive field width." */
2956 flags |= FLAG_LEFT;
2957 width = -width;
2960 else
2962 const FCHAR_T *digitp = dp->width_start;
2965 width = xsum (xtimes (width, 10), *digitp++ - '0');
2966 while (digitp != dp->width_end);
2968 has_width = 1;
2971 has_precision = 0;
2972 precision = 6;
2973 if (dp->precision_start != dp->precision_end)
2975 if (dp->precision_arg_index != ARG_NONE)
2977 int arg;
2979 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2980 abort ();
2981 arg = a.arg[dp->precision_arg_index].a.a_int;
2982 /* "A negative precision is taken as if the precision
2983 were omitted." */
2984 if (arg >= 0)
2986 precision = arg;
2987 has_precision = 1;
2990 else
2992 const FCHAR_T *digitp = dp->precision_start + 1;
2994 precision = 0;
2995 while (digitp != dp->precision_end)
2996 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2997 has_precision = 1;
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;
3006 size_t characters;
3008 if (has_precision)
3010 /* Use only as many bytes as needed to produce PRECISION
3011 wide characters, from the left. */
3012 # if HAVE_MBRTOWC
3013 mbstate_t state;
3014 mbszero (&state);
3015 # endif
3016 arg_end = arg;
3017 characters = 0;
3018 for (; precision > 0; precision--)
3020 int count;
3021 # if HAVE_MBRTOWC
3022 count = mbrlen (arg_end, MB_CUR_MAX, &state);
3023 # else
3024 count = mblen (arg_end, MB_CUR_MAX);
3025 # endif
3026 if (count == 0)
3027 /* Found the terminating NUL. */
3028 break;
3029 if (count < 0)
3030 /* Invalid or incomplete multibyte character. */
3031 goto fail_with_EILSEQ;
3032 arg_end += count;
3033 characters++;
3036 else if (has_width)
3038 /* Use the entire string, and count the number of wide
3039 characters. */
3040 # if HAVE_MBRTOWC
3041 mbstate_t state;
3042 mbszero (&state);
3043 # endif
3044 arg_end = arg;
3045 characters = 0;
3046 for (;;)
3048 int count;
3049 # if HAVE_MBRTOWC
3050 count = mbrlen (arg_end, MB_CUR_MAX, &state);
3051 # else
3052 count = mblen (arg_end, MB_CUR_MAX);
3053 # endif
3054 if (count == 0)
3055 /* Found the terminating NUL. */
3056 break;
3057 if (count < 0)
3058 /* Invalid or incomplete multibyte character. */
3059 goto fail_with_EILSEQ;
3060 arg_end += count;
3061 characters++;
3064 else
3066 /* Use the entire string. */
3067 arg_end = arg + strlen (arg);
3068 /* The number of characters doesn't matter. */
3069 characters = 0;
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);
3077 length += n;
3080 if (has_precision || has_width)
3082 /* We know the number of wide characters in advance. */
3083 size_t remaining;
3084 # if HAVE_MBRTOWC
3085 mbstate_t state;
3086 mbszero (&state);
3087 # endif
3088 ENSURE_ALLOCATION (xsum (length, characters));
3089 for (remaining = characters; remaining > 0; remaining--)
3091 wchar_t wc;
3092 int count;
3093 # if HAVE_MBRTOWC
3094 count = mbrtowc (&wc, arg, arg_end - arg, &state);
3095 # else
3096 count = mbtowc (&wc, arg, arg_end - arg);
3097 # endif
3098 if (count <= 0)
3099 /* mbrtowc not consistent with mbrlen, or mbtowc
3100 not consistent with mblen. */
3101 abort ();
3102 result[length++] = wc;
3103 arg += count;
3105 if (!(arg == arg_end))
3106 abort ();
3108 else
3110 # if HAVE_MBRTOWC
3111 mbstate_t state;
3112 mbszero (&state);
3113 # endif
3114 while (arg < arg_end)
3116 wchar_t wc;
3117 int count;
3118 # if HAVE_MBRTOWC
3119 count = mbrtowc (&wc, arg, arg_end - arg, &state);
3120 # else
3121 count = mbtowc (&wc, arg, arg_end - arg);
3122 # endif
3123 if (count == 0)
3124 /* mbrtowc not consistent with strlen. */
3125 abort ();
3126 if (count < 0)
3127 /* Invalid or incomplete multibyte character. */
3128 goto fail_with_EILSEQ;
3129 ENSURE_ALLOCATION (xsum (length, 1));
3130 result[length++] = wc;
3131 arg += count;
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);
3140 length += n;
3143 # else
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;
3148 size_t characters;
3149 # if !DCHAR_IS_TCHAR
3150 /* This code assumes that TCHAR_T is 'char'. */
3151 static_assert (sizeof (TCHAR_T) == 1);
3152 TCHAR_T *tmpsrc;
3153 DCHAR_T *tmpdst;
3154 size_t tmpdst_len;
3155 # endif
3156 size_t w;
3158 if (has_precision)
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
3163 mbstate_t state;
3164 mbszero (&state);
3165 # endif
3166 arg_end = arg;
3167 characters = 0;
3168 while (precision > 0)
3170 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3171 int count;
3173 if (*arg_end == 0)
3174 /* Found the terminating null wide character. */
3175 break;
3176 count = local_wcrtomb (cbuf, *arg_end, &state);
3177 if (count < 0)
3178 /* Cannot convert. */
3179 goto fail_with_EILSEQ;
3180 if (precision < (unsigned int) count)
3181 break;
3182 arg_end++;
3183 characters += count;
3184 precision -= count;
3187 # if DCHAR_IS_TCHAR
3188 else if (has_width)
3189 # else
3190 else
3191 # endif
3193 /* Use the entire string, and count the number of
3194 bytes. */
3195 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3196 mbstate_t state;
3197 mbszero (&state);
3198 # endif
3199 arg_end = arg;
3200 characters = 0;
3201 for (;;)
3203 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3204 int count;
3206 if (*arg_end == 0)
3207 /* Found the terminating null wide character. */
3208 break;
3209 count = local_wcrtomb (cbuf, *arg_end, &state);
3210 if (count < 0)
3211 /* Cannot convert. */
3212 goto fail_with_EILSEQ;
3213 arg_end++;
3214 characters += count;
3217 # if DCHAR_IS_TCHAR
3218 else
3220 /* Use the entire string. */
3221 arg_end = arg + local_wcslen (arg);
3222 /* The number of bytes doesn't matter. */
3223 characters = 0;
3225 # endif
3227 # if !DCHAR_IS_TCHAR
3228 /* Convert the string into a piece of temporary memory. */
3229 tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
3230 if (tmpsrc == NULL)
3231 goto out_of_memory;
3233 TCHAR_T *tmpptr = tmpsrc;
3234 size_t remaining;
3235 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3236 mbstate_t state;
3237 mbszero (&state);
3238 # endif
3239 for (remaining = characters; remaining > 0; )
3241 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3242 int count;
3244 if (*arg == 0)
3245 abort ();
3246 count = local_wcrtomb (cbuf, *arg, &state);
3247 if (count <= 0)
3248 /* Inconsistency. */
3249 abort ();
3250 memcpy (tmpptr, cbuf, count);
3251 tmpptr += count;
3252 arg++;
3253 remaining -= count;
3255 if (!(arg == arg_end))
3256 abort ();
3259 /* Convert from TCHAR_T[] to DCHAR_T[]. */
3260 tmpdst =
3261 DCHAR_CONV_FROM_ENCODING (locale_charset (),
3262 iconveh_question_mark,
3263 tmpsrc, characters,
3264 NULL,
3265 NULL, &tmpdst_len);
3266 if (tmpdst == NULL)
3268 free (tmpsrc);
3269 goto fail_with_errno;
3271 free (tmpsrc);
3272 # endif
3274 if (has_width)
3276 # if ENABLE_UNISTDIO
3277 /* Outside POSIX, it's preferable to compare the width
3278 against the number of _characters_ of the converted
3279 value. */
3280 w = DCHAR_MBSNLEN (result + length, characters);
3281 # else
3282 /* The width is compared against the number of _bytes_
3283 of the converted value, says POSIX. */
3284 w = characters;
3285 # endif
3287 else
3288 /* w doesn't matter. */
3289 w = 0;
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);
3296 length += n;
3299 # if DCHAR_IS_TCHAR
3300 if (has_precision || has_width)
3302 /* We know the number of bytes in advance. */
3303 size_t remaining;
3304 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3305 mbstate_t state;
3306 mbszero (&state);
3307 # endif
3308 ENSURE_ALLOCATION (xsum (length, characters));
3309 for (remaining = characters; remaining > 0; )
3311 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3312 int count;
3314 if (*arg == 0)
3315 abort ();
3316 count = local_wcrtomb (cbuf, *arg, &state);
3317 if (count <= 0)
3318 /* Inconsistency. */
3319 abort ();
3320 memcpy (result + length, cbuf, count);
3321 length += count;
3322 arg++;
3323 remaining -= count;
3325 if (!(arg == arg_end))
3326 abort ();
3328 else
3330 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3331 mbstate_t state;
3332 mbszero (&state);
3333 # endif
3334 while (arg < arg_end)
3336 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3337 int count;
3339 if (*arg == 0)
3340 abort ();
3341 count = local_wcrtomb (cbuf, *arg, &state);
3342 if (count <= 0)
3343 /* Cannot convert. */
3344 goto fail_with_EILSEQ;
3345 ENSURE_ALLOCATION (xsum (length, count));
3346 memcpy (result + length, cbuf, count);
3347 length += count;
3348 arg++;
3351 # else
3352 ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
3353 { free (tmpdst); goto out_of_memory; });
3354 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
3355 free (tmpdst);
3356 length += tmpdst_len;
3357 # endif
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);
3364 length += n;
3367 # endif
3369 #endif
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;
3378 int has_width;
3379 size_t width;
3381 has_width = 0;
3382 width = 0;
3383 if (dp->width_start != dp->width_end)
3385 if (dp->width_arg_index != ARG_NONE)
3387 int arg;
3389 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3390 abort ();
3391 arg = a.arg[dp->width_arg_index].a.a_int;
3392 width = arg;
3393 if (arg < 0)
3395 /* "A negative field width is taken as a '-' flag
3396 followed by a positive field width." */
3397 flags |= FLAG_LEFT;
3398 width = -width;
3401 else
3403 const FCHAR_T *digitp = dp->width_start;
3406 width = xsum (xtimes (width, 10), *digitp++ - '0');
3407 while (digitp != dp->width_end);
3409 has_width = 1;
3412 /* %lc in vasnprintf. See the specification of fprintf. */
3414 wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
3415 size_t characters;
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. */
3420 DCHAR_T *tmpdst;
3421 size_t tmpdst_len;
3422 # endif
3423 size_t w;
3425 # if DCHAR_IS_TCHAR
3426 if (has_width)
3427 # endif
3429 /* Count the number of bytes. */
3430 characters = 0;
3431 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3432 int count;
3433 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3434 mbstate_t state;
3435 mbszero (&state);
3436 # endif
3438 count = local_wcrtomb (cbuf, arg, &state);
3439 if (count < 0)
3440 /* Cannot convert. */
3441 goto fail_with_EILSEQ;
3442 characters = count;
3444 # if DCHAR_IS_TCHAR
3445 else
3447 /* The number of bytes doesn't matter. */
3448 characters = 0;
3450 # endif
3452 # if !DCHAR_IS_TCHAR
3453 /* Convert the string into a piece of temporary memory. */
3454 if (characters > 0)
3456 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3457 int count;
3458 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3459 mbstate_t state;
3460 mbszero (&state);
3461 # endif
3463 count = local_wcrtomb (cbuf, arg, &state);
3464 if (count <= 0)
3465 /* Inconsistency. */
3466 abort ();
3467 memcpy (tmpsrc, cbuf, count);
3470 /* Convert from TCHAR_T[] to DCHAR_T[]. */
3471 tmpdst =
3472 DCHAR_CONV_FROM_ENCODING (locale_charset (),
3473 iconveh_question_mark,
3474 tmpsrc, characters,
3475 NULL,
3476 NULL, &tmpdst_len);
3477 if (tmpdst == NULL)
3478 goto fail_with_errno;
3479 # endif
3481 if (has_width)
3483 # if ENABLE_UNISTDIO
3484 /* Outside POSIX, it's preferable to compare the width
3485 against the number of _characters_ of the converted
3486 value. */
3487 w = DCHAR_MBSNLEN (result + length, characters);
3488 # else
3489 /* The width is compared against the number of _bytes_
3490 of the converted value, says POSIX. */
3491 w = characters;
3492 # endif
3494 else
3495 /* w doesn't matter. */
3496 w = 0;
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);
3503 length += n;
3506 # if DCHAR_IS_TCHAR
3507 if (has_width)
3509 /* We know the number of bytes in advance. */
3510 ENSURE_ALLOCATION (xsum (length, characters));
3511 if (characters > 0)
3513 int count;
3514 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3515 mbstate_t state;
3516 mbszero (&state);
3517 # endif
3519 count = local_wcrtomb (result + length, arg, &state);
3520 if (count <= 0)
3521 /* Inconsistency. */
3522 abort ();
3523 length += count;
3526 else
3528 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3529 int count;
3530 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3531 mbstate_t state;
3532 mbszero (&state);
3533 # endif
3535 count = local_wcrtomb (cbuf, arg, &state);
3536 if (count < 0)
3537 /* Cannot convert. */
3538 goto fail_with_EILSEQ;
3539 ENSURE_ALLOCATION (xsum (length, count));
3540 memcpy (result + length, cbuf, count);
3541 length += count;
3543 # else
3544 ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
3545 { free (tmpdst); goto out_of_memory; });
3546 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
3547 free (tmpdst);
3548 length += tmpdst_len;
3549 # endif
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);
3556 length += n;
3560 #endif
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;
3568 size_t width;
3570 width = 0;
3571 if (dp->width_start != dp->width_end)
3573 if (dp->width_arg_index != ARG_NONE)
3575 int arg;
3577 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3578 abort ();
3579 arg = a.arg[dp->width_arg_index].a.a_int;
3580 width = arg;
3581 if (arg < 0)
3583 /* "A negative field width is taken as a '-' flag
3584 followed by a positive field width." */
3585 flags |= FLAG_LEFT;
3586 width = -width;
3589 else
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;
3602 mbstate_t state;
3603 wchar_t wc;
3605 mbszero (&state);
3606 int count = mbrtowc (&wc, &arg, 1, &state);
3607 if (count < 0)
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);
3616 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);
3627 length += n;
3631 #endif
3632 #if NEED_PRINTF_DIRECTIVE_B || NEED_PRINTF_DIRECTIVE_UPPERCASE_B
3633 else if (0
3634 # if NEED_PRINTF_DIRECTIVE_B
3635 || (dp->conversion == 'b')
3636 # endif
3637 # if NEED_PRINTF_DIRECTIVE_UPPERCASE_B
3638 || (dp->conversion == 'B')
3639 # endif
3642 arg_type type = a.arg[dp->arg_index].type;
3643 int flags = dp->flags;
3644 int has_width;
3645 size_t width;
3646 int has_precision;
3647 size_t precision;
3648 size_t tmp_length;
3649 size_t count;
3650 DCHAR_T tmpbuf[700];
3651 DCHAR_T *tmp;
3652 DCHAR_T *tmp_end;
3653 DCHAR_T *tmp_start;
3654 DCHAR_T *pad_ptr;
3655 DCHAR_T *p;
3657 has_width = 0;
3658 width = 0;
3659 if (dp->width_start != dp->width_end)
3661 if (dp->width_arg_index != ARG_NONE)
3663 int arg;
3665 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3666 abort ();
3667 arg = a.arg[dp->width_arg_index].a.a_int;
3668 width = arg;
3669 if (arg < 0)
3671 /* "A negative field width is taken as a '-' flag
3672 followed by a positive field width." */
3673 flags |= FLAG_LEFT;
3674 width = -width;
3677 else
3679 const FCHAR_T *digitp = dp->width_start;
3682 width = xsum (xtimes (width, 10), *digitp++ - '0');
3683 while (digitp != dp->width_end);
3685 has_width = 1;
3688 has_precision = 0;
3689 precision = 1;
3690 if (dp->precision_start != dp->precision_end)
3692 if (dp->precision_arg_index != ARG_NONE)
3694 int arg;
3696 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3697 abort ();
3698 arg = a.arg[dp->precision_arg_index].a.a_int;
3699 /* "A negative precision is taken as if the precision
3700 were omitted." */
3701 if (arg >= 0)
3703 precision = arg;
3704 has_precision = 1;
3707 else
3709 const FCHAR_T *digitp = dp->precision_start + 1;
3711 precision = 0;
3712 while (digitp != dp->precision_end)
3713 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3714 has_precision = 1;
3718 /* Allocate a temporary buffer of sufficient size. */
3719 switch (type)
3721 default:
3722 tmp_length =
3723 (unsigned int) (sizeof (unsigned int) * CHAR_BIT)
3724 + 1; /* turn floor into ceil */
3725 break;
3726 case TYPE_ULONGINT:
3727 tmp_length =
3728 (unsigned int) (sizeof (unsigned long int) * CHAR_BIT)
3729 + 1; /* turn floor into ceil */
3730 break;
3731 case TYPE_ULONGLONGINT:
3732 tmp_length =
3733 (unsigned int) (sizeof (unsigned long long int) * CHAR_BIT)
3734 + 1; /* turn floor into ceil */
3735 break;
3736 case TYPE_UINT8_T:
3737 tmp_length =
3738 (unsigned int) (sizeof (uint8_t) * CHAR_BIT)
3739 + 1; /* turn floor into ceil */
3740 break;
3741 case TYPE_UINT16_T:
3742 tmp_length =
3743 (unsigned int) (sizeof (uint16_t) * CHAR_BIT)
3744 + 1; /* turn floor into ceil */
3745 break;
3746 case TYPE_UINT32_T:
3747 tmp_length =
3748 (unsigned int) (sizeof (uint32_t) * CHAR_BIT)
3749 + 1; /* turn floor into ceil */
3750 break;
3751 case TYPE_UINT64_T:
3752 tmp_length =
3753 (unsigned int) (sizeof (uint64_t) * CHAR_BIT)
3754 + 1; /* turn floor into ceil */
3755 break;
3756 case TYPE_UINT_FAST8_T:
3757 tmp_length =
3758 (unsigned int) (sizeof (uint_fast8_t) * CHAR_BIT)
3759 + 1; /* turn floor into ceil */
3760 break;
3761 case TYPE_UINT_FAST16_T:
3762 tmp_length =
3763 (unsigned int) (sizeof (uint_fast16_t) * CHAR_BIT)
3764 + 1; /* turn floor into ceil */
3765 break;
3766 case TYPE_UINT_FAST32_T:
3767 tmp_length =
3768 (unsigned int) (sizeof (uint_fast32_t) * CHAR_BIT)
3769 + 1; /* turn floor into ceil */
3770 break;
3771 case TYPE_UINT_FAST64_T:
3772 tmp_length =
3773 (unsigned int) (sizeof (uint_fast64_t) * CHAR_BIT)
3774 + 1; /* turn floor into ceil */
3775 break;
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)
3783 tmp_length = width;
3785 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3786 tmp = tmpbuf;
3787 else
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. */
3793 goto out_of_memory;
3794 tmp = (DCHAR_T *) malloc (tmp_memsize);
3795 if (tmp == NULL)
3796 /* Out of memory. */
3797 goto out_of_memory;
3800 tmp_end = tmp + tmp_length;
3802 unsigned long long arg;
3803 switch (type)
3805 case TYPE_UCHAR:
3806 arg = a.arg[dp->arg_index].a.a_uchar;
3807 break;
3808 case TYPE_USHORT:
3809 arg = a.arg[dp->arg_index].a.a_ushort;
3810 break;
3811 case TYPE_UINT:
3812 arg = a.arg[dp->arg_index].a.a_uint;
3813 break;
3814 case TYPE_ULONGINT:
3815 arg = a.arg[dp->arg_index].a.a_ulongint;
3816 break;
3817 case TYPE_ULONGLONGINT:
3818 arg = a.arg[dp->arg_index].a.a_ulonglongint;
3819 break;
3820 case TYPE_UINT8_T:
3821 arg = a.arg[dp->arg_index].a.a_uint8_t;
3822 break;
3823 case TYPE_UINT16_T:
3824 arg = a.arg[dp->arg_index].a.a_uint16_t;
3825 break;
3826 case TYPE_UINT32_T:
3827 arg = a.arg[dp->arg_index].a.a_uint32_t;
3828 break;
3829 case TYPE_UINT64_T:
3830 arg = a.arg[dp->arg_index].a.a_uint64_t;
3831 break;
3832 case TYPE_UINT_FAST8_T:
3833 arg = a.arg[dp->arg_index].a.a_uint_fast8_t;
3834 break;
3835 case TYPE_UINT_FAST16_T:
3836 arg = a.arg[dp->arg_index].a.a_uint_fast16_t;
3837 break;
3838 case TYPE_UINT_FAST32_T:
3839 arg = a.arg[dp->arg_index].a.a_uint_fast32_t;
3840 break;
3841 case TYPE_UINT_FAST64_T:
3842 arg = a.arg[dp->arg_index].a.a_uint_fast64_t;
3843 break;
3844 default:
3845 abort ();
3847 int need_prefix = ((flags & FLAG_ALT) && arg != 0);
3849 p = tmp_end;
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);
3857 arg = arg >> 1;
3859 while (arg != 0);
3862 if (has_precision)
3864 DCHAR_T *digits_start = tmp_end - precision;
3865 while (p > digits_start)
3866 *--p = '0';
3869 pad_ptr = p;
3871 if (need_prefix)
3873 # if NEED_PRINTF_DIRECTIVE_B && !NEED_PRINTF_DIRECTIVE_UPPERCASE_B
3874 *--p = 'b';
3875 # elif NEED_PRINTF_DIRECTIVE_UPPERCASE_B && !NEED_PRINTF_DIRECTIVE_B
3876 *--p = 'B';
3877 # else
3878 *--p = dp->conversion;
3879 # endif
3880 *--p = '0';
3882 tmp_start = p;
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;
3889 if (count < width)
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++)
3897 *(p - pad) = *p;
3898 for (p = tmp_end - pad; p < tmp_end; p++)
3899 *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
3905 do so. */
3906 && !(has_width && has_precision))
3908 /* Pad with zeroes. */
3909 for (p = tmp_start; p < pad_ptr; p++)
3910 *(p - pad) = *p;
3911 for (p = pad_ptr - pad; p < pad_ptr; p++)
3912 *p = '0';
3914 else
3916 /* Pad with spaces on the left. */
3917 for (p = tmp_start - pad; p < tmp_start; p++)
3918 *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
3928 code above! */
3929 abort ();
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));
3941 if (tmp != tmpbuf)
3942 free (tmp);
3943 length += count;
3945 #endif
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))
3949 && (0
3950 # if NEED_PRINTF_DOUBLE
3951 || a.arg[dp->arg_index].type == TYPE_DOUBLE
3952 # endif
3953 # if NEED_PRINTF_LONG_DOUBLE || (NEED_WPRINTF_DIRECTIVE_LA && WIDE_CHAR_VERSION)
3954 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3955 # endif
3957 # endif
3960 arg_type type = a.arg[dp->arg_index].type;
3961 int flags = dp->flags;
3962 size_t width;
3963 int has_precision;
3964 size_t precision;
3965 size_t tmp_length;
3966 size_t count;
3967 DCHAR_T tmpbuf[700];
3968 DCHAR_T *tmp;
3969 DCHAR_T *pad_ptr;
3970 DCHAR_T *p;
3972 width = 0;
3973 if (dp->width_start != dp->width_end)
3975 if (dp->width_arg_index != ARG_NONE)
3977 int arg;
3979 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3980 abort ();
3981 arg = a.arg[dp->width_arg_index].a.a_int;
3982 width = arg;
3983 if (arg < 0)
3985 /* "A negative field width is taken as a '-' flag
3986 followed by a positive field width." */
3987 flags |= FLAG_LEFT;
3988 width = -width;
3991 else
3993 const FCHAR_T *digitp = dp->width_start;
3996 width = xsum (xtimes (width, 10), *digitp++ - '0');
3997 while (digitp != dp->width_end);
4001 has_precision = 0;
4002 precision = 0;
4003 if (dp->precision_start != dp->precision_end)
4005 if (dp->precision_arg_index != ARG_NONE)
4007 int arg;
4009 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4010 abort ();
4011 arg = a.arg[dp->precision_arg_index].a.a_int;
4012 /* "A negative precision is taken as if the precision
4013 were omitted." */
4014 if (arg >= 0)
4016 precision = arg;
4017 has_precision = 1;
4020 else
4022 const FCHAR_T *digitp = dp->precision_start + 1;
4024 precision = 0;
4025 while (digitp != dp->precision_end)
4026 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4027 has_precision = 1;
4031 /* Allocate a temporary buffer of sufficient size. */
4032 if (type == TYPE_LONGDOUBLE)
4033 tmp_length =
4034 (unsigned int) ((LDBL_DIG + 1)
4035 * 0.831 /* decimal -> hexadecimal */
4037 + 1; /* turn floor into ceil */
4038 else
4039 tmp_length =
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)
4050 tmp_length = width;
4052 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
4054 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
4055 tmp = tmpbuf;
4056 else
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. */
4062 goto out_of_memory;
4063 tmp = (DCHAR_T *) malloc (tmp_memsize);
4064 if (tmp == NULL)
4065 /* Out of memory. */
4066 goto out_of_memory;
4069 pad_ptr = NULL;
4070 p = tmp;
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;
4076 if (isnanl (arg))
4078 if (dp->conversion == 'A')
4080 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4082 else
4084 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4087 else
4089 int sign = 0;
4090 DECL_LONG_DOUBLE_ROUNDING
4092 BEGIN_LONG_DOUBLE_ROUNDING ();
4094 if (signbit (arg)) /* arg < 0.0L or negative zero */
4096 sign = -1;
4097 arg = -arg;
4100 if (sign < 0)
4101 *p++ = '-';
4102 else if (flags & FLAG_SHOWSIGN)
4103 *p++ = '+';
4104 else if (flags & FLAG_SPACE)
4105 *p++ = ' ';
4107 if (arg > 0.0L && arg + arg == arg)
4109 if (dp->conversion == 'A')
4111 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4113 else
4115 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4118 else
4120 int exponent;
4121 long double mantissa;
4123 if (arg > 0.0L)
4124 mantissa = printf_frexpl (arg, &exponent);
4125 else
4127 exponent = 0;
4128 mantissa = 0.0L;
4131 if (has_precision
4132 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
4134 /* Round the mantissa. */
4135 long double tail = mantissa;
4136 size_t q;
4138 for (q = precision; ; q--)
4140 int digit = (int) tail;
4141 tail -= digit;
4142 if (q == 0)
4144 if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
4145 tail = 1 - tail;
4146 else
4147 tail = - tail;
4148 break;
4150 tail *= 16.0L;
4152 if (tail != 0.0L)
4153 for (q = precision; q > 0; q--)
4154 tail *= 0.0625L;
4155 mantissa += tail;
4158 *p++ = '0';
4159 *p++ = dp->conversion - 'A' + 'X';
4160 pad_ptr = p;
4162 int digit;
4164 digit = (int) mantissa;
4165 mantissa -= digit;
4166 *p++ = '0' + digit;
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)
4175 mantissa *= 16.0L;
4176 digit = (int) mantissa;
4177 mantissa -= digit;
4178 *p++ = digit
4179 + (digit < 10
4180 ? '0'
4181 : dp->conversion - 10);
4182 if (precision > 0)
4183 precision--;
4185 while (precision > 0)
4187 *p++ = '0';
4188 precision--;
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);
4199 while (*p != '\0')
4200 p++;
4201 # else
4202 if (sizeof (DCHAR_T) == 1)
4204 sprintf ((char *) p, "%+d", exponent);
4205 while (*p != '\0')
4206 p++;
4208 else
4210 char expbuf[6 + 1];
4211 const char *ep;
4212 sprintf (expbuf, "%+d", exponent);
4213 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4214 p++;
4216 # endif
4219 END_LONG_DOUBLE_ROUNDING ();
4221 # else
4222 abort ();
4223 # endif
4225 else
4227 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
4228 double arg = a.arg[dp->arg_index].a.a_double;
4230 if (isnand (arg))
4232 if (dp->conversion == 'A')
4234 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4236 else
4238 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4241 else
4243 int sign = 0;
4245 if (signbit (arg)) /* arg < 0.0 or negative zero */
4247 sign = -1;
4248 arg = -arg;
4251 if (sign < 0)
4252 *p++ = '-';
4253 else if (flags & FLAG_SHOWSIGN)
4254 *p++ = '+';
4255 else if (flags & FLAG_SPACE)
4256 *p++ = ' ';
4258 if (arg > 0.0 && arg + arg == arg)
4260 if (dp->conversion == 'A')
4262 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4264 else
4266 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4269 else
4271 int exponent;
4272 double mantissa;
4274 if (arg > 0.0)
4275 mantissa = printf_frexp (arg, &exponent);
4276 else
4278 exponent = 0;
4279 mantissa = 0.0;
4282 if (has_precision
4283 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
4285 /* Round the mantissa. */
4286 double tail = mantissa;
4287 size_t q;
4289 for (q = precision; ; q--)
4291 int digit = (int) tail;
4292 tail -= digit;
4293 if (q == 0)
4295 if (digit & 1 ? tail >= 0.5 : tail > 0.5)
4296 tail = 1 - tail;
4297 else
4298 tail = - tail;
4299 break;
4301 tail *= 16.0;
4303 if (tail != 0.0)
4304 for (q = precision; q > 0; q--)
4305 tail *= 0.0625;
4306 mantissa += tail;
4309 *p++ = '0';
4310 *p++ = dp->conversion - 'A' + 'X';
4311 pad_ptr = p;
4313 int digit;
4315 digit = (int) mantissa;
4316 mantissa -= digit;
4317 *p++ = '0' + digit;
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)
4326 mantissa *= 16.0;
4327 digit = (int) mantissa;
4328 mantissa -= digit;
4329 *p++ = digit
4330 + (digit < 10
4331 ? '0'
4332 : dp->conversion - 10);
4333 if (precision > 0)
4334 precision--;
4336 while (precision > 0)
4338 *p++ = '0';
4339 precision--;
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);
4350 while (*p != '\0')
4351 p++;
4352 # else
4353 if (sizeof (DCHAR_T) == 1)
4355 sprintf ((char *) p, "%+d", exponent);
4356 while (*p != '\0')
4357 p++;
4359 else
4361 char expbuf[6 + 1];
4362 const char *ep;
4363 sprintf (expbuf, "%+d", exponent);
4364 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4365 p++;
4367 # endif
4370 # else
4371 abort ();
4372 # endif
4375 /* The generated string now extends from tmp to p, with the
4376 zero padding insertion point being at pad_ptr. */
4377 count = p - tmp;
4379 if (count < width)
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--)
4388 *p++ = ' ';
4390 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4392 /* Pad with zeroes. */
4393 DCHAR_T *q = end;
4395 while (p > pad_ptr)
4396 *--q = *--p;
4397 for (; pad > 0; pad--)
4398 *p++ = '0';
4400 else
4402 /* Pad with spaces on the left. */
4403 DCHAR_T *q = end;
4405 while (p > tmp)
4406 *--q = *--p;
4407 for (; pad > 0; pad--)
4408 *p++ = ' ';
4411 p = end;
4414 count = p - tmp;
4416 if (count >= tmp_length)
4417 /* tmp_length was incorrectly calculated - fix the
4418 code above! */
4419 abort ();
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));
4431 if (tmp != tmpbuf)
4432 free (tmp);
4433 length += count;
4435 #endif
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')
4441 && (0
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))
4450 # endif
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))
4460 # endif
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;
4465 # endif
4466 int flags = dp->flags;
4467 size_t width;
4468 size_t count;
4469 int has_precision;
4470 size_t precision;
4471 size_t tmp_length;
4472 DCHAR_T tmpbuf[700];
4473 DCHAR_T *tmp;
4474 DCHAR_T *pad_ptr;
4475 DCHAR_T *p;
4477 width = 0;
4478 if (dp->width_start != dp->width_end)
4480 if (dp->width_arg_index != ARG_NONE)
4482 int arg;
4484 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4485 abort ();
4486 arg = a.arg[dp->width_arg_index].a.a_int;
4487 width = arg;
4488 if (arg < 0)
4490 /* "A negative field width is taken as a '-' flag
4491 followed by a positive field width." */
4492 flags |= FLAG_LEFT;
4493 width = -width;
4496 else
4498 const FCHAR_T *digitp = dp->width_start;
4501 width = xsum (xtimes (width, 10), *digitp++ - '0');
4502 while (digitp != dp->width_end);
4506 has_precision = 0;
4507 precision = 0;
4508 if (dp->precision_start != dp->precision_end)
4510 if (dp->precision_arg_index != ARG_NONE)
4512 int arg;
4514 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4515 abort ();
4516 arg = a.arg[dp->precision_arg_index].a.a_int;
4517 /* "A negative precision is taken as if the precision
4518 were omitted." */
4519 if (arg >= 0)
4521 precision = arg;
4522 has_precision = 1;
4525 else
4527 const FCHAR_T *digitp = dp->precision_start + 1;
4529 precision = 0;
4530 while (digitp != dp->precision_end)
4531 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4532 has_precision = 1;
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. */
4540 if (!has_precision)
4541 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
4542 precision = 6;
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;
4553 # else
4554 tmp_length = 0;
4555 # endif
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)
4561 # endif
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;
4573 # endif
4574 # if NEED_PRINTF_DOUBLE
4575 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
4576 if (type == TYPE_DOUBLE)
4577 # endif
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;
4589 # endif
4590 /* Account for sign, decimal point etc. */
4591 tmp_length = xsum (tmp_length, 12);
4593 if (tmp_length < width)
4594 tmp_length = width;
4596 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
4598 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
4599 tmp = tmpbuf;
4600 else
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. */
4606 goto out_of_memory;
4607 tmp = (DCHAR_T *) malloc (tmp_memsize);
4608 if (tmp == NULL)
4609 /* Out of memory. */
4610 goto out_of_memory;
4613 pad_ptr = NULL;
4614 p = tmp;
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)
4619 # endif
4621 long double arg = a.arg[dp->arg_index].a.a_longdouble;
4623 if (isnanl (arg))
4625 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4627 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4629 else
4631 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4634 else
4636 int sign = 0;
4637 DECL_LONG_DOUBLE_ROUNDING
4639 BEGIN_LONG_DOUBLE_ROUNDING ();
4641 if (signbit (arg)) /* arg < 0.0L or negative zero */
4643 sign = -1;
4644 arg = -arg;
4647 if (sign < 0)
4648 *p++ = '-';
4649 else if (flags & FLAG_SHOWSIGN)
4650 *p++ = '+';
4651 else if (flags & FLAG_SPACE)
4652 *p++ = ' ';
4654 if (arg > 0.0L && arg + arg == arg)
4656 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4658 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4660 else
4662 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4665 else
4667 # if NEED_PRINTF_LONG_DOUBLE
4668 pad_ptr = p;
4670 if (dp->conversion == 'f' || dp->conversion == 'F')
4672 char *digits;
4673 size_t ndigits;
4675 digits =
4676 scale10_round_decimal_long_double (arg, precision);
4677 if (digits == NULL)
4679 END_LONG_DOUBLE_ROUNDING ();
4680 goto out_of_memory;
4682 ndigits = strlen (digits);
4684 if (ndigits > precision)
4687 --ndigits;
4688 *p++ = digits[ndigits];
4690 while (ndigits > precision);
4691 else
4692 *p++ = '0';
4693 /* Here ndigits <= precision. */
4694 if ((flags & FLAG_ALT) || precision > 0)
4696 *p++ = decimal_point_char ();
4697 for (; precision > ndigits; precision--)
4698 *p++ = '0';
4699 while (ndigits > 0)
4701 --ndigits;
4702 *p++ = digits[ndigits];
4706 free (digits);
4708 else if (dp->conversion == 'e' || dp->conversion == 'E')
4710 int exponent;
4712 if (arg == 0.0L)
4714 exponent = 0;
4715 *p++ = '0';
4716 if ((flags & FLAG_ALT) || precision > 0)
4718 *p++ = decimal_point_char ();
4719 for (; precision > 0; precision--)
4720 *p++ = '0';
4723 else
4725 /* arg > 0.0L. */
4726 int adjusted;
4727 char *digits;
4728 size_t ndigits;
4730 exponent = floorlog10l (arg);
4731 adjusted = 0;
4732 for (;;)
4734 digits =
4735 scale10_round_decimal_long_double (arg,
4736 (int)precision - exponent);
4737 if (digits == NULL)
4739 END_LONG_DOUBLE_ROUNDING ();
4740 goto out_of_memory;
4742 ndigits = strlen (digits);
4744 if (ndigits == precision + 1)
4745 break;
4746 if (ndigits < precision
4747 || ndigits > precision + 2)
4748 /* The exponent was not guessed
4749 precisely enough. */
4750 abort ();
4751 if (adjusted)
4752 /* None of two values of exponent is
4753 the right one. Prevent an endless
4754 loop. */
4755 abort ();
4756 free (digits);
4757 if (ndigits == precision)
4758 exponent -= 1;
4759 else
4760 exponent += 1;
4761 adjusted = 1;
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. */
4769 char *digits2 =
4770 scale10_round_decimal_long_double (arg,
4771 (int)precision - exponent + 1);
4772 if (digits2 == NULL)
4774 free (digits);
4775 END_LONG_DOUBLE_ROUNDING ();
4776 goto out_of_memory;
4778 if (strlen (digits2) == precision + 1)
4780 free (digits);
4781 digits = digits2;
4782 exponent -= 1;
4784 else
4785 free (digits2);
4787 /* Here ndigits = precision+1. */
4789 *p++ = digits[--ndigits];
4790 if ((flags & FLAG_ALT) || precision > 0)
4792 *p++ = decimal_point_char ();
4793 while (ndigits > 0)
4795 --ndigits;
4796 *p++ = digits[ndigits];
4800 free (digits);
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);
4810 while (*p != '\0')
4811 p++;
4812 # else
4813 if (sizeof (DCHAR_T) == 1)
4815 sprintf ((char *) p, "%+.2d", exponent);
4816 while (*p != '\0')
4817 p++;
4819 else
4821 char expbuf[6 + 1];
4822 const char *ep;
4823 sprintf (expbuf, "%+.2d", exponent);
4824 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4825 p++;
4827 # endif
4829 else if (dp->conversion == 'g' || dp->conversion == 'G')
4831 if (precision == 0)
4832 precision = 1;
4833 /* precision >= 1. */
4835 if (arg == 0.0L)
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
4841 dropped. */
4842 size_t nzeroes =
4843 (flags & FLAG_ALT ? 0 : precision - 1);
4845 --ndigits;
4846 *p++ = '0';
4847 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4849 *p++ = decimal_point_char ();
4850 while (ndigits > nzeroes)
4852 --ndigits;
4853 *p++ = '0';
4857 else
4859 /* arg > 0.0L. */
4860 int exponent;
4861 int adjusted;
4862 char *digits;
4863 size_t ndigits;
4864 size_t nzeroes;
4866 exponent = floorlog10l (arg);
4867 adjusted = 0;
4868 for (;;)
4870 digits =
4871 scale10_round_decimal_long_double (arg,
4872 (int)(precision - 1) - exponent);
4873 if (digits == NULL)
4875 END_LONG_DOUBLE_ROUNDING ();
4876 goto out_of_memory;
4878 ndigits = strlen (digits);
4880 if (ndigits == precision)
4881 break;
4882 if (ndigits < precision - 1
4883 || ndigits > precision + 1)
4884 /* The exponent was not guessed
4885 precisely enough. */
4886 abort ();
4887 if (adjusted)
4888 /* None of two values of exponent is
4889 the right one. Prevent an endless
4890 loop. */
4891 abort ();
4892 free (digits);
4893 if (ndigits < precision)
4894 exponent -= 1;
4895 else
4896 exponent += 1;
4897 adjusted = 1;
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. */
4905 char *digits2 =
4906 scale10_round_decimal_long_double (arg,
4907 (int)(precision - 1) - exponent + 1);
4908 if (digits2 == NULL)
4910 free (digits);
4911 END_LONG_DOUBLE_ROUNDING ();
4912 goto out_of_memory;
4914 if (strlen (digits2) == precision)
4916 free (digits);
4917 digits = digits2;
4918 exponent -= 1;
4920 else
4921 free (digits2);
4923 /* Here ndigits = precision. */
4925 /* Determine the number of trailing zeroes
4926 that have to be dropped. */
4927 nzeroes = 0;
4928 if ((flags & FLAG_ALT) == 0)
4929 while (nzeroes < ndigits
4930 && digits[nzeroes] == '0')
4931 nzeroes++;
4933 /* The exponent is now determined. */
4934 if (exponent >= -4
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. */
4941 if (exponent >= 0)
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)
4952 --ndigits;
4953 *p++ = digits[ndigits];
4957 else
4959 size_t ecount = -exponent - 1;
4960 *p++ = '0';
4961 *p++ = decimal_point_char ();
4962 for (; ecount > 0; ecount--)
4963 *p++ = '0';
4964 while (ndigits > nzeroes)
4966 --ndigits;
4967 *p++ = digits[ndigits];
4971 else
4973 /* Exponential notation. */
4974 *p++ = digits[--ndigits];
4975 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4977 *p++ = decimal_point_char ();
4978 while (ndigits > nzeroes)
4980 --ndigits;
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);
4991 while (*p != '\0')
4992 p++;
4993 # else
4994 if (sizeof (DCHAR_T) == 1)
4996 sprintf ((char *) p, "%+.2d", exponent);
4997 while (*p != '\0')
4998 p++;
5000 else
5002 char expbuf[6 + 1];
5003 const char *ep;
5004 sprintf (expbuf, "%+.2d", exponent);
5005 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
5006 p++;
5008 # endif
5011 free (digits);
5014 else
5015 abort ();
5016 # else
5017 /* arg is finite. */
5018 if (!(arg == 0.0L))
5019 abort ();
5021 pad_ptr = p;
5023 if (dp->conversion == 'f' || dp->conversion == 'F')
5025 *p++ = '0';
5026 if ((flags & FLAG_ALT) || precision > 0)
5028 *p++ = decimal_point_char ();
5029 for (; precision > 0; precision--)
5030 *p++ = '0';
5033 else if (dp->conversion == 'e' || dp->conversion == 'E')
5035 *p++ = '0';
5036 if ((flags & FLAG_ALT) || precision > 0)
5038 *p++ = decimal_point_char ();
5039 for (; precision > 0; precision--)
5040 *p++ = '0';
5042 *p++ = dp->conversion; /* 'e' or 'E' */
5043 *p++ = '+';
5044 *p++ = '0';
5045 *p++ = '0';
5047 else if (dp->conversion == 'g' || dp->conversion == 'G')
5049 *p++ = '0';
5050 if (flags & FLAG_ALT)
5052 size_t ndigits =
5053 (precision > 0 ? precision - 1 : 0);
5054 *p++ = decimal_point_char ();
5055 for (; ndigits > 0; --ndigits)
5056 *p++ = '0';
5059 else if (dp->conversion == 'a' || dp->conversion == 'A')
5061 *p++ = '0';
5062 *p++ = dp->conversion - 'A' + 'X';
5063 pad_ptr = p;
5064 *p++ = '0';
5065 if ((flags & FLAG_ALT) || precision > 0)
5067 *p++ = decimal_point_char ();
5068 for (; precision > 0; precision--)
5069 *p++ = '0';
5071 *p++ = dp->conversion - 'A' + 'P';
5072 *p++ = '+';
5073 *p++ = '0';
5075 else
5076 abort ();
5077 # endif
5080 END_LONG_DOUBLE_ROUNDING ();
5083 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
5084 else
5085 # endif
5086 # endif
5087 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
5089 double arg = a.arg[dp->arg_index].a.a_double;
5091 if (isnand (arg))
5093 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
5095 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
5097 else
5099 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
5102 else
5104 int sign = 0;
5106 if (signbit (arg)) /* arg < 0.0 or negative zero */
5108 sign = -1;
5109 arg = -arg;
5112 if (sign < 0)
5113 *p++ = '-';
5114 else if (flags & FLAG_SHOWSIGN)
5115 *p++ = '+';
5116 else if (flags & FLAG_SPACE)
5117 *p++ = ' ';
5119 if (arg > 0.0 && arg + arg == arg)
5121 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
5123 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
5125 else
5127 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
5130 else
5132 # if NEED_PRINTF_DOUBLE
5133 pad_ptr = p;
5135 if (dp->conversion == 'f' || dp->conversion == 'F')
5137 char *digits;
5138 size_t ndigits;
5140 digits =
5141 scale10_round_decimal_double (arg, precision);
5142 if (digits == NULL)
5143 goto out_of_memory;
5144 ndigits = strlen (digits);
5146 if (ndigits > precision)
5149 --ndigits;
5150 *p++ = digits[ndigits];
5152 while (ndigits > precision);
5153 else
5154 *p++ = '0';
5155 /* Here ndigits <= precision. */
5156 if ((flags & FLAG_ALT) || precision > 0)
5158 *p++ = decimal_point_char ();
5159 for (; precision > ndigits; precision--)
5160 *p++ = '0';
5161 while (ndigits > 0)
5163 --ndigits;
5164 *p++ = digits[ndigits];
5168 free (digits);
5170 else if (dp->conversion == 'e' || dp->conversion == 'E')
5172 int exponent;
5174 if (arg == 0.0)
5176 exponent = 0;
5177 *p++ = '0';
5178 if ((flags & FLAG_ALT) || precision > 0)
5180 *p++ = decimal_point_char ();
5181 for (; precision > 0; precision--)
5182 *p++ = '0';
5185 else
5187 /* arg > 0.0. */
5188 int adjusted;
5189 char *digits;
5190 size_t ndigits;
5192 exponent = floorlog10 (arg);
5193 adjusted = 0;
5194 for (;;)
5196 digits =
5197 scale10_round_decimal_double (arg,
5198 (int)precision - exponent);
5199 if (digits == NULL)
5200 goto out_of_memory;
5201 ndigits = strlen (digits);
5203 if (ndigits == precision + 1)
5204 break;
5205 if (ndigits < precision
5206 || ndigits > precision + 2)
5207 /* The exponent was not guessed
5208 precisely enough. */
5209 abort ();
5210 if (adjusted)
5211 /* None of two values of exponent is
5212 the right one. Prevent an endless
5213 loop. */
5214 abort ();
5215 free (digits);
5216 if (ndigits == precision)
5217 exponent -= 1;
5218 else
5219 exponent += 1;
5220 adjusted = 1;
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. */
5228 char *digits2 =
5229 scale10_round_decimal_double (arg,
5230 (int)precision - exponent + 1);
5231 if (digits2 == NULL)
5233 free (digits);
5234 goto out_of_memory;
5236 if (strlen (digits2) == precision + 1)
5238 free (digits);
5239 digits = digits2;
5240 exponent -= 1;
5242 else
5243 free (digits2);
5245 /* Here ndigits = precision+1. */
5247 *p++ = digits[--ndigits];
5248 if ((flags & FLAG_ALT) || precision > 0)
5250 *p++ = decimal_point_char ();
5251 while (ndigits > 0)
5253 --ndigits;
5254 *p++ = digits[ndigits];
5258 free (digits);
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' };
5269 # else
5270 { '%', '+', '.', '2', 'd', '\0' };
5271 # endif
5272 SNPRINTF (p, 6 + 1, decimal_format, exponent);
5274 while (*p != '\0')
5275 p++;
5276 # else
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__
5282 "%+.3d";
5283 # else
5284 "%+.2d";
5285 # endif
5286 if (sizeof (DCHAR_T) == 1)
5288 sprintf ((char *) p, decimal_format, exponent);
5289 while (*p != '\0')
5290 p++;
5292 else
5294 char expbuf[6 + 1];
5295 const char *ep;
5296 sprintf (expbuf, decimal_format, exponent);
5297 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
5298 p++;
5301 # endif
5303 else if (dp->conversion == 'g' || dp->conversion == 'G')
5305 if (precision == 0)
5306 precision = 1;
5307 /* precision >= 1. */
5309 if (arg == 0.0)
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
5315 dropped. */
5316 size_t nzeroes =
5317 (flags & FLAG_ALT ? 0 : precision - 1);
5319 --ndigits;
5320 *p++ = '0';
5321 if ((flags & FLAG_ALT) || ndigits > nzeroes)
5323 *p++ = decimal_point_char ();
5324 while (ndigits > nzeroes)
5326 --ndigits;
5327 *p++ = '0';
5331 else
5333 /* arg > 0.0. */
5334 int exponent;
5335 int adjusted;
5336 char *digits;
5337 size_t ndigits;
5338 size_t nzeroes;
5340 exponent = floorlog10 (arg);
5341 adjusted = 0;
5342 for (;;)
5344 digits =
5345 scale10_round_decimal_double (arg,
5346 (int)(precision - 1) - exponent);
5347 if (digits == NULL)
5348 goto out_of_memory;
5349 ndigits = strlen (digits);
5351 if (ndigits == precision)
5352 break;
5353 if (ndigits < precision - 1
5354 || ndigits > precision + 1)
5355 /* The exponent was not guessed
5356 precisely enough. */
5357 abort ();
5358 if (adjusted)
5359 /* None of two values of exponent is
5360 the right one. Prevent an endless
5361 loop. */
5362 abort ();
5363 free (digits);
5364 if (ndigits < precision)
5365 exponent -= 1;
5366 else
5367 exponent += 1;
5368 adjusted = 1;
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. */
5376 char *digits2 =
5377 scale10_round_decimal_double (arg,
5378 (int)(precision - 1) - exponent + 1);
5379 if (digits2 == NULL)
5381 free (digits);
5382 goto out_of_memory;
5384 if (strlen (digits2) == precision)
5386 free (digits);
5387 digits = digits2;
5388 exponent -= 1;
5390 else
5391 free (digits2);
5393 /* Here ndigits = precision. */
5395 /* Determine the number of trailing zeroes
5396 that have to be dropped. */
5397 nzeroes = 0;
5398 if ((flags & FLAG_ALT) == 0)
5399 while (nzeroes < ndigits
5400 && digits[nzeroes] == '0')
5401 nzeroes++;
5403 /* The exponent is now determined. */
5404 if (exponent >= -4
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. */
5411 if (exponent >= 0)
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)
5422 --ndigits;
5423 *p++ = digits[ndigits];
5427 else
5429 size_t ecount = -exponent - 1;
5430 *p++ = '0';
5431 *p++ = decimal_point_char ();
5432 for (; ecount > 0; ecount--)
5433 *p++ = '0';
5434 while (ndigits > nzeroes)
5436 --ndigits;
5437 *p++ = digits[ndigits];
5441 else
5443 /* Exponential notation. */
5444 *p++ = digits[--ndigits];
5445 if ((flags & FLAG_ALT) || ndigits > nzeroes)
5447 *p++ = decimal_point_char ();
5448 while (ndigits > nzeroes)
5450 --ndigits;
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' };
5462 # else
5463 { '%', '+', '.', '2', 'd', '\0' };
5464 # endif
5465 SNPRINTF (p, 6 + 1, decimal_format, exponent);
5467 while (*p != '\0')
5468 p++;
5469 # else
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__
5475 "%+.3d";
5476 # else
5477 "%+.2d";
5478 # endif
5479 if (sizeof (DCHAR_T) == 1)
5481 sprintf ((char *) p, decimal_format, exponent);
5482 while (*p != '\0')
5483 p++;
5485 else
5487 char expbuf[6 + 1];
5488 const char *ep;
5489 sprintf (expbuf, decimal_format, exponent);
5490 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
5491 p++;
5494 # endif
5497 free (digits);
5500 else
5501 abort ();
5502 # else
5503 /* arg is finite. */
5504 if (!(arg == 0.0))
5505 abort ();
5507 pad_ptr = p;
5509 if (dp->conversion == 'f' || dp->conversion == 'F')
5511 *p++ = '0';
5512 if ((flags & FLAG_ALT) || precision > 0)
5514 *p++ = decimal_point_char ();
5515 for (; precision > 0; precision--)
5516 *p++ = '0';
5519 else if (dp->conversion == 'e' || dp->conversion == 'E')
5521 *p++ = '0';
5522 if ((flags & FLAG_ALT) || precision > 0)
5524 *p++ = decimal_point_char ();
5525 for (; precision > 0; precision--)
5526 *p++ = '0';
5528 *p++ = dp->conversion; /* 'e' or 'E' */
5529 *p++ = '+';
5530 /* Produce the same number of exponent digits as
5531 the native printf implementation. */
5532 # if defined _WIN32 && ! defined __CYGWIN__
5533 *p++ = '0';
5534 # endif
5535 *p++ = '0';
5536 *p++ = '0';
5538 else if (dp->conversion == 'g' || dp->conversion == 'G')
5540 *p++ = '0';
5541 if (flags & FLAG_ALT)
5543 size_t ndigits =
5544 (precision > 0 ? precision - 1 : 0);
5545 *p++ = decimal_point_char ();
5546 for (; ndigits > 0; --ndigits)
5547 *p++ = '0';
5550 else
5551 abort ();
5552 # endif
5556 # endif
5558 /* The generated string now extends from tmp to p, with the
5559 zero padding insertion point being at pad_ptr. */
5560 count = p - tmp;
5562 if (count < width)
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--)
5571 *p++ = ' ';
5573 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5575 /* Pad with zeroes. */
5576 DCHAR_T *q = end;
5578 while (p > pad_ptr)
5579 *--q = *--p;
5580 for (; pad > 0; pad--)
5581 *p++ = '0';
5583 else
5585 /* Pad with spaces on the left. */
5586 DCHAR_T *q = end;
5588 while (p > tmp)
5589 *--q = *--p;
5590 for (; pad > 0; pad--)
5591 *p++ = ' ';
5594 p = end;
5597 count = p - tmp;
5599 if (count >= tmp_length)
5600 /* tmp_length was incorrectly calculated - fix the
5601 code above! */
5602 abort ();
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));
5614 if (tmp != tmpbuf)
5615 free (tmp);
5616 length += count;
5618 #endif
5619 else
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
5624 int has_width;
5625 #endif
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
5627 size_t width;
5628 #endif
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
5630 int has_precision;
5631 size_t precision;
5632 #endif
5633 #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5634 int prec_ourselves;
5635 #else
5636 # define prec_ourselves 0
5637 #endif
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
5641 int pad_ourselves;
5642 #else
5643 # define pad_ourselves 0
5644 #endif
5645 TCHAR_T *fbp;
5646 unsigned int prefix_count;
5647 int prefixes[2] IF_LINT (= { 0 });
5648 int orig_errno;
5649 #if !USE_SNPRINTF
5650 size_t tmp_length;
5651 TCHAR_T tmpbuf[700];
5652 TCHAR_T *tmp;
5653 #endif
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
5656 has_width = 0;
5657 #endif
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
5659 width = 0;
5660 if (dp->width_start != dp->width_end)
5662 if (dp->width_arg_index != ARG_NONE)
5664 int arg;
5666 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
5667 abort ();
5668 arg = a.arg[dp->width_arg_index].a.a_int;
5669 width = arg;
5670 if (arg < 0)
5672 /* "A negative field width is taken as a '-' flag
5673 followed by a positive field width." */
5674 flags |= FLAG_LEFT;
5675 width = -width;
5678 else
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
5687 has_width = 1;
5688 # endif
5690 #endif
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
5693 has_precision = 0;
5694 precision = 6;
5695 if (dp->precision_start != dp->precision_end)
5697 if (dp->precision_arg_index != ARG_NONE)
5699 int arg;
5701 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
5702 abort ();
5703 arg = a.arg[dp->precision_arg_index].a.a_int;
5704 /* "A negative precision is taken as if the precision
5705 were omitted." */
5706 if (arg >= 0)
5708 precision = arg;
5709 has_precision = 1;
5712 else
5714 const FCHAR_T *digitp = dp->precision_start + 1;
5716 precision = 0;
5717 while (digitp != dp->precision_end)
5718 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
5719 has_precision = 1;
5722 #endif
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':
5730 case 'b':
5731 #if SUPPORT_GNU_PRINTF_DIRECTIVES \
5732 || (__GLIBC__ + (__GLIBC_MINOR__ >= 35) > 2)
5733 case 'B':
5734 #endif
5735 case 'o':
5736 prec_ourselves = has_precision && (precision > 0);
5737 break;
5738 # endif
5739 case 'x': case 'X': case 'p':
5740 prec_ourselves =
5741 has_precision
5742 && (0
5743 # if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO
5744 || (precision == 0)
5745 # endif
5746 # if NEED_PRINTF_UNBOUNDED_PRECISION
5747 || (precision > 0)
5748 # endif
5750 break;
5751 default:
5752 prec_ourselves = 0;
5753 break;
5755 #endif
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. */
5766 case 'c': case 's':
5767 # endif
5768 # if NEED_PRINTF_FLAG_ZERO
5769 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
5770 case 'a': case 'A':
5771 # endif
5772 pad_ourselves = 1;
5773 break;
5774 default:
5775 pad_ourselves = prec_ourselves;
5776 break;
5778 #endif
5780 #if !USE_SNPRINTF
5781 /* Allocate a temporary buffer of sufficient size for calling
5782 sprintf. */
5783 tmp_length =
5784 MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
5785 flags, width, has_precision, precision,
5786 pad_ourselves);
5788 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
5789 tmp = tmpbuf;
5790 else
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. */
5796 goto out_of_memory;
5797 tmp = (TCHAR_T *) malloc (tmp_memsize);
5798 if (tmp == NULL)
5799 /* Out of memory. */
5800 goto out_of_memory;
5802 #endif
5804 /* Construct the format string for calling snprintf or
5805 sprintf. */
5806 fbp = buf;
5807 *fbp++ = '%';
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. */
5812 #else
5813 if (flags & FLAG_GROUP)
5814 *fbp++ = '\'';
5815 #endif
5816 if (flags & FLAG_LEFT)
5817 *fbp++ = '-';
5818 if (flags & FLAG_SHOWSIGN)
5819 *fbp++ = '+';
5820 if (flags & FLAG_SPACE)
5821 *fbp++ = ' ';
5822 if (flags & FLAG_ALT)
5823 *fbp++ = '#';
5824 #if __GLIBC__ >= 2 && !defined __UCLIBC__
5825 if (flags & FLAG_LOCALIZED)
5826 *fbp++ = 'I';
5827 #endif
5828 if (!pad_ourselves)
5830 if (flags & FLAG_ZERO)
5831 *fbp++ = '0';
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));
5840 fbp += n;
5842 else
5844 const FCHAR_T *mp = dp->width_start;
5846 *fbp++ = *mp++;
5847 while (--n > 0);
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));
5861 fbp += n;
5863 else
5865 const FCHAR_T *mp = dp->precision_start;
5867 *fbp++ = *mp++;
5868 while (--n > 0);
5873 switch (type)
5875 case TYPE_LONGLONGINT:
5876 case TYPE_ULONGLONGINT:
5877 #if INT8_WIDTH > LONG_WIDTH
5878 case TYPE_INT8_T:
5879 #endif
5880 #if UINT8_WIDTH > LONG_WIDTH
5881 case TYPE_UINT8_T:
5882 #endif
5883 #if INT16_WIDTH > LONG_WIDTH
5884 case TYPE_INT16_T:
5885 #endif
5886 #if UINT16_WIDTH > LONG_WIDTH
5887 case TYPE_UINT16_T:
5888 #endif
5889 #if INT32_WIDTH > LONG_WIDTH
5890 case TYPE_INT32_T:
5891 #endif
5892 #if UINT32_WIDTH > LONG_WIDTH
5893 case TYPE_UINT32_T:
5894 #endif
5895 #if INT64_WIDTH > LONG_WIDTH
5896 case TYPE_INT64_T:
5897 #endif
5898 #if UINT64_WIDTH > LONG_WIDTH
5899 case TYPE_UINT64_T:
5900 #endif
5901 #if INT_FAST8_WIDTH > LONG_WIDTH
5902 case TYPE_INT_FAST8_T:
5903 #endif
5904 #if UINT_FAST8_WIDTH > LONG_WIDTH
5905 case TYPE_UINT_FAST8_T:
5906 #endif
5907 #if INT_FAST16_WIDTH > LONG_WIDTH
5908 case TYPE_INT_FAST16_T:
5909 #endif
5910 #if UINT_FAST16_WIDTH > LONG_WIDTH
5911 case TYPE_UINT_FAST16_T:
5912 #endif
5913 #if INT_FAST32_WIDTH > LONG_WIDTH
5914 case TYPE_INT3_FAST2_T:
5915 #endif
5916 #if UINT_FAST32_WIDTH > LONG_WIDTH
5917 case TYPE_UINT_FAST32_T:
5918 #endif
5919 #if INT_FAST64_WIDTH > LONG_WIDTH
5920 case TYPE_INT_FAST64_T:
5921 #endif
5922 #if UINT_FAST64_WIDTH > LONG_WIDTH
5923 case TYPE_UINT_FAST64_T:
5924 #endif
5925 #if defined _WIN32 && ! defined __CYGWIN__
5926 *fbp++ = 'I';
5927 *fbp++ = '6';
5928 *fbp++ = '4';
5929 break;
5930 #else
5931 *fbp++ = 'l';
5932 #endif
5933 FALLTHROUGH;
5934 case TYPE_LONGINT:
5935 case TYPE_ULONGINT:
5936 #if INT8_WIDTH > INT_WIDTH && INT8_WIDTH <= LONG_WIDTH
5937 case TYPE_INT8_T:
5938 #endif
5939 #if UINT8_WIDTH > INT_WIDTH && UINT8_WIDTH <= LONG_WIDTH
5940 case TYPE_UINT8_T:
5941 #endif
5942 #if INT16_WIDTH > INT_WIDTH && INT16_WIDTH <= LONG_WIDTH
5943 case TYPE_INT16_T:
5944 #endif
5945 #if UINT16_WIDTH > INT_WIDTH && UINT16_WIDTH <= LONG_WIDTH
5946 case TYPE_UINT16_T:
5947 #endif
5948 #if INT32_WIDTH > INT_WIDTH && INT32_WIDTH <= LONG_WIDTH
5949 case TYPE_INT32_T:
5950 #endif
5951 #if UINT32_WIDTH > INT_WIDTH && UINT32_WIDTH <= LONG_WIDTH
5952 case TYPE_UINT32_T:
5953 #endif
5954 #if INT64_WIDTH > INT_WIDTH && INT64_WIDTH <= LONG_WIDTH
5955 case TYPE_INT64_T:
5956 #endif
5957 #if UINT64_WIDTH > INT_WIDTH && UINT64_WIDTH <= LONG_WIDTH
5958 case TYPE_UINT64_T:
5959 #endif
5960 #if INT_FAST8_WIDTH > INT_WIDTH && INT_FAST8_WIDTH <= LONG_WIDTH
5961 case TYPE_INT_FAST8_T:
5962 #endif
5963 #if UINT_FAST8_WIDTH > INT_WIDTH && UINT_FAST8_WIDTH <= LONG_WIDTH
5964 case TYPE_UINT_FAST8_T:
5965 #endif
5966 #if INT_FAST16_WIDTH > INT_WIDTH && INT_FAST16_WIDTH <= LONG_WIDTH
5967 case TYPE_INT_FAST16_T:
5968 #endif
5969 #if UINT_FAST16_WIDTH > INT_WIDTH && UINT_FAST16_WIDTH <= LONG_WIDTH
5970 case TYPE_UINT_FAST16_T:
5971 #endif
5972 #if INT_FAST32_WIDTH > INT_WIDTH && INT_FAST32_WIDTH <= LONG_WIDTH
5973 case TYPE_INT_FAST32_T:
5974 #endif
5975 #if UINT_FAST32_WIDTH > INT_WIDTH && UINT_FAST32_WIDTH <= LONG_WIDTH
5976 case TYPE_UINT_FAST32_T:
5977 #endif
5978 #if INT_FAST64_WIDTH > INT_WIDTH && INT_FAST64_WIDTH <= LONG_WIDTH
5979 case TYPE_INT_FAST64_T:
5980 #endif
5981 #if UINT_FAST64_WIDTH > INT_WIDTH && UINT_FAST64_WIDTH <= LONG_WIDTH
5982 case TYPE_UINT_FAST64_T:
5983 #endif
5984 #if HAVE_WINT_T
5985 case TYPE_WIDE_CHAR:
5986 #endif
5987 #if HAVE_WCHAR_T
5988 case TYPE_WIDE_STRING:
5989 #endif
5990 *fbp++ = 'l';
5991 break;
5992 case TYPE_LONGDOUBLE:
5993 *fbp++ = 'L';
5994 break;
5995 default:
5996 break;
5998 #if NEED_PRINTF_DIRECTIVE_F
5999 if (dp->conversion == 'F')
6000 *fbp = 'f';
6001 else
6002 #endif
6003 *fbp = dp->conversion;
6004 #if USE_SNPRINTF
6005 /* Decide whether to pass %n in the format string
6006 to SNPRINTF. */
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
6017 return value if
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.
6031 In the case
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
6037 MAX_ROOM_NEEDED. */
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
6044 program.
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
6062 either because:
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>. */
6073 fbp[1] = '\0';
6074 # else /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */
6075 fbp[1] = '%';
6076 fbp[2] = 'n';
6077 fbp[3] = '\0';
6078 # endif
6079 #else
6080 fbp[1] = '\0';
6081 #endif
6083 /* Construct the arguments for calling snprintf or sprintf. */
6084 prefix_count = 0;
6085 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
6087 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
6088 abort ();
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))
6094 abort ();
6095 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
6098 #if USE_SNPRINTF
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
6111 via %n. */
6112 *(TCHAR_T *) (result + length) = '\0';
6113 #endif
6115 orig_errno = errno;
6117 for (;;)
6119 int count = -1;
6121 #if USE_SNPRINTF
6122 int retcount = 0;
6123 size_t maxlen = allocated - length;
6124 /* SNPRINTF can fail if its second argument is
6125 > INT_MAX. */
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) \
6132 case 0: \
6133 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
6134 maxlen, buf, \
6135 arg, &count); \
6136 break; \
6137 case 1: \
6138 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
6139 maxlen, buf, \
6140 prefixes[0], arg, &count); \
6141 break; \
6142 case 2: \
6143 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
6144 maxlen, buf, \
6145 prefixes[0], prefixes[1], arg, \
6146 &count); \
6147 break; \
6148 default: \
6149 abort (); \
6151 #else
6152 # define SNPRINTF_BUF(arg) \
6153 switch (prefix_count) \
6155 case 0: \
6156 count = sprintf (tmp, buf, arg); \
6157 break; \
6158 case 1: \
6159 count = sprintf (tmp, buf, prefixes[0], arg); \
6160 break; \
6161 case 2: \
6162 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
6163 arg); \
6164 break; \
6165 default: \
6166 abort (); \
6168 #endif
6170 errno = 0;
6171 switch (type)
6173 case TYPE_SCHAR:
6175 int arg = a.arg[dp->arg_index].a.a_schar;
6176 SNPRINTF_BUF (arg);
6178 break;
6179 case TYPE_UCHAR:
6181 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
6182 SNPRINTF_BUF (arg);
6184 break;
6185 case TYPE_SHORT:
6187 int arg = a.arg[dp->arg_index].a.a_short;
6188 SNPRINTF_BUF (arg);
6190 break;
6191 case TYPE_USHORT:
6193 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
6194 SNPRINTF_BUF (arg);
6196 break;
6197 case TYPE_INT:
6199 int arg = a.arg[dp->arg_index].a.a_int;
6200 SNPRINTF_BUF (arg);
6202 break;
6203 case TYPE_UINT:
6205 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
6206 SNPRINTF_BUF (arg);
6208 break;
6209 case TYPE_LONGINT:
6211 long int arg = a.arg[dp->arg_index].a.a_longint;
6212 SNPRINTF_BUF (arg);
6214 break;
6215 case TYPE_ULONGINT:
6217 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
6218 SNPRINTF_BUF (arg);
6220 break;
6221 case TYPE_LONGLONGINT:
6223 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
6224 SNPRINTF_BUF (arg);
6226 break;
6227 case TYPE_ULONGLONGINT:
6229 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
6230 SNPRINTF_BUF (arg);
6232 break;
6233 case TYPE_INT8_T:
6235 int8_t arg = a.arg[dp->arg_index].a.a_int8_t;
6236 SNPRINTF_BUF (arg);
6238 break;
6239 case TYPE_UINT8_T:
6241 uint8_t arg = a.arg[dp->arg_index].a.a_uint8_t;
6242 SNPRINTF_BUF (arg);
6244 break;
6245 case TYPE_INT16_T:
6247 int16_t arg = a.arg[dp->arg_index].a.a_int16_t;
6248 SNPRINTF_BUF (arg);
6250 break;
6251 case TYPE_UINT16_T:
6253 uint16_t arg = a.arg[dp->arg_index].a.a_uint16_t;
6254 SNPRINTF_BUF (arg);
6256 break;
6257 case TYPE_INT32_T:
6259 int32_t arg = a.arg[dp->arg_index].a.a_int32_t;
6260 SNPRINTF_BUF (arg);
6262 break;
6263 case TYPE_UINT32_T:
6265 uint32_t arg = a.arg[dp->arg_index].a.a_uint32_t;
6266 SNPRINTF_BUF (arg);
6268 break;
6269 case TYPE_INT64_T:
6271 int64_t arg = a.arg[dp->arg_index].a.a_int64_t;
6272 SNPRINTF_BUF (arg);
6274 break;
6275 case TYPE_UINT64_T:
6277 uint64_t arg = a.arg[dp->arg_index].a.a_uint64_t;
6278 SNPRINTF_BUF (arg);
6280 break;
6281 case TYPE_INT_FAST8_T:
6283 int_fast8_t arg = a.arg[dp->arg_index].a.a_int_fast8_t;
6284 SNPRINTF_BUF (arg);
6286 break;
6287 case TYPE_UINT_FAST8_T:
6289 uint_fast8_t arg = a.arg[dp->arg_index].a.a_uint_fast8_t;
6290 SNPRINTF_BUF (arg);
6292 break;
6293 case TYPE_INT_FAST16_T:
6295 int_fast16_t arg = a.arg[dp->arg_index].a.a_int_fast16_t;
6296 SNPRINTF_BUF (arg);
6298 break;
6299 case TYPE_UINT_FAST16_T:
6301 uint_fast16_t arg = a.arg[dp->arg_index].a.a_uint_fast16_t;
6302 SNPRINTF_BUF (arg);
6304 break;
6305 case TYPE_INT_FAST32_T:
6307 int_fast32_t arg = a.arg[dp->arg_index].a.a_int_fast32_t;
6308 SNPRINTF_BUF (arg);
6310 break;
6311 case TYPE_UINT_FAST32_T:
6313 uint_fast32_t arg = a.arg[dp->arg_index].a.a_uint_fast32_t;
6314 SNPRINTF_BUF (arg);
6316 break;
6317 case TYPE_INT_FAST64_T:
6319 int_fast64_t arg = a.arg[dp->arg_index].a.a_int_fast64_t;
6320 SNPRINTF_BUF (arg);
6322 break;
6323 case TYPE_UINT_FAST64_T:
6325 uint_fast64_t arg = a.arg[dp->arg_index].a.a_uint_fast64_t;
6326 SNPRINTF_BUF (arg);
6328 break;
6329 case TYPE_DOUBLE:
6331 double arg = a.arg[dp->arg_index].a.a_double;
6332 SNPRINTF_BUF (arg);
6334 break;
6335 case TYPE_LONGDOUBLE:
6337 long double arg = a.arg[dp->arg_index].a.a_longdouble;
6338 SNPRINTF_BUF (arg);
6340 break;
6341 case TYPE_CHAR:
6343 int arg = a.arg[dp->arg_index].a.a_char;
6344 SNPRINTF_BUF (arg);
6346 break;
6347 #if HAVE_WINT_T
6348 case TYPE_WIDE_CHAR:
6350 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
6351 SNPRINTF_BUF (arg);
6353 break;
6354 #endif
6355 case TYPE_STRING:
6357 const char *arg = a.arg[dp->arg_index].a.a_string;
6358 SNPRINTF_BUF (arg);
6360 break;
6361 #if HAVE_WCHAR_T
6362 case TYPE_WIDE_STRING:
6364 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
6365 SNPRINTF_BUF (arg);
6367 break;
6368 #endif
6369 case TYPE_POINTER:
6371 void *arg = a.arg[dp->arg_index].a.a_pointer;
6372 SNPRINTF_BUF (arg);
6374 break;
6375 default:
6376 abort ();
6379 #if USE_SNPRINTF
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
6383 produced. */
6384 if (count >= 0)
6386 /* Verify that snprintf() has NUL-terminated its
6387 result. */
6388 if ((unsigned int) count < maxlen
6389 && ((TCHAR_T *) (result + length)) [count] != '\0')
6390 abort ();
6391 /* Portability hack. */
6392 if (retcount > count)
6393 count = retcount;
6395 else
6397 /* snprintf() doesn't understand the '%n'
6398 directive. */
6399 if (fbp[1] != '\0')
6401 /* Don't use the '%n' directive; instead, look
6402 at the snprintf() return value. */
6403 fbp[1] = '\0';
6404 continue;
6406 else
6408 /* Look at the snprintf() return value. */
6409 if (retcount < 0)
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. */
6426 size_t tmp_length =
6427 MAX_ROOM_NEEDED (&a, dp->arg_index,
6428 dp->conversion, type, flags,
6429 width,
6430 has_precision,
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 =
6438 xsum (length,
6439 xsum (tmp_length,
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
6445 previous one.) */
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);
6451 continue;
6453 # endif
6455 else
6457 count = retcount;
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. */
6462 count = 1;
6463 # endif
6467 #endif
6469 /* Attempt to handle failure. */
6470 if (count < 0)
6472 /* SNPRINTF or sprintf failed. Use the errno that it
6473 has set, if any. */
6474 if (errno == 0)
6476 if (dp->conversion == 'c' || dp->conversion == 's')
6477 errno = EILSEQ;
6478 else
6479 errno = EINVAL;
6482 goto fail_with_errno;
6485 #if USE_SNPRINTF
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)
6497 goto overflow;
6498 else
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
6508 count. */
6509 size_t n =
6510 xmax (xsum (length,
6511 ((unsigned int) count + 2
6512 + TCHARS_PER_DCHAR - 1)
6513 / TCHARS_PER_DCHAR),
6514 xtimes (allocated, 2));
6516 ENSURE_ALLOCATION (n);
6517 continue;
6520 #endif
6522 #if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
6523 if (prec_ourselves)
6525 /* Handle the precision. */
6526 TCHAR_T *prec_ptr =
6527 # if USE_SNPRINTF
6528 (TCHAR_T *) (result + length);
6529 # else
6530 tmp;
6531 # endif
6532 size_t prefix_count;
6533 size_t move;
6535 prefix_count = 0;
6536 /* Put the additional zeroes after the sign. */
6537 if (count >= 1
6538 && (*prec_ptr == '-' || *prec_ptr == '+'
6539 || *prec_ptr == ' '))
6540 prefix_count = 1;
6541 /* Put the additional zeroes after the 0x prefix if
6542 (flags & FLAG_ALT) || (dp->conversion == 'p'). */
6543 else if (count >= 2
6544 && prec_ptr[0] == '0'
6545 && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
6546 prefix_count = 2;
6548 move = count - prefix_count;
6549 if (precision > move)
6551 /* Insert zeroes. */
6552 size_t insert = precision - move;
6553 TCHAR_T *prec_end;
6555 # if USE_SNPRINTF
6556 size_t n =
6557 xsum (length,
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);
6564 # endif
6566 prec_end = prec_ptr + count;
6567 prec_ptr += prefix_count;
6569 while (prec_end > prec_ptr)
6571 prec_end--;
6572 prec_end[insert] = prec_end[0];
6575 prec_end += insert;
6577 *--prec_end = '0';
6578 while (prec_end > prec_ptr);
6580 count += insert;
6582 # if NEED_PRINTF_FLAG_ALT_PRECISION_ZERO
6583 else if (precision == 0
6584 && move == 1
6585 && prec_ptr[prefix_count] == '0')
6587 /* Replace the "0" result with an empty string. */
6588 count = prefix_count;
6590 # endif
6592 #endif
6594 #if !USE_SNPRINTF
6595 if (count >= tmp_length)
6596 /* tmp_length was incorrectly calculated - fix the
6597 code above! */
6598 abort ();
6599 #endif
6601 #if !DCHAR_IS_TCHAR
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)
6606 # endif
6609 /* The result string is not guaranteed to be ASCII. */
6610 const TCHAR_T *tmpsrc;
6611 DCHAR_T *tmpdst;
6612 size_t tmpdst_len;
6613 /* This code assumes that TCHAR_T is 'char'. */
6614 static_assert (sizeof (TCHAR_T) == 1);
6615 # if USE_SNPRINTF
6616 tmpsrc = (TCHAR_T *) (result + length);
6617 # else
6618 tmpsrc = tmp;
6619 # endif
6620 # if WIDE_CHAR_VERSION
6621 /* Convert tmpsrc[0..count-1] to a freshly allocated
6622 wide character array. */
6623 mbstate_t state;
6625 mbszero (&state);
6626 tmpdst_len = 0;
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;
6637 if (ret == 0)
6638 ret = 1;
6639 src += ret;
6640 srclen -= ret;
6644 tmpdst =
6645 (wchar_t *) malloc ((tmpdst_len + 1) * sizeof (wchar_t));
6646 if (tmpdst == NULL)
6647 goto out_of_memory;
6649 mbszero (&state);
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
6661 loop, above. */
6662 abort ();
6663 if (ret == 0)
6664 ret = 1;
6665 src += ret;
6666 srclen -= ret;
6669 # else
6670 tmpdst =
6671 DCHAR_CONV_FROM_ENCODING (locale_charset (),
6672 iconveh_question_mark,
6673 tmpsrc, count,
6674 NULL,
6675 NULL, &tmpdst_len);
6676 if (tmpdst == NULL)
6677 goto fail_with_errno;
6678 # endif
6679 ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
6680 { free (tmpdst); goto out_of_memory; });
6681 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
6682 free (tmpdst);
6683 count = tmpdst_len;
6685 else
6687 /* The result string is ASCII.
6688 Simple 1:1 conversion. */
6689 # if USE_SNPRINTF
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))
6694 # endif
6696 const TCHAR_T *tmpsrc;
6697 DCHAR_T *tmpdst;
6698 size_t n;
6700 # if USE_SNPRINTF
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));
6708 else
6710 /* ENSURE_ALLOCATION will move the array
6711 (because it uses realloc(). */
6712 ENSURE_ALLOCATION (xsum (length, count));
6713 tmpsrc = (TCHAR_T *) (result + length);
6715 # else
6716 tmpsrc = tmp;
6717 ENSURE_ALLOCATION (xsum (length, count));
6718 # endif
6719 tmpdst = result + length;
6720 /* Copy backwards, because of overlapping. */
6721 tmpsrc += count;
6722 tmpdst += count;
6723 for (n = count; n > 0; n--)
6724 *--tmpdst = *--tmpsrc;
6727 #endif
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
6734 proportionally. */
6735 size_t n =
6736 xmax (xsum (length, count), xtimes (allocated, 2));
6738 ENSURE_ALLOCATION (n);
6740 #endif
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)
6748 size_t w;
6749 # if ENABLE_UNISTDIO
6750 /* Outside POSIX, it's preferable to compare the width
6751 against the number of _characters_ of the converted
6752 value. */
6753 w = DCHAR_MBSNLEN (result + length, count);
6754 # else
6755 /* The width is compared against the number of _bytes_
6756 of the converted value, says POSIX. */
6757 w = count;
6758 # endif
6759 if (w < width)
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. */
6768 size_t n =
6769 xmax (xsum3 (length, count, pad),
6770 xtimes (allocated, 2));
6772 # if USE_SNPRINTF
6773 length += count;
6774 ENSURE_ALLOCATION (n);
6775 length -= count;
6776 # else
6777 ENSURE_ALLOCATION (n);
6778 # endif
6780 /* Here count + pad <= allocated - length. */
6783 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
6784 DCHAR_T * const rp = result + length;
6785 # else
6786 DCHAR_T * const rp = tmp;
6787 # endif
6788 DCHAR_T *p = rp + count;
6789 DCHAR_T *end = p + pad;
6790 DCHAR_T *pad_ptr;
6791 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
6792 if (dp->conversion == 'c'
6793 || dp->conversion == 's')
6794 /* No zero-padding for string directives. */
6795 pad_ptr = NULL;
6796 else
6797 # endif
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'))
6803 pad_ptr = NULL;
6804 else
6805 /* Do the zero-padding after the "0x" or
6806 "0b" prefix, not before. */
6807 if (p - rp >= 2
6808 && *rp == '0'
6809 && (((dp->conversion == 'a'
6810 || dp->conversion == 'x')
6811 && rp[1] == 'x')
6812 || ((dp->conversion == 'A'
6813 || dp->conversion == 'X')
6814 && rp[1] == 'X')
6815 || (dp->conversion == 'b'
6816 && rp[1] == 'b')
6817 || (dp->conversion == 'B'
6818 && rp[1] == 'B')))
6819 pad_ptr += 2;
6821 /* The generated string now extends from rp to p,
6822 with the zero padding insertion point being at
6823 pad_ptr. */
6825 count = count + pad; /* = end - rp */
6827 if (flags & FLAG_LEFT)
6829 /* Pad with spaces on the right. */
6830 for (; pad > 0; pad--)
6831 *p++ = ' ';
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. */
6837 && !(has_precision
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. */
6851 DCHAR_T *q = end;
6853 while (p > pad_ptr)
6854 *--q = *--p;
6855 for (; pad > 0; pad--)
6856 *p++ = '0';
6858 else
6860 /* Pad with spaces on the left. */
6861 DCHAR_T *q = end;
6863 while (p > rp)
6864 *--q = *--p;
6865 for (; pad > 0; pad--)
6866 *p++ = ' ';
6871 #endif
6873 /* Here still count <= allocated - length. */
6875 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
6876 /* The snprintf() result did fit. */
6877 #else
6878 /* Append the sprintf() result. */
6879 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
6880 #endif
6881 #if !USE_SNPRINTF
6882 if (tmp != tmpbuf)
6883 free (tmp);
6884 #endif
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;
6891 size_t rc;
6892 for (rc = count; rc > 0; rc--, rp++)
6893 if (*rp >= 'a' && *rp <= 'z')
6894 *rp = *rp - 'a' + 'A';
6896 #endif
6898 length += count;
6899 break;
6901 errno = orig_errno;
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. */
6915 DCHAR_T *memory;
6917 memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
6918 if (memory != NULL)
6919 result = memory;
6922 if (buf_malloced != NULL)
6923 free (buf_malloced);
6924 CLEANUP ();
6925 *lengthp = length;
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. */
6930 return result;
6932 #if USE_SNPRINTF
6933 overflow:
6934 errno = EOVERFLOW;
6935 goto fail_with_errno;
6936 #endif
6938 out_of_memory:
6939 errno = ENOMEM;
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)
6943 fail_with_EILSEQ:
6944 errno = EILSEQ;
6945 goto fail_with_errno;
6946 #endif
6948 fail_with_errno:
6949 if (result != resultbuf)
6950 free (result);
6951 if (buf_malloced != NULL)
6952 free (buf_malloced);
6953 CLEANUP ();
6954 return NULL;
6957 out_of_memory_1:
6958 errno = ENOMEM;
6959 goto fail_1_with_errno;
6961 fail_1_with_EINVAL:
6962 errno = EINVAL;
6963 goto fail_1_with_errno;
6965 fail_1_with_errno:
6966 CLEANUP ();
6967 return NULL;
6970 #undef MAX_ROOM_NEEDED
6971 #undef TCHARS_PER_DCHAR
6972 #undef SNPRINTF
6973 #undef USE_SNPRINTF
6974 #undef DCHAR_SET
6975 #undef DCHAR_CPY
6976 #undef PRINTF_PARSE
6977 #undef DIRECTIVES
6978 #undef DIRECTIVE
6979 #undef DCHAR_IS_TCHAR
6980 #undef TCHAR_T
6981 #undef DCHAR_T
6982 #undef FCHAR_T
6983 #undef VASNPRINTF