diff options
Diffstat (limited to 'shared/nm-utils/nm-macros-internal.h')
| -rw-r--r-- | shared/nm-utils/nm-macros-internal.h | 245 |
1 files changed, 66 insertions, 179 deletions
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index cc7205a4..29678bb6 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -35,12 +35,6 @@ #define _nm_alignof(type) __alignof (type) #define _nm_alignas(type) _nm_align (_nm_alignof (type)) -#if __GNUC__ >= 7 -#define _nm_fallthrough __attribute__ ((fallthrough)) -#else -#define _nm_fallthrough -#endif - /*****************************************************************************/ #ifdef thread_local @@ -76,30 +70,6 @@ static inline int nm_close (int fd); GS_DEFINE_CLEANUP_FUNCTION(void*, _nm_auto_free_impl, free) static inline void -nm_free_secret (char *secret) -{ - if (secret) { - memset (secret, 0, strlen (secret)); - g_free (secret); - } -} - -static inline void -_nm_auto_free_secret_impl (char **v) -{ - nm_free_secret (*v); -} - -/** - * nm_auto_free_secret: - * - * Call g_free() on a variable location when it goes out of scope. - * Also, previously, calls memset(loc, 0, strlen(loc)) to clear out - * the secret. - */ -#define nm_auto_free_secret nm_auto(_nm_auto_free_secret_impl) - -static inline void _nm_auto_unset_gvalue_impl (GValue *v) { g_value_unset (v); @@ -271,8 +241,7 @@ NM_G_ERROR_MSG (GError *error) gsize _n = 0; \ \ if (_array) { \ - _nm_unused gconstpointer _type_check_is_pointer = _array[0]; \ - \ + _nm_unused typeof (*(_array[0])) *_array_check = _array[0]; \ while (_array[_n]) \ _n++; \ } \ @@ -390,28 +359,6 @@ NM_G_ERROR_MSG (GError *error) #define NM_CONSTCAST(type, obj, ...) \ NM_CONSTCAST_FULL(type, (obj), (obj), ##__VA_ARGS__) -#if _NM_CC_SUPPORT_GENERIC -#define NM_UNCONST_PTR(type, arg) \ - _Generic ((arg), \ - const type *: ((type *) (arg)), \ - type *: ((type *) (arg))) -#else -#define NM_UNCONST_PTR(type, arg) \ - ((type *) (arg)) -#endif - -#if _NM_CC_SUPPORT_GENERIC -#define NM_UNCONST_PPTR(type, arg) \ - _Generic ((arg), \ - const type * *: ((type **) (arg)), \ - type * *: ((type **) (arg)), \ - const type *const*: ((type **) (arg)), \ - type *const*: ((type **) (arg))) -#else -#define NM_UNCONST_PPTR(type, arg) \ - ((type **) (arg)) -#endif - #define NM_GOBJECT_CAST(type, obj, is_check, ...) \ ({ \ const void *_obj = (obj); \ @@ -441,41 +388,6 @@ NM_G_ERROR_MSG (GError *error) #endif #if _NM_CC_SUPPORT_GENERIC -/* these macros cast (value) to - * - "const char **" (for "MC", mutable-const) - * - "const char *const*" (for "CC", const-const) - * The point is to do this cast, but only accepting pointers - * that are compatible already. - * - * The problem is, if you add a function like g_strdupv(), the input - * argument is not modified (CC), but you want to make it work also - * for "char **". C doesn't allow this form of casting (for good reasons), - * so the function makes a choice like g_strdupv(char**). That means, - * every time you want to call ith with a const argument, you need to - * explicitly cast it. - * - * These macros do the cast, but they only accept a compatible input - * type, otherwise they will fail compilation. - */ -#define NM_CAST_STRV_MC(value) \ - (_Generic ((value), \ - const char * *: (const char * *) (value), \ - char * *: (const char * *) (value), \ - void *: (const char * *) (value))) -#define NM_CAST_STRV_CC(value) \ - (_Generic ((value), \ - const char *const*: (const char *const*) (value), \ - const char * *: (const char *const*) (value), \ - char *const*: (const char *const*) (value), \ - char * *: (const char *const*) (value), \ - const void *: (const char *const*) (value), \ - void *: (const char *const*) (value))) -#else -#define NM_CAST_STRV_MC(value) ((const char * *) (value)) -#define NM_CAST_STRV_CC(value) ((const char *const*) (value)) -#endif - -#if _NM_CC_SUPPORT_GENERIC #define NM_PROPAGATE_CONST(test_expr, ptr) \ (_Generic ((test_expr), \ const typeof (*(test_expr)) *: ((const typeof (*(ptr)) *) (ptr)), \ @@ -829,32 +741,6 @@ nm_g_object_unref (gpointer obj) _changed; \ }) -#define nm_clear_pointer(pp, destroy) \ - ({ \ - typeof (*(pp)) *_pp = (pp); \ - typeof (*_pp) _p; \ - gboolean _changed = FALSE; \ - \ - if ( _pp \ - && (_p = *_pp)) { \ - _nm_unused gconstpointer _p_check_is_pointer = _p; \ - \ - *_pp = NULL; \ - /* g_clear_pointer() assigns @destroy first to a local variable, so that - * you can call "g_clear_pointer (pp, (GDestroyNotify) destroy);" without - * gcc emitting a warning. We don't do that, hence, you cannot cast - * "destroy" first. - * - * On the upside: you are not supposed to cast fcn, because the pointer - * types are preserved. If you really need a cast, you should cast @pp. - * But that is hardly ever necessary. */ \ - (destroy) (_p); \ - \ - _changed = TRUE; \ - } \ - _changed; \ - }) - /* basically, replaces * g_clear_pointer (&location, g_free) * with @@ -865,20 +751,42 @@ nm_g_object_unref (gpointer obj) * pointer or points to a const-pointer. */ #define nm_clear_g_free(pp) \ - nm_clear_pointer (pp, g_free) + ({ \ + typeof (*(pp)) *_pp = (pp); \ + typeof (**_pp) *_p; \ + gboolean _changed = FALSE; \ + \ + if ( _pp \ + && (_p = *_pp)) { \ + *_pp = NULL; \ + g_free (_p); \ + _changed = TRUE; \ + } \ + _changed; \ + }) #define nm_clear_g_object(pp) \ - nm_clear_pointer (pp, g_object_unref) + ({ \ + typeof (*(pp)) *_pp = (pp); \ + typeof (**_pp) *_p; \ + gboolean _changed = FALSE; \ + \ + if ( _pp \ + && (_p = *_pp)) { \ + nm_assert (G_IS_OBJECT (_p)); \ + *_pp = NULL; \ + g_object_unref (_p); \ + _changed = TRUE; \ + } \ + _changed; \ + }) static inline gboolean nm_clear_g_source (guint *id) { - guint v; - - if ( id - && (v = *id)) { + if (id && *id) { + g_source_remove (*id); *id = 0; - g_source_remove (v); return TRUE; } return FALSE; @@ -887,12 +795,9 @@ nm_clear_g_source (guint *id) static inline gboolean nm_clear_g_signal_handler (gpointer self, gulong *id) { - gulong v; - - if ( id - && (v = *id)) { + if (id && *id) { + g_signal_handler_disconnect (self, *id); *id = 0; - g_signal_handler_disconnect (self, v); return TRUE; } return FALSE; @@ -901,12 +806,9 @@ nm_clear_g_signal_handler (gpointer self, gulong *id) static inline gboolean nm_clear_g_variant (GVariant **variant) { - GVariant *v; - - if ( variant - && (v = *variant)) { + if (variant && *variant) { + g_variant_unref (*variant); *variant = NULL; - g_variant_unref (v); return TRUE; } return FALSE; @@ -915,13 +817,10 @@ nm_clear_g_variant (GVariant **variant) static inline gboolean nm_clear_g_cancellable (GCancellable **cancellable) { - GCancellable *v; - - if ( cancellable - && (v = *cancellable)) { + if (cancellable && *cancellable) { + g_cancellable_cancel (*cancellable); + g_object_unref (*cancellable); *cancellable = NULL; - g_cancellable_cancel (v); - g_object_unref (v); return TRUE; } return FALSE; @@ -1092,6 +991,35 @@ nm_strcmp_p (gconstpointer a, gconstpointer b) return strcmp (s1, s2); } +/* like nm_strcmp_p(), suitable for g_ptr_array_sort_with_data(). + * g_ptr_array_sort() just casts nm_strcmp_p() to a function of different + * signature. I guess, in glib there are knowledgeable people that ensure + * that this additional argument doesn't cause problems due to different ABI + * for every architecture that glib supports. + * For NetworkManager, we'd rather avoid such stunts. + **/ +static inline int +nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data) +{ + const char *s1 = *((const char **) a); + const char *s2 = *((const char **) b); + + return strcmp (s1, s2); +} + +static inline int +nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data) +{ + const guint32 a = *((const guint32 *) p_a); + const guint32 b = *((const guint32 *) p_b); + + if (a < b) + return -1; + if (a > b) + return 1; + return 0; +} + /*****************************************************************************/ /* Taken from systemd's UNIQ_T and UNIQ macros. */ @@ -1222,28 +1150,6 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro) _buf; \ }) -/* aims to alloca() a buffer and fill it with printf(format, name). - * Note that format must not contain any format specifier except - * "%s". - * If the resulting string would be too large for stack allocation, - * it allocates a buffer with g_malloc() and assigns it to *p_val_to_free. */ -#define nm_construct_name_a(format, name, p_val_to_free) \ - ({ \ - const char *const _name = (name); \ - char **const _p_val_to_free = (p_val_to_free); \ - const gsize _name_len = strlen (_name); \ - char *_buf2; \ - \ - nm_assert (_p_val_to_free && !*_p_val_to_free); \ - if (NM_STRLEN (format) + _name_len < 200) \ - _buf2 = nm_sprintf_bufa (NM_STRLEN (format) + _name_len, format, _name); \ - else { \ - _buf2 = g_strdup_printf (format, _name); \ - *_p_val_to_free = _buf2; \ - } \ - (const char *) _buf2; \ - }) - /*****************************************************************************/ /** @@ -1319,25 +1225,6 @@ nm_decode_version (guint version, guint *major, guint *minor, guint *micro) /*****************************************************************************/ -/** - * nm_steal_int: - * @p_val: pointer to an int type. - * - * Returns: *p_val and sets *p_val to zero the same time. - * Accepts %NULL, in which case also numeric 0 will be returned. - */ -#define nm_steal_int(p_val) \ - ({ \ - typeof (p_val) const _p_val = (p_val); \ - typeof (*_p_val) _val = 0; \ - \ - if ( _p_val \ - && (_val = *_p_val)) { \ - *_p_val = 0; \ - } \ - _val; \ - }) - static inline int nm_steal_fd (int *p_fd) { |