Here come the c-*zs*printf modules, which are like the existing c-*s*printf modules, except that - they support returning results of length > INT_MAX, - thus the length type is changed to 'ptrdiff_t' from 'int', - an attempt to return a result > PTRDIFF_MAX produces an error ENOMEM (consistently with malloc, calloc) instead of EOVERFLOW.
Module dependencies: c-snprintf -> c-vzsnprintf c-zsnprintf -> c-vasnprintf c-vasprintf -> c-vasnprintf c-vazsprintf -> c-vasnprintf c-vsnprintf -> c-vzsnprintf c-vzsnprintf -> c-vasnprintf c-xvasprintf -> c-vazsprintf Since I'm replacing the implementation of all these modules, I'm taking the opportunity to change their licenses from GPL to LGPL or LGPLv2+. This makes sense because - these functions can reasonably be used in libraries, - some of them could also be implemented based on *printf_l functions that exist in the libc of macOS, FreeBSD, NetBSD. I can do this because - I'm basing the new implementation on the modules without 'c-', which are already under LGPL / LGPLv2+, and - the remaining code pieces contributed by Ben Pfaff are below the 10-lines threshold, cf. <https://www.gnu.org/prep/maintain/html_node/Legally-Significant.html>. 2024-06-22 Bruno Haible <br...@clisp.org> c-xvasprintf: Guarantee a non-NULL result. * lib/c-xvasprintf.h: Clarify the programmer's responsibilities. (c_xasprintf, c_xvasprintf): Declare as returning non-NULL. * lib/c-xvasprintf.c: Include <stdlib.h>, <string.h>. (c_xvasprintf): Call c_vazsprintf instead of c_vasprintf. When some other error occurs, emit an error message and abort. * modules/c-xvasprintf (Files): Add m4/strerrorname_np.m4. (Depends-on): Add extensions, c-vazsprintf. Remove c-vasprintf. (configure.ac): Invoke gl_OPTIONAL_STRERRORNAME_NP. * NEWS: Mention the change. 2024-06-22 Bruno Haible <br...@clisp.org> c-vasprintf: Make return convention consistent with other modules. * lib/c-vasprintf.h (c_asprintf, c_vasprintf): Add specification. * lib/c-asprintf.c: Replaced with code based on lib/asprintf.c. * lib/c-vasprintf.c: Replaced with code based on lib/vasprintf.c. * modules/c-vasprintf (Depends-on): Add stdint. (License): Change to LGPLv2+. c-vazsprintf: New module. * lib/c-vasprintf.h: Change license to LGPLv2+. Include <stddef.h>. (c_azsprintf, c_vazsprintf): New declarations. * lib/c-azsprintf.c: New file, based on lib/azsprintf.c. * lib/c-vazsprintf.c: New file, based on lib/vazsprintf.c. * modules/c-vazsprintf: New file. 2024-06-22 Bruno Haible <br...@clisp.org> c-snprintf: Use c-vzsnprintf. * lib/c-snprintf.h (c_snprintf): Move specification to here. * lib/c-snprintf.c: Change license to LGPLv2+. Don't include <stdlib.h>, <string.h>, c-vasnprintf.h. Include <stdint.h>, c-vsnprintf.h. (c_snprintf): Implement based on c_vzsnprintf. * modules/c-snprintf (Depends-on): Add stdint, c-vzsnprintf. Remove c-vasnprintf. c-zsnprintf: New module. * lib/c-snprintf.h: Change license to LGPLv2+. (c_zsnprintf): New declaration. * lib/c-zsnprintf.c: New file, based on lib/zsnprintf.c. * modules/c-zsnprintf: New file. 2024-06-22 Bruno Haible <br...@clisp.org> c-vsnprintf: Use c-vzsnprintf. * lib/c-vsnprintf.h (c_vsnprintf): Move specification to here. * lib/c-vsnprintf.c: Change license to LGPLv2+. Don't include <stdlib.h>, <string.h>, c-vasnprintf.h. Include <stdint.h>. (c_vsnprintf): Implement based on c_vzsnprintf. * modules/c-vsnprintf (Depends-on): Add stdint, c-vzsnprintf. Remove c-vasnprintf. (License): Change to LGPLv2+. c-vzsnprintf: New module. * lib/c-vsnprintf.h: Change license to LGPLv2+. (c_vzsnprintf): New declaration. * lib/c-vzsnprintf.c: New file, based on lib/vzsnprintf.c. * modules/c-vzsnprintf: New file.
>From 9c456389c96b0532596ea62bcc320f549540d10c Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 22 Jun 2024 12:21:11 +0200 Subject: [PATCH 1/7] c-vzsnprintf: New module. * lib/c-vsnprintf.h: Change license to LGPLv2+. (c_vzsnprintf): New declaration. * lib/c-vzsnprintf.c: New file, based on lib/vzsnprintf.c. * modules/c-vzsnprintf: New file. --- ChangeLog | 8 ++++++ lib/c-vsnprintf.h | 34 +++++++++++++++++------ lib/c-vzsnprintf.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ modules/c-vzsnprintf | 27 ++++++++++++++++++ 4 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 lib/c-vzsnprintf.c create mode 100644 modules/c-vzsnprintf diff --git a/ChangeLog b/ChangeLog index ef21dcc222..0f37171285 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2024-06-22 Bruno Haible <br...@clisp.org> + + c-vzsnprintf: New module. + * lib/c-vsnprintf.h: Change license to LGPLv2+. + (c_vzsnprintf): New declaration. + * lib/c-vzsnprintf.c: New file, based on lib/vzsnprintf.c. + * modules/c-vzsnprintf: New file. + 2024-06-22 Bruno Haible <br...@clisp.org> xvasprintf: Guarantee a non-NULL result. diff --git a/lib/c-vsnprintf.h b/lib/c-vsnprintf.h index 57d689e297..e00ade93f8 100644 --- a/lib/c-vsnprintf.h +++ b/lib/c-vsnprintf.h @@ -1,18 +1,18 @@ /* vsnprintf in C locale. Copyright (C) 2012-2024 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/>. */ #ifndef _C_VSNPRINTF_H #define _C_VSNPRINTF_H @@ -22,7 +22,7 @@ #error "Please include config.h first." #endif -/* Get size_t. */ +/* Get size_t, ptrdiff_t. */ #include <stddef.h> /* Get va_list. */ @@ -35,6 +35,22 @@ extern "C" { #endif +/* Prints formatted output to string STR. Similar to vsprintf, but the + additional parameter SIZE limits how much is written into STR. + STR may be NULL, in which case nothing will be written. + Returns the string length of the formatted string (which may be larger + than SIZE). Upon failure, 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. + + Formatting takes place in the C locale, that is, the decimal point + used in floating-point formatting directives is always '.'. */ +extern ptrdiff_t c_vzsnprintf (char *restrict str, size_t size, + const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 0)); + extern int c_vsnprintf (char *restrict str, size_t size, const char *format, va_list args) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 0)); diff --git a/lib/c-vzsnprintf.c b/lib/c-vzsnprintf.c new file mode 100644 index 0000000000..948266dd99 --- /dev/null +++ b/lib/c-vzsnprintf.c @@ -0,0 +1,66 @@ +/* Formatted output to strings in C locale. + Copyright (C) 2004, 2006-2024 Free Software Foundation, Inc. + Written by Simon Josefsson and Yoann Vandoorselaere <yo...@prelude-ids.org>. + Modified for C locale by Ben Pfaff. + + 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 <https://www.gnu.org/licenses/>. */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +/* Specification. */ +#include "c-vsnprintf.h" + +#include <errno.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "c-vasnprintf.h" + +ptrdiff_t +c_vzsnprintf (char *str, size_t size, const char *format, va_list args) +{ + char *output; + size_t len; + size_t lenbuf = size; + + output = c_vasnprintf (str, &lenbuf, format, args); + len = lenbuf; + + if (!output) + return -1; + + if (output != str) + { + if (size) + { + size_t pruned_len = (len < size ? len : size - 1); + memcpy (str, output, pruned_len); + str[pruned_len] = '\0'; + } + + free (output); + } + + if (len > PTRDIFF_MAX) + { + errno = ENOMEM; + return -1; + } + + return len; +} diff --git a/modules/c-vzsnprintf b/modules/c-vzsnprintf new file mode 100644 index 0000000000..4049974f4a --- /dev/null +++ b/modules/c-vzsnprintf @@ -0,0 +1,27 @@ +Description: +c_vzsnprintf(): print formatted output from an stdarg argument list to a +fixed length string (without INT_MAX limitation) in C locale + +Files: +lib/c-vsnprintf.h +lib/c-vzsnprintf.c + +Depends-on: +stdint +stdio +c-vasnprintf + +configure.ac: +AC_REQUIRE([AC_C_RESTRICT]) + +Makefile.am: +lib_SOURCES += c-vzsnprintf.c + +Include: +"c-vsnprintf.h" + +License: +LGPLv2+ + +Maintainer: +all -- 2.34.1
>From 77838df62e9f3a1a6b5bcdf35cac1bfb55487764 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 22 Jun 2024 12:21:20 +0200 Subject: [PATCH 2/7] c-vsnprintf: Use c-vzsnprintf. * lib/c-vsnprintf.h (c_vsnprintf): Move specification to here. * lib/c-vsnprintf.c: Change license to LGPLv2+. Don't include <stdlib.h>, <string.h>, c-vasnprintf.h. Include <stdint.h>. (c_vsnprintf): Implement based on c_vzsnprintf. * modules/c-vsnprintf (Depends-on): Add stdint, c-vzsnprintf. Remove c-vasnprintf. (License): Change to LGPLv2+. --- ChangeLog | 10 +++++++++ lib/c-vsnprintf.c | 53 ++++++++++----------------------------------- lib/c-vsnprintf.h | 8 +++++++ modules/c-vsnprintf | 7 +++--- 4 files changed, 33 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0f37171285..9326d490e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2024-06-22 Bruno Haible <br...@clisp.org> + c-vsnprintf: Use c-vzsnprintf. + * lib/c-vsnprintf.h (c_vsnprintf): Move specification to here. + * lib/c-vsnprintf.c: Change license to LGPLv2+. + Don't include <stdlib.h>, <string.h>, c-vasnprintf.h. Include + <stdint.h>. + (c_vsnprintf): Implement based on c_vzsnprintf. + * modules/c-vsnprintf (Depends-on): Add stdint, c-vzsnprintf. Remove + c-vasnprintf. + (License): Change to LGPLv2+. + c-vzsnprintf: New module. * lib/c-vsnprintf.h: Change license to LGPLv2+. (c_vzsnprintf): New declaration. diff --git a/lib/c-vsnprintf.c b/lib/c-vsnprintf.c index fca53fff88..941c2d4609 100644 --- a/lib/c-vsnprintf.c +++ b/lib/c-vsnprintf.c @@ -1,19 +1,17 @@ /* Formatted output to strings in C locale. Copyright (C) 2004, 2006-2024 Free Software Foundation, Inc. - Written by Simon Josefsson and Yoann Vandoorselaere <yo...@prelude-ids.org>. - Modified for C locale by Ben Pfaff. This file 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 of the License, - or (at your option) any later version. + 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 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 + 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/>. */ #ifdef HAVE_CONFIG_H @@ -26,49 +24,20 @@ #include <errno.h> #include <limits.h> #include <stdarg.h> -#include <stdlib.h> -#include <string.h> +#include <stdint.h> -#include "c-vasnprintf.h" - -/* Print formatted output to string STR. Similar to vsprintf, but - additional length SIZE limit how much is written into STR. Returns - string length of formatted string (which may be larger than SIZE). - STR may be NULL, in which case nothing will be written. On error, - return a negative value. - - Formatting takes place in the C locale, that is, the decimal point - used in floating-point formatting directives is always '.'. */ int c_vsnprintf (char *str, size_t size, const char *format, va_list args) { - char *output; - size_t len; - size_t lenbuf = size; - - output = c_vasnprintf (str, &lenbuf, format, args); - len = lenbuf; + ptrdiff_t ret = c_vzsnprintf (str, size, format, args); - if (!output) - return -1; - - if (output != str) - { - if (size) - { - size_t pruned_len = (len < size ? len : size - 1); - memcpy (str, output, pruned_len); - str[pruned_len] = '\0'; - } - - free (output); - } - - if (len > INT_MAX) +#if PTRDIFF_MAX > INT_MAX + if (ret > INT_MAX) { errno = EOVERFLOW; return -1; } +#endif - return len; + return ret; } diff --git a/lib/c-vsnprintf.h b/lib/c-vsnprintf.h index e00ade93f8..ff9cc2250c 100644 --- a/lib/c-vsnprintf.h +++ b/lib/c-vsnprintf.h @@ -51,6 +51,14 @@ extern ptrdiff_t c_vzsnprintf (char *restrict str, size_t size, const char *format, va_list args) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 0)); +/* Prints formatted output to string STR. Similar to sprintf, but the + additional parameter SIZE limits how much is written into STR. + STR may be NULL, in which case nothing will be written. + Returns the string length of the formatted string (which may be larger + than SIZE). Upon failure, returns -1 with errno set. + + Formatting takes place in the C locale, that is, the decimal point + used in floating-point formatting directives is always '.'. */ extern int c_vsnprintf (char *restrict str, size_t size, const char *format, va_list args) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 0)); diff --git a/modules/c-vsnprintf b/modules/c-vsnprintf index 8188a96d39..835968f96a 100644 --- a/modules/c-vsnprintf +++ b/modules/c-vsnprintf @@ -7,8 +7,9 @@ lib/c-vsnprintf.h lib/c-vsnprintf.c Depends-on: +stdint stdio -c-vasnprintf +c-vzsnprintf configure.ac: AC_REQUIRE([AC_C_RESTRICT]) @@ -20,7 +21,7 @@ Include: "c-vsnprintf.h" License: -GPL +LGPLv2+ Maintainer: -Ben Pfaff +all -- 2.34.1
>From 7afd9e0f392c2a5982e157958a528bb9ddcf96bc Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 22 Jun 2024 12:21:29 +0200 Subject: [PATCH 3/7] c-zsnprintf: New module. * lib/c-snprintf.h: Change license to LGPLv2+. (c_zsnprintf): New declaration. * lib/c-zsnprintf.c: New file, based on lib/zsnprintf.c. * modules/c-zsnprintf: New file. --- ChangeLog | 8 ++++++ lib/c-snprintf.h | 34 ++++++++++++++++------- lib/c-zsnprintf.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ modules/c-zsnprintf | 27 +++++++++++++++++++ 4 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 lib/c-zsnprintf.c create mode 100644 modules/c-zsnprintf diff --git a/ChangeLog b/ChangeLog index 9326d490e7..83445e3e8c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2024-06-22 Bruno Haible <br...@clisp.org> + + c-zsnprintf: New module. + * lib/c-snprintf.h: Change license to LGPLv2+. + (c_zsnprintf): New declaration. + * lib/c-zsnprintf.c: New file, based on lib/zsnprintf.c. + * modules/c-zsnprintf: New file. + 2024-06-22 Bruno Haible <br...@clisp.org> c-vsnprintf: Use c-vzsnprintf. diff --git a/lib/c-snprintf.h b/lib/c-snprintf.h index 8e2ab729d7..8e4a6cbe59 100644 --- a/lib/c-snprintf.h +++ b/lib/c-snprintf.h @@ -1,18 +1,18 @@ /* snprintf in C locale. Copyright (C) 2012-2024 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/>. */ #ifndef _C_SNPRINTF_H #define _C_SNPRINTF_H @@ -22,7 +22,7 @@ #error "Please include config.h first." #endif -/* Get size_t. */ +/* Get size_t, ptrdiff_t. */ #include <stddef.h> /* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD. */ @@ -32,6 +32,22 @@ extern "C" { #endif +/* Prints formatted output to string STR. Similar to sprintf, but the + additional parameter SIZE limits how much is written into STR. + STR may be NULL, in which case nothing will be written. + Returns the string length of the formatted string (which may be larger + than SIZE). Upon failure, 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. + + Formatting takes place in the C locale, that is, the decimal point + used in floating-point formatting directives is always '.'. */ +extern ptrdiff_t c_zsnprintf (char *restrict str, size_t size, + const char *format, ...) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 4)); + extern int c_snprintf (char *restrict str, size_t size, const char *format, ...) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 4)); diff --git a/lib/c-zsnprintf.c b/lib/c-zsnprintf.c new file mode 100644 index 0000000000..85ed3f9191 --- /dev/null +++ b/lib/c-zsnprintf.c @@ -0,0 +1,66 @@ +/* Formatted output to strings in C locale. + Copyright (C) 2004, 2006-2024 Free Software Foundation, Inc. + Written by Simon Josefsson and Paul Eggert. + + 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 <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "c-snprintf.h" + +#include <errno.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "c-vasnprintf.h" + +ptrdiff_t +c_zsnprintf (char *str, size_t size, const char *format, ...) +{ + char *output; + size_t len; + size_t lenbuf = size; + va_list args; + + va_start (args, format); + output = c_vasnprintf (str, &lenbuf, format, args); + len = lenbuf; + va_end (args); + + if (!output) + return -1; + + if (output != str) + { + if (size) + { + size_t pruned_len = (len < size ? len : size - 1); + memcpy (str, output, pruned_len); + str[pruned_len] = '\0'; + } + + free (output); + } + + if (len > PTRDIFF_MAX) + { + errno = ENOMEM; + return -1; + } + + return len; +} diff --git a/modules/c-zsnprintf b/modules/c-zsnprintf new file mode 100644 index 0000000000..5410db03cd --- /dev/null +++ b/modules/c-zsnprintf @@ -0,0 +1,27 @@ +Description: +c_zsnprintf(): print formatted output to a fixed length string (without +INT_MAX limitation) in C locale + +Files: +lib/c-snprintf.h +lib/c-zsnprintf.c + +Depends-on: +stdint +stdio +c-vasnprintf + +configure.ac: +AC_REQUIRE([AC_C_RESTRICT]) + +Makefile.am: +lib_SOURCES += c-zsnprintf.c + +Include: +"c-snprintf.h" + +License: +LGPLv2+ + +Maintainer: +all -- 2.34.1
>From eaf2341422e0b74d594839556f74d19dcce839c1 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 22 Jun 2024 12:21:35 +0200 Subject: [PATCH 4/7] c-snprintf: Use c-vzsnprintf. * lib/c-snprintf.h (c_snprintf): Move specification to here. * lib/c-snprintf.c: Change license to LGPLv2+. Don't include <stdlib.h>, <string.h>, c-vasnprintf.h. Include <stdint.h>, c-vsnprintf.h. (c_snprintf): Implement based on c_vzsnprintf. * modules/c-snprintf (Depends-on): Add stdint, c-vzsnprintf. Remove c-vasnprintf. --- ChangeLog | 9 +++++++ lib/c-snprintf.c | 59 +++++++++++++--------------------------------- lib/c-snprintf.h | 8 +++++++ modules/c-snprintf | 7 +++--- 4 files changed, 37 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 83445e3e8c..fcc60208f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ 2024-06-22 Bruno Haible <br...@clisp.org> + c-snprintf: Use c-vzsnprintf. + * lib/c-snprintf.h (c_snprintf): Move specification to here. + * lib/c-snprintf.c: Change license to LGPLv2+. + Don't include <stdlib.h>, <string.h>, c-vasnprintf.h. Include + <stdint.h>, c-vsnprintf.h. + (c_snprintf): Implement based on c_vzsnprintf. + * modules/c-snprintf (Depends-on): Add stdint, c-vzsnprintf. Remove + c-vasnprintf. + c-zsnprintf: New module. * lib/c-snprintf.h: Change license to LGPLv2+. (c_zsnprintf): New declaration. diff --git a/lib/c-snprintf.c b/lib/c-snprintf.c index 8ded5a8fd2..658f3faed4 100644 --- a/lib/c-snprintf.c +++ b/lib/c-snprintf.c @@ -1,20 +1,18 @@ /* Formatted output to strings in C locale. Copyright (C) 2004, 2006-2024 Free Software Foundation, Inc. - Written by Simon Josefsson and Paul Eggert. - Modified for C locale by Ben Pfaff. - 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/>. */ #include <config.h> @@ -24,52 +22,27 @@ #include <errno.h> #include <limits.h> #include <stdarg.h> -#include <stdlib.h> -#include <string.h> +#include <stdint.h> -#include "c-vasnprintf.h" +#include "c-vsnprintf.h" -/* Print formatted output to string STR. Similar to sprintf, but - additional length SIZE limit how much is written into STR. Returns - string length of formatted string (which may be larger than SIZE). - STR may be NULL, in which case nothing will be written. On error, - return a negative value. - - Formatting takes place in the C locale, that is, the decimal point - used in floating-point formatting directives is always '.'. */ int c_snprintf (char *str, size_t size, const char *format, ...) { - char *output; - size_t len; - size_t lenbuf = size; va_list args; + ptrdiff_t ret; va_start (args, format); - output = c_vasnprintf (str, &lenbuf, format, args); - len = lenbuf; + ret = c_vzsnprintf (str, size, format, args); va_end (args); - if (!output) - return -1; - - if (output != str) - { - if (size) - { - size_t pruned_len = (len < size ? len : size - 1); - memcpy (str, output, pruned_len); - str[pruned_len] = '\0'; - } - - free (output); - } - - if (INT_MAX < len) +#if PTRDIFF_MAX > INT_MAX + if (ret > INT_MAX) { errno = EOVERFLOW; return -1; } +#endif - return len; + return ret; } diff --git a/lib/c-snprintf.h b/lib/c-snprintf.h index 8e4a6cbe59..f52e058e9e 100644 --- a/lib/c-snprintf.h +++ b/lib/c-snprintf.h @@ -48,6 +48,14 @@ extern ptrdiff_t c_zsnprintf (char *restrict str, size_t size, const char *format, ...) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 4)); +/* Prints formatted output to string STR. Similar to sprintf, but the + additional parameter SIZE limits how much is written into STR. + STR may be NULL, in which case nothing will be written. + Returns the string length of the formatted string (which may be larger + than SIZE). Upon failure, returns -1 with errno set. + + Formatting takes place in the C locale, that is, the decimal point + used in floating-point formatting directives is always '.'. */ extern int c_snprintf (char *restrict str, size_t size, const char *format, ...) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 3, 4)); diff --git a/modules/c-snprintf b/modules/c-snprintf index 456691d868..49857beca7 100644 --- a/modules/c-snprintf +++ b/modules/c-snprintf @@ -6,8 +6,9 @@ lib/c-snprintf.h lib/c-snprintf.c Depends-on: +stdint stdio -c-vasnprintf +c-vzsnprintf configure.ac: AC_REQUIRE([AC_C_RESTRICT]) @@ -19,7 +20,7 @@ Include: "c-snprintf.h" License: -GPL +LGPLv2+ Maintainer: -Ben Pfaff +all -- 2.34.1
>From 70d42c559229eb99ae41914ccca4f02c75d5a0bf Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 22 Jun 2024 12:21:46 +0200 Subject: [PATCH 5/7] c-vazsprintf: New module. * lib/c-vasprintf.h: Change license to LGPLv2+. Include <stddef.h>. (c_azsprintf, c_vazsprintf): New declarations. * lib/c-azsprintf.c: New file, based on lib/azsprintf.c. * lib/c-vazsprintf.c: New file, based on lib/vazsprintf.c. * modules/c-vazsprintf: New file. --- ChangeLog | 10 ++++++++++ lib/c-azsprintf.c | 34 ++++++++++++++++++++++++++++++++ lib/c-vasprintf.h | 34 +++++++++++++++++++++++++------- lib/c-vazsprintf.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ modules/c-vazsprintf | 26 +++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 lib/c-azsprintf.c create mode 100644 lib/c-vazsprintf.c create mode 100644 modules/c-vazsprintf diff --git a/ChangeLog b/ChangeLog index fcc60208f5..7a2dd7375c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2024-06-22 Bruno Haible <br...@clisp.org> + + c-vazsprintf: New module. + * lib/c-vasprintf.h: Change license to LGPLv2+. + Include <stddef.h>. + (c_azsprintf, c_vazsprintf): New declarations. + * lib/c-azsprintf.c: New file, based on lib/azsprintf.c. + * lib/c-vazsprintf.c: New file, based on lib/vazsprintf.c. + * modules/c-vazsprintf: New file. + 2024-06-22 Bruno Haible <br...@clisp.org> c-snprintf: Use c-vzsnprintf. diff --git a/lib/c-azsprintf.c b/lib/c-azsprintf.c new file mode 100644 index 0000000000..78bc973ef5 --- /dev/null +++ b/lib/c-azsprintf.c @@ -0,0 +1,34 @@ +/* Formatted output to strings in C locale. + 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 <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "c-vasprintf.h" + +#include <stdarg.h> + +ptrdiff_t +c_azsprintf (char **resultp, const char *format, ...) +{ + va_list args; + ptrdiff_t result; + + va_start (args, format); + result = c_vazsprintf (resultp, format, args); + va_end (args); + return result; +} diff --git a/lib/c-vasprintf.h b/lib/c-vasprintf.h index ca8fa63e35..7eae757e3a 100644 --- a/lib/c-vasprintf.h +++ b/lib/c-vasprintf.h @@ -1,17 +1,17 @@ /* vasprintf and asprintf, in C locale. Copyright (C) 2002-2004, 2006-2024 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 of the License, 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 + 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/>. */ #ifndef _C_VASPRINTF_H @@ -25,6 +25,9 @@ /* Get va_list. */ #include <stdarg.h> +/* Get ptrdiff_t. */ +#include <stddef.h> + /* Get _GL_ATTRIBUTE_SPEC_PRINTF_STANDARD. */ #include <stdio.h> @@ -32,6 +35,23 @@ extern "C" { #endif +/* 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. + + Formatting takes place in the C locale, that is, the decimal point + used in floating-point formatting directives is always '.'. */ +ptrdiff_t c_azsprintf (char **resultp, const char *format, ...) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 2, 3)); +ptrdiff_t c_vazsprintf (char **resultp, const char *format, va_list args) + _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 2, 0)); + /* asprintf() and vasprintf(), but formatting takes place in the C locale, that is, the decimal point used in floating-point formatting directives is always '.'. */ diff --git a/lib/c-vazsprintf.c b/lib/c-vazsprintf.c new file mode 100644 index 0000000000..88ab938489 --- /dev/null +++ b/lib/c-vazsprintf.c @@ -0,0 +1,46 @@ +/* Formatted output to strings in C locale. + 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 <https://www.gnu.org/licenses/>. */ + +#include <config.h> + +/* Specification. */ +#include "c-vasprintf.h" + +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> + +#include "c-vasnprintf.h" + +ptrdiff_t +c_vazsprintf (char **resultp, const char *format, va_list args) +{ + size_t length; + char *result = c_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/modules/c-vazsprintf b/modules/c-vazsprintf new file mode 100644 index 0000000000..5cea385926 --- /dev/null +++ b/modules/c-vazsprintf @@ -0,0 +1,26 @@ +Description: +azsprintf() and vazsprintf() in C locale + +Files: +lib/c-vasprintf.h +lib/c-azsprintf.c +lib/c-vazsprintf.c + +Depends-on: +stdint +stdio +c-vasnprintf + +configure.ac: + +Makefile.am: +lib_SOURCES += c-azsprintf.c c-vazsprintf.c + +Include: +"c-vasprintf.h" + +License: +LGPLv2+ + +Maintainer: +all -- 2.34.1
>From 82c0381e34d872590dfd3260c94e79d01da104a3 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 22 Jun 2024 12:21:51 +0200 Subject: [PATCH 6/7] c-vasprintf: Make return convention consistent with other modules. * lib/c-vasprintf.h (c_asprintf, c_vasprintf): Add specification. * lib/c-asprintf.c: Replaced with code based on lib/asprintf.c. * lib/c-vasprintf.c: Replaced with code based on lib/vasprintf.c. * modules/c-vasprintf (Depends-on): Add stdint. (License): Change to LGPLv2+. --- ChangeLog | 7 +++++++ lib/c-asprintf.c | 10 +++++----- lib/c-vasprintf.c | 22 ++++++++++++++++------ lib/c-vasprintf.h | 10 +++++++--- modules/c-vasprintf | 3 ++- 5 files changed, 37 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7a2dd7375c..f3aec5b928 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2024-06-22 Bruno Haible <br...@clisp.org> + c-vasprintf: Make return convention consistent with other modules. + * lib/c-vasprintf.h (c_asprintf, c_vasprintf): Add specification. + * lib/c-asprintf.c: Replaced with code based on lib/asprintf.c. + * lib/c-vasprintf.c: Replaced with code based on lib/vasprintf.c. + * modules/c-vasprintf (Depends-on): Add stdint. + (License): Change to LGPLv2+. + c-vazsprintf: New module. * lib/c-vasprintf.h: Change license to LGPLv2+. Include <stddef.h>. diff --git a/lib/c-asprintf.c b/lib/c-asprintf.c index c6f7719531..f626c5207b 100644 --- a/lib/c-asprintf.c +++ b/lib/c-asprintf.c @@ -3,16 +3,16 @@ Inc. This file 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 of the License, - or (at your option) any later version. + 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 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 + 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/>. */ #include <config.h> diff --git a/lib/c-vasprintf.c b/lib/c-vasprintf.c index 5adaec93f2..81d45ce0ac 100644 --- a/lib/c-vasprintf.c +++ b/lib/c-vasprintf.c @@ -2,16 +2,16 @@ Copyright (C) 1999, 2002, 2006-2024 Free Software Foundation, Inc. This file 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 of the License, - or (at your option) any later version. + 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 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 + 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/>. */ #include <config.h> @@ -21,6 +21,7 @@ #include <errno.h> #include <limits.h> +#include <stdint.h> #include <stdlib.h> #include "c-vasnprintf.h" @@ -33,12 +34,21 @@ c_vasprintf (char **resultp, const char *format, va_list args) if (result == NULL) return -1; +#if PTRDIFF_MAX > INT_MAX if (length > INT_MAX) { free (result); - errno = EOVERFLOW; + errno = (length > PTRDIFF_MAX ? ENOMEM : EOVERFLOW); return -1; } +#else + if (length > PTRDIFF_MAX) + { + free (result); + errno = ENOMEM; + return -1; + } +#endif *resultp = result; /* Return the number of resulting bytes, excluding the trailing NUL. */ diff --git a/lib/c-vasprintf.h b/lib/c-vasprintf.h index 7eae757e3a..bcd40bd5e0 100644 --- a/lib/c-vasprintf.h +++ b/lib/c-vasprintf.h @@ -52,9 +52,13 @@ ptrdiff_t c_azsprintf (char **resultp, const char *format, ...) ptrdiff_t c_vazsprintf (char **resultp, const char *format, va_list args) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 2, 0)); -/* asprintf() and vasprintf(), but formatting takes place in the C locale, that - is, the decimal point used in floating-point formatting directives is always - '.'. */ +/* 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. + + Formatting takes place in the C locale, that is, the decimal point + used in floating-point formatting directives is always '.'. */ int c_asprintf (char **resultp, const char *format, ...) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 2, 3)); int c_vasprintf (char **resultp, const char *format, va_list args) diff --git a/modules/c-vasprintf b/modules/c-vasprintf index 868dc16d10..8b012daabe 100644 --- a/modules/c-vasprintf +++ b/modules/c-vasprintf @@ -7,6 +7,7 @@ lib/c-asprintf.c lib/c-vasprintf.c Depends-on: +stdint stdio c-vasnprintf @@ -19,7 +20,7 @@ Include: "c-vasprintf.h" License: -GPL +LGPLv2+ Maintainer: Ben Pfaff -- 2.34.1
>From f7c9406a0166b76a1d9e22e349613025facf5dec Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Sat, 22 Jun 2024 12:22:12 +0200 Subject: [PATCH 7/7] c-xvasprintf: Guarantee a non-NULL result. * lib/c-xvasprintf.h: Clarify the programmer's responsibilities. (c_xasprintf, c_xvasprintf): Declare as returning non-NULL. * lib/c-xvasprintf.c: Include <stdlib.h>, <string.h>. (c_xvasprintf): Call c_vazsprintf instead of c_vasprintf. When some other error occurs, emit an error message and abort. * modules/c-xvasprintf (Files): Add m4/strerrorname_np.m4. (Depends-on): Add extensions, c-vazsprintf. Remove c-vasprintf. (configure.ac): Invoke gl_OPTIONAL_STRERRORNAME_NP. * NEWS: Mention the change. --- ChangeLog | 13 +++++++++++++ NEWS | 2 +- lib/c-xvasprintf.c | 33 +++++++++++++++++++++++++++++++-- lib/c-xvasprintf.h | 25 +++++++++++++++++-------- modules/c-xvasprintf | 7 +++++-- 5 files changed, 67 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index f3aec5b928..f81ae03de7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2024-06-22 Bruno Haible <br...@clisp.org> + + c-xvasprintf: Guarantee a non-NULL result. + * lib/c-xvasprintf.h: Clarify the programmer's responsibilities. + (c_xasprintf, c_xvasprintf): Declare as returning non-NULL. + * lib/c-xvasprintf.c: Include <stdlib.h>, <string.h>. + (c_xvasprintf): Call c_vazsprintf instead of c_vasprintf. When some + other error occurs, emit an error message and abort. + * modules/c-xvasprintf (Files): Add m4/strerrorname_np.m4. + (Depends-on): Add extensions, c-vazsprintf. Remove c-vasprintf. + (configure.ac): Invoke gl_OPTIONAL_STRERRORNAME_NP. + * NEWS: Mention the change. + 2024-06-22 Bruno Haible <br...@clisp.org> c-vasprintf: Make return convention consistent with other modules. diff --git a/NEWS b/NEWS index 36ffbb64f8..4c5d9fc5de 100644 --- a/NEWS +++ b/NEWS @@ -75,7 +75,7 @@ User visible incompatible changes Date Modules Changes 2024-06-22 xvasprintf It is now the programmer's responsibility to pass - a valid format string without %ls, %lc directives + c-xvasprintf a valid format string without %ls, %lc directives and that all widths are >= -INT_MAX and <= INT_MAX. 2024-05-16 putenv This module is renamed to 'putenv-gnu'. diff --git a/lib/c-xvasprintf.c b/lib/c-xvasprintf.c index 0fda230eb9..b058bde4c5 100644 --- a/lib/c-xvasprintf.c +++ b/lib/c-xvasprintf.c @@ -21,6 +21,8 @@ #include <errno.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include "c-vasprintf.h" #include "xalloc.h" @@ -30,11 +32,38 @@ c_xvasprintf (const char *format, va_list args) { char *result; - if (c_vasprintf (&result, format, args) < 0) + if (c_vazsprintf (&result, format, args) < 0) { if (errno == ENOMEM) xalloc_die (); - return NULL; + else + { + /* The programmer ought to have ensured that none of the other errors + can occur. */ + int err = errno; + char errbuf[20]; + const char *errname; +#if HAVE_WORKING_STRERRORNAME_NP + errname = strerrorname_np (err); + if (errname == NULL) +#else + if (err == EINVAL) + errname = "EINVAL"; + else if (err == EILSEQ) + errname = "EILSEQ"; + else if (err == EOVERFLOW) + errname = "EOVERFLOW"; + else +#endif + { + sprintf (errbuf, "%d", err); + errname = errbuf; + } + fprintf (stderr, "c_vasprintf failed! format=\"%s\", errno=%s\n", + format, errname); + fflush (stderr); + abort (); + } } return result; diff --git a/lib/c-xvasprintf.h b/lib/c-xvasprintf.h index 4cb4578584..897ecfdbf2 100644 --- a/lib/c-xvasprintf.h +++ b/lib/c-xvasprintf.h @@ -17,7 +17,8 @@ #ifndef _C_XVASPRINTF_H #define _C_XVASPRINTF_H -/* This file uses _GL_ATTRIBUTE_FORMAT, _GL_ATTRIBUTE_MALLOC. */ +/* This file uses _GL_ATTRIBUTE_FORMAT, _GL_ATTRIBUTE_MALLOC, + _GL_ATTRIBUTE_RETURNS_NONNULL. */ #if !_GL_CONFIG_H_INCLUDED #error "Please include config.h first." #endif @@ -34,22 +35,30 @@ extern "C" { #endif -/* Write formatted output to a string dynamically allocated with malloc(), - and return it. Upon [ENOMEM] memory allocation error, call xalloc_die. - On some other error - - [EOVERFLOW] resulting string length is > INT_MAX, +/* Prints formatted output to a string dynamically allocated with malloc(), + and returns it. Upon [ENOMEM] memory allocation error, it calls xalloc_die. + + It is the responsibility of the programmer to ensure that + - the format string is valid, + - the format string does not use %ls or %lc directives, and + - all widths in the format string and passed as arguments are >= -INT_MAX + and <= INT_MAX, + so that other errors - [EINVAL] invalid format string, - [EILSEQ] error during conversion between wide and multibyte characters, - return NULL. + - [EOVERFLOW] some specified width is > INT_MAX, + cannot occur. Formatting takes place in the C locale, that is, the decimal point used in floating-point formatting directives is always '.'. */ extern char *c_xasprintf (const char *format, ...) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 1, 2)) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; extern char *c_xvasprintf (const char *format, va_list args) _GL_ATTRIBUTE_FORMAT ((_GL_ATTRIBUTE_SPEC_PRINTF_STANDARD, 1, 0)) - _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE; + _GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE + _GL_ATTRIBUTE_RETURNS_NONNULL; #ifdef __cplusplus } diff --git a/modules/c-xvasprintf b/modules/c-xvasprintf index b952128fb6..ccbc93d794 100644 --- a/modules/c-xvasprintf +++ b/modules/c-xvasprintf @@ -5,13 +5,16 @@ Files: lib/c-xvasprintf.h lib/c-xasprintf.c lib/c-xvasprintf.c +m4/strerrorname_np.m4 Depends-on: +extensions stdio -c-vasprintf +c-vazsprintf xalloc-die configure.ac: +gl_OPTIONAL_STRERRORNAME_NP Makefile.am: lib_SOURCES += c-xasprintf.c c-xvasprintf.c @@ -23,4 +26,4 @@ License: GPL Maintainer: -Ben Pfaff +all -- 2.34.1