From 7419638d4c5d21dadccfd8f234c5671c5330dc33 Mon Sep 17 00:00:00 2001 From: Daniel Elstner Date: Sun, 13 Sep 2015 15:07:54 +0200 Subject: [PATCH] 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 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. --- src/libsigrok-internal.h | 9 +++++++++ src/log.c | 5 +++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libsigrok-internal.h b/src/libsigrok-internal.h index b4280325..465f2421 100644 --- a/src/libsigrok-internal.h +++ b/src/libsigrok-internal.h @@ -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__) diff --git a/src/log.c b/src/log.c index 87c77971..db5a3fd4 100644 --- a/src/log.c +++ b/src/log.c @@ -20,6 +20,7 @@ #include #include +#include #include #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;