diff options
Diffstat (limited to 'src/libnm-std-aux')
| -rw-r--r-- | src/libnm-std-aux/nm-linux-compat.h | 1 | ||||
| -rw-r--r-- | src/libnm-std-aux/nm-std-aux.h | 107 | ||||
| -rw-r--r-- | src/libnm-std-aux/nm-std-utils.c | 40 | ||||
| -rw-r--r-- | src/libnm-std-aux/nm-std-utils.h | 2 |
4 files changed, 109 insertions, 41 deletions
diff --git a/src/libnm-std-aux/nm-linux-compat.h b/src/libnm-std-aux/nm-linux-compat.h index 2675393d..2b04b0df 100644 --- a/src/libnm-std-aux/nm-linux-compat.h +++ b/src/libnm-std-aux/nm-linux-compat.h @@ -21,7 +21,6 @@ #include "linux-headers/ethtool.h" #include "linux-headers/nl802154.h" -#include "linux-headers/nl80211-vnd-intel.h" #include "linux-headers/mptcp.h" #endif /* __NM_LINUX_COMPAT_H__ */ diff --git a/src/libnm-std-aux/nm-std-aux.h b/src/libnm-std-aux/nm-std-aux.h index d310305e..3b39a019 100644 --- a/src/libnm-std-aux/nm-std-aux.h +++ b/src/libnm-std-aux/nm-std-aux.h @@ -154,6 +154,12 @@ typedef uint64_t _nm_bitwise nm_be64_t; /*****************************************************************************/ +#define _NM_INT_IS_SIGNED(arg) (!(((typeof(arg)) -1) > 0)) + +#define _NM_INT_SAME_SIGNEDNESS(arg1, arg2) (_NM_INT_IS_SIGNED(arg1) == _NM_INT_IS_SIGNED(arg2)) + +/*****************************************************************************/ + #define NM_PASTE_ARGS(identifier1, identifier2) identifier1##identifier2 #define NM_PASTE(identifier1, identifier2) NM_PASTE_ARGS(identifier1, identifier2) @@ -386,37 +392,63 @@ nm_mult_clamped_u(unsigned a, unsigned b) return c; } -/* glib's MIN()/MAX() macros don't have function-like behavior, in that they evaluate - * the argument possibly twice. - * - * Taken from systemd's MIN()/MAX() macros. */ - -#define NM_MIN(a, b) __NM_MIN(NM_UNIQ, a, NM_UNIQ, b) -#define __NM_MIN(aq, a, bq, b) \ - ({ \ - typeof(a) NM_UNIQ_T(A, aq) = (a); \ - typeof(b) NM_UNIQ_T(B, bq) = (b); \ - ((NM_UNIQ_T(A, aq) < NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ +/* In a few places where a constant expression is required, NM_MIN() doesn't work. + * In that case, use NM_MIN_CONST(). */ +#define NM_MIN_CONST(a, b) \ + ((NM_STATIC_ASSERT_EXPR_1(_NM_INT_SAME_SIGNEDNESS((a), (b)) && __builtin_constant_p((a)) \ + && __builtin_constant_p((b))) \ + && ((a) <= (b))) \ + ? (a) \ + : (b)) + +#define _NM_MIN_V(aq, a, bq, b) \ + ({ \ + typeof(a) NM_UNIQ_T(A, aq) = (a); \ + typeof(b) NM_UNIQ_T(B, bq) = (b); \ + \ + ((NM_UNIQ_T(A, aq) <= NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ }) -#define NM_MAX(a, b) __NM_MAX(NM_UNIQ, a, NM_UNIQ, b) -#define __NM_MAX(aq, a, bq, b) \ - ({ \ - typeof(a) NM_UNIQ_T(A, aq) = (a); \ - typeof(b) NM_UNIQ_T(B, bq) = (b); \ - ((NM_UNIQ_T(A, aq) > NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ +#define NM_MIN(a, b) \ + __builtin_choose_expr(__builtin_constant_p((a)) && __builtin_constant_p((b)) \ + && NM_STATIC_ASSERT_EXPR_1(_NM_INT_SAME_SIGNEDNESS((a), (b))), \ + (((a) <= (b)) ? (a) : (b)), \ + _NM_MIN_V(NM_UNIQ, a, NM_UNIQ, b)) + +#define NM_MAX_CONST(a, b) \ + ((NM_STATIC_ASSERT_EXPR_1(_NM_INT_SAME_SIGNEDNESS((a), (b)) && __builtin_constant_p((a)) \ + && __builtin_constant_p((b))) \ + && ((a) >= (b))) \ + ? (a) \ + : (b)) + +#define _NM_MAX_V(aq, a, bq, b) \ + ({ \ + typeof(a) NM_UNIQ_T(A, aq) = (a); \ + typeof(b) NM_UNIQ_T(B, bq) = (b); \ + \ + ((NM_UNIQ_T(A, aq) >= NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ }) +#define NM_MAX(a, b) \ + __builtin_choose_expr(__builtin_constant_p((a)) && __builtin_constant_p((b)) \ + && NM_STATIC_ASSERT_EXPR_1(_NM_INT_SAME_SIGNEDNESS((a), (b))), \ + (((a) >= (b)) ? (a) : (b)), \ + _NM_MAX_V(NM_UNIQ, a, NM_UNIQ, b)) + #define NM_CLAMP(x, low, high) __NM_CLAMP(NM_UNIQ, x, NM_UNIQ, low, NM_UNIQ, high) -#define __NM_CLAMP(xq, x, lowq, low, highq, high) \ - ({ \ - typeof(x) NM_UNIQ_T(X, xq) = (x); \ - typeof(low) NM_UNIQ_T(LOW, lowq) = (low); \ - typeof(high) NM_UNIQ_T(HIGH, highq) = (high); \ - \ - ((NM_UNIQ_T(X, xq) > NM_UNIQ_T(HIGH, highq)) ? NM_UNIQ_T(HIGH, highq) \ - : (NM_UNIQ_T(X, xq) < NM_UNIQ_T(LOW, lowq)) ? NM_UNIQ_T(LOW, lowq) \ - : NM_UNIQ_T(X, xq)); \ +#define __NM_CLAMP(xq, x, lowq, low, highq, high) \ + ({ \ + typeof(x) NM_UNIQ_T(X, xq) = (x); \ + typeof(low) NM_UNIQ_T(LOW, lowq) = (low); \ + typeof(high) NM_UNIQ_T(HIGH, highq) = (high); \ + \ + NM_STATIC_ASSERT(_NM_INT_SAME_SIGNEDNESS(NM_UNIQ_T(X, xq), NM_UNIQ_T(LOW, lowq))); \ + NM_STATIC_ASSERT(_NM_INT_SAME_SIGNEDNESS(NM_UNIQ_T(X, xq), NM_UNIQ_T(HIGH, highq))); \ + \ + ((NM_UNIQ_T(X, xq) > NM_UNIQ_T(HIGH, highq)) ? NM_UNIQ_T(HIGH, highq) \ + : (NM_UNIQ_T(X, xq) < NM_UNIQ_T(LOW, lowq)) ? NM_UNIQ_T(LOW, lowq) \ + : NM_UNIQ_T(X, xq)); \ }) #define NM_MAX_WITH_CMP(cmp, a, b) \ @@ -427,13 +459,6 @@ nm_mult_clamped_u(unsigned a, unsigned b) (((cmp(_a, _b)) >= 0) ? _a : _b); \ }) -/* evaluates to (void) if _A or _B are not constant or of different types */ -#define NM_CONST_MAX(_A, _B) \ - (__builtin_choose_expr((__builtin_constant_p(_A) && __builtin_constant_p(_B) \ - && __builtin_types_compatible_p(typeof(_A), typeof(_B))), \ - ((_A) > (_B)) ? (_A) : (_B), \ - ((void) 0))) - /* Determine whether @x is a power of two (@x being an integer type). * Basically, this returns TRUE, if @x has exactly one bit set. * For negative values and zero, this always returns FALSE. */ @@ -1287,13 +1312,15 @@ nm_ptr_to_uintptr(const void *p) /*****************************************************************************/ -#define NM_CMP_DIRECT(a, b) \ - do { \ - typeof(a) _a = (a); \ - typeof(b) _b = (b); \ - \ - if (_a != _b) \ - return (_a < _b) ? -1 : 1; \ +#define NM_CMP_DIRECT(a, b) \ + do { \ + typeof(a) _a = (a); \ + typeof(b) _b = (b); \ + \ + NM_STATIC_ASSERT(_NM_INT_SAME_SIGNEDNESS(_a, _b)); \ + \ + if (_a != _b) \ + return (_a < _b) ? -1 : 1; \ } while (0) #define NM_CMP_DIRECT_UNSAFE(a, b) \ diff --git a/src/libnm-std-aux/nm-std-utils.c b/src/libnm-std-aux/nm-std-utils.c index 8901378c..8bc109f2 100644 --- a/src/libnm-std-aux/nm-std-utils.c +++ b/src/libnm-std-aux/nm-std-utils.c @@ -92,3 +92,43 @@ out_huge: } return SIZE_MAX; } + +/*****************************************************************************/ + +/** + * _nm_strerror_r: + * @errsv: the errno passed to strerror_r() + * @buf: the string buffer, must be non-null + * @buf_size: the size of the buffer, must be positive. + * + * A wrapper around strerror_r(). Does little else, aside clearing up the + * confusion about the different versions of the function. + * + * errno is preserved. + * + * Returns: the error string. This is either a static strong or @buf. It + * is not guaranteed to be @buf. + */ +const char * +_nm_strerror_r(int errsv, char *buf, size_t buf_size) +{ + NM_AUTO_PROTECT_ERRNO(errsv2); + char *buf2; + + nm_assert(buf); + nm_assert(buf_size > 0); + +#if (!defined(__GLIBC__) && !defined(__UCLIBC__)) || ((_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE) + /* XSI-compliant */ + if (strerror_r(errsv, buf, buf_size) != 0) { + snprintf(buf, buf_size, "Unspecified errno %d", errsv); + } + buf2 = buf; +#else + /* GNU-specific */ + buf2 = strerror_r(errsv, buf, buf_size); +#endif + + nm_assert(buf2); + return buf2; +} diff --git a/src/libnm-std-aux/nm-std-utils.h b/src/libnm-std-aux/nm-std-utils.h index 6aa787eb..015444c9 100644 --- a/src/libnm-std-aux/nm-std-utils.h +++ b/src/libnm-std-aux/nm-std-utils.h @@ -35,4 +35,6 @@ size_t nm_utils_get_next_realloc_size(bool true_realloc, size_t requested); +const char *_nm_strerror_r(int errsv, char *buf, size_t buf_size); + #endif /* __NM_STD_UTILS_H__ */ |