Build: Force ISO-conforming format syntax on MinGW

On MinGW, two implementations of printf() are available: either
the Microsoft native one or a standard-conforming replacement from
gnulib. Since we build in C99 mode, headers such as <inttypes.h>
already select the standard-conforming variant. However, MinGW's
GCC does not seem to know about this and assumes MS-style format
syntax by default, which triggers a lot of wrong warnings.

Thus, on MinGW, explicitly decorate sr_log() with the gnu_printf
format flavor attribute. Also use GLib's printf replacements in
the logging implementation to make sure we link to a conforming
printf on any platform, independently of the compiler flags.

This gets rid of the mistaken -Wformat warnings for sr_log(), but
does not cover functions such as g_strdup_printf() which do not
explicitly specify the gnu_printf flavor in the format attribute.
This can be overcome by adding "-D__printf__=__gnu_printf__" to
CPPFLAGS, but it would be inappropriate for libsigrok to define
this on its own.
This commit is contained in:
Daniel Elstner 2015-09-13 15:07:54 +02:00
parent 22c50ed973
commit 7419638d4c
2 changed files with 12 additions and 2 deletions

View File

@ -595,7 +595,16 @@ struct drv_context {
/*--- log.c -----------------------------------------------------------------*/
#if defined(G_OS_WIN32) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
/*
* On MinGW, we need to specify the gnu_printf format flavor or GCC
* will assume non-standard Microsoft printf syntax.
*/
SR_PRIV int sr_log(int loglevel, const char *format, ...)
__attribute__((__format__ (__gnu_printf__, 2, 3)));
#else
SR_PRIV int sr_log(int loglevel, const char *format, ...) G_GNUC_PRINTF(2, 3);
#endif
/* Message logging helpers with subsystem-specific prefix string. */
#define sr_spew(...) sr_log(SR_LOG_SPEW, LOG_PREFIX ": " __VA_ARGS__)

View File

@ -20,6 +20,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <glib/gprintf.h>
#include <libsigrok/libsigrok.h>
#include "libsigrok-internal.h"
@ -178,13 +179,13 @@ static int sr_logv(void *cb_data, int loglevel, const char *format, va_list args
seconds = rest_us / G_TIME_SPAN_SECOND;
microseconds = rest_us % G_TIME_SPAN_SECOND;
ret = fprintf(stderr, "sr: [%.2" PRIu64 ":%.2u.%.6u] ",
ret = g_fprintf(stderr, "sr: [%.2" PRIu64 ":%.2u.%.6u] ",
minutes, seconds, microseconds);
} else {
ret = fputs("sr: ", stderr);
}
if (ret < 0 || vfprintf(stderr, format, args) < 0
if (ret < 0 || g_vfprintf(stderr, format, args) < 0
|| putc('\n', stderr) < 0)
return SR_ERR;