| /* |
| * Copyright (c) 2011-2014, Wind River Systems, Inc. |
| * Copyright (c) 2020, Nordic Semiconductor ASA |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /** |
| * @file |
| * @brief Misc utilities |
| * |
| * Repetitive or obscure helper macros needed by sys/util.h. |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ |
| #define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ |
| |
| #include "util_loops.h" |
| |
| /* IS_ENABLED() helpers */ |
| |
| /* This is called from IS_ENABLED(), and sticks on a "_XXXX" prefix, |
| * it will now be "_XXXX1" if config_macro is "1", or just "_XXXX" if it's |
| * undefined. |
| * ENABLED: Z_IS_ENABLED2(_XXXX1) |
| * DISABLED Z_IS_ENABLED2(_XXXX) |
| */ |
| #define Z_IS_ENABLED1(config_macro) Z_IS_ENABLED2(_XXXX##config_macro) |
| |
| /* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string |
| * with a trailing comma), so it has the effect of making this a |
| * two-argument tuple to the preprocessor only in the case where the |
| * value is defined to "1" |
| * ENABLED: _YYYY, <--- note comma! |
| * DISABLED: _XXXX |
| */ |
| #define _XXXX1 _YYYY, |
| |
| /* Then we append an extra argument to fool the gcc preprocessor into |
| * accepting it as a varargs macro. |
| * arg1 arg2 arg3 |
| * ENABLED: Z_IS_ENABLED3(_YYYY, 1, 0) |
| * DISABLED Z_IS_ENABLED3(_XXXX 1, 0) |
| */ |
| #define Z_IS_ENABLED2(one_or_two_args) Z_IS_ENABLED3(one_or_two_args 1, 0) |
| |
| /* And our second argument is thus now cooked to be 1 in the case |
| * where the value is defined to 1, and 0 if not: |
| */ |
| #define Z_IS_ENABLED3(ignore_this, val, ...) val |
| |
| /* Used internally by COND_CODE_1 and COND_CODE_0. */ |
| #define Z_COND_CODE_1(_flag, _if_1_code, _else_code) \ |
| __COND_CODE(_XXXX##_flag, _if_1_code, _else_code) |
| #define Z_COND_CODE_0(_flag, _if_0_code, _else_code) \ |
| __COND_CODE(_ZZZZ##_flag, _if_0_code, _else_code) |
| #define _ZZZZ0 _YYYY, |
| #define __COND_CODE(one_or_two_args, _if_code, _else_code) \ |
| __GET_ARG2_DEBRACKET(one_or_two_args _if_code, _else_code) |
| |
| /* Gets second argument and removes brackets around that argument. It |
| * is expected that the parameter is provided in brackets/parentheses. |
| */ |
| #define __GET_ARG2_DEBRACKET(ignore_this, val, ...) __DEBRACKET val |
| |
| /* Used to remove brackets from around a single argument. */ |
| #define __DEBRACKET(...) __VA_ARGS__ |
| |
| /* Used by IS_EMPTY() */ |
| #define Z_IS_EMPTY_(...) Z_IS_EMPTY__(__VA_ARGS__) |
| #define Z_IS_EMPTY__(a, ...) Z_IS_EMPTY___(_ZZ##a##ZZ0, __VA_ARGS__) |
| #define Z_IS_EMPTY___(...) GET_ARG_N(3, __VA_ARGS__) |
| |
| /* Used by LIST_DROP_EMPTY() */ |
| /* Adding ',' after each element would add empty element at the end of |
| * list, which is hard to remove, so instead precede each element with ',', |
| * this way first element is empty, and this one is easy to drop. |
| */ |
| #define Z_LIST_ADD_ELEM(e) EMPTY, e |
| #define Z_LIST_DROP_FIRST(...) GET_ARGS_LESS_N(1, __VA_ARGS__) |
| #define Z_LIST_NO_EMPTIES(e) \ |
| COND_CODE_1(IS_EMPTY(e), (), (Z_LIST_ADD_ELEM(e))) |
| |
| #define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__) |
| #define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__ |
| #define UTIL_CHECK_N(x, n, ...) n |
| #define UTIL_CHECK(...) UTIL_CHECK_N(__VA_ARGS__, 0,) |
| #define UTIL_NOT(x) UTIL_CHECK(UTIL_PRIMITIVE_CAT(UTIL_NOT_, x)) |
| #define UTIL_NOT_0 ~, 1, |
| #define UTIL_COMPL(b) UTIL_PRIMITIVE_CAT(UTIL_COMPL_, b) |
| #define UTIL_COMPL_0 1 |
| #define UTIL_COMPL_1 0 |
| #define UTIL_BOOL(x) UTIL_COMPL(UTIL_NOT(x)) |
| |
| #define UTIL_EVAL(...) __VA_ARGS__ |
| #define UTIL_EXPAND(...) __VA_ARGS__ |
| #define UTIL_REPEAT(...) UTIL_LISTIFY(__VA_ARGS__) |
| |
| /* Implementation details for NUM_VA_ARGS_LESS_1 */ |
| #define NUM_VA_ARGS_LESS_1_IMPL( \ |
| _ignored, \ |
| _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ |
| _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ |
| _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ |
| _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ |
| _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ |
| _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ |
| _61, _62, N, ...) N |
| |
| /* Used by MACRO_MAP_CAT */ |
| #define MACRO_MAP_CAT_(...) \ |
| /* To make sure it works also for 2 arguments in total */ \ |
| MACRO_MAP_CAT_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) |
| #define MACRO_MAP_CAT_N_(N, ...) UTIL_CAT(MACRO_MC_, N)(__VA_ARGS__,) |
| #define MACRO_MC_0(...) |
| #define MACRO_MC_1(m, a, ...) m(a) |
| #define MACRO_MC_2(m, a, ...) UTIL_CAT(m(a), MACRO_MC_1(m, __VA_ARGS__,)) |
| #define MACRO_MC_3(m, a, ...) UTIL_CAT(m(a), MACRO_MC_2(m, __VA_ARGS__,)) |
| #define MACRO_MC_4(m, a, ...) UTIL_CAT(m(a), MACRO_MC_3(m, __VA_ARGS__,)) |
| #define MACRO_MC_5(m, a, ...) UTIL_CAT(m(a), MACRO_MC_4(m, __VA_ARGS__,)) |
| #define MACRO_MC_6(m, a, ...) UTIL_CAT(m(a), MACRO_MC_5(m, __VA_ARGS__,)) |
| #define MACRO_MC_7(m, a, ...) UTIL_CAT(m(a), MACRO_MC_6(m, __VA_ARGS__,)) |
| #define MACRO_MC_8(m, a, ...) UTIL_CAT(m(a), MACRO_MC_7(m, __VA_ARGS__,)) |
| #define MACRO_MC_9(m, a, ...) UTIL_CAT(m(a), MACRO_MC_8(m, __VA_ARGS__,)) |
| #define MACRO_MC_10(m, a, ...) UTIL_CAT(m(a), MACRO_MC_9(m, __VA_ARGS__,)) |
| #define MACRO_MC_11(m, a, ...) UTIL_CAT(m(a), MACRO_MC_10(m, __VA_ARGS__,)) |
| #define MACRO_MC_12(m, a, ...) UTIL_CAT(m(a), MACRO_MC_11(m, __VA_ARGS__,)) |
| #define MACRO_MC_13(m, a, ...) UTIL_CAT(m(a), MACRO_MC_12(m, __VA_ARGS__,)) |
| #define MACRO_MC_14(m, a, ...) UTIL_CAT(m(a), MACRO_MC_13(m, __VA_ARGS__,)) |
| #define MACRO_MC_15(m, a, ...) UTIL_CAT(m(a), MACRO_MC_14(m, __VA_ARGS__,)) |
| |
| #endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */ |