summaryrefslogtreecommitdiff
path: root/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-11-09 03:02:50 +0000
committerNorbert Preining <norbert@preining.info>2022-11-09 03:02:50 +0000
commit5de83ec843cdc88e6adc42b1fe3f0ec48c52b7f3 (patch)
treeb49f7c180396c8ef389c8fd519370b6d03f4e100 /macros/texinfo/texinfo/gnulib/lib/vasnprintf.c
parent118cb5bbc5236bf86ca1088b9b3bae04c7b09beb (diff)
CTAN sync 202211090302
Diffstat (limited to 'macros/texinfo/texinfo/gnulib/lib/vasnprintf.c')
-rw-r--r--macros/texinfo/texinfo/gnulib/lib/vasnprintf.c329
1 files changed, 99 insertions, 230 deletions
diff --git a/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c b/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c
index f9124fa716..01d18bf598 100644
--- a/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c
+++ b/macros/texinfo/texinfo/gnulib/lib/vasnprintf.c
@@ -1,18 +1,18 @@
/* vsprintf with automatic memory allocation.
- Copyright (C) 1999, 2002-2021 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002-2022 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
+ This file is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, see <https://www.gnu.org/licenses/>. */
+ You should have received a copy of the GNU Lesser General Public License
+ along 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.
@@ -60,10 +60,16 @@
#ifndef VASNPRINTF
# include <config.h>
#endif
-#ifndef IN_LIBINTL
-# include <alloca.h>
+
+/* As of GCC 11.2.1, gcc -Wanalyzer-too-complex reports that main's
+ use of CHECK macros expands to code that is too complicated for gcc
+ -fanalyzer. Suppress the resulting bogus warnings. */
+#if 10 <= __GNUC__
+# pragma GCC diagnostic ignored "-Wanalyzer-null-argument"
#endif
+#include <alloca.h>
+
/* Specification. */
#ifndef VASNPRINTF
# if WIDE_CHAR_VERSION
@@ -95,7 +101,6 @@
#include "xsize.h"
#include "attribute.h"
-#include "verify.h"
#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
# include <math.h>
@@ -402,11 +407,11 @@ is_infinite_or_zerol (long double x)
typedef unsigned int mp_limb_t;
# define GMP_LIMB_BITS 32
-verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
+static_assert (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
typedef unsigned long long mp_twolimb_t;
# define GMP_TWOLIMB_BITS 64
-verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
+static_assert (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
/* Representation of a bignum >= 0. */
typedef struct
@@ -909,8 +914,7 @@ divide (mpn_t a, mpn_t b, mpn_t *q)
q_ptr[q_len++] = 1;
}
keep_q:
- if (tmp_roomptr != NULL)
- free (tmp_roomptr);
+ free (tmp_roomptr);
q->limbs = q_ptr;
q->nlimbs = q_len;
return roomptr;
@@ -1859,6 +1863,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* errno is already set. */
return NULL;
+ /* Frees the memory allocated by this function. Preserves errno. */
#define CLEANUP() \
if (d.dir != d.direct_alloc_dir) \
free (d.dir); \
@@ -1866,11 +1871,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
free (a.arg);
if (PRINTF_FETCHARGS (args, &a) < 0)
- {
- CLEANUP ();
- errno = EINVAL;
- return NULL;
- }
+ goto fail_1_with_EINVAL;
{
size_t buf_neededlength;
@@ -1906,24 +1907,17 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
buf_malloced = buf;
}
- if (resultbuf != NULL)
- {
- result = resultbuf;
- allocated = *lengthp;
- }
- else
- {
- result = NULL;
- allocated = 0;
- }
+ result = resultbuf;
+ allocated = (resultbuf != NULL ? *lengthp : 0);
length = 0;
/* Invariants:
- result is either == resultbuf or == NULL or malloc-allocated.
+ result is either == resultbuf or malloc-allocated.
+ If result == NULL, resultbuf is == NULL as well.
If length > 0, then result != NULL. */
/* Ensures that allocated >= needed. Aborts through a jump to
out_of_memory if needed is SIZE_MAX or otherwise too big. */
-#define ENSURE_ALLOCATION(needed) \
+#define ENSURE_ALLOCATION_ELSE(needed, oom_statement) \
if ((needed) > allocated) \
{ \
size_t memory_size; \
@@ -1934,17 +1928,19 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
allocated = (needed); \
memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
if (size_overflow_p (memory_size)) \
- goto out_of_memory; \
- if (result == resultbuf || result == NULL) \
+ oom_statement \
+ if (result == resultbuf) \
memory = (DCHAR_T *) malloc (memory_size); \
else \
memory = (DCHAR_T *) realloc (result, memory_size); \
if (memory == NULL) \
- goto out_of_memory; \
+ oom_statement \
if (result == resultbuf && length > 0) \
DCHAR_CPY (memory, result, length); \
result = memory; \
}
+#define ENSURE_ALLOCATION(needed) \
+ ENSURE_ALLOCATION_ELSE((needed), goto out_of_memory; )
for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
{
@@ -2103,15 +2099,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (count == 0)
break;
if (count < 0)
- {
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ goto fail_with_EILSEQ;
arg_end += count;
characters++;
}
@@ -2128,15 +2116,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (count == 0)
break;
if (count < 0)
- {
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ goto fail_with_EILSEQ;
arg_end += count;
characters++;
}
@@ -2182,19 +2162,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
converted, &converted_len);
# endif
if (converted == 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;
- }
+ goto fail_with_errno;
if (converted != result + length)
{
- ENSURE_ALLOCATION (xsum (length, converted_len));
+ ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
+ { free (converted); goto out_of_memory; });
DCHAR_CPY (result + length, converted, converted_len);
free (converted);
}
@@ -2229,15 +2201,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (count == 0)
break;
if (count < 0)
- {
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ goto fail_with_EILSEQ;
arg_end += count;
characters++;
}
@@ -2254,15 +2218,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (count == 0)
break;
if (count < 0)
- {
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ goto fail_with_EILSEQ;
arg_end += count;
characters++;
}
@@ -2308,19 +2264,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
converted, &converted_len);
# endif
if (converted == 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;
- }
+ goto fail_with_errno;
if (converted != result + length)
{
- ENSURE_ALLOCATION (xsum (length, converted_len));
+ ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
+ { free (converted); goto out_of_memory; });
DCHAR_CPY (result + length, converted, converted_len);
free (converted);
}
@@ -2355,15 +2303,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (count == 0)
break;
if (count < 0)
- {
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ goto fail_with_EILSEQ;
arg_end += count;
characters++;
}
@@ -2380,15 +2320,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
if (count == 0)
break;
if (count < 0)
- {
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ goto fail_with_EILSEQ;
arg_end += count;
characters++;
}
@@ -2434,19 +2366,11 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
converted, &converted_len);
# endif
if (converted == 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;
- }
+ goto fail_with_errno;
if (converted != result + length)
{
- ENSURE_ALLOCATION (xsum (length, converted_len));
+ ENSURE_ALLOCATION_ELSE (xsum (length, converted_len),
+ { free (converted); goto out_of_memory; });
DCHAR_CPY (result + length, converted, converted_len);
free (converted);
}
@@ -2584,16 +2508,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* Found the terminating NUL. */
break;
if (count < 0)
- {
- /* Invalid or incomplete multibyte character. */
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ /* Invalid or incomplete multibyte character. */
+ goto fail_with_EILSEQ;
arg_end += count;
characters++;
}
@@ -2620,16 +2536,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* Found the terminating NUL. */
break;
if (count < 0)
- {
- /* Invalid or incomplete multibyte character. */
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ /* Invalid or incomplete multibyte character. */
+ goto fail_with_EILSEQ;
arg_end += count;
characters++;
}
@@ -2719,7 +2627,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
size_t characters;
# if !DCHAR_IS_TCHAR
/* This code assumes that TCHAR_T is 'char'. */
- verify (sizeof (TCHAR_T) == 1);
+ static_assert (sizeof (TCHAR_T) == 1);
TCHAR_T *tmpsrc;
DCHAR_T *tmpdst;
size_t tmpdst_len;
@@ -2746,16 +2654,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
break;
count = local_wcrtomb (cbuf, *arg_end, &state);
if (count < 0)
- {
- /* Cannot convert. */
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ /* Cannot convert. */
+ goto fail_with_EILSEQ;
if (precision < (unsigned int) count)
break;
arg_end++;
@@ -2787,16 +2687,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
break;
count = local_wcrtomb (cbuf, *arg_end, &state);
if (count < 0)
- {
- /* Cannot convert. */
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ /* Cannot convert. */
+ goto fail_with_EILSEQ;
arg_end++;
characters += count;
}
@@ -2852,15 +2744,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
NULL, &tmpdst_len);
if (tmpdst == NULL)
{
- int saved_errno = errno;
free (tmpsrc);
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = saved_errno;
- return NULL;
+ goto fail_with_errno;
}
free (tmpsrc);
# endif
@@ -2934,16 +2819,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
abort ();
count = local_wcrtomb (cbuf, *arg, &state);
if (count <= 0)
- {
- /* Cannot convert. */
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
- errno = EILSEQ;
- return NULL;
- }
+ /* Cannot convert. */
+ goto fail_with_EILSEQ;
ENSURE_ALLOCATION (xsum (length, count));
memcpy (result + length, cbuf, count);
length += count;
@@ -2951,7 +2828,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
# else
- ENSURE_ALLOCATION (xsum (length, tmpdst_len));
+ ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
+ { free (tmpdst); goto out_of_memory; });
DCHAR_CPY (result + length, tmpdst, tmpdst_len);
free (tmpdst);
length += tmpdst_len;
@@ -3015,7 +2893,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
size_t characters;
# if !DCHAR_IS_TCHAR
/* This code assumes that TCHAR_T is 'char'. */
- verify (sizeof (TCHAR_T) == 1);
+ static_assert (sizeof (TCHAR_T) == 1);
TCHAR_T tmpsrc[64]; /* Assume MB_CUR_MAX <= 64. */
DCHAR_T *tmpdst;
size_t tmpdst_len;
@@ -3078,16 +2956,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
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;
- }
+ goto fail_with_errno;
# endif
if (has_width)
@@ -3156,7 +3025,8 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
}
}
# else
- ENSURE_ALLOCATION (xsum (length, tmpdst_len));
+ ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
+ { free (tmpdst); goto out_of_memory; });
DCHAR_CPY (result + length, tmpdst, tmpdst_len);
free (tmpdst);
length += tmpdst_len;
@@ -5449,25 +5319,17 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
/* Attempt to handle failure. */
if (count < 0)
{
- /* SNPRINTF or sprintf failed. Save and use the errno
- that it has set, if any. */
- int saved_errno = errno;
- if (saved_errno == 0)
+ /* SNPRINTF or sprintf failed. Use the errno that it
+ has set, if any. */
+ if (errno == 0)
{
if (dp->conversion == 'c' || dp->conversion == 's')
- saved_errno = EILSEQ;
+ errno = EILSEQ;
else
- saved_errno = EINVAL;
+ errno = EINVAL;
}
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
-
- errno = saved_errno;
- return NULL;
+ goto fail_with_errno;
}
#if USE_SNPRINTF
@@ -5588,7 +5450,7 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
DCHAR_T *tmpdst;
size_t tmpdst_len;
/* This code assumes that TCHAR_T is 'char'. */
- verify (sizeof (TCHAR_T) == 1);
+ static_assert (sizeof (TCHAR_T) == 1);
# if USE_SNPRINTF
tmpsrc = (TCHAR_T *) (result + length);
# else
@@ -5601,17 +5463,9 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
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;
- }
- ENSURE_ALLOCATION (xsum (length, tmpdst_len));
+ goto fail_with_errno;
+ ENSURE_ALLOCATION_ELSE (xsum (length, tmpdst_len),
+ { free (tmpdst); goto out_of_memory; });
DCHAR_CPY (result + length, tmpdst, tmpdst_len);
free (tmpdst);
count = tmpdst_len;
@@ -5834,25 +5688,40 @@ VASNPRINTF (DCHAR_T *resultbuf, size_t *lengthp,
#if USE_SNPRINTF
overflow:
- if (!(result == resultbuf || result == NULL))
- free (result);
- if (buf_malloced != NULL)
- free (buf_malloced);
- CLEANUP ();
errno = EOVERFLOW;
- return NULL;
+ goto fail_with_errno;
#endif
out_of_memory:
- if (!(result == resultbuf || result == NULL))
+ errno = ENOMEM;
+ goto fail_with_errno;
+
+#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)
+ fail_with_EILSEQ:
+ errno = EILSEQ;
+ goto fail_with_errno;
+#endif
+
+ fail_with_errno:
+ if (result != resultbuf)
free (result);
if (buf_malloced != NULL)
free (buf_malloced);
- out_of_memory_1:
CLEANUP ();
- errno = ENOMEM;
return NULL;
}
+
+ out_of_memory_1:
+ errno = ENOMEM;
+ goto fail_1_with_errno;
+
+ fail_1_with_EINVAL:
+ errno = EINVAL;
+ goto fail_1_with_errno;
+
+ fail_1_with_errno:
+ CLEANUP ();
+ return NULL;
}
#undef MAX_ROOM_NEEDED