From: Bruno Haible Date: Sat, 22 Jun 2024 10:17:02 +0000 (+0200) Subject: vazsprintf: New module. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=cf5774e94a80589b8fd92fd7166dea82c925cfcc;p=gnulib.git vazsprintf: New module. * lib/stdio.in.h (azsprintf, vazsprintf): New declarations. * lib/vazsprintf.c: New file, based on lib/vasprintf.c. * lib/azsprintf.c: New file, based on lib/asprintf.c. * m4/stdio_h.m4 (gl_STDIO_H_REQUIRE_DEFAULTS): Initialize GNULIB_VAZSPRINTF. * modules/stdio (Makefile.am): Substitute GNULIB_VAZSPRINTF. * modules/vazsprintf: New file. --- diff --git a/ChangeLog b/ChangeLog index 76c8dc4dce..b38ebee8a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2024-06-22 Bruno Haible + + vazsprintf: New module. + * lib/stdio.in.h (azsprintf, vazsprintf): New declarations. + * lib/vazsprintf.c: New file, based on lib/vasprintf.c. + * lib/azsprintf.c: New file, based on lib/asprintf.c. + * m4/stdio_h.m4 (gl_STDIO_H_REQUIRE_DEFAULTS): Initialize + GNULIB_VAZSPRINTF. + * modules/stdio (Makefile.am): Substitute GNULIB_VAZSPRINTF. + * modules/vazsprintf: New file. + 2024-06-22 Bruno Haible sprintf-posix: Use vzsprintf. diff --git a/lib/azsprintf.c b/lib/azsprintf.c new file mode 100644 index 0000000000..9489854cb9 --- /dev/null +++ b/lib/azsprintf.c @@ -0,0 +1,34 @@ +/* Formatted output to strings. + Copyright (C) 1999-2024 Free Software Foundation, Inc. + + 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 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 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 . */ + +#include + +/* Specification. */ +#include + +#include + +ptrdiff_t +azsprintf (char **resultp, const char *format, ...) +{ + va_list args; + ptrdiff_t result; + + va_start (args, format); + result = vazsprintf (resultp, format, args); + va_end (args); + return result; +} diff --git a/lib/stdio.in.h b/lib/stdio.in.h index 5a70aa20ba..4844ea1ebf 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -1603,6 +1603,29 @@ _GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - " # endif #endif +#if @GNULIB_VAZSPRINTF@ +/* Prints formatted output to a string dynamically allocated with malloc(). + If the memory allocation succeeds, it stores the address of the string in + *RESULT and returns the number of resulting bytes, excluding the trailing + NUL. Upon memory allocation error, or some other error, it returns -1 + with errno set. + Failure code EOVERFLOW can only occur when a width > INT_MAX is used. + Therefore, if the format string is valid and does not use %ls/%lc + directives nor widths, the only possible failure code is ENOMEM. */ +_GL_FUNCDECL_SYS (azsprintf, ptrdiff_t, + (char **result, const char *format, ...) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_SYS (azsprintf, ptrdiff_t, + (char **result, const char *format, ...)); +_GL_FUNCDECL_SYS (vazsprintf, ptrdiff_t, + (char **result, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0) + _GL_ARG_NONNULL ((1, 2))); +_GL_CXXALIAS_SYS (vazsprintf, ptrdiff_t, + (char **result, const char *format, va_list args)); +#endif + #if @GNULIB_VASPRINTF@ /* Write formatted output to a string dynamically allocated with malloc(). If the memory allocation succeeds, store the address of the string in diff --git a/lib/vazsprintf.c b/lib/vazsprintf.c new file mode 100644 index 0000000000..73002a17d5 --- /dev/null +++ b/lib/vazsprintf.c @@ -0,0 +1,46 @@ +/* Formatted output to strings. + Copyright (C) 1999-2024 Free Software Foundation, Inc. + + 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 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 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 . */ + +#include + +/* Specification. */ +#include + +#include +#include +#include + +#include "vasnprintf.h" + +ptrdiff_t +vazsprintf (char **resultp, const char *format, va_list args) +{ + size_t length; + char *result = vasnprintf (NULL, &length, format, args); + if (result == NULL) + return -1; + + if (length > PTRDIFF_MAX) + { + free (result); + errno = ENOMEM; + return -1; + } + + *resultp = result; + /* Return the number of resulting bytes, excluding the trailing NUL. */ + return length; +} diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 index 69d4b88b4b..aa06d77027 100644 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -1,5 +1,5 @@ # stdio_h.m4 -# serial 67 +# serial 68 dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -177,6 +177,7 @@ AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS], gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_SIGPIPE]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TMPFILE]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VASPRINTF]) + gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VAZSPRINTF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFSCANF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSCANF]) gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VDPRINTF]) diff --git a/modules/stdio b/modules/stdio index 29ed8e0bfa..b0cf4ea207 100644 --- a/modules/stdio +++ b/modules/stdio @@ -112,6 +112,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) -e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GNULIB_STDIO_H_SIGPIPE)/g' \ -e 's/@''GNULIB_TMPFILE''@/$(GNULIB_TMPFILE)/g' \ -e 's/@''GNULIB_VASPRINTF''@/$(GNULIB_VASPRINTF)/g' \ + -e 's/@''GNULIB_VAZSPRINTF''@/$(GNULIB_VAZSPRINTF)/g' \ -e 's/@''GNULIB_VDPRINTF''@/$(GNULIB_VDPRINTF)/g' \ -e 's/@''GNULIB_VFPRINTF''@/$(GNULIB_VFPRINTF)/g' \ -e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GNULIB_VFPRINTF_POSIX)/g' \ diff --git a/modules/vazsprintf b/modules/vazsprintf new file mode 100644 index 0000000000..787825aa71 --- /dev/null +++ b/modules/vazsprintf @@ -0,0 +1,30 @@ +Description: +vsprintf (without INT_MAX limitation) with automatic memory allocation + +Files: +lib/vazsprintf.c +lib/azsprintf.c + +Depends-on: +stdio +vasnprintf +errno +stdint + +configure.ac: +gl_STDIO_MODULE_INDICATOR([vazsprintf]) +m4_ifdef([AM_XGETTEXT_OPTION], + [AM_][XGETTEXT_OPTION([--flag=azsprintf:2:c-format]) + AM_][XGETTEXT_OPTION([--flag=vazsprintf:2:c-format])]) + +Makefile.am: +lib_SOURCES += vazsprintf.c azsprintf.c + +Include: + + +License: +LGPLv2+ + +Maintainer: +all