From e74c568b07b50b97873fb4ee1d776dedefbd54d6 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 1 Oct 2021 23:05:04 +0200 Subject: New upstream version 1.32.12 --- shared/nm-std-aux/c-list-util.c | 184 ---- shared/nm-std-aux/c-list-util.h | 56 -- shared/nm-std-aux/nm-dbus-compat.h | 25 - shared/nm-std-aux/nm-default-std.h | 102 --- shared/nm-std-aux/nm-networkmanager-compilation.h | 54 -- shared/nm-std-aux/nm-std-aux.h | 985 ---------------------- shared/nm-std-aux/nm-std-utils.c | 90 -- shared/nm-std-aux/nm-std-utils.h | 36 - shared/nm-std-aux/unaligned.h | 99 --- 9 files changed, 1631 deletions(-) delete mode 100644 shared/nm-std-aux/c-list-util.c delete mode 100644 shared/nm-std-aux/c-list-util.h delete mode 100644 shared/nm-std-aux/nm-dbus-compat.h delete mode 100644 shared/nm-std-aux/nm-default-std.h delete mode 100644 shared/nm-std-aux/nm-networkmanager-compilation.h delete mode 100644 shared/nm-std-aux/nm-std-aux.h delete mode 100644 shared/nm-std-aux/nm-std-utils.c delete mode 100644 shared/nm-std-aux/nm-std-utils.h delete mode 100644 shared/nm-std-aux/unaligned.h (limited to 'shared/nm-std-aux') diff --git a/shared/nm-std-aux/c-list-util.c b/shared/nm-std-aux/c-list-util.c deleted file mode 100644 index d16bd6b7..00000000 --- a/shared/nm-std-aux/c-list-util.c +++ /dev/null @@ -1,184 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2017 Red Hat, Inc. - */ - -#include "c-list-util.h" - -/*****************************************************************************/ - -/** - * c_list_relink: - * @lst: the head list entry - * - * Takes an invalid list, that has undefined prev pointers. - * Only the next pointers are valid, and the tail's next - * pointer points to %NULL instead of the head. - * - * c_list_relink() fixes the list by updating all prev pointers - * and close the circular linking by pointing the tails' next - * pointer to @lst. - * - * The use of this function is to do a bulk update, that lets the - * list degenerate by not updating the prev pointers. At the end, - * the list can be fixed by c_list_relink(). - */ -void -c_list_relink(CList *lst) -{ - CList *ls, *ls_prev; - - ls_prev = lst; - ls = lst->next; - do { - ls->prev = ls_prev; - ls_prev = ls; - ls = ls->next; - } while (ls); - ls_prev->next = lst; - lst->prev = ls_prev; -} - -/*****************************************************************************/ - -static CList * -_c_list_srt_split(CList *ls) -{ - CList *ls2; - - ls2 = ls; - ls = ls->next; - if (!ls) - return NULL; - do { - ls = ls->next; - if (!ls) - break; - ls = ls->next; - ls2 = ls2->next; - } while (ls); - ls = ls2->next; - ls2->next = NULL; - return ls; -} - -static CList * -_c_list_srt_merge(CList *ls1, CList *ls2, CListSortCmp cmp, const void *user_data) -{ - CList *ls; - CList head; - - ls = &head; - for (;;) { - /* while invoking the @cmp function, the list - * elements are not properly linked. Don't try to access - * their next/prev pointers. */ - if (cmp(ls1, ls2, user_data) <= 0) { - ls->next = ls1; - ls = ls1; - ls1 = ls1->next; - if (!ls1) - break; - } else { - ls->next = ls2; - ls = ls2; - ls2 = ls2->next; - if (!ls2) - break; - } - } - ls->next = ls1 ?: ls2; - - return head.next; -} - -typedef struct { - CList *ls1; - CList *ls2; - char ls1_sorted; -} SortStack; - -static CList * -_c_list_sort(CList *ls, CListSortCmp cmp, const void *user_data) -{ - /* reserve a huge stack-size. We need roughly log2(n) entries, hence this - * is much more we will ever need. We don't guard for stack-overflow either. */ - SortStack stack_arr[70]; - SortStack *stack_head = stack_arr; - - stack_arr[0].ls1 = ls; - - /* A simple top-down, non-recursive, stable merge-sort. - * - * Maybe natural merge-sort would be better, to do better for - * partially sorted lists. Doing that would be much more complicated, - * so it's not done. */ -_split: - stack_head[0].ls2 = _c_list_srt_split(stack_head[0].ls1); - if (stack_head[0].ls2) { - stack_head[0].ls1_sorted = 0; - stack_head[1].ls1 = stack_head[0].ls1; - stack_head++; - goto _split; - } - -_backtrack: - if (stack_head == stack_arr) - return stack_arr[0].ls1; - - stack_head--; - if (!stack_head[0].ls1_sorted) { - stack_head[0].ls1 = stack_head[1].ls1; - stack_head[0].ls1_sorted = 1; - stack_head[1].ls1 = stack_head[0].ls2; - stack_head++; - goto _split; - } - - stack_head[0].ls1 = _c_list_srt_merge(stack_head[0].ls1, stack_head[1].ls1, cmp, user_data); - goto _backtrack; -} - -/** - * c_list_sort_headless: - * @lst: the list. - * @cmp: compare function for sorting. While comparing two - * CList elements, their next/prev pointers are in undefined - * state. - * @user_data: user data for @cmp. - * - * Sorts the list @lst according to @cmp. Contrary to - * c_list_sort(), @lst is not the list head but a - * valid entry as well. This function returns the new - * list head. - */ -CList * -c_list_sort_headless(CList *lst, CListSortCmp cmp, const void *user_data) -{ - if (!c_list_is_empty(lst)) { - lst->prev->next = NULL; - lst = _c_list_sort(lst, cmp, user_data); - c_list_relink(lst); - } - return lst; -} - -/** - * c_list_sort: - * @head: the list head. - * @cmp: compare function for sorting. While comparing two - * CList elements, their next/prev pointers are in undefined - * state. - * @user_data: user data for @cmp. - * - * Sorts the list @head according to @cmp. - */ -void -c_list_sort(CList *head, CListSortCmp cmp, const void *user_data) -{ - if (!c_list_is_empty(head) && head->next->next != head) { - head->prev->next = NULL; - head->next = _c_list_sort(head->next, cmp, user_data); - c_list_relink(head); - } -} diff --git a/shared/nm-std-aux/c-list-util.h b/shared/nm-std-aux/c-list-util.h deleted file mode 100644 index 9d86d663..00000000 --- a/shared/nm-std-aux/c-list-util.h +++ /dev/null @@ -1,56 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2017 Red Hat, Inc. - */ - -#ifndef __C_LIST_UTIL_H__ -#define __C_LIST_UTIL_H__ - -#include "c-list/src/c-list.h" - -/*****************************************************************************/ - -void c_list_relink(CList *lst); - -typedef int (*CListSortCmp)(const CList *a, const CList *b, const void *user_data); - -CList *c_list_sort_headless(CList *lst, CListSortCmp cmp, const void *user_data); - -void c_list_sort(CList *head, CListSortCmp cmp, const void *user_data); - -/* c_list_length_is: - * @list: the #CList list head - * @check_len: the length to compare - * - * Returns: basically the same as (c_list_length (@list) == @check_len), - * but does not require to iterate the entire list first. There is only - * one real use: to find out whether there is exactly one element in the - * list, by passing @check_len as 1. - */ -static inline int -c_list_length_is(const CList *list, unsigned long check_len) -{ - unsigned long n = 0; - const CList * iter; - - c_list_for_each (iter, list) { - ++n; - if (n > check_len) - return 0; - } - - return n == check_len; -} - -#define c_list_for_each_prev(_iter, _list) \ - for (_iter = (_list)->prev; (_iter) != (_list); _iter = (_iter)->prev) - -#define c_list_for_each_prev_safe(_iter, _safe, _list) \ - for (_iter = (_list)->prev, _safe = (_iter)->prev; (_iter) != (_list); \ - _iter = (_safe), _safe = (_safe)->prev) - -#define c_list_for_each_entry_prev(_iter, _list, _m) \ - for (_iter = c_list_entry((_list)->prev, __typeof__(*_iter), _m); &(_iter)->_m != (_list); \ - _iter = c_list_entry((_iter)->_m.prev, __typeof__(*_iter), _m)) - -#endif /* __C_LIST_UTIL_H__ */ diff --git a/shared/nm-std-aux/nm-dbus-compat.h b/shared/nm-std-aux/nm-dbus-compat.h deleted file mode 100644 index c1076200..00000000 --- a/shared/nm-std-aux/nm-dbus-compat.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#ifndef __NM_DBUS_COMPAT_H__ -#define __NM_DBUS_COMPAT_H__ - -#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" - -#define DBUS_PATH_DBUS "/org/freedesktop/DBus" - -#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" -#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" -#define DBUS_INTERFACE_OBJECT_MANAGER "org.freedesktop.DBus.ObjectManager" -#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer" -#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" - -#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 -#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 -#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 - -#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 -#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 -#define DBUS_REQUEST_NAME_REPLY_EXISTS 3 -#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 - -#endif /* __NM_DBUS_COMPAT_H__ */ diff --git a/shared/nm-std-aux/nm-default-std.h b/shared/nm-std-aux/nm-default-std.h deleted file mode 100644 index fe16d35f..00000000 --- a/shared/nm-std-aux/nm-default-std.h +++ /dev/null @@ -1,102 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2015 Red Hat, Inc. - */ - -#ifndef __NM_DEFAULT_STD_H__ -#define __NM_DEFAULT_STD_H__ - -#include "nm-networkmanager-compilation.h" - -#ifdef NETWORKMANAGER_COMPILATION - #error Dont define NETWORKMANAGER_COMPILATION -#endif - -#ifndef G_LOG_DOMAIN - #error Define G_LOG_DOMAIN -#endif - -/*****************************************************************************/ - -#define NETWORKMANAGER_COMPILATION 0 - -/*****************************************************************************/ - -/* always include these headers for our internal source files. */ - -#ifndef ___CONFIG_H__ - #define ___CONFIG_H__ - #include -#endif - -#include "config-extra.h" - -/* for internal compilation we don't want the deprecation macros - * to be in effect. Define the widest range of versions to effectively - * disable deprecation checks */ -#define NM_VERSION_MIN_REQUIRED NM_VERSION_0_9_8 - -#ifndef NM_MORE_ASSERTS - #define NM_MORE_ASSERTS 0 -#endif - -#if NM_MORE_ASSERTS == 0 - /* The cast macros like NM_TYPE() are implemented via G_TYPE_CHECK_INSTANCE_CAST() - * and _G_TYPE_CIC(). The latter, by default performs runtime checks of the type - * by calling g_type_check_instance_cast(). - * This check has a certain overhead without being helpful. - * - * Example 1: - * static void foo (NMType *obj) - * { - * access_obj_without_check (obj); - * } - * foo ((NMType *) obj); - * // There is no runtime check and passing an invalid pointer - * // leads to a crash. - * - * Example 2: - * static void foo (NMType *obj) - * { - * access_obj_without_check (obj); - * } - * foo (NM_TYPE (obj)); - * // There is a runtime check which prints a g_warning(), but that doesn't - * // avoid the crash as NM_TYPE() cannot do anything then passing on the - * // invalid pointer. - * - * Example 3: - * static void foo (NMType *obj) - * { - * g_return_if_fail (NM_IS_TYPE (obj)); - * access_obj_without_check (obj); - * } - * foo ((NMType *) obj); - * // There is a runtime check which prints a g_critical() which also avoids - * // the crash. That is actually helpful to catch bugs and avoid crashes. - * - * Example 4: - * static void foo (NMType *obj) - * { - * g_return_if_fail (NM_IS_TYPE (obj)); - * access_obj_without_check (obj); - * } - * foo (NM_TYPE (obj)); - * // The runtime check is performed twice, with printing a g_warning() and - * // a g_critical() and avoiding the crash. - * - * Example 3 is how it should be done. Type checks in NM_TYPE() are pointless. - * Disable them for our production builds. - */ - #ifndef G_DISABLE_CAST_CHECKS - #define G_DISABLE_CAST_CHECKS - #endif -#endif - -/*****************************************************************************/ - -#include - -/*****************************************************************************/ - -#endif /* __NM_DEFAULT_STD_H__ */ diff --git a/shared/nm-std-aux/nm-networkmanager-compilation.h b/shared/nm-std-aux/nm-networkmanager-compilation.h deleted file mode 100644 index 025a158d..00000000 --- a/shared/nm-std-aux/nm-networkmanager-compilation.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2015 Red Hat, Inc. - */ - -#ifndef __NM_NETWORKMANAGER_COMPILATION_H__ -#define __NM_NETWORKMANAGER_COMPILATION_H__ - -#define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB (1 << 0) -#define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB (1 << 1) -#define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG (1 << 2) -#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM (1 << 3) -#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE (1 << 4) -#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE (1 << 5) -#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL (1 << 6) -#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE (1 << 7) -#define NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON (1 << 10) -#define NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD (1 << 11) - -#define NM_NETWORKMANAGER_COMPILATION_LIBNM_CORE \ - (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ - | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB \ - | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ - | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE \ - | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL) - -#define NM_NETWORKMANAGER_COMPILATION_LIBNM \ - (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ - | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM \ - | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE \ - | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ - | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL) - -#define NM_NETWORKMANAGER_COMPILATION_CLIENT \ - (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ - | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG \ - | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE) - -#define NM_NETWORKMANAGER_COMPILATION_DAEMON \ - (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ - | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG \ - | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ - | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL \ - | NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON) - -#define NM_NETWORKMANAGER_COMPILATION_SYSTEMD_SHARED \ - (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB | NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD) - -#define NM_NETWORKMANAGER_COMPILATION_SYSTEMD \ - (0 | NM_NETWORKMANAGER_COMPILATION_DAEMON | NM_NETWORKMANAGER_COMPILATION_SYSTEMD_SHARED) - -#define NM_NETWORKMANAGER_COMPILATION_GLIB (0 | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB) - -#endif /* __NM_NETWORKMANAGER_COMPILATION_H__ */ diff --git a/shared/nm-std-aux/nm-std-aux.h b/shared/nm-std-aux/nm-std-aux.h deleted file mode 100644 index a619cebd..00000000 --- a/shared/nm-std-aux/nm-std-aux.h +++ /dev/null @@ -1,985 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#ifndef __NM_STD_AUX_H__ -#define __NM_STD_AUX_H__ - -#include -#include -#include -#include -#include -#include -#include - -/*****************************************************************************/ - -#define _nm_packed __attribute__((__packed__)) -#define _nm_unused __attribute__((__unused__)) -#define _nm_used __attribute__((__used__)) -#define _nm_pure __attribute__((__pure__)) -#define _nm_const __attribute__((__const__)) -#define _nm_printf(a, b) __attribute__((__format__(__printf__, a, b))) -#define _nm_align(s) __attribute__((__aligned__(s))) -#define _nm_section(s) __attribute__((__section__(s))) -#define _nm_alignof(type) __alignof(type) -#define _nm_alignas(type) _nm_align(_nm_alignof(type)) -#define nm_auto(fcn) __attribute__((__cleanup__(fcn))) - -/* This is required to make LTO working. - * - * See https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/76#note_112694 - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48200#c28 - */ -#ifndef __clang__ - #define _nm_externally_visible __attribute__((__externally_visible__)) -#else - #define _nm_externally_visible -#endif - -#if __GNUC__ >= 7 - #define _nm_fallthrough __attribute__((__fallthrough__)) -#else - #define _nm_fallthrough -#endif - -/*****************************************************************************/ - -#ifdef __CHECKER__ - #define _nm_bitwise __attribute__((__bitwise__)) - #define _nm_force __attribute__((__force__)) -#else - #define _nm_bitwise - #define _nm_force -#endif - -typedef uint16_t _nm_bitwise nm_le16_t; -typedef uint16_t _nm_bitwise nm_be16_t; -typedef uint32_t _nm_bitwise nm_le32_t; -typedef uint32_t _nm_bitwise nm_be32_t; -typedef uint64_t _nm_bitwise nm_le64_t; -typedef uint64_t _nm_bitwise nm_be64_t; - -/*****************************************************************************/ - -#ifdef thread_local - #define _nm_thread_local thread_local -/* - * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ - * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 - */ -#elif __STDC_VERSION__ >= 201112L \ - && !(defined(__STDC_NO_THREADS__) \ - || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) - #define _nm_thread_local _Thread_local -#else - #define _nm_thread_local __thread -#endif - -/*****************************************************************************/ - -#define _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON struct _nm_dummy_struct_for_trailing_semicolon - -/*****************************************************************************/ - -#define NM_PASTE_ARGS(identifier1, identifier2) identifier1##identifier2 -#define NM_PASTE(identifier1, identifier2) NM_PASTE_ARGS(identifier1, identifier2) - -/* Taken from systemd's UNIQ_T and UNIQ macros. */ - -#define NM_UNIQ_T(x, uniq) NM_PASTE(__unique_prefix_, NM_PASTE(x, uniq)) -#define NM_UNIQ __COUNTER__ - -/*****************************************************************************/ - -#define _NM_BOOLEAN_EXPR_IMPL(v, expr) \ - ({ \ - int NM_UNIQ_T(V, v); \ - \ - if (expr) \ - NM_UNIQ_T(V, v) = 1; \ - else \ - NM_UNIQ_T(V, v) = 0; \ - NM_UNIQ_T(V, v); \ - }) -#define NM_BOOLEAN_EXPR(expr) _NM_BOOLEAN_EXPR_IMPL(NM_UNIQ, expr) - -#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) - #define NM_LIKELY(expr) (__builtin_expect(NM_BOOLEAN_EXPR(expr), 1)) - #define NM_UNLIKELY(expr) (__builtin_expect(NM_BOOLEAN_EXPR(expr), 0)) -#else - #define NM_LIKELY(expr) NM_BOOLEAN_EXPR(expr) - #define NM_UNLIKELY(expr) NM_BOOLEAN_EXPR(expr) -#endif - -/*****************************************************************************/ - -/* glib/C provides the following kind of assertions: - * - assert() -- disable with NDEBUG - * - g_return_if_fail() -- disable with G_DISABLE_CHECKS - * - g_assert() -- disable with G_DISABLE_ASSERT - * but they are all enabled by default and usually even production builds have - * these kind of assertions enabled. It also means, that disabling assertions - * is an untested configuration, and might have bugs. - * - * Add our own assertion macro nm_assert(), which is disabled by default and must - * be explicitly enabled. They are useful for more expensive checks or checks that - * depend less on runtime conditions (that is, are generally expected to be true). */ - -#ifndef NM_MORE_ASSERTS - #define NM_MORE_ASSERTS 0 -#endif - -#ifndef _nm_assert_call - #define _nm_assert_call(cond) assert(cond) - #define _nm_assert_call_not_reached() assert(0) -#endif - -#if NM_MORE_ASSERTS - #define nm_assert(cond) \ - do { \ - _nm_assert_call(cond); \ - } while (0) - #define nm_assert_se(cond) \ - do { \ - if (NM_LIKELY(cond)) { \ - ; \ - } else { \ - _nm_assert_call(0 && (cond)); \ - } \ - } while (0) - #define nm_assert_not_reached() \ - do { \ - _nm_assert_call_not_reached(); \ - } while (0) -#else - #define nm_assert(cond) \ - do { \ - if (0) { \ - if (cond) {} \ - } \ - } while (0) - #define nm_assert_se(cond) \ - do { \ - if (NM_LIKELY(cond)) { \ - ; \ - } \ - } while (0) - #define nm_assert_not_reached() \ - do { \ - ; \ - } while (0) -#endif - -#define nm_assert_unreachable_val(val) \ - ({ \ - nm_assert_not_reached(); \ - (val); \ - }) - -#define NM_STATIC_ASSERT(cond) static_assert(cond, "") -#define NM_STATIC_ASSERT_EXPR(cond) \ - ({ \ - NM_STATIC_ASSERT(cond); \ - 1; \ - }) - -/*****************************************************************************/ - -#define NM_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) - -/*****************************************************************************/ - -static inline uint32_t -nm_add_clamped_u32(uint32_t a, uint32_t b) -{ - uint32_t c; - - /* returns a+b, or UINT32_MAX if the result would overflow. */ - - c = a + b; - if (c < a) - return UINT32_MAX; - return c; -} - -static inline unsigned -nm_mult_clamped_u(unsigned a, unsigned b) -{ - unsigned c; - - /* returns a*b, or UINT_MAX if the result would overflow. */ - - if (b == 0) - return 0; - - c = a * b; - - if (c / b != a) - return (unsigned) -1; - - 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)); \ - }) - -#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_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_MAX_WITH_CMP(cmp, a, b) \ - ({ \ - typeof(a) _a = (a); \ - typeof(b) _b = (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. */ -#define nm_utils_is_power_of_two(x) \ - ({ \ - typeof(x) _x2 = (x); \ - const typeof(_x2) _X_0 = ((typeof(_x2)) 0); \ - const typeof(_x2) _X_1 = ((typeof(_x2)) 1); \ - \ - ((_x2 > _X_0) && ((_x2 & (_x2 - _X_1)) == _X_0)); \ - }) - -#define nm_utils_is_power_of_two_or_zero(x) \ - ({ \ - typeof(x) _x1 = (x); \ - \ - ((_x1 == 0) || nm_utils_is_power_of_two(_x1)); \ - }) - -/*****************************************************************************/ - -#define NM_SWAP(p_a, p_b) \ - do { \ - typeof(*(p_a)) *const _p_a = (p_a); \ - typeof(*(p_a)) *const _p_b = (p_b); \ - typeof(*(p_a)) _tmp; \ - \ - _tmp = *_p_a; \ - *_p_a = *_p_b; \ - *_p_b = _tmp; \ - } while (0) - -/*****************************************************************************/ - -/* macro to return strlen() of a compile time string. */ -#define NM_STRLEN(str) (sizeof("" str "") - 1u) - -/* returns the length of a NULL terminated array of pointers, - * 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); \ - size_t _n = 0; \ - \ - if (_array) { \ - _nm_unused const void *_type_check_is_pointer = _array[0]; \ - \ - while (_array[_n]) \ - _n++; \ - } \ - _n; \ - }) - -/*****************************************************************************/ - -static inline int -nm_strcmp0(const char *s1, const char *s2) -{ - int c; - - /* like g_strcmp0(), but this is inlinable. - * - * Also, it is guaranteed to return either -1, 0, or 1. */ - if (s1 == s2) - return 0; - if (!s1) - return -1; - if (!s2) - return 1; - c = strcmp(s1, s2); - if (c < 0) - return -1; - if (c > 0) - return 1; - return 0; -} - -static inline int -nm_streq(const char *s1, const char *s2) -{ - return strcmp(s1, s2) == 0; -} - -static inline int -nm_streq0(const char *s1, const char *s2) -{ - return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0); -} - -#define NM_STR_HAS_PREFIX(str, prefix) \ - ({ \ - const char *const _str_has_prefix = (str); \ - \ - nm_assert(strlen(prefix) == NM_STRLEN(prefix)); \ - \ - _str_has_prefix && (strncmp(_str_has_prefix, "" prefix "", NM_STRLEN(prefix)) == 0); \ - }) - -#define NM_STR_HAS_SUFFIX(str, suffix) \ - ({ \ - const char *const _str_has_suffix = (str); \ - size_t _l; \ - \ - nm_assert(strlen(suffix) == NM_STRLEN(suffix)); \ - \ - (_str_has_suffix && ((_l = strlen(_str_has_suffix)) >= NM_STRLEN(suffix)) \ - && (memcmp(&_str_has_suffix[_l - NM_STRLEN(suffix)], "" suffix "", NM_STRLEN(suffix)) \ - == 0)); \ - }) - -/* whether @str starts with the string literal @prefix and is followed by - * some other text. It is like NM_STR_HAS_PREFIX() && !nm_streq() together. */ -#define NM_STR_HAS_PREFIX_WITH_MORE(str, prefix) \ - ({ \ - const char *const _str_has_prefix_with_more = (str); \ - \ - NM_STR_HAS_PREFIX(_str_has_prefix_with_more, "" prefix "") \ - &&_str_has_prefix_with_more[NM_STRLEN(prefix)] != '\0'; \ - }) - -#define NM_STR_HAS_SUFFIX_WITH_MORE(str, suffix) \ - ({ \ - const char *const _str_has_suffix = (str); \ - size_t _l; \ - \ - nm_assert(strlen(suffix) == NM_STRLEN(suffix)); \ - \ - (_str_has_suffix && ((_l = strlen(_str_has_suffix)) > NM_STRLEN(suffix)) \ - && (memcmp(&_str_has_suffix[_l - NM_STRLEN(suffix)], "" suffix "", NM_STRLEN(suffix)) \ - == 0)); \ - }) - -/*****************************************************************************/ - -#define _NM_IN_SET_EVAL_1(op, _x, y) (_x == (y)) -#define _NM_IN_SET_EVAL_2(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_1(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_3(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_2(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_4(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_3(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_5(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_4(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_6(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_5(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_7(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_6(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_8(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_7(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_9(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_8(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_10(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_9(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_11(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_10(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_12(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_11(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_13(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_12(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_14(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_13(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_15(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_14(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_16(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_15(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_17(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_16(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_18(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_17(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_19(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_18(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_20(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_19(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_21(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_20(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_22(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_21(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_23(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_22(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_24(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_23(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_25(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_24(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_26(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_25(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_27(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_26(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_28(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_27(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_29(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_28(op, _x, __VA_ARGS__) -#define _NM_IN_SET_EVAL_30(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_29(op, _x, __VA_ARGS__) - -#define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__)) -#define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \ - ({ \ - type _x = (x); \ - \ - /* trigger a -Wenum-compare warning */ \ - nm_assert(true || _x == (x)); \ - \ - !!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__); \ - }) - -#define _NM_IN_SET(op, type, x, ...) \ - _NM_IN_SET_EVAL_N(op, type, x, NM_NARG(__VA_ARGS__), __VA_ARGS__) - -/* Beware that this does short-circuit evaluation (use "||" instead of "|") - * which has a possibly unexpected non-function-like behavior. - * Use NM_IN_SET_SE if you need all arguments to be evaluated. */ -#define NM_IN_SET(x, ...) _NM_IN_SET(||, typeof(x), x, __VA_ARGS__) - -/* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do - * short-circuit evaluation, which can make a difference if the arguments have - * side-effects. */ -#define NM_IN_SET_SE(x, ...) _NM_IN_SET(|, typeof(x), x, __VA_ARGS__) - -/* the *_TYPED forms allow to explicitly select the type of "x". This is useful - * if "x" doesn't support typeof (bitfields) or you want to gracefully convert - * a type using automatic type conversion rules (but not forcing the conversion - * with a cast). */ -#define NM_IN_SET_TYPED(type, x, ...) _NM_IN_SET(||, type, x, __VA_ARGS__) -#define NM_IN_SET_SE_TYPED(type, x, ...) _NM_IN_SET(|, type, x, __VA_ARGS__) - -/*****************************************************************************/ - -#define _NM_IN_SETOP_EVAL_1(op, op_eq, _x, y) (op_eq(_x, y)) -#define _NM_IN_SETOP_EVAL_2(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_1(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_3(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_2(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_4(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_3(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_5(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_4(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_6(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_5(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_7(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_6(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_8(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_7(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_9(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_8(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_10(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_9(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_11(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_10(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_12(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_11(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_13(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_12(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_14(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_13(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_15(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_14(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_16(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_15(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_17(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_16(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_18(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_17(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_19(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_18(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_20(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_19(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_21(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_20(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_22(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_21(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_23(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_22(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_24(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_23(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_25(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_24(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_26(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_25(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_27(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_26(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_28(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_27(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_29(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_28(op, op_eq, _x, __VA_ARGS__) -#define _NM_IN_SETOP_EVAL_30(op, op_eq, _x, y, ...) \ - (op_eq(_x, y)) op _NM_IN_SETOP_EVAL_29(op, op_eq, _x, __VA_ARGS__) - -/*****************************************************************************/ - -#define _NM_IN_STRSET_EVAL_N2(op, op_ed, _x, n, ...) \ - (_NM_IN_SETOP_EVAL_##n(op, op_ed, _x, __VA_ARGS__)) -#define _NM_IN_STRSET_EVAL_N(op, op_ed, x, n, ...) \ - ({ \ - const char *_x = (x); \ - (((_x == NULL) && _NM_IN_SET_EVAL_N2(op, ((const char *) NULL), n, __VA_ARGS__)) \ - || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2(op, op_ed, _x, n, __VA_ARGS__))); \ - }) - -/*****************************************************************************/ - -static inline int -_NM_IN_STRSET_op_streq(const char *x, const char *s) -{ - return s && strcmp(x, s) == 0; -} - -/* Beware that this does short-circuit evaluation (use "||" instead of "|") - * which has a possibly unexpected non-function-like behavior. - * Use NM_IN_STRSET_SE if you need all arguments to be evaluated. */ -#define NM_IN_STRSET(x, ...) \ - _NM_IN_STRSET_EVAL_N(||, _NM_IN_STRSET_op_streq, x, NM_NARG(__VA_ARGS__), __VA_ARGS__) - -/* "SE" stands for "side-effect". Contrary to NM_IN_STRSET(), this does not do - * short-circuit evaluation, which can make a difference if the arguments have - * side-effects. */ -#define NM_IN_STRSET_SE(x, ...) \ - _NM_IN_STRSET_EVAL_N(|, _NM_IN_STRSET_op_streq, x, NM_NARG(__VA_ARGS__), __VA_ARGS__) - -/*****************************************************************************/ - -#define NM_STRCHAR_ALL(str, ch_iter, predicate) \ - ({ \ - int _val = true; \ - const char *_str = (str); \ - \ - if (_str) { \ - for (;;) { \ - const char ch_iter = _str[0]; \ - \ - if (ch_iter != '\0') { \ - if (predicate) { \ - _str++; \ - continue; \ - } \ - _val = false; \ - } \ - break; \ - } \ - } \ - _val; \ - }) - -#define NM_STRCHAR_ANY(str, ch_iter, predicate) \ - ({ \ - int _val = false; \ - const char *_str = (str); \ - \ - if (_str) { \ - for (;;) { \ - const char ch_iter = _str[0]; \ - \ - if (ch_iter != '\0') { \ - if (predicate) { \ - ; \ - } else { \ - _str++; \ - continue; \ - } \ - _val = true; \ - } \ - break; \ - } \ - } \ - _val; \ - }) - -/*****************************************************************************/ - -/** - * nm_close: - * - * Like close() but throws an assertion if the input fd is - * invalid. Closing an invalid fd is a programming error, so - * it's better to catch it early. - */ -static inline int -nm_close(int fd) -{ - int r; - - r = close(fd); - nm_assert(r != -1 || fd < 0 || errno != EBADF); - return r; -} - -/*****************************************************************************/ - -/* Note: @value is only evaluated when *out_val is present. - * Thus, - * NM_SET_OUT (out_str, g_strdup ("hallo")); - * does the right thing. - */ -#define NM_SET_OUT(out_val, value) \ - ({ \ - typeof(*(out_val)) *_out_val = (out_val); \ - \ - if (_out_val) { \ - *_out_val = (value); \ - } \ - \ - (!!_out_val); \ - }) - -/*****************************************************************************/ - -#define NM_AUTO_DEFINE_FCN_VOID(CastType, name, func) \ - static inline void name(void *v) \ - { \ - func(*((CastType *) v)); \ - } \ - _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON - -#define NM_AUTO_DEFINE_FCN_VOID0(CastType, name, func) \ - static inline void name(void *v) \ - { \ - if (*((CastType *) v)) \ - func(*((CastType *) v)); \ - } \ - _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON - -#define NM_AUTO_DEFINE_FCN(Type, name, func) \ - static inline void name(Type *v) \ - { \ - func(*v); \ - } \ - _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON - -#define NM_AUTO_DEFINE_FCN0(Type, name, func) \ - static inline void name(Type *v) \ - { \ - if (*v) \ - func(*v); \ - } \ - _NM_DUMMY_STRUCT_FOR_TRAILING_SEMICOLON - -/*****************************************************************************/ - -/** - * nm_auto_free: - * - * Call free() on a variable location when it goes out of scope. - * This is for pointers that are allocated with malloc() instead of - * g_malloc(). - * - * In practice, since glib 2.45, g_malloc()/g_free() always wraps malloc()/free(). - * See bgo#751592. In that case, it would be safe to free pointers allocated with - * malloc() with gs_free or g_free(). - * - * However, let's never mix them. To free malloc'ed memory, always use - * free() or nm_auto_free. - */ -NM_AUTO_DEFINE_FCN_VOID0(void *, _nm_auto_free_impl, free); -#define nm_auto_free nm_auto(_nm_auto_free_impl) - -static inline void -_nm_auto_protect_errno(const int *p_saved_errno) -{ - errno = *p_saved_errno; -} -#define NM_AUTO_PROTECT_ERRNO(errsv_saved) \ - nm_auto(_nm_auto_protect_errno) _nm_unused const int errsv_saved = (errno) - -/*****************************************************************************/ - -static inline void -_nm_auto_close(int *pfd) -{ - if (*pfd >= 0) { - int errsv = errno; - - (void) nm_close(*pfd); - errno = errsv; - } -} -#define nm_auto_close nm_auto(_nm_auto_close) - -static inline void -_nm_auto_fclose(FILE **pfd) -{ - if (*pfd) { - int errsv = errno; - - (void) fclose(*pfd); - errno = errsv; - } -} -#define nm_auto_fclose nm_auto(_nm_auto_fclose) - -/*****************************************************************************/ - -#define nm_clear_pointer(pp, destroy) \ - ({ \ - typeof(*(pp)) *_pp = (pp); \ - typeof(*_pp) _p; \ - int _changed = false; \ - \ - if (_pp && (_p = *_pp)) { \ - _nm_unused const void *_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; \ - }) - -#define nm_clear_free(pp) nm_clear_pointer(pp, free) - -/*****************************************************************************/ - -static inline void * -_nm_steal_pointer(void *pp) -{ - void **ptr = (void **) pp; - void * ref; - - ref = *ptr; - *ptr = NULL; - return ref; -} - -#define nm_steal_pointer(pp) ((typeof(*(pp))) _nm_steal_pointer(pp)) - -/** - * 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) -{ - int fd; - - if (p_fd && ((fd = *p_fd) >= 0)) { - *p_fd = -1; - return fd; - } - return -1; -} - -/*****************************************************************************/ - -static inline uintptr_t -nm_ptr_to_uintptr(const void *p) -{ - /* in C, pointers can only be compared (with less-than or greater-than) under certain - * circumstances. Since uintptr_t is supposed to be able to represent the pointer - * as a plain integer and also support to convert the integer back to the pointer, - * it should be safer to compare the pointers directly. - * - * Of course, this function isn't very useful beyond that its use makes it clear - * that we want to compare pointers by value, which otherwise may not be valid. */ - return (uintptr_t) p; -} - -/*****************************************************************************/ - -#define NM_CMP_RETURN(c) \ - do { \ - const int _cc = (c); \ - if (_cc) \ - return _cc < 0 ? -1 : 1; \ - } while (0) - -#define NM_CMP_RETURN_DIRECT(c) \ - do { \ - const int _cc = (c); \ - if (_cc) \ - return _cc; \ - } while (0) - -#define NM_CMP_SELF(a, b) \ - do { \ - typeof(a) _a = (a); \ - typeof(b) _b = (b); \ - \ - if (_a == _b) \ - return 0; \ - if (!_a) \ - return -1; \ - if (!_b) \ - return 1; \ - } while (0) - -#define NM_CMP_DIRECT(a, b) \ - do { \ - typeof(a) _a = (a); \ - typeof(b) _b = (b); \ - \ - if (_a != _b) \ - return (_a < _b) ? -1 : 1; \ - } while (0) - -#define NM_CMP_DIRECT_UNSAFE(a, b) \ - do { \ - if ((a) != (b)) \ - return ((a) < (b)) ? -1 : 1; \ - } while (0) - -/* In the general case, direct pointer comparison is undefined behavior in C. - * Avoid that by casting pointers to void* and then to uintptr_t. This comparison - * is not really meaningful, except that it provides some kind of stable sort order - * between pointers (that can otherwise not be compared). */ -#define NM_CMP_DIRECT_PTR(a, b) NM_CMP_DIRECT(nm_ptr_to_uintptr(a), nm_ptr_to_uintptr(b)) - -#define NM_CMP_DIRECT_MEMCMP(a, b, size) NM_CMP_RETURN(memcmp((a), (b), (size))) - -#define NM_CMP_DIRECT_STRCMP(a, b) NM_CMP_RETURN_DIRECT(strcmp((a), (b))) - -#define NM_CMP_DIRECT_STRCMP0(a, b) NM_CMP_RETURN_DIRECT(nm_strcmp0((a), (b))) - -#define NM_CMP_DIRECT_IN6ADDR(a, b) \ - do { \ - const struct in6_addr *const _a = (a); \ - const struct in6_addr *const _b = (b); \ - NM_CMP_RETURN(memcmp(_a, _b, sizeof(struct in6_addr))); \ - } while (0) - -#define NM_CMP_FIELD(a, b, field) NM_CMP_DIRECT(((a)->field), ((b)->field)) - -#define NM_CMP_FIELD_UNSAFE(a, b, field) \ - do { \ - /* it's unsafe, because it evaluates the arguments more then once. - * This is necessary for bitfields, for which typeof() doesn't work. */ \ - if (((a)->field) != ((b)->field)) \ - return ((a)->field < ((b)->field)) ? -1 : 1; \ - } while (0) - -#define NM_CMP_FIELD_BOOL(a, b, field) NM_CMP_DIRECT(!!((a)->field), !!((b)->field)) - -#define NM_CMP_FIELD_STR(a, b, field) NM_CMP_RETURN(strcmp(((a)->field), ((b)->field))) - -#define NM_CMP_FIELD_STR_INTERNED(a, b, field) \ - do { \ - const char *_a = ((a)->field); \ - const char *_b = ((b)->field); \ - \ - if (_a != _b) { \ - NM_CMP_RETURN_DIRECT(nm_strcmp0(_a, _b)); \ - } \ - } while (0) - -#define NM_CMP_FIELD_STR0(a, b, field) NM_CMP_RETURN_DIRECT(nm_strcmp0(((a)->field), ((b)->field))) - -#define NM_CMP_FIELD_MEMCMP_LEN(a, b, field, len) \ - NM_CMP_RETURN(memcmp(&((a)->field), &((b)->field), NM_MIN(len, sizeof((a)->field)))) - -#define NM_CMP_FIELD_MEMCMP(a, b, field) \ - NM_CMP_RETURN(memcmp(&((a)->field), &((b)->field), sizeof((a)->field))) - -#define NM_CMP_FIELD_IN6ADDR(a, b, field) \ - do { \ - const struct in6_addr *const _a = &((a)->field); \ - const struct in6_addr *const _b = &((b)->field); \ - NM_CMP_RETURN(memcmp(_a, _b, sizeof(struct in6_addr))); \ - } while (0) - -/*****************************************************************************/ - -#define NM_AF_UNSPEC 0 /* AF_UNSPEC */ -#define NM_AF_INET 2 /* AF_INET */ -#define NM_AF_INET6 10 /* AF_INET6 */ - -#define NM_AF_INET_SIZE 4 /* sizeof (in_addr_t) */ -#define NM_AF_INET6_SIZE 16 /* sizeof (stuct in6_addr) */ - -static inline char -nm_utils_addr_family_to_char(int addr_family) -{ - switch (addr_family) { - case NM_AF_UNSPEC: - return 'X'; - case NM_AF_INET: - return '4'; - case NM_AF_INET6: - return '6'; - } - nm_assert_not_reached(); - return '?'; -} - -static inline size_t -nm_utils_addr_family_to_size(int addr_family) -{ - switch (addr_family) { - case NM_AF_INET: - return NM_AF_INET_SIZE; - case NM_AF_INET6: - return NM_AF_INET6_SIZE; - } - nm_assert_not_reached(); - return 0; -} - -static inline int -nm_utils_addr_family_from_size(size_t len) -{ - switch (len) { - case NM_AF_INET_SIZE: - return NM_AF_INET; - case NM_AF_INET6_SIZE: - return NM_AF_INET6; - } - return NM_AF_UNSPEC; -} - -#define nm_assert_addr_family(addr_family) \ - nm_assert(NM_IN_SET((addr_family), NM_AF_INET, NM_AF_INET6)) - -#define NM_IS_IPv4(addr_family) \ - ({ \ - const int _addr_family = (addr_family); \ - \ - nm_assert_addr_family(_addr_family); \ - \ - (_addr_family == NM_AF_INET); \ - }) - -#endif /* __NM_STD_AUX_H__ */ diff --git a/shared/nm-std-aux/nm-std-utils.c b/shared/nm-std-aux/nm-std-utils.c deleted file mode 100644 index 18692b19..00000000 --- a/shared/nm-std-aux/nm-std-utils.c +++ /dev/null @@ -1,90 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include "nm-default-std.h" - -#include "nm-std-utils.h" - -#include -#include -#include - -/*****************************************************************************/ - -size_t -nm_utils_get_next_realloc_size(bool true_realloc, size_t requested) -{ - size_t n, x; - - /* https://doc.qt.io/qt-5/containers.html#growth-strategies */ - - if (requested <= 40) { - /* small allocations. Increase in small steps of 8 bytes. - * - * We get thus sizes of 8, 16, 32, 40. */ - if (requested <= 8) - return 8; - if (requested <= 16) - return 16; - if (requested <= 32) - return 32; - - /* The return values for < 104 are essentially hard-coded, and the choice here is - * made without very strong reasons. - * - * We want to stay 24 bytes below the power-of-two border 64. Hence, return 40 here. - * However, the next step then is already 104 (128 - 24). It's a larger gap than in - * the steps before. - * - * It's not clear whether some of the steps should be adjusted (or how exactly). */ - return 40; - } - - if (requested <= 0x2000u - 24u || NM_UNLIKELY(!true_realloc)) { - /* mid sized allocations. Return next power of two, minus 24 bytes extra space - * at the beginning. - * That means, we double the size as we grow. - * - * With !true_realloc, it means that the caller does not intend to call - * realloc() but instead clone the buffer. This is for example the case, when we - * want to nm_explicit_bzero() the old buffer. In that case we really want to grow - * the buffer exponentially every time and not increment in page sizes of 4K (below). - * - * We get thus sizes of 104, 232, 488, 1000, 2024, 4072, 8168... */ - - if (NM_UNLIKELY(requested > SIZE_MAX / 2u - 24u)) - goto out_huge; - - x = requested + 24u; - n = 128u; - while (n < x) { - n <<= 1; - nm_assert(n > 128u); - } - - nm_assert(n > 24u && n - 24u >= requested); - return n - 24u; - } - - if (NM_UNLIKELY(requested > SIZE_MAX - 0x1000u - 24u)) { - /* overflow happened. */ - goto out_huge; - } - - /* For large allocations (with !true_realloc) we allocate memory in chunks of - * 4K (- 24 bytes extra), assuming that the memory gets mmapped and thus - * realloc() is efficient by just reordering pages. */ - n = ((requested + (0x0FFFu + 24u)) & ~((size_t) 0x0FFFu)) - 24u; - nm_assert(n >= requested); - return n; - -out_huge: - if (sizeof(size_t) > 4u) { - /* on s390x (64 bit), gcc with LTO can complain that the size argument to - * malloc must not be larger than 9223372036854775807. - * - * Work around that by returning SSIZE_MAX. It should be plenty still! */ - assert(requested <= (size_t) SSIZE_MAX); - return (size_t) SSIZE_MAX; - } - return SIZE_MAX; -} diff --git a/shared/nm-std-aux/nm-std-utils.h b/shared/nm-std-aux/nm-std-utils.h deleted file mode 100644 index 9c851f1f..00000000 --- a/shared/nm-std-aux/nm-std-utils.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#ifndef __NM_STD_UTILS_H__ -#define __NM_STD_UTILS_H__ - -#include - -#include "nm-std-aux.h" - -/*****************************************************************************/ - -/* nm_utils_get_next_realloc_size() is used to grow buffers exponentially, when - * the final size is unknown. As such, it has borders for which it allocates - * certain buffer sizes. - * - * The use of these defines is to get favorable allocation sequences. - * For example, nm_str_buf_init() asks for an initial allocation size. Note that - * it reserves the exactly requested amount, under the assumption that the - * user may know how many bytes will be required. However, often the caller - * doesn't know in advance, and NMStrBuf grows exponentially by calling - * nm_utils_get_next_realloc_size(). - * Imagine you call nm_str_buf_init() with an initial buffer size 100, and you - * add one character at a time. Then the first reallocation will increase the - * buffer size only from 100 to 104. - * If you however start with an initial buffer size of 104, then the next reallocation - * via nm_utils_get_next_realloc_size() gives you 232, and so on. By using - * these sizes, it results in one less allocation, if you anyway don't know the - * exact size in advance. */ -#define NM_UTILS_GET_NEXT_REALLOC_SIZE_32 ((size_t) 32) -#define NM_UTILS_GET_NEXT_REALLOC_SIZE_40 ((size_t) 40) -#define NM_UTILS_GET_NEXT_REALLOC_SIZE_104 ((size_t) 104) -#define NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 ((size_t) 1000) - -size_t nm_utils_get_next_realloc_size(bool true_realloc, size_t requested); - -#endif /* __NM_STD_UTILS_H__ */ diff --git a/shared/nm-std-aux/unaligned.h b/shared/nm-std-aux/unaligned.h deleted file mode 100644 index 4100be08..00000000 --- a/shared/nm-std-aux/unaligned.h +++ /dev/null @@ -1,99 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#include -#include - -/* BE */ - -static inline uint16_t unaligned_read_be16(const void *_u) { - const struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u; - - return be16toh(u->x); -} - -static inline uint32_t unaligned_read_be32(const void *_u) { - const struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u; - - return be32toh(u->x); -} - -static inline uint64_t unaligned_read_be64(const void *_u) { - const struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u; - - return be64toh(u->x); -} - -static inline void unaligned_write_be16(void *_u, uint16_t a) { - struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u; - - u->x = be16toh(a); -} - -static inline void unaligned_write_be32(void *_u, uint32_t a) { - struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u; - - u->x = be32toh(a); -} - -static inline void unaligned_write_be64(void *_u, uint64_t a) { - struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u; - - u->x = be64toh(a); -} - -/* LE */ - -static inline uint16_t unaligned_read_le16(const void *_u) { - const struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u; - - return le16toh(u->x); -} - -static inline uint32_t unaligned_read_le32(const void *_u) { - const struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u; - - return le32toh(u->x); -} - -static inline uint64_t unaligned_read_le64(const void *_u) { - const struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u; - - return le64toh(u->x); -} - -static inline void unaligned_write_le16(void *_u, uint16_t a) { - struct __attribute__((__packed__, __may_alias__)) { uint16_t x; } *u = _u; - - u->x = le16toh(a); -} - -static inline void unaligned_write_le32(void *_u, uint32_t a) { - struct __attribute__((__packed__, __may_alias__)) { uint32_t x; } *u = _u; - - u->x = le32toh(a); -} - -static inline void unaligned_write_le64(void *_u, uint64_t a) { - struct __attribute__((__packed__, __may_alias__)) { uint64_t x; } *u = _u; - - u->x = le64toh(a); -} - -#if __BYTE_ORDER == __BIG_ENDIAN -#define unaligned_read_ne16 unaligned_read_be16 -#define unaligned_read_ne32 unaligned_read_be32 -#define unaligned_read_ne64 unaligned_read_be64 - -#define unaligned_write_ne16 unaligned_write_be16 -#define unaligned_write_ne32 unaligned_write_be32 -#define unaligned_write_ne64 unaligned_write_be64 -#else -#define unaligned_read_ne16 unaligned_read_le16 -#define unaligned_read_ne32 unaligned_read_le32 -#define unaligned_read_ne64 unaligned_read_le64 - -#define unaligned_write_ne16 unaligned_write_le16 -#define unaligned_write_ne32 unaligned_write_le32 -#define unaligned_write_ne64 unaligned_write_le64 -#endif -- cgit 1.3.0-6-gf8a5