2024-06-22 Bruno Haible <bruno@clisp.org>
+ vsprintf-posix: Use vzsprintf.
+ * lib/stdio.in.h (vsprintf): Move specification to here.
+ * lib/vsprintf.c: Don't include <stdlib.h>, vasnprintf.h.
+ (SIZE_MAX): Remove macro.
+ (vsprintf): Implement based on vzsprintf.
+ * modules/vsprintf-posix (Depends-on): Add vzsprintf. Remove vasnprintf.
+
vzsprintf: New module.
* lib/stdio.in.h (vzsprintf): New declaration, based on
lib/vsprintf.c.
#endif
#if @GNULIB_VSPRINTF_POSIX@
+/* Prints formatted output to string STR.
+ Returns the string length of the formatted string. Upon failure,
+ returns a negative value. */
# if @REPLACE_VSPRINTF@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define vsprintf rpl_vsprintf
#include <limits.h>
#include <stdarg.h>
#include <stdint.h>
-#include <stdlib.h>
-#include "vasnprintf.h"
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
-/* Print formatted output to string STR.
- Return string length of formatted string. On error, return a negative
- value. */
int
vsprintf (char *str, const char *format, va_list args)
{
- char *output;
- size_t len;
- size_t lenbuf;
-
- /* vasnprintf fails with EOVERFLOW when the buffer size argument is larger
- than INT_MAX (if that fits into a 'size_t' at all).
- Also note that glibc's iconv fails with E2BIG when we pass a length that
- is so large that str + lenbuf wraps around, i.e.
- (uintptr_t) (str + lenbuf) < (uintptr_t) str.
- Therefore set lenbuf = min (SIZE_MAX, INT_MAX, - (uintptr_t) str - 1). */
- lenbuf = (SIZE_MAX < INT_MAX ? SIZE_MAX : INT_MAX);
- if (lenbuf > ~ (uintptr_t) str)
- lenbuf = ~ (uintptr_t) str;
-
- output = vasnprintf (str, &lenbuf, format, args);
- len = lenbuf;
-
- if (!output)
- return -1;
+ ptrdiff_t ret = vzsprintf (str, format, args);
- if (output != str)
- {
- /* len is near SIZE_MAX. */
- free (output);
- errno = EOVERFLOW;
- return -1;
- }
-
- if (len > INT_MAX)
+#if PTRDIFF_MAX > INT_MAX
+ if (ret > INT_MAX)
{
errno = EOVERFLOW;
return -1;
}
+#endif
- return len;
+ return ret;
}
nocrash
printf-safe
multiarch
-vasnprintf [test $REPLACE_VSPRINTF = 1]
+vzsprintf [test $REPLACE_VSPRINTF = 1]
isnand-nolibm [test $REPLACE_VSPRINTF = 1]
isnanl-nolibm [test $REPLACE_VSPRINTF = 1]
frexp-nolibm [test $REPLACE_VSPRINTF = 1]