From: Bruno Haible Date: Sat, 22 Jun 2024 10:15:38 +0000 (+0200) Subject: snprintf: Use vzsnprintf. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=fdcddac143b28818efadd52f2f3c840778eda0bb;p=gnulib.git snprintf: Use vzsnprintf. * lib/stdio.in.h (snprintf): Move specification to here. * lib/snprintf.c: Don't include , , vasnprintf.h. Include . (snprintf): Implement based on vzsnprintf. * modules/snprintf (Depends-on): Add stdint, vzsnprintf. Remove vasnprintf. --- diff --git a/ChangeLog b/ChangeLog index 458561b9fe..68677a44ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2024-06-22 Bruno Haible + snprintf: Use vzsnprintf. + * lib/stdio.in.h (snprintf): Move specification to here. + * lib/snprintf.c: Don't include , , vasnprintf.h. + Include . + (snprintf): Implement based on vzsnprintf. + * modules/snprintf (Depends-on): Add stdint, vzsnprintf. Remove + vasnprintf. + zsnprintf: New module. * lib/stdio.in.h (zsnprintf): New declaration, based on lib/snprintf.c. diff --git a/lib/snprintf.c b/lib/snprintf.c index c1b93562ec..80f69225ac 100644 --- a/lib/snprintf.c +++ b/lib/snprintf.c @@ -1,6 +1,5 @@ /* Formatted output to strings. 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 @@ -23,49 +22,25 @@ #include #include #include -#include -#include +#include -#include "vasnprintf.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. */ int 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 = vasnprintf (str, &lenbuf, format, args); - len = lenbuf; + ret = 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/stdio.in.h b/lib/stdio.in.h index 4a942a92ed..d0479c10ae 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -1453,6 +1453,11 @@ _GL_CXXALIAS_SYS (zsnprintf, ptrdiff_t, #endif #if @GNULIB_SNPRINTF@ +/* 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 a negative value. */ # if @REPLACE_SNPRINTF@ # if !(defined __cplusplus && defined GNULIB_NAMESPACE) # define snprintf rpl_snprintf diff --git a/modules/snprintf b/modules/snprintf index 102d629706..cd4eb6b2c4 100644 --- a/modules/snprintf +++ b/modules/snprintf @@ -8,8 +8,9 @@ m4/printf.m4 Depends-on: stdio -vasnprintf [test $ac_cv_func_snprintf = no || test $REPLACE_SNPRINTF = 1] errno [test $ac_cv_func_snprintf = no || test $REPLACE_SNPRINTF = 1] +stdint [test $ac_cv_func_snprintf = no || test $REPLACE_SNPRINTF = 1] +vzsnprintf [test $ac_cv_func_snprintf = no || test $REPLACE_SNPRINTF = 1] configure.ac: gl_FUNC_SNPRINTF @@ -25,4 +26,4 @@ License: LGPLv2+ Maintainer: -Simon Josefsson, Paul Eggert +all