]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
intl: Annotate *printf functions with __attribute__ __format__.
authorBruno Haible <bruno@clisp.org>
Wed, 21 Feb 2024 10:14:21 +0000 (11:14 +0100)
committerBruno Haible <bruno@clisp.org>
Wed, 21 Feb 2024 10:19:50 +0000 (11:19 +0100)
Reported by Pierre Ossman <ossman@cendio.se> at
<https://savannah.gnu.org/bugs/?64384>.

* gettext-runtime/intl/libgnuintl.in.h (_INTL_ATTRIBUTE_FORMAT,
_INTL_ATTRIBUTE_SPEC_PRINTF_STANDARD, _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD):
New macros.
(fprintf, vfprintf, printf, vprintf, sprintf, vsprintf, snprintf, vsnprintf,
asprintf, vasprintf): Annotate with _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD.
* gettext-runtime/intl/printf.c: Update comment.
* gettext-runtime/NEWS: Mention this change.
* NEWS: Likewise.

NEWS
gettext-runtime/NEWS
gettext-runtime/intl/libgnuintl.in.h
gettext-runtime/intl/printf.c

diff --git a/NEWS b/NEWS
index a525eb62b59095b6fb251009314146e127eb5d8d..035f2cda5ea8aed6fad7b651129034ea57e0f254 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+Version 0.22.5 - February 2024
+
+* The replacements for the printf()/fprintf()/... functions that are
+  provided through <libintl.h> on native Windows and NetBSD now enable
+  GCC's format string analysis (-Wformat).
+
 Version 0.22.4 - November 2023
 
 * Bug fixes:
index 48d245778eafeb28b1c44323fe6dd7fcd3a05a30..5fc1ac3ca6a8b5a8d654aabf0eb604c1b64b8c3f 100644 (file)
@@ -1,3 +1,9 @@
+Version 0.22.5 - February 2024
+
+* The replacements for the printf()/fprintf()/... functions that are
+  provided through <libintl.h> on native Windows and NetBSD now enable
+  GCC's format string analysis (-Wformat).
+
 Version 0.22.3 - October 2023
 
 * Portability:
index e8642a783eb0e6d163842022dec503b5e52e6e40..359f85fb87be09f731789e0194cdb011018e736b 100644 (file)
@@ -1,5 +1,5 @@
 /* Message catalogs for internationalization.
-   Copyright (C) 1995-1997, 2000-2016, 2018-2023 Free Software Foundation, Inc.
+   Copyright (C) 1995-1997, 2000-2016, 2018-2024 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
@@ -117,6 +117,41 @@ extern int libintl_version;
 # define _INTL_MAY_RETURN_STRING_ARG(n)
 #endif
 
+/* _INTL_ATTRIBUTE_FORMAT ((ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK))
+   declares that the STRING-INDEXth function argument is a format string of
+   style ARCHETYPE, which is one of:
+     printf, gnu_printf
+     scanf, gnu_scanf,
+     strftime, gnu_strftime,
+     strfmon,
+   or the same thing prefixed and suffixed with '__'.
+   If FIRST-TO-CHECK is not 0, arguments starting at FIRST-TO_CHECK
+   are suitable for the format string.  */
+/* Applies to: functions.  */
+#if (defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 7) > 2) || defined __clang__
+# define _INTL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
+#else
+# define _INTL_ATTRIBUTE_FORMAT(spec)
+#endif
+
+/* _INTL_ATTRIBUTE_SPEC_PRINTF_STANDARD
+   An __attribute__ __format__ specifier for a function that takes a format
+   string and arguments, where the format string directives are the ones
+   standardized by ISO C99 and POSIX.  */
+/* __gnu_printf__ is supported in GCC >= 4.4.  */
+#if defined __GNUC__ && __GNUC__ + (__GNUC_MINOR__ >= 4) > 4
+# define _INTL_ATTRIBUTE_SPEC_PRINTF_STANDARD __gnu_printf__
+#else
+# define _INTL_ATTRIBUTE_SPEC_PRINTF_STANDARD __printf__
+#endif
+
+/* _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD
+   indicates to GCC that the function takes a format string and arguments,
+   where the format string directives are the ones standardized by ISO C99
+   and POSIX.  */
+#define _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD(formatstring_parameter, first_argument) \
+  _INTL_ATTRIBUTE_FORMAT ((_INTL_ATTRIBUTE_SPEC_PRINTF_STANDARD, formatstring_parameter, first_argument))
+
 /* Look up MSGID in the current default message catalog for the current
    LC_MESSAGES locale.  If not found, returns MSGID itself (the default
    text).  */
@@ -369,7 +404,8 @@ extern char *bind_textdomain_codeset (const char *__domainname,
 # if !((defined fprintf && defined _GL_STDIO_H) || defined GNULIB_overrides_fprintf) /* don't override gnulib */
 #  undef fprintf
 #  define fprintf libintl_fprintf
-extern int fprintf (FILE *, const char *, ...);
+extern int fprintf (FILE *, const char *, ...)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3);
 #  if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_fprintf; }
 #  endif
@@ -377,7 +413,8 @@ namespace std { using ::libintl_fprintf; }
 # if !((defined vfprintf && defined _GL_STDIO_H) || defined GNULIB_overrides_vfprintf) /* don't override gnulib */
 #  undef vfprintf
 #  define vfprintf libintl_vfprintf
-extern int vfprintf (FILE *, const char *, va_list);
+extern int vfprintf (FILE *, const char *, va_list)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0);
 #  if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_vfprintf; }
 #  endif
@@ -398,7 +435,8 @@ namespace std { using ::libintl_vfprintf; }
 #   define libintl_printf __printf__
 #  endif
 #  define printf libintl_printf
-extern int printf (const char *, ...);
+extern int printf (const char *, ...)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 2);
 #  if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_printf; }
 #  endif
@@ -406,7 +444,8 @@ namespace std { using ::libintl_printf; }
 # if !((defined vprintf && defined _GL_STDIO_H) || defined GNULIB_overrides_vprintf) /* don't override gnulib */
 #  undef vprintf
 #  define vprintf libintl_vprintf
-extern int vprintf (const char *, va_list);
+extern int vprintf (const char *, va_list)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (1, 0);
 #  if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_vprintf; }
 #  endif
@@ -415,7 +454,8 @@ namespace std { using ::libintl_vprintf; }
 # if !((defined sprintf && defined _GL_STDIO_H) || defined GNULIB_overrides_sprintf) /* don't override gnulib */
 #  undef sprintf
 #  define sprintf libintl_sprintf
-extern int sprintf (char *, const char *, ...);
+extern int sprintf (char *, const char *, ...)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3);
 #  if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_sprintf; }
 #  endif
@@ -423,7 +463,8 @@ namespace std { using ::libintl_sprintf; }
 # if !((defined vsprintf && defined _GL_STDIO_H) || defined GNULIB_overrides_vsprintf) /* don't override gnulib */
 #  undef vsprintf
 #  define vsprintf libintl_vsprintf
-extern int vsprintf (char *, const char *, va_list);
+extern int vsprintf (char *, const char *, va_list)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0);
 #  if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_vsprintf; }
 #  endif
@@ -434,7 +475,8 @@ namespace std { using ::libintl_vsprintf; }
 #  if !((defined snprintf && defined _GL_STDIO_H) || defined GNULIB_overrides_snprintf) /* don't override gnulib */
 #   undef snprintf
 #   define snprintf libintl_snprintf
-extern int snprintf (char *, size_t, const char *, ...);
+extern int snprintf (char *, size_t, const char *, ...)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 4);
 #   if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_snprintf; }
 #   endif
@@ -442,7 +484,8 @@ namespace std { using ::libintl_snprintf; }
 #  if !((defined vsnprintf && defined _GL_STDIO_H) || defined GNULIB_overrides_vsnprintf) /* don't override gnulib */
 #   undef vsnprintf
 #   define vsnprintf libintl_vsnprintf
-extern int vsnprintf (char *, size_t, const char *, va_list);
+extern int vsnprintf (char *, size_t, const char *, va_list)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0);
 #   if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_vsnprintf; }
 #   endif
@@ -455,7 +498,8 @@ namespace std { using ::libintl_vsnprintf; }
 #  if !((defined asprintf && defined _GL_STDIO_H) || defined GNULIB_overrides_asprintf) /* don't override gnulib */
 #   undef asprintf
 #   define asprintf libintl_asprintf
-extern int asprintf (char **, const char *, ...);
+extern int asprintf (char **, const char *, ...)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3);
 #   if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_asprintf; }
 #   endif
@@ -463,7 +507,8 @@ namespace std { using ::libintl_asprintf; }
 #  if !((defined vasprintf && defined _GL_STDIO_H) || defined GNULIB_overrides_vasprintf) /* don't override gnulib */
 #   undef vasprintf
 #   define vasprintf libintl_vasprintf
-extern int vasprintf (char **, const char *, va_list);
+extern int vasprintf (char **, const char *, va_list)
+  _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0);
 #   if defined __cplusplus && !defined _INTL_CXX_NO_CLOBBER_STD_NAMESPACE
 namespace std { using ::libintl_vasprintf; }
 #   endif
index 836cc07329417fd091384ed8f47de3e83e20c719..65a8edc2b2dc50a17cf61e462e5a9d69b288aca9 100644 (file)
@@ -1,5 +1,5 @@
 /* Formatted output to strings, using POSIX/XSI format strings with positions.
-   Copyright (C) 2003, 2006-2007, 2009-2011, 2018, 2020-2023 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006-2007, 2009-2011, 2018, 2020-2024 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software: you can redistribute it and/or modify
@@ -121,7 +121,9 @@ char *alloca ();
 /* Users don't expect libintl_fprintf to be less POSIX compliant
    than the fprintf implementation provided by gnulib or - on mingw -
    the one provided by mingw libs when __USE_MINGW_ANSI_STDIO is in
-   effect.  */
+   effect.
+   This definition is necessary, so that libgnuintl.h can declare
+   the *printf functions with _INTL_ATTRIBUTE_FORMAT_PRINTF_STANDARD.  */
 #define USE_REPLACEMENT_CODE_ALWAYS 1
 
 DLL_EXPORTED