summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-07-09 13:20:17 +0200
committerThomas Haller <thaller@redhat.com>2018-07-09 16:30:12 +0200
commit56ddc8904d832b7d9aee16ba800b16c46cf1709e (patch)
tree20510717fad8d62868b4eed4e201676ae4a8bb28
parent29c9ef3f46e8bf5a4ff704e63b113d435d42376b (diff)
downloadNetworkManager-56ddc8904d832b7d9aee16ba800b16c46cf1709e.tar.gz
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.
-rw-r--r--shared/nm-utils/nm-glib.h372
-rw-r--r--shared/nm-utils/nm-test-utils.h20
2 files changed, 391 insertions, 1 deletions
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);
}