glib: enforce the minimum required version and warn about old APIs
There are two useful macros that can be defined before including glib.h that are related to the min required glib version - GLIB_VERSION_MIN_REQUIRED When this is defined, if code uses an API that was deprecated in this version, or older, a compiler warning will be emitted. This alerts maintainers to update their code to whatever new replacement API is now recommended best practice. - GLIB_VERSION_MAX_ALLOWED When this is defined, if code uses an API that was introduced in a version that is newer than the declared version, a compiler warning will be emitted. This alerts maintainers if new code accidentally uses functionality that won't be available on some supported platforms. The GLIB_VERSION_MAX_ALLOWED constant makes it a bit harder to opt in to using specific new APIs with a GLIB_CHECK_VERSION conditional. To workaround this Pragmas can be used to temporarily turn off the -Wdeprecated-declarations compiler warning, while a static inline compat function is implemented. This workaround is illustrated with the implementation of the g_strv_contains method to satisfy the test suite. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
e7b3af8159
commit
e71e8cc035
@ -16,8 +16,74 @@
|
|||||||
#ifndef QEMU_GLIB_COMPAT_H
|
#ifndef QEMU_GLIB_COMPAT_H
|
||||||
#define QEMU_GLIB_COMPAT_H
|
#define QEMU_GLIB_COMPAT_H
|
||||||
|
|
||||||
|
/* Ask for warnings for anything that was marked deprecated in
|
||||||
|
* the defined version, or before. It is a candidate for rewrite.
|
||||||
|
*/
|
||||||
|
#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_40
|
||||||
|
|
||||||
|
/* Ask for warnings if code tries to use function that did not
|
||||||
|
* exist in the defined version. These risk breaking builds
|
||||||
|
*/
|
||||||
|
#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_40
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that because of the GLIB_VERSION_MAX_ALLOWED constant above, allowing
|
||||||
|
* use of functions from newer GLib via this compat header needs a little
|
||||||
|
* trickery to prevent warnings being emitted.
|
||||||
|
*
|
||||||
|
* Consider a function from newer glib-X.Y that we want to use
|
||||||
|
*
|
||||||
|
* int g_foo(const char *wibble)
|
||||||
|
*
|
||||||
|
* We must define a static inline function with the same signature that does
|
||||||
|
* what we need, but with a "_qemu" suffix e.g.
|
||||||
|
*
|
||||||
|
* static inline void g_foo_qemu(const char *wibble)
|
||||||
|
* {
|
||||||
|
* #if GLIB_CHECK_VERSION(X, Y, 0)
|
||||||
|
* g_foo(wibble)
|
||||||
|
* #else
|
||||||
|
* g_something_equivalent_in_older_glib(wibble);
|
||||||
|
* #endif
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* The #pragma at the top of this file turns off -Wdeprecated-declarations,
|
||||||
|
* ensuring this wrapper function impl doesn't trigger the compiler warning
|
||||||
|
* about using too new glib APIs. Finally we can do
|
||||||
|
*
|
||||||
|
* #define g_foo(a) g_foo_qemu(a)
|
||||||
|
*
|
||||||
|
* So now the code elsewhere in QEMU, which *does* have the
|
||||||
|
* -Wdeprecated-declarations warning active, can call g_foo(...) as normal,
|
||||||
|
* without generating warnings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline gboolean g_strv_contains_qemu(const gchar *const *strv,
|
||||||
|
const gchar *str)
|
||||||
|
{
|
||||||
|
#if GLIB_CHECK_VERSION(2, 44, 0)
|
||||||
|
return g_strv_contains(strv, str);
|
||||||
|
#else
|
||||||
|
g_return_val_if_fail(strv != NULL, FALSE);
|
||||||
|
g_return_val_if_fail(str != NULL, FALSE);
|
||||||
|
|
||||||
|
for (; *strv != NULL; strv++) {
|
||||||
|
if (g_str_equal(str, *strv)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#define g_strv_contains(a, b) g_strv_contains_qemu(a, b)
|
||||||
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !GLIB_CHECK_VERSION(2, 50, 0)
|
#if defined(_WIN32) && !GLIB_CHECK_VERSION(2, 50, 0)
|
||||||
/*
|
/*
|
||||||
* g_poll has a problem on Windows when using
|
* g_poll has a problem on Windows when using
|
||||||
@ -45,4 +111,6 @@ gint g_poll_fixed(GPollFD *fds, guint nfds, gint timeout);
|
|||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -744,12 +744,10 @@ static void test_qga_config(gconstpointer data)
|
|||||||
|
|
||||||
strv = g_key_file_get_string_list(kf, "general", "blacklist", &n, &error);
|
strv = g_key_file_get_string_list(kf, "general", "blacklist", &n, &error);
|
||||||
g_assert_cmpint(n, ==, 2);
|
g_assert_cmpint(n, ==, 2);
|
||||||
#if GLIB_CHECK_VERSION(2, 44, 0)
|
|
||||||
g_assert_true(g_strv_contains((const char * const *)strv,
|
g_assert_true(g_strv_contains((const char * const *)strv,
|
||||||
"guest-ping"));
|
"guest-ping"));
|
||||||
g_assert_true(g_strv_contains((const char * const *)strv,
|
g_assert_true(g_strv_contains((const char * const *)strv,
|
||||||
"guest-get-time"));
|
"guest-get-time"));
|
||||||
#endif
|
|
||||||
g_assert_no_error(error);
|
g_assert_no_error(error);
|
||||||
g_strfreev(strv);
|
g_strfreev(strv);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user