1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-17 09:10:22 +02:00

Update Gnulib to v0.1-4379-g2ef5a9b4b

Also bump required autoconf version to 2.64, as required by Gnulib.
This commit is contained in:
Andy Wingo 2021-01-20 21:52:54 +01:00
parent 758b31994c
commit a91b95cca2
483 changed files with 26665 additions and 10031 deletions

View file

@ -1,5 +1,5 @@
/* vsprintf with automatic memory allocation.
Copyright (C) 1999, 2002-2017 Free Software Foundation, Inc.
Copyright (C) 1999, 2002-2021 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@ -12,7 +12,7 @@
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, see <http://www.gnu.org/licenses/>. */
with this program; if not, see <https://www.gnu.org/licenses/>. */
/* This file can be parametrized with the following macros:
VASNPRINTF The name of the function being defined.
@ -41,7 +41,14 @@
DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t.
ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
ENABLE_WCHAR_FALLBACK Set to 1 to avoid EILSEQ during conversion of wide
characters (wchar_t) and wide character strings
(wchar_t[]) to multibyte sequences. The fallback is the
hexadecimal escape syntax (\unnnn or \Unnnnnnnn) or,
if wchar_t is not Unicode encoded, \wnnnn or \Wnnnnnnnn.
*/
/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
This must come before <config.h> because <config.h> may include
@ -87,6 +94,7 @@
/* Checked size_t computations. */
#include "xsize.h"
#include "attribute.h"
#include "verify.h"
#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
@ -156,6 +164,7 @@
# define SNPRINTF snwprintf
# else
# define SNPRINTF _snwprintf
# define USE_MSVC__SNPRINTF 1
# endif
# else
/* Unix. */
@ -181,7 +190,9 @@
/* Here we need to call the native snprintf, not rpl_snprintf. */
# undef snprintf
# else
/* MSVC versions < 14 did not have snprintf, only _snprintf. */
# define SNPRINTF _snprintf
# define USE_MSVC__SNPRINTF 1
# endif
# else
/* Unix. */
@ -208,7 +219,7 @@
#undef remainder
#define remainder rem
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && !WIDE_CHAR_VERSION
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && !WIDE_CHAR_VERSION
# if (HAVE_STRNLEN && !defined _AIX)
# define local_strnlen strnlen
# else
@ -224,7 +235,7 @@ local_strnlen (const char *string, size_t maxlen)
# endif
#endif
#if (((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && WIDE_CHAR_VERSION) || ((!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && !WIDE_CHAR_VERSION && DCHAR_IS_TCHAR)) && HAVE_WCHAR_T
#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
# if HAVE_WCSLEN
# define local_wcslen wcslen
# else
@ -247,7 +258,7 @@ local_wcslen (const wchar_t *s)
# endif
#endif
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF) && HAVE_WCHAR_T && WIDE_CHAR_VERSION
# if HAVE_WCSNLEN
# define local_wcsnlen wcsnlen
# else
@ -266,6 +277,74 @@ local_wcsnlen (const wchar_t *s, size_t maxlen)
# endif
#endif
#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
# if ENABLE_WCHAR_FALLBACK
static size_t
wctomb_fallback (char *s, wchar_t wc)
{
static char hex[16] = "0123456789ABCDEF";
s[0] = '\\';
if (sizeof (wchar_t) > 2 && wc > 0xffff)
{
# if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
s[1] = 'U';
# else
s[1] = 'W';
# endif
s[2] = hex[(wc & 0xf0000000U) >> 28];
s[3] = hex[(wc & 0xf000000U) >> 24];
s[4] = hex[(wc & 0xf00000U) >> 20];
s[5] = hex[(wc & 0xf0000U) >> 16];
s[6] = hex[(wc & 0xf000U) >> 12];
s[7] = hex[(wc & 0xf00U) >> 8];
s[8] = hex[(wc & 0xf0U) >> 4];
s[9] = hex[wc & 0xfU];
return 10;
}
else
{
# if __STDC_ISO_10646__ || (__GLIBC__ >= 2) || (defined _WIN32 || defined __CYGWIN__)
s[1] = 'u';
# else
s[1] = 'w';
# endif
s[2] = hex[(wc & 0xf000U) >> 12];
s[3] = hex[(wc & 0xf00U) >> 8];
s[4] = hex[(wc & 0xf0U) >> 4];
s[5] = hex[wc & 0xfU];
return 6;
}
}
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
static size_t
local_wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
{
size_t count = wcrtomb (s, wc, ps);
if (count == (size_t)(-1))
count = wctomb_fallback (s, wc);
return count;
}
# else
static int
local_wctomb (char *s, wchar_t wc)
{
int count = wctomb (s, wc);
if (count < 0)
count = wctomb_fallback (s, wc);
return count;
}
# define local_wcrtomb(S, WC, PS) local_wctomb ((S), (WC))
# endif
# else
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
# define local_wcrtomb(S, WC, PS) wcrtomb ((S), (WC), (PS))
# else
# define local_wcrtomb(S, WC, PS) wctomb ((S), (WC))
# endif
# endif
#endif
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
/* Determine the decimal-point character according to the current locale. */
# ifndef decimal_point_char_defined
@ -554,7 +633,8 @@ divide (mpn_t a, mpn_t b, mpn_t *q)
mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
/* Determine s = GMP_LIMB_BITS - integer_length (msd).
Code copied from gnulib's integer_length.c. */
# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
|| (__clang_major__ >= 4)
s = __builtin_clz (msd);
# else
# if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
@ -849,7 +929,9 @@ convert_to_decimal (mpn_t a, size_t extra_zeroes)
size_t a_len = a.nlimbs;
/* 0.03345 is slightly larger than log(2)/(9*log(10)). */
size_t c_len = 9 * ((size_t)(a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
/* We need extra_zeroes bytes for zeroes, followed by c_len bytes for the
digits of a, followed by 1 byte for the terminating NUL. */
char *c_ptr = (char *) malloc (xsum (xsum (extra_zeroes, c_len), 1));
if (c_ptr != NULL)
{
char *d_ptr = c_ptr;
@ -1517,7 +1599,7 @@ is_borderline (const char *digits, size_t precision)
#endif
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
/* Use a different function name, to make it possible that the 'wchar_t'
parametrization and the 'char' parametrization get compiled in the same
@ -1540,16 +1622,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
switch (conversion)
{
case 'd': case 'i': case 'u':
# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.30103 /* binary -> decimal */
@ -1570,16 +1649,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
break;
case 'o':
# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.333334 /* binary -> octal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.333334 /* binary -> octal */
@ -1598,16 +1674,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
break;
case 'x': case 'X':
# if HAVE_LONG_LONG_INT
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
)
+ 1; /* turn floor into ceil */
else
# endif
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
else if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
* 0.25 /* binary -> hexadecimal */
@ -1673,7 +1746,13 @@ MAX_ROOM_NEEDED (const arguments *ap, size_t arg_index, FCHAR_T conversion,
case 'c':
# if HAVE_WINT_T && !WIDE_CHAR_VERSION
if (type == TYPE_WIDE_CHAR)
tmp_length = MB_CUR_MAX;
{
tmp_length = MB_CUR_MAX;
# if ENABLE_WCHAR_FALLBACK
if (tmp_length < (sizeof (wchar_t) > 2 ? 10 : 6))
tmp_length = (sizeof (wchar_t) > 2 ? 10 : 6);
# endif
}
else
# endif
tmp_length = 1;
@ -1926,11 +2005,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
case TYPE_COUNT_LONGINT_POINTER:
*a.arg[dp->arg_index].a.a_count_longint_pointer = length;
break;
#if HAVE_LONG_LONG_INT
case TYPE_COUNT_LONGLONGINT_POINTER:
*a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
break;
#endif
default:
abort ();
}
@ -2392,7 +2469,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
#endif
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL)) && HAVE_WCHAR_T
#if (!USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || (NEED_PRINTF_DIRECTIVE_LS && !defined IN_LIBINTL) || ENABLE_WCHAR_FALLBACK) && HAVE_WCHAR_T
else if (dp->conversion == 's'
# if WIDE_CHAR_VERSION
&& a.arg[dp->arg_index].type != TYPE_WIDE_STRING
@ -2667,11 +2744,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg_end == 0)
/* Found the terminating null wide character. */
break;
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
count = wcrtomb (cbuf, *arg_end, &state);
# else
count = wctomb (cbuf, *arg_end);
# endif
count = local_wcrtomb (cbuf, *arg_end, &state);
if (count < 0)
{
/* Cannot convert. */
@ -2683,7 +2756,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
errno = EILSEQ;
return NULL;
}
if (precision < count)
if (precision < (unsigned int) count)
break;
arg_end++;
characters += count;
@ -2712,11 +2785,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg_end == 0)
/* Found the terminating null wide character. */
break;
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
count = wcrtomb (cbuf, *arg_end, &state);
# else
count = wctomb (cbuf, *arg_end);
# endif
count = local_wcrtomb (cbuf, *arg_end, &state);
if (count < 0)
{
/* Cannot convert. */
@ -2761,11 +2830,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg == 0)
abort ();
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
count = wcrtomb (cbuf, *arg, &state);
# else
count = wctomb (cbuf, *arg);
# endif
count = local_wcrtomb (cbuf, *arg, &state);
if (count <= 0)
/* Inconsistency. */
abort ();
@ -2842,11 +2907,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg == 0)
abort ();
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
count = wcrtomb (cbuf, *arg, &state);
# else
count = wctomb (cbuf, *arg);
# endif
count = local_wcrtomb (cbuf, *arg, &state);
if (count <= 0)
/* Inconsistency. */
abort ();
@ -2871,11 +2932,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (*arg == 0)
abort ();
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
count = wcrtomb (cbuf, *arg, &state);
# else
count = wctomb (cbuf, *arg);
# endif
count = local_wcrtomb (cbuf, *arg, &state);
if (count <= 0)
{
/* Cannot convert. */
@ -2911,6 +2968,210 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
# endif
}
#endif
#if ENABLE_WCHAR_FALLBACK && HAVE_WINT_T && !WIDE_CHAR_VERSION
else if (dp->conversion == 'c'
&& a.arg[dp->arg_index].type == TYPE_WIDE_CHAR)
{
/* Implement the 'lc' directive ourselves, in order to provide
the fallback that avoids EILSEQ. */
int flags = dp->flags;
int has_width;
size_t width;
has_width = 0;
width = 0;
if (dp->width_start != dp->width_end)
{
if (dp->width_arg_index != ARG_NONE)
{
int arg;
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
abort ();
arg = a.arg[dp->width_arg_index].a.a_int;
width = arg;
if (arg < 0)
{
/* "A negative field width is taken as a '-' flag
followed by a positive field width." */
flags |= FLAG_LEFT;
width = -width;
}
}
else
{
const FCHAR_T *digitp = dp->width_start;
do
width = xsum (xtimes (width, 10), *digitp++ - '0');
while (digitp != dp->width_end);
}
has_width = 1;
}
/* %lc in vasnprintf. See the specification of fprintf. */
{
wchar_t arg = (wchar_t) a.arg[dp->arg_index].a.a_wide_char;
size_t characters;
# if !DCHAR_IS_TCHAR
/* This code assumes that TCHAR_T is 'char'. */
verify (sizeof (TCHAR_T) == 1);
TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64. */
DCHAR_T *tmpdst;
size_t tmpdst_len;
# endif
size_t w;
# if DCHAR_IS_TCHAR
if (has_width)
# endif
{
/* Count the number of bytes. */
characters = 0;
if (arg != 0)
{
char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
int count;
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
mbstate_t state;
memset (&state, '\0', sizeof (mbstate_t));
# endif
count = local_wcrtomb (cbuf, arg, &state);
if (count < 0)
/* Inconsistency. */
abort ();
characters = count;
}
}
# if DCHAR_IS_TCHAR
else
{
/* The number of bytes doesn't matter. */
characters = 0;
}
# endif
# if !DCHAR_IS_TCHAR
/* Convert the string into a piece of temporary memory. */
if (characters > 0) /* implies arg != 0 */
{
char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
int count;
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
mbstate_t state;
memset (&state, '\0', sizeof (mbstate_t));
# endif
count = local_wcrtomb (cbuf, arg, &state);
if (count <= 0)
/* Inconsistency. */
abort ();
memcpy (tmpsrc, cbuf, count);
}
/* Convert from TCHAR_T[] to DCHAR_T[]. */
tmpdst =
DCHAR_CONV_FROM_ENCODING (locale_charset (),
iconveh_question_mark,
tmpsrc, characters,
NULL,
NULL, &tmpdst_len);
if (tmpdst == NULL)
{
int saved_errno = errno;
if (!(result == resultbuf || result == NULL))
free (result);
if (buf_malloced != NULL)
free (buf_malloced);
CLEANUP ();
errno = saved_errno;
return NULL;
}
# endif
if (has_width)
{
# if ENABLE_UNISTDIO
/* Outside POSIX, it's preferable to compare the width
against the number of _characters_ of the converted
value. */
w = DCHAR_MBSNLEN (result + length, characters);
# else
/* The width is compared against the number of _bytes_
of the converted value, says POSIX. */
w = characters;
# endif
}
else
/* w doesn't matter. */
w = 0;
if (w < width && !(dp->flags & FLAG_LEFT))
{
size_t n = width - w;
ENSURE_ALLOCATION (xsum (length, n));
DCHAR_SET (result + length, ' ', n);
length += n;
}
# if DCHAR_IS_TCHAR
if (has_width)
{
/* We know the number of bytes in advance. */
ENSURE_ALLOCATION (xsum (length, characters));
if (characters > 0) /* implies arg != 0 */
{
int count;
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
mbstate_t state;
memset (&state, '\0', sizeof (mbstate_t));
# endif
count = local_wcrtomb (result + length, arg, &state);
if (count <= 0)
/* Inconsistency. */
abort ();
length += count;
}
}
else
{
if (arg != 0)
{
char cbuf[64]; /* Assume MB_CUR_MAX <= 64. */
int count;
# if HAVE_WCRTOMB && !defined GNULIB_defined_mbstate_t
mbstate_t state;
memset (&state, '\0', sizeof (mbstate_t));
# endif
count = local_wcrtomb (cbuf, arg, &state);
if (count <= 0)
/* Inconsistency. */
abort ();
ENSURE_ALLOCATION (xsum (length, count));
memcpy (result + length, cbuf, count);
length += count;
}
}
# else
ENSURE_ALLOCATION (xsum (length, tmpdst_len));
DCHAR_CPY (result + length, tmpdst, tmpdst_len);
free (tmpdst);
length += tmpdst_len;
# endif
if (w < width && (dp->flags & FLAG_LEFT))
{
size_t n = width - w;
ENSURE_ALLOCATION (xsum (length, n));
DCHAR_SET (result + length, ' ', n);
length += n;
}
}
}
#endif
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
else if ((dp->conversion == 'a' || dp->conversion == 'A')
# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
@ -4232,7 +4493,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
static const wchar_t decimal_format[] =
/* Produce the same number of exponent digits
as the native printf implementation. */
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# if defined _WIN32 && ! defined __CYGWIN__
{ '%', '+', '.', '3', 'd', '\0' };
# else
{ '%', '+', '.', '2', 'd', '\0' };
@ -4246,7 +4507,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
static const char decimal_format[] =
/* Produce the same number of exponent digits
as the native printf implementation. */
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# if defined _WIN32 && ! defined __CYGWIN__
"%+.3d";
# else
"%+.2d";
@ -4425,7 +4686,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
static const wchar_t decimal_format[] =
/* Produce the same number of exponent digits
as the native printf implementation. */
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# if defined _WIN32 && ! defined __CYGWIN__
{ '%', '+', '.', '3', 'd', '\0' };
# else
{ '%', '+', '.', '2', 'd', '\0' };
@ -4439,7 +4700,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
static const char decimal_format[] =
/* Produce the same number of exponent digits
as the native printf implementation. */
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# if defined _WIN32 && ! defined __CYGWIN__
"%+.3d";
# else
"%+.2d";
@ -4497,7 +4758,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
*p++ = '+';
/* Produce the same number of exponent digits as
the native printf implementation. */
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
# if defined _WIN32 && ! defined __CYGWIN__
*p++ = '0';
# endif
*p++ = '0';
@ -4591,10 +4852,10 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
int has_width;
#endif
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
#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
size_t width;
#endif
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
int has_precision;
size_t precision;
#endif
@ -4623,7 +4884,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
has_width = 0;
#endif
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_LEFTADJUST || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
#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
width = 0;
if (dp->width_start != dp->width_end)
{
@ -4657,7 +4918,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
#endif
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || NEED_PRINTF_UNBOUNDED_PRECISION
#if !USE_SNPRINTF || !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
has_precision = 0;
precision = 6;
if (dp->precision_start != dp->precision_end)
@ -4822,19 +5083,17 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
switch (type)
{
#if HAVE_LONG_LONG_INT
case TYPE_LONGLONGINT:
case TYPE_ULONGLONGINT:
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
#if defined _WIN32 && ! defined __CYGWIN__
*fbp++ = 'I';
*fbp++ = '6';
*fbp++ = '4';
break;
# else
#else
*fbp++ = 'l';
# endif
#endif
/*FALLTHROUGH*/
FALLTHROUGH;
case TYPE_LONGINT:
case TYPE_ULONGINT:
#if HAVE_WINT_T
@ -4858,20 +5117,32 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#endif
*fbp = dp->conversion;
#if USE_SNPRINTF
# if !(((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined __UCLIBC__) || ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
fbp[1] = '%';
fbp[2] = 'n';
fbp[3] = '\0';
# else
/* On glibc2 systems from glibc >= 2.3 - probably also older
ones - we know that snprintf's return value conforms to
ISO C 99: the tests gl_SNPRINTF_RETVAL_C99 and
gl_SNPRINTF_TRUNCATION_C99 pass.
Therefore we can avoid using %n in this situation.
On glibc2 systems from 2004-10-18 or newer, the use of %n
in format strings in writable memory may crash the program
(if compiled with _FORTIFY_SOURCE=2), so we should avoid it
in this situation. */
# if ((HAVE_SNPRINTF_RETVAL_C99 && HAVE_SNPRINTF_TRUNCATION_C99) \
|| ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) \
&& !defined __UCLIBC__) \
|| (defined __APPLE__ && defined __MACH__) \
|| defined __ANDROID__ \
|| (defined _WIN32 && ! defined __CYGWIN__))
/* On systems where we know that snprintf's return value
conforms to ISO C 99 (HAVE_SNPRINTF_RETVAL_C99) and that
snprintf always produces NUL-terminated strings
(HAVE_SNPRINTF_TRUNCATION_C99), it is possible to avoid
using %n. And it is desirable to do so, because more and
more platforms no longer support %n, for "security reasons".
In particular, the following platforms:
- On glibc2 systems from 2004-10-18 or newer, the use of
%n in format strings in writable memory may crash the
program (if compiled with _FORTIFY_SOURCE=2).
- On Mac OS X 10.13 or newer, the use of %n in format
strings in writable memory by default crashes the
program.
- On Android, starting on 2018-03-07, the use of %n in
format strings produces a fatal error (see
<https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336>).
On these platforms, HAVE_SNPRINTF_RETVAL_C99 and
HAVE_SNPRINTF_TRUNCATION_C99 are 1. We have listed them
explicitly in the condition above, in case of cross-
compilation (just to be sure). */
/* On native Windows systems (such as mingw), we can avoid using
%n because:
- Although the gl_SNPRINTF_TRUNCATION_C99 test fails,
@ -4884,10 +5155,14 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
On native Windows systems (such as mingw) where the OS is
Windows Vista, the use of %n in format strings by default
crashes the program. See
<http://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
<http://msdn2.microsoft.com/en-us/library/ms175782(VS.80).aspx>
<https://gcc.gnu.org/ml/gcc/2007-06/msg00122.html> and
<https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-printf-count-output>
So we should avoid %n in this situation. */
fbp[1] = '\0';
# else /* AIX <= 5.1, HP-UX, IRIX, OSF/1, Solaris <= 9, BeOS */
fbp[1] = '%';
fbp[2] = 'n';
fbp[3] = '\0';
# endif
#else
fbp[1] = '\0';
@ -5031,7 +5306,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
SNPRINTF_BUF (arg);
}
break;
#if HAVE_LONG_LONG_INT
case TYPE_LONGLONGINT:
{
long long int arg = a.arg[dp->arg_index].a.a_longlongint;
@ -5044,7 +5318,6 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
SNPRINTF_BUF (arg);
}
break;
#endif
case TYPE_DOUBLE:
{
double arg = a.arg[dp->arg_index].a.a_double;
@ -5104,7 +5377,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
{
/* Verify that snprintf() has NUL-terminated its
result. */
if (count < maxlen
if ((unsigned int) count < maxlen
&& ((TCHAR_T *) (result + length)) [count] != '\0')
abort ();
/* Portability hack. */
@ -5127,7 +5400,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* Look at the snprintf() return value. */
if (retcount < 0)
{
# if !HAVE_SNPRINTF_RETVAL_C99
# if !HAVE_SNPRINTF_RETVAL_C99 || USE_MSVC__SNPRINTF
/* HP-UX 10.20 snprintf() is doubly deficient:
It doesn't understand the '%n' directive,
*and* it returns -1 (rather than the length