diff options
Diffstat (limited to 'Build/source/libs/mpfr/mpfr-src/src/vasprintf.c')
-rw-r--r-- | Build/source/libs/mpfr/mpfr-src/src/vasprintf.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/Build/source/libs/mpfr/mpfr-src/src/vasprintf.c b/Build/source/libs/mpfr/mpfr-src/src/vasprintf.c index 6173f149c97..60d7ef59864 100644 --- a/Build/source/libs/mpfr/mpfr-src/src/vasprintf.c +++ b/Build/source/libs/mpfr/mpfr-src/src/vasprintf.c @@ -1,7 +1,7 @@ /* mpfr_vasnprintf_aux -- helper function for the formatted output functions (printf functions family). -Copyright 2007-2020 Free Software Foundation, Inc. +Copyright 2007-2022 Free Software Foundation, Inc. Contributed by the AriC and Caramba projects, INRIA. This file is part of the GNU MPFR Library. @@ -26,7 +26,7 @@ https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., function to return a negative value and set errno to EOVERFLOW. [*] The Open Group Base Specifications Issue 7, 2018 edition IEEE Std 1003.1-2017 (Revision of IEEE Std 1003.1-2008) - http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html + https://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html This follows a defect report submitted in 2007 to austin-review-l. Even in case of such a failure (just because of the limitation on int), we try to support %n, %ln, %jn when possible. That's why the sizes (or @@ -218,8 +218,11 @@ specinfo_init (struct printf_spec *specinfo) specinfo->pad = ' '; } +/* Note: LONG_ARG is unusual, but is accepted (ISO C99 says "as no effect + on a following a, A, e, E, f, F, g, or G conversion specifier"). */ #define FLOATING_POINT_ARG_TYPE(at) \ - ((at) == MPFR_ARG || (at) == MPF_ARG || (at) == LONG_DOUBLE_ARG) + ((at) == MPFR_ARG || (at) == MPF_ARG \ + || (at) == LONG_ARG || (at) == LONG_DOUBLE_ARG) #define INTEGER_LIKE_ARG_TYPE(at) \ ((at) == SHORT_ARG || (at) == LONG_ARG || (at) == LONG_LONG_ARG \ @@ -237,16 +240,18 @@ specinfo_is_valid (struct printf_spec spec) case 'a': case 'A': case 'e': case 'E': - case 'f': case 'F': + case 'f': /* 'F': see below */ case 'g': case 'G': return (spec.arg_type == NONE || FLOATING_POINT_ARG_TYPE (spec.arg_type)); + case 'F': /* only MPFR_ARG is supported since GMP doesn't support it + due to its use as the mpf_t type specifier */ case 'b': return spec.arg_type == MPFR_ARG; case 'd': case 'i': - case 'u': case 'o': + case 'o': case 'u': case 'x': case 'X': return (spec.arg_type == NONE || INTEGER_LIKE_ARG_TYPE (spec.arg_type)); @@ -402,7 +407,6 @@ parse_arg_type (const char *format, struct printf_spec *specinfo) to int (because wchar_t <= int). For wint_t, we assume that the case WINT_MAX < INT_MAX yields an integer promotion. */ -#ifdef HAVE_WCHAR_H #if defined(WINT_MAX) && WINT_MAX < INT_MAX typedef int mpfr_va_wint; /* integer promotion */ #else @@ -418,13 +422,14 @@ typedef wint_t mpfr_va_wint; (void) va_arg ((ap), mpfr_va_wint); \ else if ((specinfo).spec == 's') \ (void) va_arg ((ap), int); /* we assume integer promotion */ \ + else if ((specinfo).spec == 'a' || (specinfo).spec == 'A' \ + || (specinfo).spec == 'e' || (specinfo).spec == 'E' \ + || (specinfo).spec == 'f' /* 'F' impossible */ \ + || (specinfo).spec == 'g' || (specinfo).spec == 'G') \ + (void) va_arg ((ap), double); \ + else \ + MPFR_RET_NEVER_GO_HERE(); \ break; -#else -#define CASE_LONG_ARG(specinfo, ap) \ - case LONG_ARG: \ - (void) va_arg ((ap), long); \ - break; -#endif #if defined(_MPFR_H_HAVE_INTMAX_T) #define CASE_INTMAX_ARG(specinfo, ap) \ @@ -494,14 +499,14 @@ typedef wint_t mpfr_va_wint; case 'c': \ (void) va_arg ((ap), int); \ break; \ - case 'f': \ - case 'F': \ + case 'a': \ + case 'A': \ case 'e': \ case 'E': \ + case 'f': \ + /* 'F' impossible */ \ case 'g': \ case 'G': \ - case 'a': \ - case 'A': \ (void) va_arg ((ap), double); \ break; \ case 's': \ @@ -635,7 +640,13 @@ buffer_widen (struct string_buffer *b, size_t len) static int buffer_cat (struct string_buffer *b, const char *s, size_t len) { - MPFR_ASSERTD (len > 0); + /* If len == 0, which is possible when outputting an integer 0 + (either a native one or mpfr_prec_t) with precision field = 0, + do nothing. This test is not necessary since the code below is + valid for len == 0, but this is safer, just in case. */ + if (len == 0) + return 0; + MPFR_ASSERTD (len <= strlen (s)); if (buffer_incr_len (b, len)) @@ -963,7 +974,7 @@ floor_log10 (mpfr_srcptr x) #define NDIGITS 8 MPFR_RETURNS_NONNULL static char * -mpfr_get_str_wrapper (mpfr_exp_t *exp, int base, size_t n, const mpfr_t op, +mpfr_get_str_wrapper (mpfr_exp_t *exp, int base, size_t n, mpfr_srcptr op, const struct printf_spec spec) { size_t ndigits; @@ -1636,7 +1647,7 @@ regular_fg (struct number_parts *np, mpfr_srcptr p, } if (str_len > 0) - /* some nonzero digits in fractional part */ + /* some non-zero digits in fractional part */ { np->point = MPFR_DECIMAL_POINT; np->fp_ptr = str; |