Merge branch 'master' of github.com:monitoring-plugins/monitoring-plugins
[monitoring-plugins.git] / gl / vasnprintf.c
blob277c39e3e07a9ecc1c35e0158b278521e4c5241c
1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 2002-2023 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() */
87 #include <errno.h> /* errno */
88 #include <limits.h> /* CHAR_BIT */
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) && !defined IN_LIBINTL
107 # include <math.h>
108 # include "float+.h"
109 #endif
111 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
112 # include <math.h>
113 # include "isnand-nolibm.h"
114 #endif
116 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
117 # include <math.h>
118 # include "isnanl-nolibm.h"
119 # include "fpucw.h"
120 #endif
122 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
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) && !defined IN_LIBINTL
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 TCHAR_T wchar_t
142 # define DCHAR_IS_TCHAR 1
143 # define DIRECTIVE wchar_t_directive
144 # define DIRECTIVES wchar_t_directives
145 # define PRINTF_PARSE wprintf_parse
146 # define DCHAR_CPY wmemcpy
147 # define DCHAR_SET wmemset
148 # else
149 # define VASNPRINTF vasnprintf
150 # define FCHAR_T char
151 # define DCHAR_T char
152 # define TCHAR_T char
153 # define DCHAR_IS_TCHAR 1
154 # define DIRECTIVE char_directive
155 # define DIRECTIVES char_directives
156 # define PRINTF_PARSE printf_parse
157 # define DCHAR_CPY memcpy
158 # define DCHAR_SET memset
159 # endif
160 #endif
161 #if WIDE_CHAR_VERSION
162 /* TCHAR_T is wchar_t. */
163 # define USE_SNPRINTF 1
164 # if HAVE_DECL__SNWPRINTF
165 /* On Windows, the function swprintf() has a different signature than
166 on Unix; we use the function _snwprintf() or - on mingw - snwprintf()
167 instead. The mingw function snwprintf() has fewer bugs than the
168 MSVCRT function _snwprintf(), so prefer that. */
169 # if defined __MINGW32__
170 # define SNPRINTF snwprintf
171 # else
172 # define SNPRINTF _snwprintf
173 # define USE_MSVC__SNPRINTF 1
174 # endif
175 # else
176 /* Unix. */
177 # define SNPRINTF swprintf
178 # endif
179 #else
180 /* TCHAR_T is char. */
181 /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
182 But don't use it on BeOS, since BeOS snprintf produces no output if the
183 size argument is >= 0x3000000.
184 Also don't use it on Linux libc5, since there snprintf with size = 1
185 writes any output without bounds, like sprintf. */
186 # if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__ && !(__GNU_LIBRARY__ == 1)
187 # define USE_SNPRINTF 1
188 # else
189 # define USE_SNPRINTF 0
190 # endif
191 # if HAVE_DECL__SNPRINTF
192 /* Windows. The mingw function snprintf() has fewer bugs than the MSVCRT
193 function _snprintf(), so prefer that. */
194 # if defined __MINGW32__
195 # define SNPRINTF snprintf
196 /* Here we need to call the native snprintf, not rpl_snprintf. */
197 # undef snprintf
198 # else
199 /* MSVC versions < 14 did not have snprintf, only _snprintf. */
200 # define SNPRINTF _snprintf
201 # define USE_MSVC__SNPRINTF 1
202 # endif
203 # else
204 /* Unix. */
205 # define SNPRINTF snprintf
206 /* Here we need to call the native snprintf, not rpl_snprintf. */
207 # undef snprintf
208 # endif
209 #endif
210 /* Here we need to call the native sprintf, not rpl_sprintf. */
211 #undef sprintf
213 /* GCC >= 4.0 with -Wall emits unjustified "... may be used uninitialized"
214 warnings in this file. Use -Dlint to suppress them. */
215 #if defined GCC_LINT || defined lint
216 # define IF_LINT(Code) Code
217 #else
218 # define IF_LINT(Code) /* empty */
219 #endif
221 /* Avoid some warnings from "gcc -Wshadow".
222 This file doesn't use the exp() and remainder() functions. */
223 #undef exp
224 #define exp expo
225 #undef remainder
226 #define remainder rem
228 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION
229 # if (HAVE_STRNLEN && !defined _AIX)
230 # define local_strnlen strnlen
231 # else
232 # ifndef local_strnlen_defined
233 # define local_strnlen_defined 1
234 static size_t
235 local_strnlen (const char *string, size_t maxlen)
237 const char *end = memchr (string, '\0', maxlen);
238 return end ? (size_t) (end - string) : maxlen;
240 # endif
241 # endif
242 #endif
244 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
245 # if HAVE_WCSLEN
246 # define local_wcslen wcslen
247 # else
248 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
249 a dependency towards this library, here is a local substitute.
250 Define this substitute only once, even if this file is included
251 twice in the same compilation unit. */
252 # ifndef local_wcslen_defined
253 # define local_wcslen_defined 1
254 static size_t
255 local_wcslen (const wchar_t *s)
257 const wchar_t *ptr;
259 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
261 return ptr - s;
263 # endif
264 # endif
265 #endif
267 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
268 # if HAVE_WCSNLEN
269 # define local_wcsnlen wcsnlen
270 # else
271 # ifndef local_wcsnlen_defined
272 # define local_wcsnlen_defined 1
273 static size_t
274 local_wcsnlen (const wchar_t *s, size_t maxlen)
276 const wchar_t *ptr;
278 for (ptr = s; maxlen > 0 && *ptr != (wchar_t) 0; ptr++, maxlen--)
280 return ptr - s;
282 # endif
283 # endif
284 #endif
286 #if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T) || (ENABLE_WCHAR_FALLBACK && HAVE_WINT_T)) && !WIDE_CHAR_VERSION
287 # if ENABLE_WCHAR_FALLBACK
288 static size_t
289 wctomb_fallback (char *s, wchar_t wc)
291 static char hex[16] = "0123456789ABCDEF";
293 s[0] = '\\';
294 if (sizeof (wchar_t) > 2 && wc > 0xffff)
296 # if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
297 s[1] = 'U';
298 # else
299 s[1] = 'W';
300 # endif
301 s[2] = hex[(wc & 0xf0000000U) >> 28];
302 s[3] = hex[(wc & 0xf000000U) >> 24];
303 s[4] = hex[(wc & 0xf00000U) >> 20];
304 s[5] = hex[(wc & 0xf0000U) >> 16];
305 s[6] = hex[(wc & 0xf000U) >> 12];
306 s[7] = hex[(wc & 0xf00U) >> 8];
307 s[8] = hex[(wc & 0xf0U) >> 4];
308 s[9] = hex[wc & 0xfU];
309 return 10;
311 else
313 # if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
314 s[1] = 'u';
315 # else
316 s[1] = 'w';
317 # endif
318 s[2] = hex[(wc & 0xf000U) >> 12];
319 s[3] = hex[(wc & 0xf00U) >> 8];
320 s[4] = hex[(wc & 0xf0U) >> 4];
321 s[5] = hex[wc & 0xfU];
322 return 6;
325 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
326 static size_t
327 local_wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
329 size_t count = wcrtomb (s, wc, ps);
330 if (count == (size_t)(-1))
331 count = wctomb_fallback (s, wc);
332 return count;
334 # else
335 static int
336 local_wctomb (char *s, wchar_t wc)
338 int count = wctomb (s, wc);
339 if (count < 0)
340 count = wctomb_fallback (s, wc);
341 return count;
343 # define local_wcrtomb(S, WC, PS) local_wctomb ((S), (WC))
344 # endif
345 # else
346 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
347 # define local_wcrtomb(S, WC, PS) wcrtomb ((S), (WC), (PS))
348 # else
349 # define local_wcrtomb(S, WC, PS) wctomb ((S), (WC))
350 # endif
351 # endif
352 #endif
354 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
355 /* Determine the decimal-point character according to the current locale. */
356 # ifndef decimal_point_char_defined
357 # define decimal_point_char_defined 1
358 static char
359 decimal_point_char (void)
361 const char *point;
362 /* Determine it in a multithread-safe way. We know nl_langinfo is
363 multithread-safe on glibc systems and Mac OS X systems, but is not required
364 to be multithread-safe by POSIX. sprintf(), however, is multithread-safe.
365 localeconv() is rarely multithread-safe. */
366 # if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
367 point = nl_langinfo (RADIXCHAR);
368 # elif 1
369 char pointbuf[5];
370 sprintf (pointbuf, "%#.0f", 1.0);
371 point = &pointbuf[1];
372 # else
373 point = localeconv () -> decimal_point;
374 # endif
375 /* The decimal point is always a single byte: either '.' or ','. */
376 return (point[0] != '\0' ? point[0] : '.');
378 # endif
379 #endif
381 #if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
383 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
384 static int
385 is_infinite_or_zero (double x)
387 return isnand (x) || x + x == x;
390 #endif
392 #if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
394 /* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
395 static int
396 is_infinite_or_zerol (long double x)
398 return isnanl (x) || x + x == x;
401 #endif
403 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
405 /* Converting 'long double' to decimal without rare rounding bugs requires
406 real bignums. We use the naming conventions of GNU gmp, but vastly simpler
407 (and slower) algorithms. */
409 typedef unsigned int mp_limb_t;
410 # define GMP_LIMB_BITS 32
411 static_assert (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
413 typedef unsigned long long mp_twolimb_t;
414 # define GMP_TWOLIMB_BITS 64
415 static_assert (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
417 /* Representation of a bignum >= 0. */
418 typedef struct
420 size_t nlimbs;
421 mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
422 } mpn_t;
424 /* Compute the product of two bignums >= 0.
425 Return the allocated memory in case of success, NULL in case of memory
426 allocation failure. */
427 static void *
428 multiply (mpn_t src1, mpn_t src2, mpn_t *dest)
430 const mp_limb_t *p1;
431 const mp_limb_t *p2;
432 size_t len1;
433 size_t len2;
435 if (src1.nlimbs <= src2.nlimbs)
437 len1 = src1.nlimbs;
438 p1 = src1.limbs;
439 len2 = src2.nlimbs;
440 p2 = src2.limbs;
442 else
444 len1 = src2.nlimbs;
445 p1 = src2.limbs;
446 len2 = src1.nlimbs;
447 p2 = src1.limbs;
449 /* Now 0 <= len1 <= len2. */
450 if (len1 == 0)
452 /* src1 or src2 is zero. */
453 dest->nlimbs = 0;
454 dest->limbs = (mp_limb_t *) malloc (1);
456 else
458 /* Here 1 <= len1 <= len2. */
459 size_t dlen;
460 mp_limb_t *dp;
461 size_t k, i, j;
463 dlen = len1 + len2;
464 dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
465 if (dp == NULL)
466 return NULL;
467 for (k = len2; k > 0; )
468 dp[--k] = 0;
469 for (i = 0; i < len1; i++)
471 mp_limb_t digit1 = p1[i];
472 mp_twolimb_t carry = 0;
473 for (j = 0; j < len2; j++)
475 mp_limb_t digit2 = p2[j];
476 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
477 carry += dp[i + j];
478 dp[i + j] = (mp_limb_t) carry;
479 carry = carry >> GMP_LIMB_BITS;
481 dp[i + len2] = (mp_limb_t) carry;
483 /* Normalise. */
484 while (dlen > 0 && dp[dlen - 1] == 0)
485 dlen--;
486 dest->nlimbs = dlen;
487 dest->limbs = dp;
489 return dest->limbs;
492 /* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
493 a is written as a = q * b + r with 0 <= r < b. q is the quotient, r
494 the remainder.
495 Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
496 q is incremented.
497 Return the allocated memory in case of success, NULL in case of memory
498 allocation failure. */
499 static void *
500 divide (mpn_t a, mpn_t b, mpn_t *q)
502 /* Algorithm:
503 First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
504 with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
505 If m<n, then q:=0 and r:=a.
506 If m>=n=1, perform a single-precision division:
507 r:=0, j:=m,
508 while j>0 do
509 {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
510 = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
511 j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
512 Normalise [q[m-1],...,q[0]], yields q.
513 If m>=n>1, perform a multiple-precision division:
514 We have a/b < beta^(m-n+1).
515 s:=intDsize-1-(highest bit in b[n-1]), 0<=s<intDsize.
516 Shift a and b left by s bits, copying them. r:=a.
517 r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
518 For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
519 Compute q* :
520 q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
521 In case of overflow (q* >= beta) set q* := beta-1.
522 Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
523 and c3 := b[n-2] * q*.
524 {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
525 occurred. Furthermore 0 <= c3 < beta^2.
526 If there was overflow and
527 r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
528 the next test can be skipped.}
529 While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
530 Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
531 If q* > 0:
532 Put r := r - b * q* * beta^j. In detail:
533 [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
534 hence: u:=0, for i:=0 to n-1 do
535 u := u + q* * b[i],
536 r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
537 u:=u div beta (+ 1, if carry in subtraction)
538 r[n+j]:=r[n+j]-u.
539 {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
540 < q* + 1 <= beta,
541 the carry u does not overflow.}
542 If a negative carry occurs, put q* := q* - 1
543 and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
544 Set q[j] := q*.
545 Normalise [q[m-n],..,q[0]]; this yields the quotient q.
546 Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
547 rest r.
548 The room for q[j] can be allocated at the memory location of r[n+j].
549 Finally, round-to-even:
550 Shift r left by 1 bit.
551 If r > b or if r = b and q[0] is odd, q := q+1.
553 const mp_limb_t *a_ptr = a.limbs;
554 size_t a_len = a.nlimbs;
555 const mp_limb_t *b_ptr = b.limbs;
556 size_t b_len = b.nlimbs;
557 mp_limb_t *roomptr;
558 mp_limb_t *tmp_roomptr = NULL;
559 mp_limb_t *q_ptr;
560 size_t q_len;
561 mp_limb_t *r_ptr;
562 size_t r_len;
564 /* Allocate room for a_len+2 digits.
565 (Need a_len+1 digits for the real division and 1 more digit for the
566 final rounding of q.) */
567 roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
568 if (roomptr == NULL)
569 return NULL;
571 /* Normalise a. */
572 while (a_len > 0 && a_ptr[a_len - 1] == 0)
573 a_len--;
575 /* Normalise b. */
576 for (;;)
578 if (b_len == 0)
579 /* Division by zero. */
580 abort ();
581 if (b_ptr[b_len - 1] == 0)
582 b_len--;
583 else
584 break;
587 /* Here m = a_len >= 0 and n = b_len > 0. */
589 if (a_len < b_len)
591 /* m<n: trivial case. q=0, r := copy of a. */
592 r_ptr = roomptr;
593 r_len = a_len;
594 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
595 q_ptr = roomptr + a_len;
596 q_len = 0;
598 else if (b_len == 1)
600 /* n=1: single precision division.
601 beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
602 r_ptr = roomptr;
603 q_ptr = roomptr + 1;
605 mp_limb_t den = b_ptr[0];
606 mp_limb_t remainder = 0;
607 const mp_limb_t *sourceptr = a_ptr + a_len;
608 mp_limb_t *destptr = q_ptr + a_len;
609 size_t count;
610 for (count = a_len; count > 0; count--)
612 mp_twolimb_t num =
613 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
614 *--destptr = num / den;
615 remainder = num % den;
617 /* Normalise and store r. */
618 if (remainder > 0)
620 r_ptr[0] = remainder;
621 r_len = 1;
623 else
624 r_len = 0;
625 /* Normalise q. */
626 q_len = a_len;
627 if (q_ptr[q_len - 1] == 0)
628 q_len--;
631 else
633 /* n>1: multiple precision division.
634 beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==>
635 beta^(m-n-1) <= a/b < beta^(m-n+1). */
636 /* Determine s. */
637 size_t s;
639 mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
640 /* Determine s = GMP_LIMB_BITS - integer_length (msd).
641 Code copied from gnulib's integer_length.c. */
642 # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
643 || (__clang_major__ >= 4)
644 s = __builtin_clz (msd);
645 # else
646 # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
647 if (GMP_LIMB_BITS <= DBL_MANT_BIT)
649 /* Use 'double' operations.
650 Assumes an IEEE 754 'double' implementation. */
651 # define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
652 # define DBL_EXP_BIAS (DBL_EXP_MASK / 2 - 1)
653 # define NWORDS \
654 ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
655 union { double value; unsigned int word[NWORDS]; } m;
657 /* Use a single integer to floating-point conversion. */
658 m.value = msd;
660 s = GMP_LIMB_BITS
661 - (((m.word[DBL_EXPBIT0_WORD] >> DBL_EXPBIT0_BIT) & DBL_EXP_MASK)
662 - DBL_EXP_BIAS);
664 else
665 # undef NWORDS
666 # endif
668 s = 31;
669 if (msd >= 0x10000)
671 msd = msd >> 16;
672 s -= 16;
674 if (msd >= 0x100)
676 msd = msd >> 8;
677 s -= 8;
679 if (msd >= 0x10)
681 msd = msd >> 4;
682 s -= 4;
684 if (msd >= 0x4)
686 msd = msd >> 2;
687 s -= 2;
689 if (msd >= 0x2)
691 msd = msd >> 1;
692 s -= 1;
695 # endif
697 /* 0 <= s < GMP_LIMB_BITS.
698 Copy b, shifting it left by s bits. */
699 if (s > 0)
701 tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
702 if (tmp_roomptr == NULL)
704 free (roomptr);
705 return NULL;
708 const mp_limb_t *sourceptr = b_ptr;
709 mp_limb_t *destptr = tmp_roomptr;
710 mp_twolimb_t accu = 0;
711 size_t count;
712 for (count = b_len; count > 0; count--)
714 accu += (mp_twolimb_t) *sourceptr++ << s;
715 *destptr++ = (mp_limb_t) accu;
716 accu = accu >> GMP_LIMB_BITS;
718 /* accu must be zero, since that was how s was determined. */
719 if (accu != 0)
720 abort ();
722 b_ptr = tmp_roomptr;
724 /* Copy a, shifting it left by s bits, yields r.
725 Memory layout:
726 At the beginning: r = roomptr[0..a_len],
727 at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */
728 r_ptr = roomptr;
729 if (s == 0)
731 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
732 r_ptr[a_len] = 0;
734 else
736 const mp_limb_t *sourceptr = a_ptr;
737 mp_limb_t *destptr = r_ptr;
738 mp_twolimb_t accu = 0;
739 size_t count;
740 for (count = a_len; count > 0; count--)
742 accu += (mp_twolimb_t) *sourceptr++ << s;
743 *destptr++ = (mp_limb_t) accu;
744 accu = accu >> GMP_LIMB_BITS;
746 *destptr++ = (mp_limb_t) accu;
748 q_ptr = roomptr + b_len;
749 q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
751 size_t j = a_len - b_len; /* m-n */
752 mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
753 mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
754 mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
755 ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
756 /* Division loop, traversed m-n+1 times.
757 j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */
758 for (;;)
760 mp_limb_t q_star;
761 mp_limb_t c1;
762 if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
764 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */
765 mp_twolimb_t num =
766 ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
767 | r_ptr[j + b_len - 1];
768 q_star = num / b_msd;
769 c1 = num % b_msd;
771 else
773 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */
774 q_star = (mp_limb_t)~(mp_limb_t)0; /* q* = beta-1 */
775 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
776 <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
777 <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
778 {<= beta !}.
779 If yes, jump directly to the subtraction loop.
780 (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
781 <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
782 if (r_ptr[j + b_len] > b_msd
783 || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
784 /* r[j+n] >= b[n-1]+1 or
785 r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
786 carry. */
787 goto subtract;
789 /* q_star = q*,
790 c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
792 mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
793 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
794 mp_twolimb_t c3 = /* b[n-2] * q* */
795 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
796 /* While c2 < c3, increase c2 and decrease c3.
797 Consider c3-c2. While it is > 0, decrease it by
798 b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2
799 this can happen only twice. */
800 if (c3 > c2)
802 q_star = q_star - 1; /* q* := q* - 1 */
803 if (c3 - c2 > b_msdd)
804 q_star = q_star - 1; /* q* := q* - 1 */
807 if (q_star > 0)
808 subtract:
810 /* Subtract r := r - b * q* * beta^j. */
811 mp_limb_t cr;
813 const mp_limb_t *sourceptr = b_ptr;
814 mp_limb_t *destptr = r_ptr + j;
815 mp_twolimb_t carry = 0;
816 size_t count;
817 for (count = b_len; count > 0; count--)
819 /* Here 0 <= carry <= q*. */
820 carry =
821 carry
822 + (mp_twolimb_t) q_star * (mp_twolimb_t) *sourceptr++
823 + (mp_limb_t) ~(*destptr);
824 /* Here 0 <= carry <= beta*q* + beta-1. */
825 *destptr++ = ~(mp_limb_t) carry;
826 carry = carry >> GMP_LIMB_BITS; /* <= q* */
828 cr = (mp_limb_t) carry;
830 /* Subtract cr from r_ptr[j + b_len], then forget about
831 r_ptr[j + b_len]. */
832 if (cr > r_ptr[j + b_len])
834 /* Subtraction gave a carry. */
835 q_star = q_star - 1; /* q* := q* - 1 */
836 /* Add b back. */
838 const mp_limb_t *sourceptr = b_ptr;
839 mp_limb_t *destptr = r_ptr + j;
840 mp_limb_t carry = 0;
841 size_t count;
842 for (count = b_len; count > 0; count--)
844 mp_limb_t source1 = *sourceptr++;
845 mp_limb_t source2 = *destptr;
846 *destptr++ = source1 + source2 + carry;
847 carry =
848 (carry
849 ? source1 >= (mp_limb_t) ~source2
850 : source1 > (mp_limb_t) ~source2);
853 /* Forget about the carry and about r[j+n]. */
856 /* q* is determined. Store it as q[j]. */
857 q_ptr[j] = q_star;
858 if (j == 0)
859 break;
860 j--;
863 r_len = b_len;
864 /* Normalise q. */
865 if (q_ptr[q_len - 1] == 0)
866 q_len--;
867 # if 0 /* Not needed here, since we need r only to compare it with b/2, and
868 b is shifted left by s bits. */
869 /* Shift r right by s bits. */
870 if (s > 0)
872 mp_limb_t ptr = r_ptr + r_len;
873 mp_twolimb_t accu = 0;
874 size_t count;
875 for (count = r_len; count > 0; count--)
877 accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
878 accu += (mp_twolimb_t) *--ptr << (GMP_LIMB_BITS - s);
879 *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
882 # endif
883 /* Normalise r. */
884 while (r_len > 0 && r_ptr[r_len - 1] == 0)
885 r_len--;
887 /* Compare r << 1 with b. */
888 if (r_len > b_len)
889 goto increment_q;
891 size_t i;
892 for (i = b_len;;)
894 mp_limb_t r_i =
895 (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
896 | (i < r_len ? r_ptr[i] << 1 : 0);
897 mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
898 if (r_i > b_i)
899 goto increment_q;
900 if (r_i < b_i)
901 goto keep_q;
902 if (i == 0)
903 break;
904 i--;
907 if (q_len > 0 && ((q_ptr[0] & 1) != 0))
908 /* q is odd. */
909 increment_q:
911 size_t i;
912 for (i = 0; i < q_len; i++)
913 if (++(q_ptr[i]) != 0)
914 goto keep_q;
915 q_ptr[q_len++] = 1;
917 keep_q:
918 free (tmp_roomptr);
919 q->limbs = q_ptr;
920 q->nlimbs = q_len;
921 return roomptr;
924 /* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
925 representation.
926 Destroys the contents of a.
927 Return the allocated memory - containing the decimal digits in low-to-high
928 order, terminated with a NUL character - in case of success, NULL in case
929 of memory allocation failure. */
930 static char *
931 convert_to_decimal (mpn_t a, size_t extra_zeroes)
933 mp_limb_t *a_ptr = a.limbs;
934 size_t a_len = a.nlimbs;
935 /* 0.03345 is slightly larger than log(2)/(9*log(10)). */
936 size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
937 /* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the
938 digits of a, followed by 1 byte for the terminating NUL. */
939 char *c_ptr = (char *) malloc (xsum (xsum (extra_zeroes, c_len), 1));
940 if (c_ptr != NULL)
942 char *d_ptr = c_ptr;
943 for (; extra_zeroes > 0; extra_zeroes--)
944 *d_ptr++ = '0';
945 while (a_len > 0)
947 /* Divide a by 10^9, in-place. */
948 mp_limb_t remainder = 0;
949 mp_limb_t *ptr = a_ptr + a_len;
950 size_t count;
951 for (count = a_len; count > 0; count--)
953 mp_twolimb_t num =
954 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
955 *ptr = num / 1000000000;
956 remainder = num % 1000000000;
958 /* Store the remainder as 9 decimal digits. */
959 for (count = 9; count > 0; count--)
961 *d_ptr++ = '0' + (remainder % 10);
962 remainder = remainder / 10;
964 /* Normalize a. */
965 if (a_ptr[a_len - 1] == 0)
966 a_len--;
968 /* Remove leading zeroes. */
969 while (d_ptr > c_ptr && d_ptr[-1] == '0')
970 d_ptr--;
971 /* But keep at least one zero. */
972 if (d_ptr == c_ptr)
973 *d_ptr++ = '0';
974 /* Terminate the string. */
975 *d_ptr = '\0';
977 return c_ptr;
980 # if NEED_PRINTF_LONG_DOUBLE
982 /* Assuming x is finite and >= 0:
983 write x as x = 2^e * m, where m is a bignum.
984 Return the allocated memory in case of success, NULL in case of memory
985 allocation failure. */
986 static void *
987 decode_long_double (long double x, int *ep, mpn_t *mp)
989 mpn_t m;
990 int exp;
991 long double y;
992 size_t i;
994 /* Allocate memory for result. */
995 m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
996 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
997 if (m.limbs == NULL)
998 return NULL;
999 /* Split into exponential part and mantissa. */
1000 y = frexpl (x, &exp);
1001 if (!(y >= 0.0L && y < 1.0L))
1002 abort ();
1003 /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * 2^LDBL_MANT_BIT), and the
1004 latter is an integer. */
1005 /* Convert the mantissa (y * 2^LDBL_MANT_BIT) to a sequence of limbs.
1006 I'm not sure whether it's safe to cast a 'long double' value between
1007 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1008 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1009 doesn't matter). */
1010 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
1011 # if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1013 mp_limb_t hi, lo;
1014 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1015 hi = (int) y;
1016 y -= hi;
1017 if (!(y >= 0.0L && y < 1.0L))
1018 abort ();
1019 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1020 lo = (int) y;
1021 y -= lo;
1022 if (!(y >= 0.0L && y < 1.0L))
1023 abort ();
1024 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1026 # else
1028 mp_limb_t d;
1029 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
1030 d = (int) y;
1031 y -= d;
1032 if (!(y >= 0.0L && y < 1.0L))
1033 abort ();
1034 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
1036 # endif
1037 # endif
1038 for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1040 mp_limb_t hi, lo;
1041 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1042 hi = (int) y;
1043 y -= hi;
1044 if (!(y >= 0.0L && y < 1.0L))
1045 abort ();
1046 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1047 lo = (int) y;
1048 y -= lo;
1049 if (!(y >= 0.0L && y < 1.0L))
1050 abort ();
1051 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1053 # if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
1054 precision. */
1055 if (!(y == 0.0L))
1056 abort ();
1057 # endif
1058 /* Normalise. */
1059 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1060 m.nlimbs--;
1061 *mp = m;
1062 *ep = exp - LDBL_MANT_BIT;
1063 return m.limbs;
1066 # endif
1068 # if NEED_PRINTF_DOUBLE
1070 /* Assuming x is finite and >= 0:
1071 write x as x = 2^e * m, where m is a bignum.
1072 Return the allocated memory in case of success, NULL in case of memory
1073 allocation failure. */
1074 static void *
1075 decode_double (double x, int *ep, mpn_t *mp)
1077 mpn_t m;
1078 int exp;
1079 double y;
1080 size_t i;
1082 /* Allocate memory for result. */
1083 m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
1084 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
1085 if (m.limbs == NULL)
1086 return NULL;
1087 /* Split into exponential part and mantissa. */
1088 y = frexp (x, &exp);
1089 if (!(y >= 0.0 && y < 1.0))
1090 abort ();
1091 /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * 2^DBL_MANT_BIT), and the
1092 latter is an integer. */
1093 /* Convert the mantissa (y * 2^DBL_MANT_BIT) to a sequence of limbs.
1094 I'm not sure whether it's safe to cast a 'double' value between
1095 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
1096 'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
1097 doesn't matter). */
1098 # if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
1099 # if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
1101 mp_limb_t hi, lo;
1102 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
1103 hi = (int) y;
1104 y -= hi;
1105 if (!(y >= 0.0 && y < 1.0))
1106 abort ();
1107 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1108 lo = (int) y;
1109 y -= lo;
1110 if (!(y >= 0.0 && y < 1.0))
1111 abort ();
1112 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1114 # else
1116 mp_limb_t d;
1117 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
1118 d = (int) y;
1119 y -= d;
1120 if (!(y >= 0.0 && y < 1.0))
1121 abort ();
1122 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
1124 # endif
1125 # endif
1126 for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0; )
1128 mp_limb_t hi, lo;
1129 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1130 hi = (int) y;
1131 y -= hi;
1132 if (!(y >= 0.0 && y < 1.0))
1133 abort ();
1134 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
1135 lo = (int) y;
1136 y -= lo;
1137 if (!(y >= 0.0 && y < 1.0))
1138 abort ();
1139 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
1141 if (!(y == 0.0))
1142 abort ();
1143 /* Normalise. */
1144 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
1145 m.nlimbs--;
1146 *mp = m;
1147 *ep = exp - DBL_MANT_BIT;
1148 return m.limbs;
1151 # endif
1153 /* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
1154 Returns the decimal representation of round (x * 10^n).
1155 Return the allocated memory - containing the decimal digits in low-to-high
1156 order, terminated with a NUL character - in case of success, NULL in case
1157 of memory allocation failure. */
1158 static char *
1159 scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
1161 int s;
1162 size_t extra_zeroes;
1163 unsigned int abs_n;
1164 unsigned int abs_s;
1165 mp_limb_t *pow5_ptr;
1166 size_t pow5_len;
1167 unsigned int s_limbs;
1168 unsigned int s_bits;
1169 mpn_t pow5;
1170 mpn_t z;
1171 void *z_memory;
1172 char *digits;
1174 if (memory == NULL)
1175 return NULL;
1176 /* x = 2^e * m, hence
1177 y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1178 = round (2^s * 5^n * m). */
1179 s = e + n;
1180 extra_zeroes = 0;
1181 /* Factor out a common power of 10 if possible. */
1182 if (s > 0 && n > 0)
1184 extra_zeroes = (s < n ? s : n);
1185 s -= extra_zeroes;
1186 n -= extra_zeroes;
1188 /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1189 Before converting to decimal, we need to compute
1190 z = round (2^s * 5^n * m). */
1191 /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1192 sign. 2.322 is slightly larger than log(5)/log(2). */
1193 abs_n = (n >= 0 ? n : -n);
1194 abs_s = (s >= 0 ? s : -s);
1195 pow5_ptr = (mp_limb_t *) malloc (((int)(abs_n * (2.322f / GMP_LIMB_BITS)) + 1
1196 + abs_s / GMP_LIMB_BITS + 1)
1197 * sizeof (mp_limb_t));
1198 if (pow5_ptr == NULL)
1200 free (memory);
1201 return NULL;
1203 /* Initialize with 1. */
1204 pow5_ptr[0] = 1;
1205 pow5_len = 1;
1206 /* Multiply with 5^|n|. */
1207 if (abs_n > 0)
1209 static mp_limb_t const small_pow5[13 + 1] =
1211 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1212 48828125, 244140625, 1220703125
1214 unsigned int n13;
1215 for (n13 = 0; n13 <= abs_n; n13 += 13)
1217 mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1218 size_t j;
1219 mp_twolimb_t carry = 0;
1220 for (j = 0; j < pow5_len; j++)
1222 mp_limb_t digit2 = pow5_ptr[j];
1223 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
1224 pow5_ptr[j] = (mp_limb_t) carry;
1225 carry = carry >> GMP_LIMB_BITS;
1227 if (carry > 0)
1228 pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1231 s_limbs = abs_s / GMP_LIMB_BITS;
1232 s_bits = abs_s % GMP_LIMB_BITS;
1233 if (n >= 0 ? s >= 0 : s <= 0)
1235 /* Multiply with 2^|s|. */
1236 if (s_bits > 0)
1238 mp_limb_t *ptr = pow5_ptr;
1239 mp_twolimb_t accu = 0;
1240 size_t count;
1241 for (count = pow5_len; count > 0; count--)
1243 accu += (mp_twolimb_t) *ptr << s_bits;
1244 *ptr++ = (mp_limb_t) accu;
1245 accu = accu >> GMP_LIMB_BITS;
1247 if (accu > 0)
1249 *ptr = (mp_limb_t) accu;
1250 pow5_len++;
1253 if (s_limbs > 0)
1255 size_t count;
1256 for (count = pow5_len; count > 0;)
1258 count--;
1259 pow5_ptr[s_limbs + count] = pow5_ptr[count];
1261 for (count = s_limbs; count > 0;)
1263 count--;
1264 pow5_ptr[count] = 0;
1266 pow5_len += s_limbs;
1268 pow5.limbs = pow5_ptr;
1269 pow5.nlimbs = pow5_len;
1270 if (n >= 0)
1272 /* Multiply m with pow5. No division needed. */
1273 z_memory = multiply (m, pow5, &z);
1275 else
1277 /* Divide m by pow5 and round. */
1278 z_memory = divide (m, pow5, &z);
1281 else
1283 pow5.limbs = pow5_ptr;
1284 pow5.nlimbs = pow5_len;
1285 if (n >= 0)
1287 /* n >= 0, s < 0.
1288 Multiply m with pow5, then divide by 2^|s|. */
1289 mpn_t numerator;
1290 mpn_t denominator;
1291 void *tmp_memory;
1292 tmp_memory = multiply (m, pow5, &numerator);
1293 if (tmp_memory == NULL)
1295 free (pow5_ptr);
1296 free (memory);
1297 return NULL;
1299 /* Construct 2^|s|. */
1301 mp_limb_t *ptr = pow5_ptr + pow5_len;
1302 size_t i;
1303 for (i = 0; i < s_limbs; i++)
1304 ptr[i] = 0;
1305 ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1306 denominator.limbs = ptr;
1307 denominator.nlimbs = s_limbs + 1;
1309 z_memory = divide (numerator, denominator, &z);
1310 free (tmp_memory);
1312 else
1314 /* n < 0, s > 0.
1315 Multiply m with 2^s, then divide by pow5. */
1316 mpn_t numerator;
1317 mp_limb_t *num_ptr;
1318 num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1319 * sizeof (mp_limb_t));
1320 if (num_ptr == NULL)
1322 free (pow5_ptr);
1323 free (memory);
1324 return NULL;
1327 mp_limb_t *destptr = num_ptr;
1329 size_t i;
1330 for (i = 0; i < s_limbs; i++)
1331 *destptr++ = 0;
1333 if (s_bits > 0)
1335 const mp_limb_t *sourceptr = m.limbs;
1336 mp_twolimb_t accu = 0;
1337 size_t count;
1338 for (count = m.nlimbs; count > 0; count--)
1340 accu += (mp_twolimb_t) *sourceptr++ << s_bits;
1341 *destptr++ = (mp_limb_t) accu;
1342 accu = accu >> GMP_LIMB_BITS;
1344 if (accu > 0)
1345 *destptr++ = (mp_limb_t) accu;
1347 else
1349 const mp_limb_t *sourceptr = m.limbs;
1350 size_t count;
1351 for (count = m.nlimbs; count > 0; count--)
1352 *destptr++ = *sourceptr++;
1354 numerator.limbs = num_ptr;
1355 numerator.nlimbs = destptr - num_ptr;
1357 z_memory = divide (numerator, pow5, &z);
1358 free (num_ptr);
1361 free (pow5_ptr);
1362 free (memory);
1364 /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1366 if (z_memory == NULL)
1367 return NULL;
1368 digits = convert_to_decimal (z, extra_zeroes);
1369 free (z_memory);
1370 return digits;
1373 # if NEED_PRINTF_LONG_DOUBLE
1375 /* Assuming x is finite and >= 0, and n is an integer:
1376 Returns the decimal representation of round (x * 10^n).
1377 Return the allocated memory - containing the decimal digits in low-to-high
1378 order, terminated with a NUL character - in case of success, NULL in case
1379 of memory allocation failure. */
1380 static char *
1381 scale10_round_decimal_long_double (long double x, int n)
1383 int e IF_LINT(= 0);
1384 mpn_t m;
1385 void *memory = decode_long_double (x, &e, &m);
1386 return scale10_round_decimal_decoded (e, m, memory, n);
1389 # endif
1391 # if NEED_PRINTF_DOUBLE
1393 /* Assuming x is finite and >= 0, and n is an integer:
1394 Returns the decimal representation of round (x * 10^n).
1395 Return the allocated memory - containing the decimal digits in low-to-high
1396 order, terminated with a NUL character - in case of success, NULL in case
1397 of memory allocation failure. */
1398 static char *
1399 scale10_round_decimal_double (double x, int n)
1401 int e IF_LINT(= 0);
1402 mpn_t m;
1403 void *memory = decode_double (x, &e, &m);
1404 return scale10_round_decimal_decoded (e, m, memory, n);
1407 # endif
1409 # if NEED_PRINTF_LONG_DOUBLE
1411 /* Assuming x is finite and > 0:
1412 Return an approximation for n with 10^n <= x < 10^(n+1).
1413 The approximation is usually the right n, but may be off by 1 sometimes. */
1414 static int
1415 floorlog10l (long double x)
1417 int exp;
1418 long double y;
1419 double z;
1420 double l;
1422 /* Split into exponential part and mantissa. */
1423 y = frexpl (x, &exp);
1424 if (!(y >= 0.0L && y < 1.0L))
1425 abort ();
1426 if (y == 0.0L)
1427 return INT_MIN;
1428 if (y < 0.5L)
1430 while (y < (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1432 y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1433 exp -= GMP_LIMB_BITS;
1435 if (y < (1.0L / (1 << 16)))
1437 y *= 1.0L * (1 << 16);
1438 exp -= 16;
1440 if (y < (1.0L / (1 << 8)))
1442 y *= 1.0L * (1 << 8);
1443 exp -= 8;
1445 if (y < (1.0L / (1 << 4)))
1447 y *= 1.0L * (1 << 4);
1448 exp -= 4;
1450 if (y < (1.0L / (1 << 2)))
1452 y *= 1.0L * (1 << 2);
1453 exp -= 2;
1455 if (y < (1.0L / (1 << 1)))
1457 y *= 1.0L * (1 << 1);
1458 exp -= 1;
1461 if (!(y >= 0.5L && y < 1.0L))
1462 abort ();
1463 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1464 l = exp;
1465 z = y;
1466 if (z < 0.70710678118654752444)
1468 z *= 1.4142135623730950488;
1469 l -= 0.5;
1471 if (z < 0.8408964152537145431)
1473 z *= 1.1892071150027210667;
1474 l -= 0.25;
1476 if (z < 0.91700404320467123175)
1478 z *= 1.0905077326652576592;
1479 l -= 0.125;
1481 if (z < 0.9576032806985736469)
1483 z *= 1.0442737824274138403;
1484 l -= 0.0625;
1486 /* Now 0.95 <= z <= 1.01. */
1487 z = 1 - z;
1488 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1489 Four terms are enough to get an approximation with error < 10^-7. */
1490 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1491 /* Finally multiply with log(2)/log(10), yields an approximation for
1492 log10(x). */
1493 l *= 0.30102999566398119523;
1494 /* Round down to the next integer. */
1495 return (int) l + (l < 0 ? -1 : 0);
1498 # endif
1500 # if NEED_PRINTF_DOUBLE
1502 /* Assuming x is finite and > 0:
1503 Return an approximation for n with 10^n <= x < 10^(n+1).
1504 The approximation is usually the right n, but may be off by 1 sometimes. */
1505 static int
1506 floorlog10 (double x)
1508 int exp;
1509 double y;
1510 double z;
1511 double l;
1513 /* Split into exponential part and mantissa. */
1514 y = frexp (x, &exp);
1515 if (!(y >= 0.0 && y < 1.0))
1516 abort ();
1517 if (y == 0.0)
1518 return INT_MIN;
1519 if (y < 0.5)
1521 while (y < (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1523 y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1524 exp -= GMP_LIMB_BITS;
1526 if (y < (1.0 / (1 << 16)))
1528 y *= 1.0 * (1 << 16);
1529 exp -= 16;
1531 if (y < (1.0 / (1 << 8)))
1533 y *= 1.0 * (1 << 8);
1534 exp -= 8;
1536 if (y < (1.0 / (1 << 4)))
1538 y *= 1.0 * (1 << 4);
1539 exp -= 4;
1541 if (y < (1.0 / (1 << 2)))
1543 y *= 1.0 * (1 << 2);
1544 exp -= 2;
1546 if (y < (1.0 / (1 << 1)))
1548 y *= 1.0 * (1 << 1);
1549 exp -= 1;
1552 if (!(y >= 0.5 && y < 1.0))
1553 abort ();
1554 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1555 l = exp;
1556 z = y;
1557 if (z < 0.70710678118654752444)
1559 z *= 1.4142135623730950488;
1560 l -= 0.5;
1562 if (z < 0.8408964152537145431)
1564 z *= 1.1892071150027210667;
1565 l -= 0.25;
1567 if (z < 0.91700404320467123175)
1569 z *= 1.0905077326652576592;
1570 l -= 0.125;
1572 if (z < 0.9576032806985736469)
1574 z *= 1.0442737824274138403;
1575 l -= 0.0625;
1577 /* Now 0.95 <= z <= 1.01. */
1578 z = 1 - z;
1579 /* log2(1-z) = 1/log(2) * (- z - z^2/2 - z^3/3 - z^4/4 - ...)
1580 Four terms are enough to get an approximation with error < 10^-7. */
1581 l -= 1.4426950408889634074 * z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1582 /* Finally multiply with log(2)/log(10), yields an approximation for
1583 log10(x). */
1584 l *= 0.30102999566398119523;
1585 /* Round down to the next integer. */
1586 return (int) l + (l < 0 ? -1 : 0);
1589 # endif
1591 /* Tests whether a string of digits consists of exactly PRECISION zeroes and
1592 a single '1' digit. */
1593 static int
1594 is_borderline (const char *digits, size_t precision)
1596 for (; precision > 0; precision--, digits++)
1597 if (*digits != '0')
1598 return 0;
1599 if (*digits != '1')
1600 return 0;
1601 digits++;
1602 return *digits == '\0';
1605 #endif
1607 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
1609 /* Use a different function name, to make it possible that the 'wchar_t'
1610 parametrization and the 'char' parametrization get compiled in the same
1611 translation unit. */
1612 # if WIDE_CHAR_VERSION
1613 # define MAX_ROOM_NEEDED wmax_room_needed
1614 # else
1615 # define MAX_ROOM_NEEDED max_room_needed
1616 # endif
1618 /* Returns the number of TCHAR_T units needed as temporary space for the result
1619 of sprintf or SNPRINTF of a single conversion directive. */
1620 static size_t
1621 MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
1622 arg_type type, int flags, size_t width, int has_precision,
1623 size_t precision, int pad_ourselves)
1625 size_t tmp_length;
1627 switch (conversion)
1629 case 'd': case 'i': case 'u':
1630 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1631 tmp_length =
1632 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1633 * 0.30103 /* binary -> decimal */
1635 + 1; /* turn floor into ceil */
1636 else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1637 tmp_length =
1638 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1639 * 0.30103 /* binary -> decimal */
1641 + 1; /* turn floor into ceil */
1642 else
1643 tmp_length =
1644 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1645 * 0.30103 /* binary -> decimal */
1647 + 1; /* turn floor into ceil */
1648 if (tmp_length < precision)
1649 tmp_length = precision;
1650 /* Multiply by 2, as an estimate for FLAG_GROUP. */
1651 tmp_length = xsum (tmp_length, tmp_length);
1652 /* Add 1, to account for a leading sign. */
1653 tmp_length = xsum (tmp_length, 1);
1654 break;
1656 case 'o':
1657 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1658 tmp_length =
1659 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1660 * 0.333334 /* binary -> octal */
1662 + 1; /* turn floor into ceil */
1663 else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1664 tmp_length =
1665 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1666 * 0.333334 /* binary -> octal */
1668 + 1; /* turn floor into ceil */
1669 else
1670 tmp_length =
1671 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1672 * 0.333334 /* binary -> octal */
1674 + 1; /* turn floor into ceil */
1675 if (tmp_length < precision)
1676 tmp_length = precision;
1677 /* Add 1, to account for a leading sign. */
1678 tmp_length = xsum (tmp_length, 1);
1679 break;
1681 case 'x': case 'X':
1682 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
1683 tmp_length =
1684 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
1685 * 0.25 /* binary -> hexadecimal */
1687 + 1; /* turn floor into ceil */
1688 else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
1689 tmp_length =
1690 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
1691 * 0.25 /* binary -> hexadecimal */
1693 + 1; /* turn floor into ceil */
1694 else
1695 tmp_length =
1696 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
1697 * 0.25 /* binary -> hexadecimal */
1699 + 1; /* turn floor into ceil */
1700 if (tmp_length < precision)
1701 tmp_length = precision;
1702 /* Add 2, to account for a leading sign or alternate form. */
1703 tmp_length = xsum (tmp_length, 2);
1704 break;
1706 case 'f': case 'F':
1707 if (type == TYPE_LONGDOUBLE)
1708 tmp_length =
1709 (unsigned int) (LDBL_MAX_EXP
1710 * 0.30103 /* binary -> decimal */
1711 * 2 /* estimate for FLAG_GROUP */
1713 + 1 /* turn floor into ceil */
1714 + 10; /* sign, decimal point etc. */
1715 else
1716 tmp_length =
1717 (unsigned int) (DBL_MAX_EXP
1718 * 0.30103 /* binary -> decimal */
1719 * 2 /* estimate for FLAG_GROUP */
1721 + 1 /* turn floor into ceil */
1722 + 10; /* sign, decimal point etc. */
1723 tmp_length = xsum (tmp_length, precision);
1724 break;
1726 case 'e': case 'E': case 'g': case 'G':
1727 tmp_length =
1728 12; /* sign, decimal point, exponent etc. */
1729 tmp_length = xsum (tmp_length, precision);
1730 break;
1732 case 'a': case 'A':
1733 if (type == TYPE_LONGDOUBLE)
1734 tmp_length =
1735 (unsigned int) (LDBL_DIG
1736 * 0.831 /* decimal -> hexadecimal */
1738 + 1; /* turn floor into ceil */
1739 else
1740 tmp_length =
1741 (unsigned int) (DBL_DIG
1742 * 0.831 /* decimal -> hexadecimal */
1744 + 1; /* turn floor into ceil */
1745 if (tmp_length < precision)
1746 tmp_length = precision;
1747 /* Account for sign, decimal point etc. */
1748 tmp_length = xsum (tmp_length, 12);
1749 break;
1751 case 'c':
1752 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
1753 if (type == TYPE_WIDE_CHAR)
1755 tmp_length = MB_CUR_MAX;
1756 # if ENABLE_WCHAR_FALLBACK
1757 if (tmp_length < (sizeof (wchar_t) > 2 ? 10 : 6))
1758 tmp_length = (sizeof (wchar_t) > 2 ? 10 : 6);
1759 # endif
1761 else
1762 # endif
1763 tmp_length = 1;
1764 break;
1766 case 's':
1767 # if HAVE_WCHAR_T
1768 if (type == TYPE_WIDE_STRING)
1770 # if WIDE_CHAR_VERSION
1771 /* ISO C says about %ls in fwprintf:
1772 "If the precision is not specified or is greater than the size
1773 of the array, the array shall contain a null wide character."
1774 So if there is a precision, we must not use wcslen. */
1775 const wchar_t *arg = ap->arg[arg_index].a.a_wide_string;
1777 if (has_precision)
1778 tmp_length = local_wcsnlen (arg, precision);
1779 else
1780 tmp_length = local_wcslen (arg);
1781 # else
1782 /* ISO C says about %ls in fprintf:
1783 "If a precision is specified, no more than that many bytes are
1784 written (including shift sequences, if any), and the array
1785 shall contain a null wide character if, to equal the multibyte
1786 character sequence length given by the precision, the function
1787 would need to access a wide character one past the end of the
1788 array."
1789 So if there is a precision, we must not use wcslen. */
1790 /* This case has already been handled separately in VASNPRINTF. */
1791 abort ();
1792 # endif
1794 else
1795 # endif
1797 # if WIDE_CHAR_VERSION
1798 /* ISO C says about %s in fwprintf:
1799 "If the precision is not specified or is greater than the size
1800 of the converted array, the converted array shall contain a
1801 null wide character."
1802 So if there is a precision, we must not use strlen. */
1803 /* This case has already been handled separately in VASNPRINTF. */
1804 abort ();
1805 # else
1806 /* ISO C says about %s in fprintf:
1807 "If the precision is not specified or greater than the size of
1808 the array, the array shall contain a null character."
1809 So if there is a precision, we must not use strlen. */
1810 const char *arg = ap->arg[arg_index].a.a_string;
1812 if (has_precision)
1813 tmp_length = local_strnlen (arg, precision);
1814 else
1815 tmp_length = strlen (arg);
1816 # endif
1818 break;
1820 case 'p':
1821 tmp_length =
1822 (unsigned int) (sizeof (void *) * CHAR_BIT
1823 * 0.25 /* binary -> hexadecimal */
1825 + 1 /* turn floor into ceil */
1826 + 2; /* account for leading 0x */
1827 break;
1829 default:
1830 abort ();
1833 if (!pad_ourselves)
1835 # if ENABLE_UNISTDIO
1836 /* Padding considers the number of characters, therefore the number of
1837 elements after padding may be
1838 > max (tmp_length, width)
1839 but is certainly
1840 <= tmp_length + width. */
1841 tmp_length = xsum (tmp_length, width);
1842 # else
1843 /* Padding considers the number of elements, says POSIX. */
1844 if (tmp_length < width)
1845 tmp_length = width;
1846 # endif
1849 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1851 return tmp_length;
1854 #endif
1856 DCHAR_T *
1857 VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
1858 const FCHAR_T *format, va_list args)
1860 DIRECTIVES d;
1861 arguments a;
1863 if (PRINTF_PARSE (format, &d, &a) < 0)
1864 /* errno is already set. */
1865 return NULL;
1867 /* Frees the memory allocated by this function. Preserves errno. */
1868 #define CLEANUP() \
1869 if (d.dir != d.direct_alloc_dir) \
1870 free (d.dir); \
1871 if (a.arg != a.direct_alloc_arg) \
1872 free (a.arg);
1874 if (PRINTF_FETCHARGS (args, &a) < 0)
1875 goto fail_1_with_EINVAL;
1878 size_t buf_neededlength;
1879 TCHAR_T *buf;
1880 TCHAR_T *buf_malloced;
1881 const FCHAR_T *cp;
1882 size_t i;
1883 DIRECTIVE *dp;
1884 /* Output string accumulator. */
1885 DCHAR_T *result;
1886 size_t allocated;
1887 size_t length;
1889 /* Allocate a small buffer that will hold a directive passed to
1890 sprintf or snprintf. */
1891 buf_neededlength =
1892 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1893 #if HAVE_ALLOCA
1894 if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1896 buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1897 buf_malloced = NULL;
1899 else
1900 #endif
1902 size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1903 if (size_overflow_p (buf_memsize))
1904 goto out_of_memory_1;
1905 buf = (TCHAR_T *) malloc (buf_memsize);
1906 if (buf == NULL)
1907 goto out_of_memory_1;
1908 buf_malloced = buf;
1911 result = resultbuf;
1912 allocated = (resultbuf != NULL ? *lengthp : 0);
1913 length = 0;
1914 /* Invariants:
1915 result is either == resultbuf or malloc-allocated.
1916 If result == NULL, resultbuf is == NULL as well.
1917 If length > 0, then result != NULL. */
1919 /* Ensures that allocated >= needed. Aborts through a jump to
1920 out_of_memory if needed is SIZE_MAX or otherwise too big. */
1921 #define ENSURE_ALLOCATION_ELSE(needed, oom_statement) \
1922 if ((needed) > allocated) \
1924 size_t memory_size; \
1925 DCHAR_T *memory; \
1927 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
1928 if ((needed) > allocated) \
1929 allocated = (needed); \
1930 memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
1931 if (size_overflow_p (memory_size)) \
1932 oom_statement \
1933 if (result == resultbuf) \
1934 memory = (DCHAR_T *) malloc (memory_size); \
1935 else \
1936 memory = (DCHAR_T *) realloc (result, memory_size); \
1937 if (memory == NULL) \
1938 oom_statement \
1939 if (result == resultbuf && length > 0) \
1940 DCHAR_CPY (memory, result, length); \
1941 result = memory; \
1943 #define ENSURE_ALLOCATION(needed) \
1944 ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; )
1946 for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
1948 if (cp != dp->dir_start)
1950 size_t n = dp->dir_start - cp;
1951 size_t augmented_length = xsum (length, n);
1953 ENSURE_ALLOCATION (augmented_length);
1954 /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we
1955 need that the format string contains only ASCII characters
1956 if FCHAR_T and DCHAR_T are not the same type. */
1957 if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1959 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1960 length = augmented_length;
1962 else
1965 result[length++] = *cp++;
1966 while (--n > 0);
1969 if (i == d.count)
1970 break;
1972 /* Execute a single directive. */
1973 if (dp->conversion == '%')
1975 size_t augmented_length;
1977 if (!(dp->arg_index == ARG_NONE))
1978 abort ();
1979 augmented_length = xsum (length, 1);
1980 ENSURE_ALLOCATION (augmented_length);
1981 result[length] = '%';
1982 length = augmented_length;
1984 else
1986 if (!(dp->arg_index != ARG_NONE))
1987 abort ();
1989 if (dp->conversion == 'n')
1991 switch (a.arg[dp->arg_index].type)
1993 case TYPE_COUNT_SCHAR_POINTER:
1994 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1995 break;
1996 case TYPE_COUNT_SHORT_POINTER:
1997 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1998 break;
1999 case TYPE_COUNT_INT_POINTER:
2000 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
2001 break;
2002 case TYPE_COUNT_LONGINT_POINTER:
2003 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
2004 break;
2005 case TYPE_COUNT_LONGLONGINT_POINTER:
2006 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
2007 break;
2008 default:
2009 abort ();
2012 #if ENABLE_UNISTDIO
2013 /* The unistdio extensions. */
2014 else if (dp->conversion == 'U')
2016 arg_type type = a.arg[dp->arg_index].type;
2017 int flags = dp->flags;
2018 int has_width;
2019 size_t width;
2020 int has_precision;
2021 size_t precision;
2023 has_width = 0;
2024 width = 0;
2025 if (dp->width_start != dp->width_end)
2027 if (dp->width_arg_index != ARG_NONE)
2029 int arg;
2031 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2032 abort ();
2033 arg = a.arg[dp->width_arg_index].a.a_int;
2034 width = arg;
2035 if (arg < 0)
2037 /* "A negative field width is taken as a '-' flag
2038 followed by a positive field width." */
2039 flags |= FLAG_LEFT;
2040 width = -width;
2043 else
2045 const FCHAR_T *digitp = dp->width_start;
2048 width = xsum (xtimes (width, 10), *digitp++ - '0');
2049 while (digitp != dp->width_end);
2051 has_width = 1;
2054 has_precision = 0;
2055 precision = 0;
2056 if (dp->precision_start != dp->precision_end)
2058 if (dp->precision_arg_index != ARG_NONE)
2060 int arg;
2062 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2063 abort ();
2064 arg = a.arg[dp->precision_arg_index].a.a_int;
2065 /* "A negative precision is taken as if the precision
2066 were omitted." */
2067 if (arg >= 0)
2069 precision = arg;
2070 has_precision = 1;
2073 else
2075 const FCHAR_T *digitp = dp->precision_start + 1;
2077 precision = 0;
2078 while (digitp != dp->precision_end)
2079 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2080 has_precision = 1;
2084 switch (type)
2086 case TYPE_U8_STRING:
2088 const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
2089 const uint8_t *arg_end;
2090 size_t characters;
2092 if (has_precision)
2094 /* Use only PRECISION characters, from the left. */
2095 arg_end = arg;
2096 characters = 0;
2097 for (; precision > 0; precision--)
2099 int count = u8_strmblen (arg_end);
2100 if (count == 0)
2101 break;
2102 if (count < 0)
2103 goto fail_with_EILSEQ;
2104 arg_end += count;
2105 characters++;
2108 else if (has_width)
2110 /* Use the entire string, and count the number of
2111 characters. */
2112 arg_end = arg;
2113 characters = 0;
2114 for (;;)
2116 int count = u8_strmblen (arg_end);
2117 if (count == 0)
2118 break;
2119 if (count < 0)
2120 goto fail_with_EILSEQ;
2121 arg_end += count;
2122 characters++;
2125 else
2127 /* Use the entire string. */
2128 arg_end = arg + u8_strlen (arg);
2129 /* The number of characters doesn't matter. */
2130 characters = 0;
2133 if (characters < width && !(dp->flags & FLAG_LEFT))
2135 size_t n = width - characters;
2136 ENSURE_ALLOCATION (xsum (length, n));
2137 DCHAR_SET (result + length, ' ', n);
2138 length += n;
2141 # if DCHAR_IS_UINT8_T
2143 size_t n = arg_end - arg;
2144 ENSURE_ALLOCATION (xsum (length, n));
2145 DCHAR_CPY (result + length, arg, n);
2146 length += n;
2148 # else
2149 { /* Convert. */
2150 DCHAR_T *converted = result + length;
2151 size_t converted_len = allocated - length;
2152 # if DCHAR_IS_TCHAR
2153 /* Convert from UTF-8 to locale encoding. */
2154 converted =
2155 u8_conv_to_encoding (locale_charset (),
2156 iconveh_question_mark,
2157 arg, arg_end - arg, NULL,
2158 converted, &converted_len);
2159 # else
2160 /* Convert from UTF-8 to UTF-16/UTF-32. */
2161 converted =
2162 U8_TO_DCHAR (arg, arg_end - arg,
2163 converted, &converted_len);
2164 # endif
2165 if (converted == NULL)
2166 goto fail_with_errno;
2167 if (converted != result + length)
2169 ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
2170 { free (converted); goto out_of_memory; });
2171 DCHAR_CPY (result + length, converted, converted_len);
2172 free (converted);
2174 length += converted_len;
2176 # endif
2178 if (characters < width && (dp->flags & FLAG_LEFT))
2180 size_t n = width - characters;
2181 ENSURE_ALLOCATION (xsum (length, n));
2182 DCHAR_SET (result + length, ' ', n);
2183 length += n;
2186 break;
2188 case TYPE_U16_STRING:
2190 const uint16_t *arg = a.arg[dp->arg_index].a.a_u16_string;
2191 const uint16_t *arg_end;
2192 size_t characters;
2194 if (has_precision)
2196 /* Use only PRECISION characters, from the left. */
2197 arg_end = arg;
2198 characters = 0;
2199 for (; precision > 0; precision--)
2201 int count = u16_strmblen (arg_end);
2202 if (count == 0)
2203 break;
2204 if (count < 0)
2205 goto fail_with_EILSEQ;
2206 arg_end += count;
2207 characters++;
2210 else if (has_width)
2212 /* Use the entire string, and count the number of
2213 characters. */
2214 arg_end = arg;
2215 characters = 0;
2216 for (;;)
2218 int count = u16_strmblen (arg_end);
2219 if (count == 0)
2220 break;
2221 if (count < 0)
2222 goto fail_with_EILSEQ;
2223 arg_end += count;
2224 characters++;
2227 else
2229 /* Use the entire string. */
2230 arg_end = arg + u16_strlen (arg);
2231 /* The number of characters doesn't matter. */
2232 characters = 0;
2235 if (characters < width && !(dp->flags & FLAG_LEFT))
2237 size_t n = width - characters;
2238 ENSURE_ALLOCATION (xsum (length, n));
2239 DCHAR_SET (result + length, ' ', n);
2240 length += n;
2243 # if DCHAR_IS_UINT16_T
2245 size_t n = arg_end - arg;
2246 ENSURE_ALLOCATION (xsum (length, n));
2247 DCHAR_CPY (result + length, arg, n);
2248 length += n;
2250 # else
2251 { /* Convert. */
2252 DCHAR_T *converted = result + length;
2253 size_t converted_len = allocated - length;
2254 # if DCHAR_IS_TCHAR
2255 /* Convert from UTF-16 to locale encoding. */
2256 converted =
2257 u16_conv_to_encoding (locale_charset (),
2258 iconveh_question_mark,
2259 arg, arg_end - arg, NULL,
2260 converted, &converted_len);
2261 # else
2262 /* Convert from UTF-16 to UTF-8/UTF-32. */
2263 converted =
2264 U16_TO_DCHAR (arg, arg_end - arg,
2265 converted, &converted_len);
2266 # endif
2267 if (converted == NULL)
2268 goto fail_with_errno;
2269 if (converted != result + length)
2271 ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
2272 { free (converted); goto out_of_memory; });
2273 DCHAR_CPY (result + length, converted, converted_len);
2274 free (converted);
2276 length += converted_len;
2278 # endif
2280 if (characters < width && (dp->flags & FLAG_LEFT))
2282 size_t n = width - characters;
2283 ENSURE_ALLOCATION (xsum (length, n));
2284 DCHAR_SET (result + length, ' ', n);
2285 length += n;
2288 break;
2290 case TYPE_U32_STRING:
2292 const uint32_t *arg = a.arg[dp->arg_index].a.a_u32_string;
2293 const uint32_t *arg_end;
2294 size_t characters;
2296 if (has_precision)
2298 /* Use only PRECISION characters, from the left. */
2299 arg_end = arg;
2300 characters = 0;
2301 for (; precision > 0; precision--)
2303 int count = u32_strmblen (arg_end);
2304 if (count == 0)
2305 break;
2306 if (count < 0)
2307 goto fail_with_EILSEQ;
2308 arg_end += count;
2309 characters++;
2312 else if (has_width)
2314 /* Use the entire string, and count the number of
2315 characters. */
2316 arg_end = arg;
2317 characters = 0;
2318 for (;;)
2320 int count = u32_strmblen (arg_end);
2321 if (count == 0)
2322 break;
2323 if (count < 0)
2324 goto fail_with_EILSEQ;
2325 arg_end += count;
2326 characters++;
2329 else
2331 /* Use the entire string. */
2332 arg_end = arg + u32_strlen (arg);
2333 /* The number of characters doesn't matter. */
2334 characters = 0;
2337 if (characters < width && !(dp->flags & FLAG_LEFT))
2339 size_t n = width - characters;
2340 ENSURE_ALLOCATION (xsum (length, n));
2341 DCHAR_SET (result + length, ' ', n);
2342 length += n;
2345 # if DCHAR_IS_UINT32_T
2347 size_t n = arg_end - arg;
2348 ENSURE_ALLOCATION (xsum (length, n));
2349 DCHAR_CPY (result + length, arg, n);
2350 length += n;
2352 # else
2353 { /* Convert. */
2354 DCHAR_T *converted = result + length;
2355 size_t converted_len = allocated - length;
2356 # if DCHAR_IS_TCHAR
2357 /* Convert from UTF-32 to locale encoding. */
2358 converted =
2359 u32_conv_to_encoding (locale_charset (),
2360 iconveh_question_mark,
2361 arg, arg_end - arg, NULL,
2362 converted, &converted_len);
2363 # else
2364 /* Convert from UTF-32 to UTF-8/UTF-16. */
2365 converted =
2366 U32_TO_DCHAR (arg, arg_end - arg,
2367 converted, &converted_len);
2368 # endif
2369 if (converted == NULL)
2370 goto fail_with_errno;
2371 if (converted != result + length)
2373 ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
2374 { free (converted); goto out_of_memory; });
2375 DCHAR_CPY (result + length, converted, converted_len);
2376 free (converted);
2378 length += converted_len;
2380 # endif
2382 if (characters < width && (dp->flags & FLAG_LEFT))
2384 size_t n = width - characters;
2385 ENSURE_ALLOCATION (xsum (length, n));
2386 DCHAR_SET (result + length, ' ', n);
2387 length += n;
2390 break;
2392 default:
2393 abort ();
2396 #endif
2397 #if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T
2398 else if (dp->conversion == 's'
2399 # if WIDE_CHAR_VERSION
2400 && a.arg[dp->arg_index].type != TYPE_WIDE_STRING
2401 # else
2402 && a.arg[dp->arg_index].type == TYPE_WIDE_STRING
2403 # endif
2406 /* The normal handling of the 's' directive below requires
2407 allocating a temporary buffer. The determination of its
2408 length (tmp_length), in the case when a precision is
2409 specified, below requires a conversion between a char[]
2410 string and a wchar_t[] wide string. It could be done, but
2411 we have no guarantee that the implementation of sprintf will
2412 use the exactly same algorithm. Without this guarantee, it
2413 is possible to have buffer overrun bugs. In order to avoid
2414 such bugs, we implement the entire processing of the 's'
2415 directive ourselves. */
2416 int flags = dp->flags;
2417 int has_width;
2418 size_t width;
2419 int has_precision;
2420 size_t precision;
2422 has_width = 0;
2423 width = 0;
2424 if (dp->width_start != dp->width_end)
2426 if (dp->width_arg_index != ARG_NONE)
2428 int arg;
2430 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2431 abort ();
2432 arg = a.arg[dp->width_arg_index].a.a_int;
2433 width = arg;
2434 if (arg < 0)
2436 /* "A negative field width is taken as a '-' flag
2437 followed by a positive field width." */
2438 flags |= FLAG_LEFT;
2439 width = -width;
2442 else
2444 const FCHAR_T *digitp = dp->width_start;
2447 width = xsum (xtimes (width, 10), *digitp++ - '0');
2448 while (digitp != dp->width_end);
2450 has_width = 1;
2453 has_precision = 0;
2454 precision = 6;
2455 if (dp->precision_start != dp->precision_end)
2457 if (dp->precision_arg_index != ARG_NONE)
2459 int arg;
2461 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
2462 abort ();
2463 arg = a.arg[dp->precision_arg_index].a.a_int;
2464 /* "A negative precision is taken as if the precision
2465 were omitted." */
2466 if (arg >= 0)
2468 precision = arg;
2469 has_precision = 1;
2472 else
2474 const FCHAR_T *digitp = dp->precision_start + 1;
2476 precision = 0;
2477 while (digitp != dp->precision_end)
2478 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
2479 has_precision = 1;
2483 # if WIDE_CHAR_VERSION
2484 /* %s in vasnwprintf. See the specification of fwprintf. */
2486 const char *arg = a.arg[dp->arg_index].a.a_string;
2487 const char *arg_end;
2488 size_t characters;
2490 if (has_precision)
2492 /* Use only as many bytes as needed to produce PRECISION
2493 wide characters, from the left. */
2494 # if HAVE_MBRTOWC
2495 mbstate_t state;
2496 memset (&state, '\0', sizeof (mbstate_t));
2497 # endif
2498 arg_end = arg;
2499 characters = 0;
2500 for (; precision > 0; precision--)
2502 int count;
2503 # if HAVE_MBRTOWC
2504 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2505 # else
2506 count = mblen (arg_end, MB_CUR_MAX);
2507 # endif
2508 if (count == 0)
2509 /* Found the terminating NUL. */
2510 break;
2511 if (count < 0)
2512 /* Invalid or incomplete multibyte character. */
2513 goto fail_with_EILSEQ;
2514 arg_end += count;
2515 characters++;
2518 else if (has_width)
2520 /* Use the entire string, and count the number of wide
2521 characters. */
2522 # if HAVE_MBRTOWC
2523 mbstate_t state;
2524 memset (&state, '\0', sizeof (mbstate_t));
2525 # endif
2526 arg_end = arg;
2527 characters = 0;
2528 for (;;)
2530 int count;
2531 # if HAVE_MBRTOWC
2532 count = mbrlen (arg_end, MB_CUR_MAX, &state);
2533 # else
2534 count = mblen (arg_end, MB_CUR_MAX);
2535 # endif
2536 if (count == 0)
2537 /* Found the terminating NUL. */
2538 break;
2539 if (count < 0)
2540 /* Invalid or incomplete multibyte character. */
2541 goto fail_with_EILSEQ;
2542 arg_end += count;
2543 characters++;
2546 else
2548 /* Use the entire string. */
2549 arg_end = arg + strlen (arg);
2550 /* The number of characters doesn't matter. */
2551 characters = 0;
2554 if (characters < width && !(dp->flags & FLAG_LEFT))
2556 size_t n = width - characters;
2557 ENSURE_ALLOCATION (xsum (length, n));
2558 DCHAR_SET (result + length, ' ', n);
2559 length += n;
2562 if (has_precision || has_width)
2564 /* We know the number of wide characters in advance. */
2565 size_t remaining;
2566 # if HAVE_MBRTOWC
2567 mbstate_t state;
2568 memset (&state, '\0', sizeof (mbstate_t));
2569 # endif
2570 ENSURE_ALLOCATION (xsum (length, characters));
2571 for (remaining = characters; remaining > 0; remaining--)
2573 wchar_t wc;
2574 int count;
2575 # if HAVE_MBRTOWC
2576 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2577 # else
2578 count = mbtowc (&wc, arg, arg_end - arg);
2579 # endif
2580 if (count <= 0)
2581 /* mbrtowc not consistent with mbrlen, or mbtowc
2582 not consistent with mblen. */
2583 abort ();
2584 result[length++] = wc;
2585 arg += count;
2587 if (!(arg == arg_end))
2588 abort ();
2590 else
2592 # if HAVE_MBRTOWC
2593 mbstate_t state;
2594 memset (&state, '\0', sizeof (mbstate_t));
2595 # endif
2596 while (arg < arg_end)
2598 wchar_t wc;
2599 int count;
2600 # if HAVE_MBRTOWC
2601 count = mbrtowc (&wc, arg, arg_end - arg, &state);
2602 # else
2603 count = mbtowc (&wc, arg, arg_end - arg);
2604 # endif
2605 if (count <= 0)
2606 /* mbrtowc not consistent with mbrlen, or mbtowc
2607 not consistent with mblen. */
2608 abort ();
2609 ENSURE_ALLOCATION (xsum (length, 1));
2610 result[length++] = wc;
2611 arg += count;
2615 if (characters < width && (dp->flags & FLAG_LEFT))
2617 size_t n = width - characters;
2618 ENSURE_ALLOCATION (xsum (length, n));
2619 DCHAR_SET (result + length, ' ', n);
2620 length += n;
2623 # else
2624 /* %ls in vasnprintf. See the specification of fprintf. */
2626 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
2627 const wchar_t *arg_end;
2628 size_t characters;
2629 # if !DCHAR_IS_TCHAR
2630 /* This code assumes that TCHAR_T is 'char'. */
2631 static_assert (sizeof (TCHAR_T) == 1);
2632 TCHAR_T *tmpsrc;
2633 DCHAR_T *tmpdst;
2634 size_t tmpdst_len;
2635 # endif
2636 size_t w;
2638 if (has_precision)
2640 /* Use only as many wide characters as needed to produce
2641 at most PRECISION bytes, from the left. */
2642 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2643 mbstate_t state;
2644 memset (&state, '\0', sizeof (mbstate_t));
2645 # endif
2646 arg_end = arg;
2647 characters = 0;
2648 while (precision > 0)
2650 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2651 int count;
2653 if (*arg_end == 0)
2654 /* Found the terminating null wide character. */
2655 break;
2656 count = local_wcrtomb (cbuf, *arg_end, &state);
2657 if (count < 0)
2658 /* Cannot convert. */
2659 goto fail_with_EILSEQ;
2660 if (precision < (unsigned int) count)
2661 break;
2662 arg_end++;
2663 characters += count;
2664 precision -= count;
2667 # if DCHAR_IS_TCHAR
2668 else if (has_width)
2669 # else
2670 else
2671 # endif
2673 /* Use the entire string, and count the number of
2674 bytes. */
2675 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2676 mbstate_t state;
2677 memset (&state, '\0', sizeof (mbstate_t));
2678 # endif
2679 arg_end = arg;
2680 characters = 0;
2681 for (;;)
2683 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2684 int count;
2686 if (*arg_end == 0)
2687 /* Found the terminating null wide character. */
2688 break;
2689 count = local_wcrtomb (cbuf, *arg_end, &state);
2690 if (count < 0)
2691 /* Cannot convert. */
2692 goto fail_with_EILSEQ;
2693 arg_end++;
2694 characters += count;
2697 # if DCHAR_IS_TCHAR
2698 else
2700 /* Use the entire string. */
2701 arg_end = arg + local_wcslen (arg);
2702 /* The number of bytes doesn't matter. */
2703 characters = 0;
2705 # endif
2707 # if !DCHAR_IS_TCHAR
2708 /* Convert the string into a piece of temporary memory. */
2709 tmpsrc = (TCHAR_T *) malloc (characters * sizeof (TCHAR_T));
2710 if (tmpsrc == NULL)
2711 goto out_of_memory;
2713 TCHAR_T *tmpptr = tmpsrc;
2714 size_t remaining;
2715 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2716 mbstate_t state;
2717 memset (&state, '\0', sizeof (mbstate_t));
2718 # endif
2719 for (remaining = characters; remaining > 0; )
2721 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2722 int count;
2724 if (*arg == 0)
2725 abort ();
2726 count = local_wcrtomb (cbuf, *arg, &state);
2727 if (count <= 0)
2728 /* Inconsistency. */
2729 abort ();
2730 memcpy (tmpptr, cbuf, count);
2731 tmpptr += count;
2732 arg++;
2733 remaining -= count;
2735 if (!(arg == arg_end))
2736 abort ();
2739 /* Convert from TCHAR_T[] to DCHAR_T[]. */
2740 tmpdst =
2741 DCHAR_CONV_FROM_ENCODING (locale_charset (),
2742 iconveh_question_mark,
2743 tmpsrc, characters,
2744 NULL,
2745 NULL, &tmpdst_len);
2746 if (tmpdst == NULL)
2748 free (tmpsrc);
2749 goto fail_with_errno;
2751 free (tmpsrc);
2752 # endif
2754 if (has_width)
2756 # if ENABLE_UNISTDIO
2757 /* Outside POSIX, it's preferable to compare the width
2758 against the number of _characters_ of the converted
2759 value. */
2760 w = DCHAR_MBSNLEN (result + length, characters);
2761 # else
2762 /* The width is compared against the number of _bytes_
2763 of the converted value, says POSIX. */
2764 w = characters;
2765 # endif
2767 else
2768 /* w doesn't matter. */
2769 w = 0;
2771 if (w < width && !(dp->flags & FLAG_LEFT))
2773 size_t n = width - w;
2774 ENSURE_ALLOCATION (xsum (length, n));
2775 DCHAR_SET (result + length, ' ', n);
2776 length += n;
2779 # if DCHAR_IS_TCHAR
2780 if (has_precision || has_width)
2782 /* We know the number of bytes in advance. */
2783 size_t remaining;
2784 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2785 mbstate_t state;
2786 memset (&state, '\0', sizeof (mbstate_t));
2787 # endif
2788 ENSURE_ALLOCATION (xsum (length, characters));
2789 for (remaining = characters; remaining > 0; )
2791 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2792 int count;
2794 if (*arg == 0)
2795 abort ();
2796 count = local_wcrtomb (cbuf, *arg, &state);
2797 if (count <= 0)
2798 /* Inconsistency. */
2799 abort ();
2800 memcpy (result + length, cbuf, count);
2801 length += count;
2802 arg++;
2803 remaining -= count;
2805 if (!(arg == arg_end))
2806 abort ();
2808 else
2810 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2811 mbstate_t state;
2812 memset (&state, '\0', sizeof (mbstate_t));
2813 # endif
2814 while (arg < arg_end)
2816 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2817 int count;
2819 if (*arg == 0)
2820 abort ();
2821 count = local_wcrtomb (cbuf, *arg, &state);
2822 if (count <= 0)
2823 /* Cannot convert. */
2824 goto fail_with_EILSEQ;
2825 ENSURE_ALLOCATION (xsum (length, count));
2826 memcpy (result + length, cbuf, count);
2827 length += count;
2828 arg++;
2831 # else
2832 ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
2833 { free (tmpdst); goto out_of_memory; });
2834 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
2835 free (tmpdst);
2836 length += tmpdst_len;
2837 # endif
2839 if (w < width && (dp->flags & FLAG_LEFT))
2841 size_t n = width - w;
2842 ENSURE_ALLOCATION (xsum (length, n));
2843 DCHAR_SET (result + length, ' ', n);
2844 length += n;
2847 # endif
2849 #endif
2850 #if ENABLE_WCHAR_FALLBACK && HAVE_WINT_T && !WIDE_CHAR_VERSION
2851 else if (dp->conversion == 'c'
2852 && a.arg[dp->arg_index].type == TYPE_WIDE_CHAR)
2854 /* Implement the 'lc' directive ourselves, in order to provide
2855 the fallback that avoids EILSEQ. */
2856 int flags = dp->flags;
2857 int has_width;
2858 size_t width;
2860 has_width = 0;
2861 width = 0;
2862 if (dp->width_start != dp->width_end)
2864 if (dp->width_arg_index != ARG_NONE)
2866 int arg;
2868 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2869 abort ();
2870 arg = a.arg[dp->width_arg_index].a.a_int;
2871 width = arg;
2872 if (arg < 0)
2874 /* "A negative field width is taken as a '-' flag
2875 followed by a positive field width." */
2876 flags |= FLAG_LEFT;
2877 width = -width;
2880 else
2882 const FCHAR_T *digitp = dp->width_start;
2885 width = xsum (xtimes (width, 10), *digitp++ - '0');
2886 while (digitp != dp->width_end);
2888 has_width = 1;
2891 /* %lc in vasnprintf. See the specification of fprintf. */
2893 wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
2894 size_t characters;
2895 # if !DCHAR_IS_TCHAR
2896 /* This code assumes that TCHAR_T is 'char'. */
2897 static_assert (sizeof (TCHAR_T) == 1);
2898 TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64. */
2899 DCHAR_T *tmpdst;
2900 size_t tmpdst_len;
2901 # endif
2902 size_t w;
2904 # if DCHAR_IS_TCHAR
2905 if (has_width)
2906 # endif
2908 /* Count the number of bytes. */
2909 characters = 0;
2910 if (arg != 0)
2912 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2913 int count;
2914 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2915 mbstate_t state;
2916 memset (&state, '\0', sizeof (mbstate_t));
2917 # endif
2919 count = local_wcrtomb (cbuf, arg, &state);
2920 if (count < 0)
2921 /* Inconsistency. */
2922 abort ();
2923 characters = count;
2926 # if DCHAR_IS_TCHAR
2927 else
2929 /* The number of bytes doesn't matter. */
2930 characters = 0;
2932 # endif
2934 # if !DCHAR_IS_TCHAR
2935 /* Convert the string into a piece of temporary memory. */
2936 if (characters > 0) /* implies arg != 0 */
2938 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
2939 int count;
2940 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2941 mbstate_t state;
2942 memset (&state, '\0', sizeof (mbstate_t));
2943 # endif
2945 count = local_wcrtomb (cbuf, arg, &state);
2946 if (count <= 0)
2947 /* Inconsistency. */
2948 abort ();
2949 memcpy (tmpsrc, cbuf, count);
2952 /* Convert from TCHAR_T[] to DCHAR_T[]. */
2953 tmpdst =
2954 DCHAR_CONV_FROM_ENCODING (locale_charset (),
2955 iconveh_question_mark,
2956 tmpsrc, characters,
2957 NULL,
2958 NULL, &tmpdst_len);
2959 if (tmpdst == NULL)
2960 goto fail_with_errno;
2961 # endif
2963 if (has_width)
2965 # if ENABLE_UNISTDIO
2966 /* Outside POSIX, it's preferable to compare the width
2967 against the number of _characters_ of the converted
2968 value. */
2969 w = DCHAR_MBSNLEN (result + length, characters);
2970 # else
2971 /* The width is compared against the number of _bytes_
2972 of the converted value, says POSIX. */
2973 w = characters;
2974 # endif
2976 else
2977 /* w doesn't matter. */
2978 w = 0;
2980 if (w < width && !(dp->flags & FLAG_LEFT))
2982 size_t n = width - w;
2983 ENSURE_ALLOCATION (xsum (length, n));
2984 DCHAR_SET (result + length, ' ', n);
2985 length += n;
2988 # if DCHAR_IS_TCHAR
2989 if (has_width)
2991 /* We know the number of bytes in advance. */
2992 ENSURE_ALLOCATION (xsum (length, characters));
2993 if (characters > 0) /* implies arg != 0 */
2995 int count;
2996 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
2997 mbstate_t state;
2998 memset (&state, '\0', sizeof (mbstate_t));
2999 # endif
3001 count = local_wcrtomb (result + length, arg, &state);
3002 if (count <= 0)
3003 /* Inconsistency. */
3004 abort ();
3005 length += count;
3008 else
3010 if (arg != 0)
3012 char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
3013 int count;
3014 # if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
3015 mbstate_t state;
3016 memset (&state, '\0', sizeof (mbstate_t));
3017 # endif
3019 count = local_wcrtomb (cbuf, arg, &state);
3020 if (count <= 0)
3021 /* Inconsistency. */
3022 abort ();
3023 ENSURE_ALLOCATION (xsum (length, count));
3024 memcpy (result + length, cbuf, count);
3025 length += count;
3028 # else
3029 ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
3030 { free (tmpdst); goto out_of_memory; });
3031 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
3032 free (tmpdst);
3033 length += tmpdst_len;
3034 # endif
3036 if (w < width && (dp->flags & FLAG_LEFT))
3038 size_t n = width - w;
3039 ENSURE_ALLOCATION (xsum (length, n));
3040 DCHAR_SET (result + length, ' ', n);
3041 length += n;
3045 #endif
3046 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
3047 else if ((dp->conversion == 'a' || dp->conversion == 'A')
3048 # if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
3049 && (0
3050 # if NEED_PRINTF_DOUBLE
3051 || a.arg[dp->arg_index].type == TYPE_DOUBLE
3052 # endif
3053 # if NEED_PRINTF_LONG_DOUBLE
3054 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3055 # endif
3057 # endif
3060 arg_type type = a.arg[dp->arg_index].type;
3061 int flags = dp->flags;
3062 size_t width;
3063 int has_precision;
3064 size_t precision;
3065 size_t tmp_length;
3066 size_t count;
3067 DCHAR_T tmpbuf[700];
3068 DCHAR_T *tmp;
3069 DCHAR_T *pad_ptr;
3070 DCHAR_T *p;
3072 width = 0;
3073 if (dp->width_start != dp->width_end)
3075 if (dp->width_arg_index != ARG_NONE)
3077 int arg;
3079 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3080 abort ();
3081 arg = a.arg[dp->width_arg_index].a.a_int;
3082 width = arg;
3083 if (arg < 0)
3085 /* "A negative field width is taken as a '-' flag
3086 followed by a positive field width." */
3087 flags |= FLAG_LEFT;
3088 width = -width;
3091 else
3093 const FCHAR_T *digitp = dp->width_start;
3096 width = xsum (xtimes (width, 10), *digitp++ - '0');
3097 while (digitp != dp->width_end);
3101 has_precision = 0;
3102 precision = 0;
3103 if (dp->precision_start != dp->precision_end)
3105 if (dp->precision_arg_index != ARG_NONE)
3107 int arg;
3109 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3110 abort ();
3111 arg = a.arg[dp->precision_arg_index].a.a_int;
3112 /* "A negative precision is taken as if the precision
3113 were omitted." */
3114 if (arg >= 0)
3116 precision = arg;
3117 has_precision = 1;
3120 else
3122 const FCHAR_T *digitp = dp->precision_start + 1;
3124 precision = 0;
3125 while (digitp != dp->precision_end)
3126 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3127 has_precision = 1;
3131 /* Allocate a temporary buffer of sufficient size. */
3132 if (type == TYPE_LONGDOUBLE)
3133 tmp_length =
3134 (unsigned int) ((LDBL_DIG + 1)
3135 * 0.831 /* decimal -> hexadecimal */
3137 + 1; /* turn floor into ceil */
3138 else
3139 tmp_length =
3140 (unsigned int) ((DBL_DIG + 1)
3141 * 0.831 /* decimal -> hexadecimal */
3143 + 1; /* turn floor into ceil */
3144 if (tmp_length < precision)
3145 tmp_length = precision;
3146 /* Account for sign, decimal point etc. */
3147 tmp_length = xsum (tmp_length, 12);
3149 if (tmp_length < width)
3150 tmp_length = width;
3152 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3154 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3155 tmp = tmpbuf;
3156 else
3158 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3160 if (size_overflow_p (tmp_memsize))
3161 /* Overflow, would lead to out of memory. */
3162 goto out_of_memory;
3163 tmp = (DCHAR_T *) malloc (tmp_memsize);
3164 if (tmp == NULL)
3165 /* Out of memory. */
3166 goto out_of_memory;
3169 pad_ptr = NULL;
3170 p = tmp;
3171 if (type == TYPE_LONGDOUBLE)
3173 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
3174 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3176 if (isnanl (arg))
3178 if (dp->conversion == 'A')
3180 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3182 else
3184 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3187 else
3189 int sign = 0;
3190 DECL_LONG_DOUBLE_ROUNDING
3192 BEGIN_LONG_DOUBLE_ROUNDING ();
3194 if (signbit (arg)) /* arg < 0.0L or negative zero */
3196 sign = -1;
3197 arg = -arg;
3200 if (sign < 0)
3201 *p++ = '-';
3202 else if (flags & FLAG_SHOWSIGN)
3203 *p++ = '+';
3204 else if (flags & FLAG_SPACE)
3205 *p++ = ' ';
3207 if (arg > 0.0L && arg + arg == arg)
3209 if (dp->conversion == 'A')
3211 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3213 else
3215 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3218 else
3220 int exponent;
3221 long double mantissa;
3223 if (arg > 0.0L)
3224 mantissa = printf_frexpl (arg, &exponent);
3225 else
3227 exponent = 0;
3228 mantissa = 0.0L;
3231 if (has_precision
3232 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
3234 /* Round the mantissa. */
3235 long double tail = mantissa;
3236 size_t q;
3238 for (q = precision; ; q--)
3240 int digit = (int) tail;
3241 tail -= digit;
3242 if (q == 0)
3244 if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
3245 tail = 1 - tail;
3246 else
3247 tail = - tail;
3248 break;
3250 tail *= 16.0L;
3252 if (tail != 0.0L)
3253 for (q = precision; q > 0; q--)
3254 tail *= 0.0625L;
3255 mantissa += tail;
3258 *p++ = '0';
3259 *p++ = dp->conversion - 'A' + 'X';
3260 pad_ptr = p;
3262 int digit;
3264 digit = (int) mantissa;
3265 mantissa -= digit;
3266 *p++ = '0' + digit;
3267 if ((flags & FLAG_ALT)
3268 || mantissa > 0.0L || precision > 0)
3270 *p++ = decimal_point_char ();
3271 /* This loop terminates because we assume
3272 that FLT_RADIX is a power of 2. */
3273 while (mantissa > 0.0L)
3275 mantissa *= 16.0L;
3276 digit = (int) mantissa;
3277 mantissa -= digit;
3278 *p++ = digit
3279 + (digit < 10
3280 ? '0'
3281 : dp->conversion - 10);
3282 if (precision > 0)
3283 precision--;
3285 while (precision > 0)
3287 *p++ = '0';
3288 precision--;
3292 *p++ = dp->conversion - 'A' + 'P';
3293 # if WIDE_CHAR_VERSION
3295 static const wchar_t decimal_format[] =
3296 { '%', '+', 'd', '\0' };
3297 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3299 while (*p != '\0')
3300 p++;
3301 # else
3302 if (sizeof (DCHAR_T) == 1)
3304 sprintf ((char *) p, "%+d", exponent);
3305 while (*p != '\0')
3306 p++;
3308 else
3310 char expbuf[6 + 1];
3311 const char *ep;
3312 sprintf (expbuf, "%+d", exponent);
3313 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3314 p++;
3316 # endif
3319 END_LONG_DOUBLE_ROUNDING ();
3321 # else
3322 abort ();
3323 # endif
3325 else
3327 # if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
3328 double arg = a.arg[dp->arg_index].a.a_double;
3330 if (isnand (arg))
3332 if (dp->conversion == 'A')
3334 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3336 else
3338 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3341 else
3343 int sign = 0;
3345 if (signbit (arg)) /* arg < 0.0 or negative zero */
3347 sign = -1;
3348 arg = -arg;
3351 if (sign < 0)
3352 *p++ = '-';
3353 else if (flags & FLAG_SHOWSIGN)
3354 *p++ = '+';
3355 else if (flags & FLAG_SPACE)
3356 *p++ = ' ';
3358 if (arg > 0.0 && arg + arg == arg)
3360 if (dp->conversion == 'A')
3362 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3364 else
3366 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3369 else
3371 int exponent;
3372 double mantissa;
3374 if (arg > 0.0)
3375 mantissa = printf_frexp (arg, &exponent);
3376 else
3378 exponent = 0;
3379 mantissa = 0.0;
3382 if (has_precision
3383 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
3385 /* Round the mantissa. */
3386 double tail = mantissa;
3387 size_t q;
3389 for (q = precision; ; q--)
3391 int digit = (int) tail;
3392 tail -= digit;
3393 if (q == 0)
3395 if (digit & 1 ? tail >= 0.5 : tail > 0.5)
3396 tail = 1 - tail;
3397 else
3398 tail = - tail;
3399 break;
3401 tail *= 16.0;
3403 if (tail != 0.0)
3404 for (q = precision; q > 0; q--)
3405 tail *= 0.0625;
3406 mantissa += tail;
3409 *p++ = '0';
3410 *p++ = dp->conversion - 'A' + 'X';
3411 pad_ptr = p;
3413 int digit;
3415 digit = (int) mantissa;
3416 mantissa -= digit;
3417 *p++ = '0' + digit;
3418 if ((flags & FLAG_ALT)
3419 || mantissa > 0.0 || precision > 0)
3421 *p++ = decimal_point_char ();
3422 /* This loop terminates because we assume
3423 that FLT_RADIX is a power of 2. */
3424 while (mantissa > 0.0)
3426 mantissa *= 16.0;
3427 digit = (int) mantissa;
3428 mantissa -= digit;
3429 *p++ = digit
3430 + (digit < 10
3431 ? '0'
3432 : dp->conversion - 10);
3433 if (precision > 0)
3434 precision--;
3436 while (precision > 0)
3438 *p++ = '0';
3439 precision--;
3443 *p++ = dp->conversion - 'A' + 'P';
3444 # if WIDE_CHAR_VERSION
3446 static const wchar_t decimal_format[] =
3447 { '%', '+', 'd', '\0' };
3448 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3450 while (*p != '\0')
3451 p++;
3452 # else
3453 if (sizeof (DCHAR_T) == 1)
3455 sprintf ((char *) p, "%+d", exponent);
3456 while (*p != '\0')
3457 p++;
3459 else
3461 char expbuf[6 + 1];
3462 const char *ep;
3463 sprintf (expbuf, "%+d", exponent);
3464 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3465 p++;
3467 # endif
3470 # else
3471 abort ();
3472 # endif
3475 /* The generated string now extends from tmp to p, with the
3476 zero padding insertion point being at pad_ptr. */
3477 count = p - tmp;
3479 if (count < width)
3481 size_t pad = width - count;
3482 DCHAR_T *end = p + pad;
3484 if (flags & FLAG_LEFT)
3486 /* Pad with spaces on the right. */
3487 for (; pad > 0; pad--)
3488 *p++ = ' ';
3490 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3492 /* Pad with zeroes. */
3493 DCHAR_T *q = end;
3495 while (p > pad_ptr)
3496 *--q = *--p;
3497 for (; pad > 0; pad--)
3498 *p++ = '0';
3500 else
3502 /* Pad with spaces on the left. */
3503 DCHAR_T *q = end;
3505 while (p > tmp)
3506 *--q = *--p;
3507 for (; pad > 0; pad--)
3508 *p++ = ' ';
3511 p = end;
3514 count = p - tmp;
3516 if (count >= tmp_length)
3517 /* tmp_length was incorrectly calculated - fix the
3518 code above! */
3519 abort ();
3521 /* Make room for the result. */
3522 if (count >= allocated - length)
3524 size_t n = xsum (length, count);
3526 ENSURE_ALLOCATION (n);
3529 /* Append the result. */
3530 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3531 if (tmp != tmpbuf)
3532 free (tmp);
3533 length += count;
3535 #endif
3536 #if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
3537 else if ((dp->conversion == 'f' || dp->conversion == 'F'
3538 || dp->conversion == 'e' || dp->conversion == 'E'
3539 || dp->conversion == 'g' || dp->conversion == 'G'
3540 || dp->conversion == 'a' || dp->conversion == 'A')
3541 && (0
3542 # if NEED_PRINTF_DOUBLE
3543 || a.arg[dp->arg_index].type == TYPE_DOUBLE
3544 # elif NEED_PRINTF_INFINITE_DOUBLE
3545 || (a.arg[dp->arg_index].type == TYPE_DOUBLE
3546 /* The systems (mingw) which produce wrong output
3547 for Inf, -Inf, and NaN also do so for -0.0.
3548 Therefore we treat this case here as well. */
3549 && is_infinite_or_zero (a.arg[dp->arg_index].a.a_double))
3550 # endif
3551 # if NEED_PRINTF_LONG_DOUBLE
3552 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3553 # elif NEED_PRINTF_INFINITE_LONG_DOUBLE
3554 || (a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
3555 /* Some systems produce wrong output for Inf,
3556 -Inf, and NaN. Some systems in this category
3557 (IRIX 5.3) also do so for -0.0. Therefore we
3558 treat this case here as well. */
3559 && is_infinite_or_zerol (a.arg[dp->arg_index].a.a_longdouble))
3560 # endif
3563 # if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
3564 arg_type type = a.arg[dp->arg_index].type;
3565 # endif
3566 int flags = dp->flags;
3567 size_t width;
3568 size_t count;
3569 int has_precision;
3570 size_t precision;
3571 size_t tmp_length;
3572 DCHAR_T tmpbuf[700];
3573 DCHAR_T *tmp;
3574 DCHAR_T *pad_ptr;
3575 DCHAR_T *p;
3577 width = 0;
3578 if (dp->width_start != dp->width_end)
3580 if (dp->width_arg_index != ARG_NONE)
3582 int arg;
3584 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3585 abort ();
3586 arg = a.arg[dp->width_arg_index].a.a_int;
3587 width = arg;
3588 if (arg < 0)
3590 /* "A negative field width is taken as a '-' flag
3591 followed by a positive field width." */
3592 flags |= FLAG_LEFT;
3593 width = -width;
3596 else
3598 const FCHAR_T *digitp = dp->width_start;
3601 width = xsum (xtimes (width, 10), *digitp++ - '0');
3602 while (digitp != dp->width_end);
3606 has_precision = 0;
3607 precision = 0;
3608 if (dp->precision_start != dp->precision_end)
3610 if (dp->precision_arg_index != ARG_NONE)
3612 int arg;
3614 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
3615 abort ();
3616 arg = a.arg[dp->precision_arg_index].a.a_int;
3617 /* "A negative precision is taken as if the precision
3618 were omitted." */
3619 if (arg >= 0)
3621 precision = arg;
3622 has_precision = 1;
3625 else
3627 const FCHAR_T *digitp = dp->precision_start + 1;
3629 precision = 0;
3630 while (digitp != dp->precision_end)
3631 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
3632 has_precision = 1;
3636 /* POSIX specifies the default precision to be 6 for %f, %F,
3637 %e, %E, but not for %g, %G. Implementations appear to use
3638 the same default precision also for %g, %G. But for %a, %A,
3639 the default precision is 0. */
3640 if (!has_precision)
3641 if (!(dp->conversion == 'a' || dp->conversion == 'A'))
3642 precision = 6;
3644 /* Allocate a temporary buffer of sufficient size. */
3645 # if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3646 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
3647 # elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
3648 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
3649 # elif NEED_PRINTF_LONG_DOUBLE
3650 tmp_length = LDBL_DIG + 1;
3651 # elif NEED_PRINTF_DOUBLE
3652 tmp_length = DBL_DIG + 1;
3653 # else
3654 tmp_length = 0;
3655 # endif
3656 if (tmp_length < precision)
3657 tmp_length = precision;
3658 # if NEED_PRINTF_LONG_DOUBLE
3659 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3660 if (type == TYPE_LONGDOUBLE)
3661 # endif
3662 if (dp->conversion == 'f' || dp->conversion == 'F')
3664 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3665 if (!(isnanl (arg) || arg + arg == arg))
3667 /* arg is finite and nonzero. */
3668 int exponent = floorlog10l (arg < 0 ? -arg : arg);
3669 if (exponent >= 0 && tmp_length < exponent + precision)
3670 tmp_length = exponent + precision;
3673 # endif
3674 # if NEED_PRINTF_DOUBLE
3675 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3676 if (type == TYPE_DOUBLE)
3677 # endif
3678 if (dp->conversion == 'f' || dp->conversion == 'F')
3680 double arg = a.arg[dp->arg_index].a.a_double;
3681 if (!(isnand (arg) || arg + arg == arg))
3683 /* arg is finite and nonzero. */
3684 int exponent = floorlog10 (arg < 0 ? -arg : arg);
3685 if (exponent >= 0 && tmp_length < exponent + precision)
3686 tmp_length = exponent + precision;
3689 # endif
3690 /* Account for sign, decimal point etc. */
3691 tmp_length = xsum (tmp_length, 12);
3693 if (tmp_length < width)
3694 tmp_length = width;
3696 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3698 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
3699 tmp = tmpbuf;
3700 else
3702 size_t tmp_memsize = xtimes (tmp_length, sizeof (DCHAR_T));
3704 if (size_overflow_p (tmp_memsize))
3705 /* Overflow, would lead to out of memory. */
3706 goto out_of_memory;
3707 tmp = (DCHAR_T *) malloc (tmp_memsize);
3708 if (tmp == NULL)
3709 /* Out of memory. */
3710 goto out_of_memory;
3713 pad_ptr = NULL;
3714 p = tmp;
3716 # if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
3717 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3718 if (type == TYPE_LONGDOUBLE)
3719 # endif
3721 long double arg = a.arg[dp->arg_index].a.a_longdouble;
3723 if (isnanl (arg))
3725 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3727 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
3729 else
3731 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
3734 else
3736 int sign = 0;
3737 DECL_LONG_DOUBLE_ROUNDING
3739 BEGIN_LONG_DOUBLE_ROUNDING ();
3741 if (signbit (arg)) /* arg < 0.0L or negative zero */
3743 sign = -1;
3744 arg = -arg;
3747 if (sign < 0)
3748 *p++ = '-';
3749 else if (flags & FLAG_SHOWSIGN)
3750 *p++ = '+';
3751 else if (flags & FLAG_SPACE)
3752 *p++ = ' ';
3754 if (arg > 0.0L && arg + arg == arg)
3756 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3758 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
3760 else
3762 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
3765 else
3767 # if NEED_PRINTF_LONG_DOUBLE
3768 pad_ptr = p;
3770 if (dp->conversion == 'f' || dp->conversion == 'F')
3772 char *digits;
3773 size_t ndigits;
3775 digits =
3776 scale10_round_decimal_long_double (arg, precision);
3777 if (digits == NULL)
3779 END_LONG_DOUBLE_ROUNDING ();
3780 goto out_of_memory;
3782 ndigits = strlen (digits);
3784 if (ndigits > precision)
3787 --ndigits;
3788 *p++ = digits[ndigits];
3790 while (ndigits > precision);
3791 else
3792 *p++ = '0';
3793 /* Here ndigits <= precision. */
3794 if ((flags & FLAG_ALT) || precision > 0)
3796 *p++ = decimal_point_char ();
3797 for (; precision > ndigits; precision--)
3798 *p++ = '0';
3799 while (ndigits > 0)
3801 --ndigits;
3802 *p++ = digits[ndigits];
3806 free (digits);
3808 else if (dp->conversion == 'e' || dp->conversion == 'E')
3810 int exponent;
3812 if (arg == 0.0L)
3814 exponent = 0;
3815 *p++ = '0';
3816 if ((flags & FLAG_ALT) || precision > 0)
3818 *p++ = decimal_point_char ();
3819 for (; precision > 0; precision--)
3820 *p++ = '0';
3823 else
3825 /* arg > 0.0L. */
3826 int adjusted;
3827 char *digits;
3828 size_t ndigits;
3830 exponent = floorlog10l (arg);
3831 adjusted = 0;
3832 for (;;)
3834 digits =
3835 scale10_round_decimal_long_double (arg,
3836 (int)precision - exponent);
3837 if (digits == NULL)
3839 END_LONG_DOUBLE_ROUNDING ();
3840 goto out_of_memory;
3842 ndigits = strlen (digits);
3844 if (ndigits == precision + 1)
3845 break;
3846 if (ndigits < precision
3847 || ndigits > precision + 2)
3848 /* The exponent was not guessed
3849 precisely enough. */
3850 abort ();
3851 if (adjusted)
3852 /* None of two values of exponent is
3853 the right one. Prevent an endless
3854 loop. */
3855 abort ();
3856 free (digits);
3857 if (ndigits == precision)
3858 exponent -= 1;
3859 else
3860 exponent += 1;
3861 adjusted = 1;
3863 /* Here ndigits = precision+1. */
3864 if (is_borderline (digits, precision))
3866 /* Maybe the exponent guess was too high
3867 and a smaller exponent can be reached
3868 by turning a 10...0 into 9...9x. */
3869 char *digits2 =
3870 scale10_round_decimal_long_double (arg,
3871 (int)precision - exponent + 1);
3872 if (digits2 == NULL)
3874 free (digits);
3875 END_LONG_DOUBLE_ROUNDING ();
3876 goto out_of_memory;
3878 if (strlen (digits2) == precision + 1)
3880 free (digits);
3881 digits = digits2;
3882 exponent -= 1;
3884 else
3885 free (digits2);
3887 /* Here ndigits = precision+1. */
3889 *p++ = digits[--ndigits];
3890 if ((flags & FLAG_ALT) || precision > 0)
3892 *p++ = decimal_point_char ();
3893 while (ndigits > 0)
3895 --ndigits;
3896 *p++ = digits[ndigits];
3900 free (digits);
3903 *p++ = dp->conversion; /* 'e' or 'E' */
3904 # if WIDE_CHAR_VERSION
3906 static const wchar_t decimal_format[] =
3907 { '%', '+', '.', '2', 'd', '\0' };
3908 SNPRINTF (p, 6 + 1, decimal_format, exponent);
3910 while (*p != '\0')
3911 p++;
3912 # else
3913 if (sizeof (DCHAR_T) == 1)
3915 sprintf ((char *) p, "%+.2d", exponent);
3916 while (*p != '\0')
3917 p++;
3919 else
3921 char expbuf[6 + 1];
3922 const char *ep;
3923 sprintf (expbuf, "%+.2d", exponent);
3924 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
3925 p++;
3927 # endif
3929 else if (dp->conversion == 'g' || dp->conversion == 'G')
3931 if (precision == 0)
3932 precision = 1;
3933 /* precision >= 1. */
3935 if (arg == 0.0L)
3936 /* The exponent is 0, >= -4, < precision.
3937 Use fixed-point notation. */
3939 size_t ndigits = precision;
3940 /* Number of trailing zeroes that have to be
3941 dropped. */
3942 size_t nzeroes =
3943 (flags & FLAG_ALT ? 0 : precision - 1);
3945 --ndigits;
3946 *p++ = '0';
3947 if ((flags & FLAG_ALT) || ndigits > nzeroes)
3949 *p++ = decimal_point_char ();
3950 while (ndigits > nzeroes)
3952 --ndigits;
3953 *p++ = '0';
3957 else
3959 /* arg > 0.0L. */
3960 int exponent;
3961 int adjusted;
3962 char *digits;
3963 size_t ndigits;
3964 size_t nzeroes;
3966 exponent = floorlog10l (arg);
3967 adjusted = 0;
3968 for (;;)
3970 digits =
3971 scale10_round_decimal_long_double (arg,
3972 (int)(precision - 1) - exponent);
3973 if (digits == NULL)
3975 END_LONG_DOUBLE_ROUNDING ();
3976 goto out_of_memory;
3978 ndigits = strlen (digits);
3980 if (ndigits == precision)
3981 break;
3982 if (ndigits < precision - 1
3983 || ndigits > precision + 1)
3984 /* The exponent was not guessed
3985 precisely enough. */
3986 abort ();
3987 if (adjusted)
3988 /* None of two values of exponent is
3989 the right one. Prevent an endless
3990 loop. */
3991 abort ();
3992 free (digits);
3993 if (ndigits < precision)
3994 exponent -= 1;
3995 else
3996 exponent += 1;
3997 adjusted = 1;
3999 /* Here ndigits = precision. */
4000 if (is_borderline (digits, precision - 1))
4002 /* Maybe the exponent guess was too high
4003 and a smaller exponent can be reached
4004 by turning a 10...0 into 9...9x. */
4005 char *digits2 =
4006 scale10_round_decimal_long_double (arg,
4007 (int)(precision - 1) - exponent + 1);
4008 if (digits2 == NULL)
4010 free (digits);
4011 END_LONG_DOUBLE_ROUNDING ();
4012 goto out_of_memory;
4014 if (strlen (digits2) == precision)
4016 free (digits);
4017 digits = digits2;
4018 exponent -= 1;
4020 else
4021 free (digits2);
4023 /* Here ndigits = precision. */
4025 /* Determine the number of trailing zeroes
4026 that have to be dropped. */
4027 nzeroes = 0;
4028 if ((flags & FLAG_ALT) == 0)
4029 while (nzeroes < ndigits
4030 && digits[nzeroes] == '0')
4031 nzeroes++;
4033 /* The exponent is now determined. */
4034 if (exponent >= -4
4035 && exponent < (long)precision)
4037 /* Fixed-point notation:
4038 max(exponent,0)+1 digits, then the
4039 decimal point, then the remaining
4040 digits without trailing zeroes. */
4041 if (exponent >= 0)
4043 size_t ecount = exponent + 1;
4044 /* Note: count <= precision = ndigits. */
4045 for (; ecount > 0; ecount--)
4046 *p++ = digits[--ndigits];
4047 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4049 *p++ = decimal_point_char ();
4050 while (ndigits > nzeroes)
4052 --ndigits;
4053 *p++ = digits[ndigits];
4057 else
4059 size_t ecount = -exponent - 1;
4060 *p++ = '0';
4061 *p++ = decimal_point_char ();
4062 for (; ecount > 0; ecount--)
4063 *p++ = '0';
4064 while (ndigits > nzeroes)
4066 --ndigits;
4067 *p++ = digits[ndigits];
4071 else
4073 /* Exponential notation. */
4074 *p++ = digits[--ndigits];
4075 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4077 *p++ = decimal_point_char ();
4078 while (ndigits > nzeroes)
4080 --ndigits;
4081 *p++ = digits[ndigits];
4084 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4085 # if WIDE_CHAR_VERSION
4087 static const wchar_t decimal_format[] =
4088 { '%', '+', '.', '2', 'd', '\0' };
4089 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4091 while (*p != '\0')
4092 p++;
4093 # else
4094 if (sizeof (DCHAR_T) == 1)
4096 sprintf ((char *) p, "%+.2d", exponent);
4097 while (*p != '\0')
4098 p++;
4100 else
4102 char expbuf[6 + 1];
4103 const char *ep;
4104 sprintf (expbuf, "%+.2d", exponent);
4105 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4106 p++;
4108 # endif
4111 free (digits);
4114 else
4115 abort ();
4116 # else
4117 /* arg is finite. */
4118 if (!(arg == 0.0L))
4119 abort ();
4121 pad_ptr = p;
4123 if (dp->conversion == 'f' || dp->conversion == 'F')
4125 *p++ = '0';
4126 if ((flags & FLAG_ALT) || precision > 0)
4128 *p++ = decimal_point_char ();
4129 for (; precision > 0; precision--)
4130 *p++ = '0';
4133 else if (dp->conversion == 'e' || dp->conversion == 'E')
4135 *p++ = '0';
4136 if ((flags & FLAG_ALT) || precision > 0)
4138 *p++ = decimal_point_char ();
4139 for (; precision > 0; precision--)
4140 *p++ = '0';
4142 *p++ = dp->conversion; /* 'e' or 'E' */
4143 *p++ = '+';
4144 *p++ = '0';
4145 *p++ = '0';
4147 else if (dp->conversion == 'g' || dp->conversion == 'G')
4149 *p++ = '0';
4150 if (flags & FLAG_ALT)
4152 size_t ndigits =
4153 (precision > 0 ? precision - 1 : 0);
4154 *p++ = decimal_point_char ();
4155 for (; ndigits > 0; --ndigits)
4156 *p++ = '0';
4159 else if (dp->conversion == 'a' || dp->conversion == 'A')
4161 *p++ = '0';
4162 *p++ = dp->conversion - 'A' + 'X';
4163 pad_ptr = p;
4164 *p++ = '0';
4165 if ((flags & FLAG_ALT) || precision > 0)
4167 *p++ = decimal_point_char ();
4168 for (; precision > 0; precision--)
4169 *p++ = '0';
4171 *p++ = dp->conversion - 'A' + 'P';
4172 *p++ = '+';
4173 *p++ = '0';
4175 else
4176 abort ();
4177 # endif
4180 END_LONG_DOUBLE_ROUNDING ();
4183 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4184 else
4185 # endif
4186 # endif
4187 # if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
4189 double arg = a.arg[dp->arg_index].a.a_double;
4191 if (isnand (arg))
4193 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4195 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
4197 else
4199 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
4202 else
4204 int sign = 0;
4206 if (signbit (arg)) /* arg < 0.0 or negative zero */
4208 sign = -1;
4209 arg = -arg;
4212 if (sign < 0)
4213 *p++ = '-';
4214 else if (flags & FLAG_SHOWSIGN)
4215 *p++ = '+';
4216 else if (flags & FLAG_SPACE)
4217 *p++ = ' ';
4219 if (arg > 0.0 && arg + arg == arg)
4221 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
4223 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
4225 else
4227 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
4230 else
4232 # if NEED_PRINTF_DOUBLE
4233 pad_ptr = p;
4235 if (dp->conversion == 'f' || dp->conversion == 'F')
4237 char *digits;
4238 size_t ndigits;
4240 digits =
4241 scale10_round_decimal_double (arg, precision);
4242 if (digits == NULL)
4243 goto out_of_memory;
4244 ndigits = strlen (digits);
4246 if (ndigits > precision)
4249 --ndigits;
4250 *p++ = digits[ndigits];
4252 while (ndigits > precision);
4253 else
4254 *p++ = '0';
4255 /* Here ndigits <= precision. */
4256 if ((flags & FLAG_ALT) || precision > 0)
4258 *p++ = decimal_point_char ();
4259 for (; precision > ndigits; precision--)
4260 *p++ = '0';
4261 while (ndigits > 0)
4263 --ndigits;
4264 *p++ = digits[ndigits];
4268 free (digits);
4270 else if (dp->conversion == 'e' || dp->conversion == 'E')
4272 int exponent;
4274 if (arg == 0.0)
4276 exponent = 0;
4277 *p++ = '0';
4278 if ((flags & FLAG_ALT) || precision > 0)
4280 *p++ = decimal_point_char ();
4281 for (; precision > 0; precision--)
4282 *p++ = '0';
4285 else
4287 /* arg > 0.0. */
4288 int adjusted;
4289 char *digits;
4290 size_t ndigits;
4292 exponent = floorlog10 (arg);
4293 adjusted = 0;
4294 for (;;)
4296 digits =
4297 scale10_round_decimal_double (arg,
4298 (int)precision - exponent);
4299 if (digits == NULL)
4300 goto out_of_memory;
4301 ndigits = strlen (digits);
4303 if (ndigits == precision + 1)
4304 break;
4305 if (ndigits < precision
4306 || ndigits > precision + 2)
4307 /* The exponent was not guessed
4308 precisely enough. */
4309 abort ();
4310 if (adjusted)
4311 /* None of two values of exponent is
4312 the right one. Prevent an endless
4313 loop. */
4314 abort ();
4315 free (digits);
4316 if (ndigits == precision)
4317 exponent -= 1;
4318 else
4319 exponent += 1;
4320 adjusted = 1;
4322 /* Here ndigits = precision+1. */
4323 if (is_borderline (digits, precision))
4325 /* Maybe the exponent guess was too high
4326 and a smaller exponent can be reached
4327 by turning a 10...0 into 9...9x. */
4328 char *digits2 =
4329 scale10_round_decimal_double (arg,
4330 (int)precision - exponent + 1);
4331 if (digits2 == NULL)
4333 free (digits);
4334 goto out_of_memory;
4336 if (strlen (digits2) == precision + 1)
4338 free (digits);
4339 digits = digits2;
4340 exponent -= 1;
4342 else
4343 free (digits2);
4345 /* Here ndigits = precision+1. */
4347 *p++ = digits[--ndigits];
4348 if ((flags & FLAG_ALT) || precision > 0)
4350 *p++ = decimal_point_char ();
4351 while (ndigits > 0)
4353 --ndigits;
4354 *p++ = digits[ndigits];
4358 free (digits);
4361 *p++ = dp->conversion; /* 'e' or 'E' */
4362 # if WIDE_CHAR_VERSION
4364 static const wchar_t decimal_format[] =
4365 /* Produce the same number of exponent digits
4366 as the native printf implementation. */
4367 # if defined _WIN32 && ! defined __CYGWIN__
4368 { '%', '+', '.', '3', 'd', '\0' };
4369 # else
4370 { '%', '+', '.', '2', 'd', '\0' };
4371 # endif
4372 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4374 while (*p != '\0')
4375 p++;
4376 # else
4378 static const char decimal_format[] =
4379 /* Produce the same number of exponent digits
4380 as the native printf implementation. */
4381 # if defined _WIN32 && ! defined __CYGWIN__
4382 "%+.3d";
4383 # else
4384 "%+.2d";
4385 # endif
4386 if (sizeof (DCHAR_T) == 1)
4388 sprintf ((char *) p, decimal_format, exponent);
4389 while (*p != '\0')
4390 p++;
4392 else
4394 char expbuf[6 + 1];
4395 const char *ep;
4396 sprintf (expbuf, decimal_format, exponent);
4397 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4398 p++;
4401 # endif
4403 else if (dp->conversion == 'g' || dp->conversion == 'G')
4405 if (precision == 0)
4406 precision = 1;
4407 /* precision >= 1. */
4409 if (arg == 0.0)
4410 /* The exponent is 0, >= -4, < precision.
4411 Use fixed-point notation. */
4413 size_t ndigits = precision;
4414 /* Number of trailing zeroes that have to be
4415 dropped. */
4416 size_t nzeroes =
4417 (flags & FLAG_ALT ? 0 : precision - 1);
4419 --ndigits;
4420 *p++ = '0';
4421 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4423 *p++ = decimal_point_char ();
4424 while (ndigits > nzeroes)
4426 --ndigits;
4427 *p++ = '0';
4431 else
4433 /* arg > 0.0. */
4434 int exponent;
4435 int adjusted;
4436 char *digits;
4437 size_t ndigits;
4438 size_t nzeroes;
4440 exponent = floorlog10 (arg);
4441 adjusted = 0;
4442 for (;;)
4444 digits =
4445 scale10_round_decimal_double (arg,
4446 (int)(precision - 1) - exponent);
4447 if (digits == NULL)
4448 goto out_of_memory;
4449 ndigits = strlen (digits);
4451 if (ndigits == precision)
4452 break;
4453 if (ndigits < precision - 1
4454 || ndigits > precision + 1)
4455 /* The exponent was not guessed
4456 precisely enough. */
4457 abort ();
4458 if (adjusted)
4459 /* None of two values of exponent is
4460 the right one. Prevent an endless
4461 loop. */
4462 abort ();
4463 free (digits);
4464 if (ndigits < precision)
4465 exponent -= 1;
4466 else
4467 exponent += 1;
4468 adjusted = 1;
4470 /* Here ndigits = precision. */
4471 if (is_borderline (digits, precision - 1))
4473 /* Maybe the exponent guess was too high
4474 and a smaller exponent can be reached
4475 by turning a 10...0 into 9...9x. */
4476 char *digits2 =
4477 scale10_round_decimal_double (arg,
4478 (int)(precision - 1) - exponent + 1);
4479 if (digits2 == NULL)
4481 free (digits);
4482 goto out_of_memory;
4484 if (strlen (digits2) == precision)
4486 free (digits);
4487 digits = digits2;
4488 exponent -= 1;
4490 else
4491 free (digits2);
4493 /* Here ndigits = precision. */
4495 /* Determine the number of trailing zeroes
4496 that have to be dropped. */
4497 nzeroes = 0;
4498 if ((flags & FLAG_ALT) == 0)
4499 while (nzeroes < ndigits
4500 && digits[nzeroes] == '0')
4501 nzeroes++;
4503 /* The exponent is now determined. */
4504 if (exponent >= -4
4505 && exponent < (long)precision)
4507 /* Fixed-point notation:
4508 max(exponent,0)+1 digits, then the
4509 decimal point, then the remaining
4510 digits without trailing zeroes. */
4511 if (exponent >= 0)
4513 size_t ecount = exponent + 1;
4514 /* Note: ecount <= precision = ndigits. */
4515 for (; ecount > 0; ecount--)
4516 *p++ = digits[--ndigits];
4517 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4519 *p++ = decimal_point_char ();
4520 while (ndigits > nzeroes)
4522 --ndigits;
4523 *p++ = digits[ndigits];
4527 else
4529 size_t ecount = -exponent - 1;
4530 *p++ = '0';
4531 *p++ = decimal_point_char ();
4532 for (; ecount > 0; ecount--)
4533 *p++ = '0';
4534 while (ndigits > nzeroes)
4536 --ndigits;
4537 *p++ = digits[ndigits];
4541 else
4543 /* Exponential notation. */
4544 *p++ = digits[--ndigits];
4545 if ((flags & FLAG_ALT) || ndigits > nzeroes)
4547 *p++ = decimal_point_char ();
4548 while (ndigits > nzeroes)
4550 --ndigits;
4551 *p++ = digits[ndigits];
4554 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
4555 # if WIDE_CHAR_VERSION
4557 static const wchar_t decimal_format[] =
4558 /* Produce the same number of exponent digits
4559 as the native printf implementation. */
4560 # if defined _WIN32 && ! defined __CYGWIN__
4561 { '%', '+', '.', '3', 'd', '\0' };
4562 # else
4563 { '%', '+', '.', '2', 'd', '\0' };
4564 # endif
4565 SNPRINTF (p, 6 + 1, decimal_format, exponent);
4567 while (*p != '\0')
4568 p++;
4569 # else
4571 static const char decimal_format[] =
4572 /* Produce the same number of exponent digits
4573 as the native printf implementation. */
4574 # if defined _WIN32 && ! defined __CYGWIN__
4575 "%+.3d";
4576 # else
4577 "%+.2d";
4578 # endif
4579 if (sizeof (DCHAR_T) == 1)
4581 sprintf ((char *) p, decimal_format, exponent);
4582 while (*p != '\0')
4583 p++;
4585 else
4587 char expbuf[6 + 1];
4588 const char *ep;
4589 sprintf (expbuf, decimal_format, exponent);
4590 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
4591 p++;
4594 # endif
4597 free (digits);
4600 else
4601 abort ();
4602 # else
4603 /* arg is finite. */
4604 if (!(arg == 0.0))
4605 abort ();
4607 pad_ptr = p;
4609 if (dp->conversion == 'f' || dp->conversion == 'F')
4611 *p++ = '0';
4612 if ((flags & FLAG_ALT) || precision > 0)
4614 *p++ = decimal_point_char ();
4615 for (; precision > 0; precision--)
4616 *p++ = '0';
4619 else if (dp->conversion == 'e' || dp->conversion == 'E')
4621 *p++ = '0';
4622 if ((flags & FLAG_ALT) || precision > 0)
4624 *p++ = decimal_point_char ();
4625 for (; precision > 0; precision--)
4626 *p++ = '0';
4628 *p++ = dp->conversion; /* 'e' or 'E' */
4629 *p++ = '+';
4630 /* Produce the same number of exponent digits as
4631 the native printf implementation. */
4632 # if defined _WIN32 && ! defined __CYGWIN__
4633 *p++ = '0';
4634 # endif
4635 *p++ = '0';
4636 *p++ = '0';
4638 else if (dp->conversion == 'g' || dp->conversion == 'G')
4640 *p++ = '0';
4641 if (flags & FLAG_ALT)
4643 size_t ndigits =
4644 (precision > 0 ? precision - 1 : 0);
4645 *p++ = decimal_point_char ();
4646 for (; ndigits > 0; --ndigits)
4647 *p++ = '0';
4650 else
4651 abort ();
4652 # endif
4656 # endif
4658 /* The generated string now extends from tmp to p, with the
4659 zero padding insertion point being at pad_ptr. */
4660 count = p - tmp;
4662 if (count < width)
4664 size_t pad = width - count;
4665 DCHAR_T *end = p + pad;
4667 if (flags & FLAG_LEFT)
4669 /* Pad with spaces on the right. */
4670 for (; pad > 0; pad--)
4671 *p++ = ' ';
4673 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4675 /* Pad with zeroes. */
4676 DCHAR_T *q = end;
4678 while (p > pad_ptr)
4679 *--q = *--p;
4680 for (; pad > 0; pad--)
4681 *p++ = '0';
4683 else
4685 /* Pad with spaces on the left. */
4686 DCHAR_T *q = end;
4688 while (p > tmp)
4689 *--q = *--p;
4690 for (; pad > 0; pad--)
4691 *p++ = ' ';
4694 p = end;
4697 count = p - tmp;
4699 if (count >= tmp_length)
4700 /* tmp_length was incorrectly calculated - fix the
4701 code above! */
4702 abort ();
4704 /* Make room for the result. */
4705 if (count >= allocated - length)
4707 size_t n = xsum (length, count);
4709 ENSURE_ALLOCATION (n);
4712 /* Append the result. */
4713 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4714 if (tmp != tmpbuf)
4715 free (tmp);
4716 length += count;
4718 #endif
4719 else
4721 arg_type type = a.arg[dp->arg_index].type;
4722 int flags = dp->flags;
4723 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4724 int has_width;
4725 #endif
4726 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4727 size_t width;
4728 #endif
4729 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4730 int has_precision;
4731 size_t precision;
4732 #endif
4733 #if NEED_PRINTF_UNBOUNDED_PRECISION
4734 int prec_ourselves;
4735 #else
4736 # define prec_ourselves 0
4737 #endif
4738 #if NEED_PRINTF_FLAG_LEFTADJUST
4739 # define pad_ourselves 1
4740 #elif !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4741 int pad_ourselves;
4742 #else
4743 # define pad_ourselves 0
4744 #endif
4745 TCHAR_T *fbp;
4746 unsigned int prefix_count;
4747 int prefixes[2] IF_LINT (= { 0 });
4748 int orig_errno;
4749 #if !USE_SNPRINTF
4750 size_t tmp_length;
4751 TCHAR_T tmpbuf[700];
4752 TCHAR_T *tmp;
4753 #endif
4755 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4756 has_width = 0;
4757 #endif
4758 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4759 width = 0;
4760 if (dp->width_start != dp->width_end)
4762 if (dp->width_arg_index != ARG_NONE)
4764 int arg;
4766 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4767 abort ();
4768 arg = a.arg[dp->width_arg_index].a.a_int;
4769 width = arg;
4770 if (arg < 0)
4772 /* "A negative field width is taken as a '-' flag
4773 followed by a positive field width." */
4774 flags |= FLAG_LEFT;
4775 width = -width;
4778 else
4780 const FCHAR_T *digitp = dp->width_start;
4783 width = xsum (xtimes (width, 10), *digitp++ - '0');
4784 while (digitp != dp->width_end);
4786 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4787 has_width = 1;
4788 #endif
4790 #endif
4792 #if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
4793 has_precision = 0;
4794 precision = 6;
4795 if (dp->precision_start != dp->precision_end)
4797 if (dp->precision_arg_index != ARG_NONE)
4799 int arg;
4801 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4802 abort ();
4803 arg = a.arg[dp->precision_arg_index].a.a_int;
4804 /* "A negative precision is taken as if the precision
4805 were omitted." */
4806 if (arg >= 0)
4808 precision = arg;
4809 has_precision = 1;
4812 else
4814 const FCHAR_T *digitp = dp->precision_start + 1;
4816 precision = 0;
4817 while (digitp != dp->precision_end)
4818 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
4819 has_precision = 1;
4822 #endif
4824 /* Decide whether to handle the precision ourselves. */
4825 #if NEED_PRINTF_UNBOUNDED_PRECISION
4826 switch (dp->conversion)
4828 case 'd': case 'i': case 'u':
4829 case 'o':
4830 case 'x': case 'X': case 'p':
4831 prec_ourselves = has_precision && (precision > 0);
4832 break;
4833 default:
4834 prec_ourselves = 0;
4835 break;
4837 #endif
4839 /* Decide whether to perform the padding ourselves. */
4840 #if !NEED_PRINTF_FLAG_LEFTADJUST && (!DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION)
4841 switch (dp->conversion)
4843 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4844 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4845 to perform the padding after this conversion. Functions
4846 with unistdio extensions perform the padding based on
4847 character count rather than element count. */
4848 case 'c': case 's':
4849 # endif
4850 # if NEED_PRINTF_FLAG_ZERO
4851 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
4852 case 'a': case 'A':
4853 # endif
4854 pad_ourselves = 1;
4855 break;
4856 default:
4857 pad_ourselves = prec_ourselves;
4858 break;
4860 #endif
4862 #if !USE_SNPRINTF
4863 /* Allocate a temporary buffer of sufficient size for calling
4864 sprintf. */
4865 tmp_length =
4866 MAX_ROOM_NEEDED (&a, dp->arg_index, dp->conversion, type,
4867 flags, width, has_precision, precision,
4868 pad_ourselves);
4870 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
4871 tmp = tmpbuf;
4872 else
4874 size_t tmp_memsize = xtimes (tmp_length, sizeof (TCHAR_T));
4876 if (size_overflow_p (tmp_memsize))
4877 /* Overflow, would lead to out of memory. */
4878 goto out_of_memory;
4879 tmp = (TCHAR_T *) malloc (tmp_memsize);
4880 if (tmp == NULL)
4881 /* Out of memory. */
4882 goto out_of_memory;
4884 #endif
4886 /* Construct the format string for calling snprintf or
4887 sprintf. */
4888 fbp = buf;
4889 *fbp++ = '%';
4890 #if NEED_PRINTF_FLAG_GROUPING
4891 /* The underlying implementation doesn't support the ' flag.
4892 Produce no grouping characters in this case; this is
4893 acceptable because the grouping is locale dependent. */
4894 #else
4895 if (flags & FLAG_GROUP)
4896 *fbp++ = '\'';
4897 #endif
4898 if (flags & FLAG_LEFT)
4899 *fbp++ = '-';
4900 if (flags & FLAG_SHOWSIGN)
4901 *fbp++ = '+';
4902 if (flags & FLAG_SPACE)
4903 *fbp++ = ' ';
4904 if (flags & FLAG_ALT)
4905 *fbp++ = '#';
4906 #if __GLIBC__ >= 2 && !defined __UCLIBC__
4907 if (flags & FLAG_LOCALIZED)
4908 *fbp++ = 'I';
4909 #endif
4910 if (!pad_ourselves)
4912 if (flags & FLAG_ZERO)
4913 *fbp++ = '0';
4914 if (dp->width_start != dp->width_end)
4916 size_t n = dp->width_end - dp->width_start;
4917 /* The width specification is known to consist only
4918 of standard ASCII characters. */
4919 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4921 memcpy (fbp, dp->width_start, n * sizeof (TCHAR_T));
4922 fbp += n;
4924 else
4926 const FCHAR_T *mp = dp->width_start;
4928 *fbp++ = *mp++;
4929 while (--n > 0);
4933 if (!prec_ourselves)
4935 if (dp->precision_start != dp->precision_end)
4937 size_t n = dp->precision_end - dp->precision_start;
4938 /* The precision specification is known to consist only
4939 of standard ASCII characters. */
4940 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4942 memcpy (fbp, dp->precision_start, n * sizeof (TCHAR_T));
4943 fbp += n;
4945 else
4947 const FCHAR_T *mp = dp->precision_start;
4949 *fbp++ = *mp++;
4950 while (--n > 0);
4955 switch (type)
4957 case TYPE_LONGLONGINT:
4958 case TYPE_ULONGLONGINT:
4959 #if defined _WIN32 && ! defined __CYGWIN__
4960 *fbp++ = 'I';
4961 *fbp++ = '6';
4962 *fbp++ = '4';
4963 break;
4964 #else
4965 *fbp++ = 'l';
4966 #endif
4967 FALLTHROUGH;
4968 case TYPE_LONGINT:
4969 case TYPE_ULONGINT:
4970 #if HAVE_WINT_T
4971 case TYPE_WIDE_CHAR:
4972 #endif
4973 #if HAVE_WCHAR_T
4974 case TYPE_WIDE_STRING:
4975 #endif
4976 *fbp++ = 'l';
4977 break;
4978 case TYPE_LONGDOUBLE:
4979 *fbp++ = 'L';
4980 break;
4981 default:
4982 break;
4984 #if NEED_PRINTF_DIRECTIVE_F
4985 if (dp->conversion == 'F')
4986 *fbp = 'f';
4987 else
4988 #endif
4989 *fbp = dp->conversion;
4990 #if USE_SNPRINTF
4991 # if ((HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99) \
4992 || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \
4993 && !defined __UCLIBC__) \
4994 || (defined __APPLE__ && defined __MACH__) \
4995 || defined __ANDROID__ \
4996 || (defined _WIN32 && ! defined __CYGWIN__))
4997 /* On systems where we know that snprintf's return value
4998 conforms to ISO C 99 (HAVE_SNPRINTF_RETVAL_C99) and that
4999 snprintf always produces NUL-terminated strings
5000 (HAVE_SNPRINTF_TRUNCATION_C99), it is possible to avoid
5001 using %n. And it is desirable to do so, because more and
5002 more platforms no longer support %n, for "security reasons".
5003 In particular, the following platforms:
5004 - On glibc2 systems from 2004-10-18 or newer, the use of
5005 %n in format strings in writable memory may crash the
5006 program (if compiled with _FORTIFY_SOURCE=2).
5007 - On Mac OS X 10.13 or newer, the use of %n in format
5008 strings in writable memory by default crashes the
5009 program.
5010 - On Android, starting on 2018-03-07, the use of %n in
5011 format strings produces a fatal error (see
5012 <https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>).
5013 On these platforms, HAVE_SNPRINTF_RETVAL_C99 and
5014 HAVE_SNPRINTF_TRUNCATION_C99 are 1. We have listed them
5015 explicitly in the condition above, in case of cross-
5016 compilation (just to be sure). */
5017 /* On native Windows systems (such as mingw), we can avoid using
5018 %n because:
5019 - Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
5020 snprintf does not write more than the specified number
5021 of bytes. (snprintf (buf, 3, "%d %d", 4567, 89) writes
5022 '4', '5', '6' into buf, not '4', '5', '\0'.)
5023 - Although the gl_SNPRINTF_RETVAL_C99 test fails, snprintf
5024 allows us to recognize the case of an insufficient
5025 buffer size: it returns -1 in this case.
5026 On native Windows systems (such as mingw) where the OS is
5027 Windows Vista, the use of %n in format strings by default
5028 crashes the program. See
5029 <https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
5030 <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output>
5031 So we should avoid %n in this situation. */
5032 fbp[1] = '\0';
5033 # else /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */
5034 fbp[1] = '%';
5035 fbp[2] = 'n';
5036 fbp[3] = '\0';
5037 # endif
5038 #else
5039 fbp[1] = '\0';
5040 #endif
5042 /* Construct the arguments for calling snprintf or sprintf. */
5043 prefix_count = 0;
5044 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
5046 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
5047 abort ();
5048 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
5050 if (!prec_ourselves && dp->precision_arg_index != ARG_NONE)
5052 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
5053 abort ();
5054 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
5057 #if USE_SNPRINTF
5058 /* The SNPRINTF result is appended after result[0..length].
5059 The latter is an array of DCHAR_T; SNPRINTF appends an
5060 array of TCHAR_T to it. This is possible because
5061 sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
5062 alignof (TCHAR_T) <= alignof (DCHAR_T). */
5063 # define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
5064 /* Ensure that maxlen below will be >= 2. Needed on BeOS,
5065 where an snprintf() with maxlen==1 acts like sprintf(). */
5066 ENSURE_ALLOCATION (xsum (length,
5067 (2 + TCHARS_PER_DCHAR - 1)
5068 / TCHARS_PER_DCHAR));
5069 /* Prepare checking whether snprintf returns the count
5070 via %n. */
5071 *(TCHAR_T *) (result + length) = '\0';
5072 #endif
5074 orig_errno = errno;
5076 for (;;)
5078 int count = -1;
5080 #if USE_SNPRINTF
5081 int retcount = 0;
5082 size_t maxlen = allocated - length;
5083 /* SNPRINTF can fail if its second argument is
5084 > INT_MAX. */
5085 if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
5086 maxlen = INT_MAX / TCHARS_PER_DCHAR;
5087 maxlen = maxlen * TCHARS_PER_DCHAR;
5088 # define SNPRINTF_BUF(arg) \
5089 switch (prefix_count) \
5091 case 0: \
5092 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
5093 maxlen, buf, \
5094 arg, &count); \
5095 break; \
5096 case 1: \
5097 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
5098 maxlen, buf, \
5099 prefixes[0], arg, &count); \
5100 break; \
5101 case 2: \
5102 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
5103 maxlen, buf, \
5104 prefixes[0], prefixes[1], arg, \
5105 &count); \
5106 break; \
5107 default: \
5108 abort (); \
5110 #else
5111 # define SNPRINTF_BUF(arg) \
5112 switch (prefix_count) \
5114 case 0: \
5115 count = sprintf (tmp, buf, arg); \
5116 break; \
5117 case 1: \
5118 count = sprintf (tmp, buf, prefixes[0], arg); \
5119 break; \
5120 case 2: \
5121 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
5122 arg); \
5123 break; \
5124 default: \
5125 abort (); \
5127 #endif
5129 errno = 0;
5130 switch (type)
5132 case TYPE_SCHAR:
5134 int arg = a.arg[dp->arg_index].a.a_schar;
5135 SNPRINTF_BUF (arg);
5137 break;
5138 case TYPE_UCHAR:
5140 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
5141 SNPRINTF_BUF (arg);
5143 break;
5144 case TYPE_SHORT:
5146 int arg = a.arg[dp->arg_index].a.a_short;
5147 SNPRINTF_BUF (arg);
5149 break;
5150 case TYPE_USHORT:
5152 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
5153 SNPRINTF_BUF (arg);
5155 break;
5156 case TYPE_INT:
5158 int arg = a.arg[dp->arg_index].a.a_int;
5159 SNPRINTF_BUF (arg);
5161 break;
5162 case TYPE_UINT:
5164 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
5165 SNPRINTF_BUF (arg);
5167 break;
5168 case TYPE_LONGINT:
5170 long int arg = a.arg[dp->arg_index].a.a_longint;
5171 SNPRINTF_BUF (arg);
5173 break;
5174 case TYPE_ULONGINT:
5176 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
5177 SNPRINTF_BUF (arg);
5179 break;
5180 case TYPE_LONGLONGINT:
5182 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
5183 SNPRINTF_BUF (arg);
5185 break;
5186 case TYPE_ULONGLONGINT:
5188 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
5189 SNPRINTF_BUF (arg);
5191 break;
5192 case TYPE_DOUBLE:
5194 double arg = a.arg[dp->arg_index].a.a_double;
5195 SNPRINTF_BUF (arg);
5197 break;
5198 case TYPE_LONGDOUBLE:
5200 long double arg = a.arg[dp->arg_index].a.a_longdouble;
5201 SNPRINTF_BUF (arg);
5203 break;
5204 case TYPE_CHAR:
5206 int arg = a.arg[dp->arg_index].a.a_char;
5207 SNPRINTF_BUF (arg);
5209 break;
5210 #if HAVE_WINT_T
5211 case TYPE_WIDE_CHAR:
5213 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
5214 SNPRINTF_BUF (arg);
5216 break;
5217 #endif
5218 case TYPE_STRING:
5220 const char *arg = a.arg[dp->arg_index].a.a_string;
5221 SNPRINTF_BUF (arg);
5223 break;
5224 #if HAVE_WCHAR_T
5225 case TYPE_WIDE_STRING:
5227 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
5228 SNPRINTF_BUF (arg);
5230 break;
5231 #endif
5232 case TYPE_POINTER:
5234 void *arg = a.arg[dp->arg_index].a.a_pointer;
5235 SNPRINTF_BUF (arg);
5237 break;
5238 default:
5239 abort ();
5242 #if USE_SNPRINTF
5243 /* Portability: Not all implementations of snprintf()
5244 are ISO C 99 compliant. Determine the number of
5245 bytes that snprintf() has produced or would have
5246 produced. */
5247 if (count >= 0)
5249 /* Verify that snprintf() has NUL-terminated its
5250 result. */
5251 if ((unsigned int) count < maxlen
5252 && ((TCHAR_T *) (result + length)) [count] != '\0')
5253 abort ();
5254 /* Portability hack. */
5255 if (retcount > count)
5256 count = retcount;
5258 else
5260 /* snprintf() doesn't understand the '%n'
5261 directive. */
5262 if (fbp[1] != '\0')
5264 /* Don't use the '%n' directive; instead, look
5265 at the snprintf() return value. */
5266 fbp[1] = '\0';
5267 continue;
5269 else
5271 /* Look at the snprintf() return value. */
5272 if (retcount < 0)
5274 # if !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
5275 /* HP-UX 10.20 snprintf() is doubly deficient:
5276 It doesn't understand the '%n' directive,
5277 *and* it returns -1 (rather than the length
5278 that would have been required) when the
5279 buffer is too small.
5280 But a failure at this point can also come
5281 from other reasons than a too small buffer,
5282 such as an invalid wide string argument to
5283 the %ls directive, or possibly an invalid
5284 floating-point argument. */
5285 size_t tmp_length =
5286 MAX_ROOM_NEEDED (&a, dp->arg_index,
5287 dp->conversion, type, flags,
5288 width,
5289 has_precision,
5290 precision, pad_ourselves);
5292 if (maxlen < tmp_length)
5294 /* Make more room. But try to do through
5295 this reallocation only once. */
5296 size_t bigger_need =
5297 xsum (length,
5298 xsum (tmp_length,
5299 TCHARS_PER_DCHAR - 1)
5300 / TCHARS_PER_DCHAR);
5301 /* And always grow proportionally.
5302 (There may be several arguments, each
5303 needing a little more room than the
5304 previous one.) */
5305 size_t bigger_need2 =
5306 xsum (xtimes (allocated, 2), 12);
5307 if (bigger_need < bigger_need2)
5308 bigger_need = bigger_need2;
5309 ENSURE_ALLOCATION (bigger_need);
5310 continue;
5312 # endif
5314 else
5315 count = retcount;
5318 #endif
5320 /* Attempt to handle failure. */
5321 if (count < 0)
5323 /* SNPRINTF or sprintf failed. Use the errno that it
5324 has set, if any. */
5325 if (errno == 0)
5327 if (dp->conversion == 'c' || dp->conversion == 's')
5328 errno = EILSEQ;
5329 else
5330 errno = EINVAL;
5333 goto fail_with_errno;
5336 #if USE_SNPRINTF
5337 /* Handle overflow of the allocated buffer.
5338 If such an overflow occurs, a C99 compliant snprintf()
5339 returns a count >= maxlen. However, a non-compliant
5340 snprintf() function returns only count = maxlen - 1. To
5341 cover both cases, test whether count >= maxlen - 1. */
5342 if ((unsigned int) count + 1 >= maxlen)
5344 /* If maxlen already has attained its allowed maximum,
5345 allocating more memory will not increase maxlen.
5346 Instead of looping, bail out. */
5347 if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
5348 goto overflow;
5349 else
5351 /* Need at least (count + 1) * sizeof (TCHAR_T)
5352 bytes. (The +1 is for the trailing NUL.)
5353 But ask for (count + 2) * sizeof (TCHAR_T)
5354 bytes, so that in the next round, we likely get
5355 maxlen > (unsigned int) count + 1
5356 and so we don't get here again.
5357 And allocate proportionally, to avoid looping
5358 eternally if snprintf() reports a too small
5359 count. */
5360 size_t n =
5361 xmax (xsum (length,
5362 ((unsigned int) count + 2
5363 + TCHARS_PER_DCHAR - 1)
5364 / TCHARS_PER_DCHAR),
5365 xtimes (allocated, 2));
5367 ENSURE_ALLOCATION (n);
5368 continue;
5371 #endif
5373 #if NEED_PRINTF_UNBOUNDED_PRECISION
5374 if (prec_ourselves)
5376 /* Handle the precision. */
5377 TCHAR_T *prec_ptr =
5378 # if USE_SNPRINTF
5379 (TCHAR_T *) (result + length);
5380 # else
5381 tmp;
5382 # endif
5383 size_t prefix_count;
5384 size_t move;
5386 prefix_count = 0;
5387 /* Put the additional zeroes after the sign. */
5388 if (count >= 1
5389 && (*prec_ptr == '-' || *prec_ptr == '+'
5390 || *prec_ptr == ' '))
5391 prefix_count = 1;
5392 /* Put the additional zeroes after the 0x prefix if
5393 (flags & FLAG_ALT) || (dp->conversion == 'p'). */
5394 else if (count >= 2
5395 && prec_ptr[0] == '0'
5396 && (prec_ptr[1] == 'x' || prec_ptr[1] == 'X'))
5397 prefix_count = 2;
5399 move = count - prefix_count;
5400 if (precision > move)
5402 /* Insert zeroes. */
5403 size_t insert = precision - move;
5404 TCHAR_T *prec_end;
5406 # if USE_SNPRINTF
5407 size_t n =
5408 xsum (length,
5409 (count + insert + TCHARS_PER_DCHAR - 1)
5410 / TCHARS_PER_DCHAR);
5411 length += (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5412 ENSURE_ALLOCATION (n);
5413 length -= (count + TCHARS_PER_DCHAR - 1) / TCHARS_PER_DCHAR;
5414 prec_ptr = (TCHAR_T *) (result + length);
5415 # endif
5417 prec_end = prec_ptr + count;
5418 prec_ptr += prefix_count;
5420 while (prec_end > prec_ptr)
5422 prec_end--;
5423 prec_end[insert] = prec_end[0];
5426 prec_end += insert;
5428 *--prec_end = '0';
5429 while (prec_end > prec_ptr);
5431 count += insert;
5434 #endif
5436 #if !USE_SNPRINTF
5437 if (count >= tmp_length)
5438 /* tmp_length was incorrectly calculated - fix the
5439 code above! */
5440 abort ();
5441 #endif
5443 #if !DCHAR_IS_TCHAR
5444 /* Convert from TCHAR_T[] to DCHAR_T[]. */
5445 if (dp->conversion == 'c' || dp->conversion == 's')
5447 /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
5448 TYPE_WIDE_STRING.
5449 The result string is not certainly ASCII. */
5450 const TCHAR_T *tmpsrc;
5451 DCHAR_T *tmpdst;
5452 size_t tmpdst_len;
5453 /* This code assumes that TCHAR_T is 'char'. */
5454 static_assert (sizeof (TCHAR_T) == 1);
5455 # if USE_SNPRINTF
5456 tmpsrc = (TCHAR_T *) (result + length);
5457 # else
5458 tmpsrc = tmp;
5459 # endif
5460 tmpdst =
5461 DCHAR_CONV_FROM_ENCODING (locale_charset (),
5462 iconveh_question_mark,
5463 tmpsrc, count,
5464 NULL,
5465 NULL, &tmpdst_len);
5466 if (tmpdst == NULL)
5467 goto fail_with_errno;
5468 ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
5469 { free (tmpdst); goto out_of_memory; });
5470 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
5471 free (tmpdst);
5472 count = tmpdst_len;
5474 else
5476 /* The result string is ASCII.
5477 Simple 1:1 conversion. */
5478 # if USE_SNPRINTF
5479 /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
5480 no-op conversion, in-place on the array starting
5481 at (result + length). */
5482 if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
5483 # endif
5485 const TCHAR_T *tmpsrc;
5486 DCHAR_T *tmpdst;
5487 size_t n;
5489 # if USE_SNPRINTF
5490 if (result == resultbuf)
5492 tmpsrc = (TCHAR_T *) (result + length);
5493 /* ENSURE_ALLOCATION will not move tmpsrc
5494 (because it's part of resultbuf). */
5495 ENSURE_ALLOCATION (xsum (length, count));
5497 else
5499 /* ENSURE_ALLOCATION will move the array
5500 (because it uses realloc(). */
5501 ENSURE_ALLOCATION (xsum (length, count));
5502 tmpsrc = (TCHAR_T *) (result + length);
5504 # else
5505 tmpsrc = tmp;
5506 ENSURE_ALLOCATION (xsum (length, count));
5507 # endif
5508 tmpdst = result + length;
5509 /* Copy backwards, because of overlapping. */
5510 tmpsrc += count;
5511 tmpdst += count;
5512 for (n = count; n > 0; n--)
5513 *--tmpdst = *--tmpsrc;
5516 #endif
5518 #if DCHAR_IS_TCHAR && !USE_SNPRINTF
5519 /* Make room for the result. */
5520 if (count > allocated - length)
5522 /* Need at least count elements. But allocate
5523 proportionally. */
5524 size_t n =
5525 xmax (xsum (length, count), xtimes (allocated, 2));
5527 ENSURE_ALLOCATION (n);
5529 #endif
5531 /* Here count <= allocated - length. */
5533 /* Perform padding. */
5534 #if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
5535 if (pad_ourselves && has_width)
5537 size_t w;
5538 # if ENABLE_UNISTDIO
5539 /* Outside POSIX, it's preferable to compare the width
5540 against the number of _characters_ of the converted
5541 value. */
5542 w = DCHAR_MBSNLEN (result + length, count);
5543 # else
5544 /* The width is compared against the number of _bytes_
5545 of the converted value, says POSIX. */
5546 w = count;
5547 # endif
5548 if (w < width)
5550 size_t pad = width - w;
5552 /* Make room for the result. */
5553 if (xsum (count, pad) > allocated - length)
5555 /* Need at least count + pad elements. But
5556 allocate proportionally. */
5557 size_t n =
5558 xmax (xsum3 (length, count, pad),
5559 xtimes (allocated, 2));
5561 # if USE_SNPRINTF
5562 length += count;
5563 ENSURE_ALLOCATION (n);
5564 length -= count;
5565 # else
5566 ENSURE_ALLOCATION (n);
5567 # endif
5569 /* Here count + pad <= allocated - length. */
5572 # if !DCHAR_IS_TCHAR || USE_SNPRINTF
5573 DCHAR_T * const rp = result + length;
5574 # else
5575 DCHAR_T * const rp = tmp;
5576 # endif
5577 DCHAR_T *p = rp + count;
5578 DCHAR_T *end = p + pad;
5579 DCHAR_T *pad_ptr;
5580 # if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
5581 if (dp->conversion == 'c'
5582 || dp->conversion == 's')
5583 /* No zero-padding for string directives. */
5584 pad_ptr = NULL;
5585 else
5586 # endif
5588 pad_ptr = (*rp == '-' ? rp + 1 : rp);
5589 /* No zero-padding of "inf" and "nan". */
5590 if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
5591 || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
5592 pad_ptr = NULL;
5594 /* The generated string now extends from rp to p,
5595 with the zero padding insertion point being at
5596 pad_ptr. */
5598 count = count + pad; /* = end - rp */
5600 if (flags & FLAG_LEFT)
5602 /* Pad with spaces on the right. */
5603 for (; pad > 0; pad--)
5604 *p++ = ' ';
5606 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
5608 /* Pad with zeroes. */
5609 DCHAR_T *q = end;
5611 while (p > pad_ptr)
5612 *--q = *--p;
5613 for (; pad > 0; pad--)
5614 *p++ = '0';
5616 else
5618 /* Pad with spaces on the left. */
5619 DCHAR_T *q = end;
5621 while (p > rp)
5622 *--q = *--p;
5623 for (; pad > 0; pad--)
5624 *p++ = ' ';
5629 #endif
5631 /* Here still count <= allocated - length. */
5633 #if !DCHAR_IS_TCHAR || USE_SNPRINTF
5634 /* The snprintf() result did fit. */
5635 #else
5636 /* Append the sprintf() result. */
5637 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
5638 #endif
5639 #if !USE_SNPRINTF
5640 if (tmp != tmpbuf)
5641 free (tmp);
5642 #endif
5644 #if NEED_PRINTF_DIRECTIVE_F
5645 if (dp->conversion == 'F')
5647 /* Convert the %f result to upper case for %F. */
5648 DCHAR_T *rp = result + length;
5649 size_t rc;
5650 for (rc = count; rc > 0; rc--, rp++)
5651 if (*rp >= 'a' && *rp <= 'z')
5652 *rp = *rp - 'a' + 'A';
5654 #endif
5656 length += count;
5657 break;
5659 errno = orig_errno;
5660 #undef pad_ourselves
5661 #undef prec_ourselves
5666 /* Add the final NUL. */
5667 ENSURE_ALLOCATION (xsum (length, 1));
5668 result[length] = '\0';
5670 if (result != resultbuf && length + 1 < allocated)
5672 /* Shrink the allocated memory if possible. */
5673 DCHAR_T *memory;
5675 memory = (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
5676 if (memory != NULL)
5677 result = memory;
5680 if (buf_malloced != NULL)
5681 free (buf_malloced);
5682 CLEANUP ();
5683 *lengthp = length;
5684 /* Note that we can produce a big string of a length > INT_MAX. POSIX
5685 says that snprintf() fails with errno = EOVERFLOW in this case, but
5686 that's only because snprintf() returns an 'int'. This function does
5687 not have this limitation. */
5688 return result;
5690 #if USE_SNPRINTF
5691 overflow:
5692 errno = EOVERFLOW;
5693 goto fail_with_errno;
5694 #endif
5696 out_of_memory:
5697 errno = ENOMEM;
5698 goto fail_with_errno;
5700 #if ENABLE_UNISTDIO || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T)
5701 fail_with_EILSEQ:
5702 errno = EILSEQ;
5703 goto fail_with_errno;
5704 #endif
5706 fail_with_errno:
5707 if (result != resultbuf)
5708 free (result);
5709 if (buf_malloced != NULL)
5710 free (buf_malloced);
5711 CLEANUP ();
5712 return NULL;
5715 out_of_memory_1:
5716 errno = ENOMEM;
5717 goto fail_1_with_errno;
5719 fail_1_with_EINVAL:
5720 errno = EINVAL;
5721 goto fail_1_with_errno;
5723 fail_1_with_errno:
5724 CLEANUP ();
5725 return NULL;
5728 #undef MAX_ROOM_NEEDED
5729 #undef TCHARS_PER_DCHAR
5730 #undef SNPRINTF
5731 #undef USE_SNPRINTF
5732 #undef DCHAR_SET
5733 #undef DCHAR_CPY
5734 #undef PRINTF_PARSE
5735 #undef DIRECTIVES
5736 #undef DIRECTIVE
5737 #undef DCHAR_IS_TCHAR
5738 #undef TCHAR_T
5739 #undef DCHAR_T
5740 #undef FCHAR_T
5741 #undef VASNPRINTF