From 56ddc8904d832b7d9aee16ba800b16c46cf1709e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 9 Jul 2018 13:20:17 +0200 Subject: [PATCH 1/3] shared: restore compat code in nm-glib.h for 2.32 compatibility In commit 8a46b25cfa8c33daa8af37bb8103ca02286001b1, NetworkManager bumped its glib dependency to 2.40 or newer. "nm-glib.h" header is precisely the compatiblity implementation that we use to cope with older glib versions. Note, that the same implementation is also used by applet and VPN plugins. However, applet and VPN plugins don't yet require 2.40 glib. Also, they don't yet require NetworkManager 1.12.0 API (which was the one that bumped the glib requirement to 2.40). Hence, when "nm-glib.h" is used in applet or VPN, it must still cope with older versions, although, the code is not used by NetworkManager itself. Partly revert 8a46b25cfa8c33daa8af37bb8103ca02286001b1 so that nm-glib.h again works for 2.32 or newer. The same is true, also for "nm-test-utils.h", which is also used by applet and VPN plugins. --- shared/nm-utils/nm-glib.h | 372 ++++++++++++++++++++++++++++++++ shared/nm-utils/nm-test-utils.h | 20 +- 2 files changed, 391 insertions(+), 1 deletion(-) diff --git a/shared/nm-utils/nm-glib.h b/shared/nm-utils/nm-glib.h index 010f182003..3da2c941b1 100644 --- a/shared/nm-utils/nm-glib.h +++ b/shared/nm-utils/nm-glib.h @@ -39,6 +39,84 @@ #endif +static inline void +__g_type_ensure (GType type) +{ +#if !GLIB_CHECK_VERSION(2,34,0) + if (G_UNLIKELY (type == (GType)-1)) + g_error ("can't happen"); +#else + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; + g_type_ensure (type); + G_GNUC_END_IGNORE_DEPRECATIONS; +#endif +} +#define g_type_ensure __g_type_ensure + +#if !GLIB_CHECK_VERSION(2,34,0) + +#define g_clear_pointer(pp, destroy) \ + G_STMT_START { \ + G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer)); \ + /* Only one access, please */ \ + gpointer *_pp = (gpointer *) (pp); \ + gpointer _p; \ + /* This assignment is needed to avoid a gcc warning */ \ + GDestroyNotify _destroy = (GDestroyNotify) (destroy); \ + \ + _p = *_pp; \ + if (_p) \ + { \ + *_pp = NULL; \ + _destroy (_p); \ + } \ + } G_STMT_END + +/* These are used to clean up the output of test programs; we can just let + * them no-op in older glib. + */ +#define g_test_expect_message(log_domain, log_level, pattern) +#define g_test_assert_expected_messages() + +#else + +/* We build with -DGLIB_MAX_ALLOWED_VERSION set to 2.32 to make sure we don't + * accidentally use new API that we shouldn't. But we don't want warnings for + * the APIs that we emulate above. + */ + +#define g_test_expect_message(domain, level, format...) \ + G_STMT_START { \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + g_test_expect_message (domain, level, format); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + } G_STMT_END + +#define g_test_assert_expected_messages_internal(domain, file, line, func) \ + G_STMT_START { \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + g_test_assert_expected_messages_internal (domain, file, line, func); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + } G_STMT_END + +#endif + + +#if GLIB_CHECK_VERSION (2, 35, 0) +/* For glib >= 2.36, g_type_init() is deprecated. + * But since 2.35.1 (7c42ab23b55c43ab96d0ac2124b550bf1f49c1ec) this function + * does nothing. Replace the call with empty statement. */ +#define nm_g_type_init() G_STMT_START { (void) 0; } G_STMT_END +#else +#define nm_g_type_init() G_STMT_START { g_type_init (); } G_STMT_END +#endif + + +/* g_test_initialized() is only available since glib 2.36. */ +#if !GLIB_CHECK_VERSION (2, 36, 0) +#define g_test_initialized() (g_test_config_vars->test_initialized) +#endif + /* g_assert_cmpmem() is only available since glib 2.46. */ #if !GLIB_CHECK_VERSION (2, 45, 7) #define g_assert_cmpmem(m1, l1, m2, l2) G_STMT_START {\ @@ -67,6 +145,239 @@ nm_glib_check_version (guint major, guint minor, guint micro) && glib_micro_version < micro)); } +/* g_test_skip() is only available since glib 2.38. Add a compatibility wrapper. */ +static inline void +__nmtst_g_test_skip (const gchar *msg) +{ +#if GLIB_CHECK_VERSION (2, 38, 0) + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_test_skip (msg); + G_GNUC_END_IGNORE_DEPRECATIONS +#else + g_debug ("%s", msg); +#endif +} +#define g_test_skip __nmtst_g_test_skip + + +/* g_test_add_data_func_full() is only available since glib 2.34. Add a compatibility wrapper. */ +static inline void +__g_test_add_data_func_full (const char *testpath, + gpointer test_data, + GTestDataFunc test_func, + GDestroyNotify data_free_func) +{ +#if GLIB_CHECK_VERSION (2, 34, 0) + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + g_test_add_data_func_full (testpath, test_data, test_func, data_free_func); + G_GNUC_END_IGNORE_DEPRECATIONS +#else + g_return_if_fail (testpath != NULL); + g_return_if_fail (testpath[0] == '/'); + g_return_if_fail (test_func != NULL); + + g_test_add_vtable (testpath, 0, test_data, NULL, + (GTestFixtureFunc) test_func, + (GTestFixtureFunc) data_free_func); +#endif +} +#define g_test_add_data_func_full __g_test_add_data_func_full + + +#if !GLIB_CHECK_VERSION (2, 34, 0) +#define G_DEFINE_QUARK(QN, q_n) \ +GQuark \ +q_n##_quark (void) \ +{ \ + static GQuark q; \ + \ + if G_UNLIKELY (q == 0) \ + q = g_quark_from_static_string (#QN); \ + \ + return q; \ +} +#endif + + +static inline gboolean +nm_g_hash_table_replace (GHashTable *hash, gpointer key, gpointer value) +{ + /* glib 2.40 added a return value indicating whether the key already existed + * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ +#if GLIB_CHECK_VERSION(2, 40, 0) + return g_hash_table_replace (hash, key, value); +#else + gboolean contained = g_hash_table_contains (hash, key); + + g_hash_table_replace (hash, key, value); + return !contained; +#endif +} + +static inline gboolean +nm_g_hash_table_insert (GHashTable *hash, gpointer key, gpointer value) +{ + /* glib 2.40 added a return value indicating whether the key already existed + * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ +#if GLIB_CHECK_VERSION(2, 40, 0) + return g_hash_table_insert (hash, key, value); +#else + gboolean contained = g_hash_table_contains (hash, key); + + g_hash_table_insert (hash, key, value); + return !contained; +#endif +} + +static inline gboolean +nm_g_hash_table_add (GHashTable *hash, gpointer key) +{ + /* glib 2.40 added a return value indicating whether the key already existed + * (910191597a6c2e5d5d460e9ce9efb4f47d9cc63c). */ +#if GLIB_CHECK_VERSION(2, 40, 0) + return g_hash_table_add (hash, key); +#else + gboolean contained = g_hash_table_contains (hash, key); + + g_hash_table_add (hash, key); + return !contained; +#endif +} + +#if !GLIB_CHECK_VERSION(2, 40, 0) || defined (NM_GLIB_COMPAT_H_TEST) +static inline void +_nm_g_ptr_array_insert (GPtrArray *array, + gint index_, + gpointer data) +{ + g_return_if_fail (array); + g_return_if_fail (index_ >= -1); + g_return_if_fail (index_ <= (gint) array->len); + + g_ptr_array_add (array, data); + + if (index_ != -1 && index_ != (gint) (array->len - 1)) { + memmove (&(array->pdata[index_ + 1]), + &(array->pdata[index_]), + (array->len - index_ - 1) * sizeof (gpointer)); + array->pdata[index_] = data; + } +} +#endif +#if !GLIB_CHECK_VERSION(2, 40, 0) +#define g_ptr_array_insert(array, index, data) G_STMT_START { _nm_g_ptr_array_insert (array, index, data); } G_STMT_END +#else +#define g_ptr_array_insert(array, index, data) \ + G_STMT_START { \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + g_ptr_array_insert (array, index, data); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + } G_STMT_END +#endif + + +#if !GLIB_CHECK_VERSION (2, 40, 0) +static inline gboolean +_g_key_file_save_to_file (GKeyFile *key_file, + const gchar *filename, + GError **error) +{ + gchar *contents; + gboolean success; + gsize length; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + contents = g_key_file_to_data (key_file, &length, NULL); + g_assert (contents != NULL); + + success = g_file_set_contents (filename, contents, length, error); + g_free (contents); + + return success; +} +#define g_key_file_save_to_file(key_file, filename, error) \ + _g_key_file_save_to_file (key_file, filename, error) +#else +#define g_key_file_save_to_file(key_file, filename, error) \ + ({ \ + gboolean _success; \ + \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + _success = g_key_file_save_to_file (key_file, filename, error); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + _success; \ + }) +#endif + + +#if GLIB_CHECK_VERSION (2, 36, 0) +#define g_credentials_get_unix_pid(creds, error) \ + ({ \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + (g_credentials_get_unix_pid) ((creds), (error)); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + }) +#else +#define g_credentials_get_unix_pid(creds, error) \ + ({ \ + struct ucred *native_creds; \ + \ + native_creds = g_credentials_get_native ((creds), G_CREDENTIALS_TYPE_LINUX_UCRED); \ + g_assert (native_creds); \ + native_creds->pid; \ + }) +#endif + + +#if !GLIB_CHECK_VERSION(2, 40, 0) || defined (NM_GLIB_COMPAT_H_TEST) +static inline gpointer * +_nm_g_hash_table_get_keys_as_array (GHashTable *hash_table, + guint *length) +{ + GHashTableIter iter; + gpointer key, *ret; + guint i = 0; + + g_return_val_if_fail (hash_table, NULL); + + ret = g_new0 (gpointer, g_hash_table_size (hash_table) + 1); + g_hash_table_iter_init (&iter, hash_table); + + while (g_hash_table_iter_next (&iter, &key, NULL)) + ret[i++] = key; + + ret[i] = NULL; + + if (length) + *length = i; + + return ret; +} +#endif +#if !GLIB_CHECK_VERSION(2, 40, 0) +#define g_hash_table_get_keys_as_array(hash_table, length) \ + ({ \ + _nm_g_hash_table_get_keys_as_array (hash_table, length); \ + }) +#else +#define g_hash_table_get_keys_as_array(hash_table, length) \ + ({ \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + (g_hash_table_get_keys_as_array) ((hash_table), (length)); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + }) +#endif + +#ifndef g_info +/* g_info was only added with 2.39.2 */ +#define g_info(...) g_log (G_LOG_DOMAIN, \ + G_LOG_LEVEL_INFO, \ + __VA_ARGS__) +#endif + #if !GLIB_CHECK_VERSION(2, 44, 0) static inline gpointer g_steal_pointer (gpointer pp) @@ -107,6 +418,67 @@ _nm_g_strv_contains (const gchar * const *strv, } #define g_strv_contains _nm_g_strv_contains +static inline GVariant * +_nm_g_variant_new_take_string (gchar *string) +{ +#if !GLIB_CHECK_VERSION(2, 36, 0) + GVariant *value; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (g_utf8_validate (string, -1, NULL), NULL); + + value = g_variant_new_string (string); + g_free (string); + return value; +#elif !GLIB_CHECK_VERSION(2, 38, 0) + GVariant *value; + GBytes *bytes; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (g_utf8_validate (string, -1, NULL), NULL); + + bytes = g_bytes_new_take (string, strlen (string) + 1); + value = g_variant_new_from_bytes (G_VARIANT_TYPE_STRING, bytes, TRUE); + g_bytes_unref (bytes); + + return value; +#else + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + return g_variant_new_take_string (string); + G_GNUC_END_IGNORE_DEPRECATIONS +#endif +} +#define g_variant_new_take_string _nm_g_variant_new_take_string + +#if !GLIB_CHECK_VERSION(2, 38, 0) +_nm_printf (1, 2) +static inline GVariant * +_nm_g_variant_new_printf (const char *format_string, ...) +{ + char *string; + va_list ap; + + g_return_val_if_fail (format_string, NULL); + + va_start (ap, format_string); + string = g_strdup_vprintf (format_string, ap); + va_end (ap); + + return g_variant_new_take_string (string); +} +#define g_variant_new_printf(...) _nm_g_variant_new_printf(__VA_ARGS__) +#else +#define g_variant_new_printf(...) \ + ({ \ + GVariant *_v; \ + \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + _v = g_variant_new_printf (__VA_ARGS__); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ + _v; \ + }) +#endif + #if !GLIB_CHECK_VERSION (2, 56, 0) #define g_object_ref(Obj) ((typeof(Obj)) g_object_ref (Obj)) #define g_object_ref_sink(Obj) ((typeof(Obj)) g_object_ref_sink (Obj)) diff --git a/shared/nm-utils/nm-test-utils.h b/shared/nm-utils/nm-test-utils.h index efb41454e7..0218b23877 100644 --- a/shared/nm-utils/nm-test-utils.h +++ b/shared/nm-utils/nm-test-utils.h @@ -344,6 +344,8 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_ __nmtst_internal.assert_logging = !!assert_logging; + nm_g_type_init (); + is_debug = g_test_verbose (); nmtst_debug = g_getenv ("NMTST_DEBUG"); @@ -550,8 +552,13 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_ *out_set_logging = TRUE; #endif g_assert (success); +#if GLIB_CHECK_VERSION(2,34,0) if (__nmtst_internal.no_expect_message) g_log_set_always_fatal (G_LOG_FATAL_MASK); +#else + /* g_test_expect_message() is a NOP, so allow any messages */ + g_log_set_always_fatal (G_LOG_FATAL_MASK); +#endif } else if (__nmtst_internal.no_expect_message) { /* We have a test that would be assert_logging, but the user specified no_expect_message. * This transforms g_test_expect_message() into a NOP, but we also have to relax @@ -571,9 +578,14 @@ __nmtst_init (int *argc, char ***argv, gboolean assert_logging, const char *log_ } #endif } else { +#if GLIB_CHECK_VERSION(2,34,0) /* We were called not to set logging levels. This means, that the user * expects to assert against (all) messages. Any uncought message is fatal. */ g_log_set_always_fatal (G_LOG_LEVEL_MASK); +#else + /* g_test_expect_message() is a NOP, so allow any messages */ + g_log_set_always_fatal (G_LOG_FATAL_MASK); +#endif } if ((!__nmtst_internal.assert_logging || (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message)) && @@ -640,6 +652,7 @@ nmtst_test_quick (void) return __nmtst_internal.test_quick; } +#if GLIB_CHECK_VERSION(2,34,0) #undef g_test_expect_message #define g_test_expect_message(...) \ G_STMT_START { \ @@ -647,7 +660,9 @@ nmtst_test_quick (void) if (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message) { \ g_debug ("nmtst: assert-logging: g_test_expect_message %s", G_STRINGIFY ((__VA_ARGS__))); \ } else { \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ g_test_expect_message (__VA_ARGS__); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ } \ } G_STMT_END #undef g_test_assert_expected_messages_internal @@ -661,8 +676,11 @@ nmtst_test_quick (void) if (__nmtst_internal.assert_logging && __nmtst_internal.no_expect_message) \ g_debug ("nmtst: assert-logging: g_test_assert_expected_messages(%s, %s:%d, %s)", _domain?:"", _file?:"", _line, _func?:""); \ \ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ g_test_assert_expected_messages_internal (_domain, _file, _line, _func); \ + G_GNUC_END_IGNORE_DEPRECATIONS \ } G_STMT_END +#endif #define NMTST_EXPECT(domain, level, msg) g_test_expect_message (domain, level, msg) @@ -1735,7 +1753,7 @@ _nmtst_assert_connection_has_settings (NMConnection *connection, gboolean has_at va_start (ap, has_at_most); while ((name = va_arg (ap, const char *))) { - if (!g_hash_table_add (names, (gpointer) name)) + if (!nm_g_hash_table_add (names, (gpointer) name)) g_assert_not_reached (); g_ptr_array_add (names_arr, (gpointer) name); } From 62cd6afd98186b137915aea78b0883cf9f3cb720 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 9 Jul 2018 13:40:53 +0200 Subject: [PATCH 2/3] shared/trivial: prettify nm-glib.h compat implementation by grouping code --- shared/nm-utils/nm-glib.h | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/shared/nm-utils/nm-glib.h b/shared/nm-utils/nm-glib.h index 3da2c941b1..08ede9e594 100644 --- a/shared/nm-utils/nm-glib.h +++ b/shared/nm-utils/nm-glib.h @@ -25,6 +25,8 @@ #include "gsystem-local-alloc.h" +/*****************************************************************************/ + #ifdef __clang__ #undef G_GNUC_BEGIN_IGNORE_DEPRECATIONS @@ -39,6 +41,8 @@ #endif +/*****************************************************************************/ + static inline void __g_type_ensure (GType type) { @@ -53,6 +57,8 @@ __g_type_ensure (GType type) } #define g_type_ensure __g_type_ensure +/*****************************************************************************/ + #if !GLIB_CHECK_VERSION(2,34,0) #define g_clear_pointer(pp, destroy) \ @@ -72,6 +78,12 @@ __g_type_ensure (GType type) } \ } G_STMT_END +#endif + +/*****************************************************************************/ + +#if !GLIB_CHECK_VERSION(2,34,0) + /* These are used to clean up the output of test programs; we can just let * them no-op in older glib. */ @@ -101,6 +113,7 @@ __g_type_ensure (GType type) #endif +/*****************************************************************************/ #if GLIB_CHECK_VERSION (2, 35, 0) /* For glib >= 2.36, g_type_init() is deprecated. @@ -111,12 +124,15 @@ __g_type_ensure (GType type) #define nm_g_type_init() G_STMT_START { g_type_init (); } G_STMT_END #endif +/*****************************************************************************/ /* g_test_initialized() is only available since glib 2.36. */ #if !GLIB_CHECK_VERSION (2, 36, 0) #define g_test_initialized() (g_test_config_vars->test_initialized) #endif +/*****************************************************************************/ + /* g_assert_cmpmem() is only available since glib 2.46. */ #if !GLIB_CHECK_VERSION (2, 45, 7) #define g_assert_cmpmem(m1, l1, m2, l2) G_STMT_START {\ @@ -131,6 +147,8 @@ __g_type_ensure (GType type) } G_STMT_END #endif +/*****************************************************************************/ + /* Rumtime check for glib version. First do a compile time check which * (if satisfied) shortcuts the runtime check. */ static inline gboolean @@ -145,6 +163,8 @@ nm_glib_check_version (guint major, guint minor, guint micro) && glib_micro_version < micro)); } +/*****************************************************************************/ + /* g_test_skip() is only available since glib 2.38. Add a compatibility wrapper. */ static inline void __nmtst_g_test_skip (const gchar *msg) @@ -159,6 +179,7 @@ __nmtst_g_test_skip (const gchar *msg) } #define g_test_skip __nmtst_g_test_skip +/*****************************************************************************/ /* g_test_add_data_func_full() is only available since glib 2.34. Add a compatibility wrapper. */ static inline void @@ -183,6 +204,7 @@ __g_test_add_data_func_full (const char *testpath, } #define g_test_add_data_func_full __g_test_add_data_func_full +/*****************************************************************************/ #if !GLIB_CHECK_VERSION (2, 34, 0) #define G_DEFINE_QUARK(QN, q_n) \ @@ -198,6 +220,7 @@ q_n##_quark (void) \ } #endif +/*****************************************************************************/ static inline gboolean nm_g_hash_table_replace (GHashTable *hash, gpointer key, gpointer value) @@ -244,6 +267,8 @@ nm_g_hash_table_add (GHashTable *hash, gpointer key) #endif } +/*****************************************************************************/ + #if !GLIB_CHECK_VERSION(2, 40, 0) || defined (NM_GLIB_COMPAT_H_TEST) static inline void _nm_g_ptr_array_insert (GPtrArray *array, @@ -264,6 +289,7 @@ _nm_g_ptr_array_insert (GPtrArray *array, } } #endif + #if !GLIB_CHECK_VERSION(2, 40, 0) #define g_ptr_array_insert(array, index, data) G_STMT_START { _nm_g_ptr_array_insert (array, index, data); } G_STMT_END #else @@ -275,6 +301,7 @@ _nm_g_ptr_array_insert (GPtrArray *array, } G_STMT_END #endif +/*****************************************************************************/ #if !GLIB_CHECK_VERSION (2, 40, 0) static inline gboolean @@ -312,6 +339,7 @@ _g_key_file_save_to_file (GKeyFile *key_file, }) #endif +/*****************************************************************************/ #if GLIB_CHECK_VERSION (2, 36, 0) #define g_credentials_get_unix_pid(creds, error) \ @@ -331,6 +359,7 @@ _g_key_file_save_to_file (GKeyFile *key_file, }) #endif +/*****************************************************************************/ #if !GLIB_CHECK_VERSION(2, 40, 0) || defined (NM_GLIB_COMPAT_H_TEST) static inline gpointer * @@ -371,6 +400,8 @@ _nm_g_hash_table_get_keys_as_array (GHashTable *hash_table, }) #endif +/*****************************************************************************/ + #ifndef g_info /* g_info was only added with 2.39.2 */ #define g_info(...) g_log (G_LOG_DOMAIN, \ @@ -378,6 +409,8 @@ _nm_g_hash_table_get_keys_as_array (GHashTable *hash_table, __VA_ARGS__) #endif +/*****************************************************************************/ + #if !GLIB_CHECK_VERSION(2, 44, 0) static inline gpointer g_steal_pointer (gpointer pp) @@ -396,6 +429,8 @@ g_steal_pointer (gpointer pp) (0 ? (*(pp)) : (g_steal_pointer) (pp)) #endif +/*****************************************************************************/ + static inline gboolean _nm_g_strv_contains (const gchar * const *strv, const gchar *str) @@ -418,6 +453,8 @@ _nm_g_strv_contains (const gchar * const *strv, } #define g_strv_contains _nm_g_strv_contains +/*****************************************************************************/ + static inline GVariant * _nm_g_variant_new_take_string (gchar *string) { @@ -450,6 +487,8 @@ _nm_g_variant_new_take_string (gchar *string) } #define g_variant_new_take_string _nm_g_variant_new_take_string +/*****************************************************************************/ + #if !GLIB_CHECK_VERSION(2, 38, 0) _nm_printf (1, 2) static inline GVariant * @@ -479,11 +518,15 @@ _nm_g_variant_new_printf (const char *format_string, ...) }) #endif +/*****************************************************************************/ + #if !GLIB_CHECK_VERSION (2, 56, 0) #define g_object_ref(Obj) ((typeof(Obj)) g_object_ref (Obj)) #define g_object_ref_sink(Obj) ((typeof(Obj)) g_object_ref_sink (Obj)) #endif +/*****************************************************************************/ + #ifndef g_autofree /* we still don't rely on recent glib to provide g_autofree. Hence, we continue * to use our gs_* free macros that we took from libgsystem. @@ -492,4 +535,6 @@ _nm_g_variant_new_printf (const char *format_string, ...) #define g_autofree gs_free #endif +/*****************************************************************************/ + #endif /* __NM_GLIB_H__ */ From bf593304ef24e04102955f2f535cf0703a8c5989 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 9 Jul 2018 13:46:47 +0200 Subject: [PATCH 3/3] shared: ensure "nm-glib.h" is not used without "nm-macros-internal.h" Note how "nm-glib.h" uses _nm_printf() macro, which is defined in "nm-macros-internal.h". There are many ways how to solve that problem. For example, we could define certain _nm_*() macros in "nm-glib.h" itself. However, that is a bit awkward, because optimally "nm-glib.h" only provides functions that are strictly related to glib compatiblity. _nm_printf() is used by "nm-glib.h" for its own implementation, it should not provide (or reimplement) this macro. We solve this instead by enforcing what NetworkManager already does. NetworkManager never includes "nm-glib.h" directly, instead "nm-macros-internal.h" is the only place that includes the glib compat header. It means, you cannot use "nm-glib.h" without "nm-macros-internal.h". But that is a reasonable compromise, with respect to granularity. The granularity at the moment is: if you use anything from "shared/nm-utils", you almost always need at least "nm-macros-internal.h" header (and automatically also get "nm-glib.h" and "gsystem-local-alloc.h"). It's not intended, to use "nm-glib.h" directly. This makes "nm-glib.h" an implementation detail of "nm-macros-internal.h" and it only exists to separate code that is related to glib compatibility to its own header. --- shared/nm-utils/nm-glib.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/shared/nm-utils/nm-glib.h b/shared/nm-utils/nm-glib.h index 08ede9e594..fd7865195c 100644 --- a/shared/nm-utils/nm-glib.h +++ b/shared/nm-utils/nm-glib.h @@ -20,6 +20,14 @@ #ifndef __NM_GLIB_H__ #define __NM_GLIB_H__ +/*****************************************************************************/ + +#ifndef __NM_MACROS_INTERNAL_H__ +#error "nm-glib.h requires nm-macros-internal.h. Do not include this directly" +#endif + +/*****************************************************************************/ + #include #include