mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-04-21 11:10:46 +02:00
std-aux: merge branch 'th/move-macros-to-std-aux'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/948
This commit is contained in:
commit
1e76fef4d1
3 changed files with 105 additions and 88 deletions
|
|
@ -411,14 +411,15 @@ _nm_g_hash_table_get_keys_as_array(GHashTable *hash_table, guint *length)
|
|||
#undef g_steal_pointer
|
||||
#endif
|
||||
|
||||
#define g_steal_pointer(pp) \
|
||||
({ \
|
||||
typeof(*(pp)) *const _pp = (pp); \
|
||||
typeof(*_pp) _p = *_pp; \
|
||||
_nm_unused const void *const _p_type_check = _p; \
|
||||
\
|
||||
*_pp = NULL; \
|
||||
_p; \
|
||||
#define g_steal_pointer(pp) \
|
||||
({ \
|
||||
typeof(*(pp)) *const _pp = (pp); \
|
||||
typeof(*_pp) _p = *_pp; \
|
||||
\
|
||||
_NM_ENSURE_POINTER(_p); \
|
||||
\
|
||||
*_pp = NULL; \
|
||||
_p; \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -43,10 +43,6 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define nm_offsetofend(t, m) (G_STRUCT_OFFSET(t, m) + sizeof(((t *) NULL)->m))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define gs_free nm_auto_g_free
|
||||
#define gs_unref_object nm_auto_unref_object
|
||||
#define gs_unref_variant nm_auto_unref_variant
|
||||
|
|
@ -228,34 +224,6 @@ NM_G_ERROR_MSG(GError *error)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef _NM_CC_SUPPORT_AUTO_TYPE
|
||||
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)))
|
||||
#define _NM_CC_SUPPORT_AUTO_TYPE 1
|
||||
#else
|
||||
#define _NM_CC_SUPPORT_AUTO_TYPE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _NM_CC_SUPPORT_GENERIC
|
||||
/* In the meantime, NetworkManager requires C11 and _Generic() should always be available.
|
||||
* However, shared/nm-utils may also be used in VPN/applet, which possibly did not yet
|
||||
* bump the C standard requirement. Leave this for the moment, but eventually we can
|
||||
* drop it.
|
||||
*
|
||||
* Technically, gcc 4.9 already has some support for _Generic(). But there seems
|
||||
* to be issues with propagating "const char *[5]" to "const char **". Only assume
|
||||
* we have _Generic() since gcc 5. */
|
||||
#if (defined(__GNUC__) && __GNUC__ >= 5) || (defined(__clang__))
|
||||
#define _NM_CC_SUPPORT_GENERIC 1
|
||||
#else
|
||||
#define _NM_CC_SUPPORT_GENERIC 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _NM_CC_SUPPORT_AUTO_TYPE
|
||||
#define _nm_auto_type __auto_type
|
||||
#endif
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC
|
||||
#define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \
|
||||
(_Generic ((obj_expr), \
|
||||
|
|
@ -375,45 +343,16 @@ NM_G_ERROR_MSG(GError *error)
|
|||
_ptr; \
|
||||
})
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC
|
||||
/* returns @value, if the type of @value matches @type.
|
||||
* This requires support for C11 _Generic(). If no support is
|
||||
* present, this returns @value directly.
|
||||
*
|
||||
* It's useful to check the let the compiler ensure that @value is
|
||||
* of a certain type. */
|
||||
#define _NM_ENSURE_TYPE(type, value) (_Generic((value), type : (value)))
|
||||
#define _NM_ENSURE_TYPE_CONST(type, value) \
|
||||
(_Generic((value), const type \
|
||||
: ((const type) (value)), const type const \
|
||||
: ((const type) (value)), type \
|
||||
: ((const type) (value)), type const \
|
||||
: ((const type) (value))))
|
||||
#else
|
||||
#define _NM_ENSURE_TYPE(type, value) (value)
|
||||
#define _NM_ENSURE_TYPE_CONST(type, value) ((const type) (value))
|
||||
#endif
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC && (!defined(__clang__) || __clang_major__ > 3)
|
||||
#define NM_STRUCT_OFFSET_ENSURE_TYPE(type, container, field) \
|
||||
(_Generic((&(((container *) NULL)->field))[0], type : G_STRUCT_OFFSET(container, field)))
|
||||
#else
|
||||
#define NM_STRUCT_OFFSET_ENSURE_TYPE(type, container, field) G_STRUCT_OFFSET(container, field)
|
||||
#endif
|
||||
|
||||
/* Casts (arg) to (type**), but also having a compile time check that
|
||||
* the arg is some sort of pointer to a pointer.
|
||||
*
|
||||
* The only purpose of this macro is some additional compile time safety,
|
||||
* that the argument is a pointer to pointer. But then it will C cast any kind
|
||||
* of such argument. */
|
||||
#define NM_CAST_PPTR(type, arg) \
|
||||
({ \
|
||||
typeof(*(arg)) *const _arg = (arg); \
|
||||
typeof(*_arg) _arg2 = _arg ? *_arg : NULL; \
|
||||
_nm_unused const void *const _arg3 = _arg2; \
|
||||
\
|
||||
(type **) _arg; \
|
||||
#define NM_CAST_PPTR(type, arg) \
|
||||
({ \
|
||||
_NM_ENSURE_POINTER(*(arg)); \
|
||||
(type **) (arg); \
|
||||
})
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -46,6 +47,36 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef _NM_CC_SUPPORT_AUTO_TYPE
|
||||
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)))
|
||||
#define _NM_CC_SUPPORT_AUTO_TYPE 1
|
||||
#else
|
||||
#define _NM_CC_SUPPORT_AUTO_TYPE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if _NM_CC_SUPPORT_AUTO_TYPE
|
||||
#define _nm_auto_type __auto_type
|
||||
#endif
|
||||
|
||||
#ifndef _NM_CC_SUPPORT_GENERIC
|
||||
/* In the meantime, NetworkManager requires C11 and _Generic() should always be available.
|
||||
* However, shared/nm-utils may also be used in VPN/applet, which possibly did not yet
|
||||
* bump the C standard requirement. Leave this for the moment, but eventually we can
|
||||
* drop it.
|
||||
*
|
||||
* Technically, gcc 4.9 already has some support for _Generic(). But there seems
|
||||
* to be issues with propagating "const char *[5]" to "const char **". Only assume
|
||||
* we have _Generic() since gcc 5. */
|
||||
#if (defined(__GNUC__) && __GNUC__ >= 5) || (defined(__clang__))
|
||||
#define _NM_CC_SUPPORT_GENERIC 1
|
||||
#else
|
||||
#define _NM_CC_SUPPORT_GENERIC 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifdef __CHECKER__
|
||||
#define _nm_bitwise __attribute__((__bitwise__))
|
||||
#define _nm_force __attribute__((__force__))
|
||||
|
|
@ -192,6 +223,14 @@ typedef uint64_t _nm_bitwise nm_be64_t;
|
|||
|
||||
#define NM_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define nm_offsetof(t, m) offsetof(t, m)
|
||||
|
||||
#define nm_offsetofend(t, m) (nm_offsetof(t, m) + sizeof(((t *) NULL)->m))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* This does a compile time check that "type" is a suitable C type. It either
|
||||
* returns a compile time constant of 1 or it fails compilation. The point
|
||||
* is only in macros to check that a macro parameter (what we might pass to
|
||||
|
|
@ -200,6 +239,45 @@ typedef uint64_t _nm_bitwise nm_be64_t;
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC
|
||||
/* returns @value, if the type of @value matches @type.
|
||||
* This requires support for C11 _Generic(). If no support is
|
||||
* present, this returns @value directly.
|
||||
*
|
||||
* It's useful to check the let the compiler ensure that @value is
|
||||
* of a certain type. */
|
||||
#define _NM_ENSURE_TYPE(type, value) (_Generic((value), type : (value)))
|
||||
#define _NM_ENSURE_TYPE_CONST(type, value) \
|
||||
(_Generic((value), const type \
|
||||
: ((const type) (value)), const type const \
|
||||
: ((const type) (value)), type \
|
||||
: ((const type) (value)), type const \
|
||||
: ((const type) (value))))
|
||||
#else
|
||||
#define _NM_ENSURE_TYPE(type, value) (value)
|
||||
#define _NM_ENSURE_TYPE_CONST(type, value) ((const type) (value))
|
||||
#endif
|
||||
|
||||
/* returns void, but does a compile time check that the argument is a pointer
|
||||
* (that is, can be converted to (const void *)). It does not actually evaluate
|
||||
* (value). That means, it's also safe to call _NM_ENSURE_POINTER(array[0]) if
|
||||
* array might be NULL. It's also safe to call on a macro argument that is
|
||||
* supposed to be evaluate at most once (this macro will not "execute" the
|
||||
* argument). */
|
||||
#define _NM_ENSURE_POINTER(value) \
|
||||
do { \
|
||||
_nm_unused const void *const _unused_for_type_check = 0 ? (value) : NULL; \
|
||||
} while (0)
|
||||
|
||||
#if _NM_CC_SUPPORT_GENERIC && (!defined(__clang__) || __clang_major__ > 3)
|
||||
#define NM_STRUCT_OFFSET_ENSURE_TYPE(type, container, field) \
|
||||
(_Generic((&(((container *) NULL)->field))[0], type : nm_offsetof(container, field)))
|
||||
#else
|
||||
#define NM_STRUCT_OFFSET_ENSURE_TYPE(type, container, field) nm_offsetof(container, field)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline uint32_t
|
||||
nm_add_clamped_u32(uint32_t a, uint32_t b)
|
||||
{
|
||||
|
|
@ -332,12 +410,10 @@ _nm_ptrarray_len_impl(const void *const *array)
|
|||
* like g_strv_length() does. The difference is:
|
||||
* - it operates on arrays of pointers (of any kind, requiring no cast).
|
||||
* - it accepts NULL to return zero. */
|
||||
#define NM_PTRARRAY_LEN(array) \
|
||||
({ \
|
||||
typeof(*(array)) *const _array = (array); \
|
||||
_nm_unused const void * _type_check_is_pointer = 0 ? _array[0] : NULL; \
|
||||
\
|
||||
_nm_ptrarray_len_impl((const void *const *) _array); \
|
||||
#define NM_PTRARRAY_LEN(array) \
|
||||
({ \
|
||||
_NM_ENSURE_POINTER((array)[0]); \
|
||||
_nm_ptrarray_len_impl((const void *const *) (array)); \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -866,7 +942,7 @@ _nm_auto_fclose(FILE **pfd)
|
|||
int _changed = false; \
|
||||
\
|
||||
if (_pp && (_p = *_pp)) { \
|
||||
_nm_unused const void *_p_check_is_pointer = _p; \
|
||||
_NM_ENSURE_POINTER(_p); \
|
||||
\
|
||||
*_pp = NULL; \
|
||||
\
|
||||
|
|
@ -889,14 +965,15 @@ _nm_auto_fclose(FILE **pfd)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define nm_steal_pointer(pp) \
|
||||
({ \
|
||||
typeof(*(pp)) *const _pp = (pp); \
|
||||
typeof(*_pp) _p = *_pp; \
|
||||
_nm_unused const void *const _p_type_check = _p; \
|
||||
\
|
||||
*_pp = NULL; \
|
||||
_p; \
|
||||
#define nm_steal_pointer(pp) \
|
||||
({ \
|
||||
typeof(*(pp)) *const _pp = (pp); \
|
||||
typeof(*_pp) _p = *_pp; \
|
||||
\
|
||||
_NM_ENSURE_POINTER(_p); \
|
||||
\
|
||||
*_pp = NULL; \
|
||||
_p; \
|
||||
})
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue