From: Eric Blake Date: Mon, 5 Jan 2015 21:08:27 +0000 (-0700) Subject: stdio: fix use of PRIdMAX on modern mingw X-Git-Tag: v1.0~7200 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=ca563b431be8c350dedab557044d8896fbf9d6ba;p=gnulib.git stdio: fix use of PRIdMAX on modern mingw Commit cf88e56ab broke the use of PRIdMAX and friends on modern mingw64 installations. Basically, when requesting _USE_MINGW_ANSI_STDIO, not only does mingw turn on support for %lld, it also rewrites to provide PRIdMAX as "lld" instead of "I64d" (but only when is also included). But if a user is NOT using the gnulib printf module, gnulib's was still giving printf() the system printf attribute, which causes the compiler to then complain about an unknown %lld specifier, even though we know we don't need to use the non-standard %I64d. So this patch adds a configure-time probe that should work with older gcc (which does not differentiate between printf flavors) and older mingw (where _USE_MINGW_ANSI_STDIO has no impact on behavior), while fixing the mismatch in flavors on modern systems. * m4/stdio_h.m4 (gl_STDIO_H): Probe for printf flavor via inttypes. * lib/stdio.in.h (_GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM): Use result to work with modern mingw. Signed-off-by: Eric Blake --- diff --git a/ChangeLog b/ChangeLog index 36fbdf2bfd..fedcc1eb8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2015-01-05 Eric Blake + + stdio: fix use of PRIdMAX on modern mingw + * m4/stdio_h.m4 (gl_STDIO_H): Probe for printf flavor via inttypes. + * lib/stdio.in.h (_GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM): Use result + to work with modern mingw. + 2015-01-05 Daniel P. Berrange (tiny change) pthread: detect git mingw builds with only partial pollution diff --git a/lib/stdio.in.h b/lib/stdio.in.h index fb2fb70388..fa6b595369 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -84,8 +84,13 @@ except that it indicates to GCC that the supported format string directives are the ones of the system printf(), rather than the ones standardized by ISO C99 and POSIX. */ -#define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ +#if GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU +# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ + _GL_ATTRIBUTE_FORMAT_PRINTF (formatstring_parameter, first_argument) +#else +# define _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM(formatstring_parameter, first_argument) \ _GL_ATTRIBUTE_FORMAT ((__printf__, formatstring_parameter, first_argument)) +#endif /* _GL_ATTRIBUTE_FORMAT_SCANF indicates to GCC that the function takes a format string and arguments, diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 index 42173387af..e0c4bde1f8 100644 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -1,4 +1,4 @@ -# stdio_h.m4 serial 43 +# stdio_h.m4 serial 44 dnl Copyright (C) 2007-2015 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -12,6 +12,24 @@ AC_DEFUN([gl_STDIO_H], AC_REQUIRE([gl_STDIO_H_DEFAULTS]) gl_NEXT_HEADERS([stdio.h]) + dnl Determine whether __USE_MINGW_ANSI_STDIO makes printf and + dnl inttypes.h behave like gnu instead of system; we must give our + dnl printf wrapper the right attribute to match. + AC_CACHE_CHECK([whether inttypes macros match system or gnu printf], + [gl_cv_func_printf_attribute_flavor], + [AC_EGREP_CPP([findme .(ll|j)d. findme], + [#define __STDC_FORMAT_MACROS 1 + #include + #include + findme PRIdMAX findme + ], [gl_cv_func_printf_attribute_flavor=gnu], + [gl_cv_func_printf_attribute_flavor=system])]) + if test "$gl_cv_func_printf_attribute_flavor" = gnu; then + AC_DEFINE([GNULIB_PRINTF_ATTRIBUTE_FLAVOR_GNU], [1], + [Define to 1 if printf and friends should be labeled with + attribute "__gnu_printf__" instead of "__printf__"]) + fi + dnl No need to create extra modules for these functions. Everyone who uses dnl likely needs them. GNULIB_FSCANF=1