1 /* 2 * Copyright (c) 2011-2014, Wind River Systems, Inc. 3 * Copyright (c) 2020, Nordic Semiconductor ASA 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 /** 9 * @file 10 * @brief Misc utilities 11 * 12 * Repetitive or obscure helper macros needed by sys/util.h. 13 */ 14 15 #ifndef ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ 16 #define ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ 17 18 #include "util_loops.h" 19 20 /* IS_ENABLED() helpers */ 21 22 /* This is called from IS_ENABLED(), and sticks on a "_XXXX" prefix, 23 * it will now be "_XXXX1" if config_macro is "1", or just "_XXXX" if it's 24 * undefined. 25 * ENABLED: Z_IS_ENABLED2(_XXXX1) 26 * DISABLED Z_IS_ENABLED2(_XXXX) 27 */ 28 #define Z_IS_ENABLED1(config_macro) Z_IS_ENABLED2(_XXXX##config_macro) 29 30 /* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string 31 * with a trailing comma), so it has the effect of making this a 32 * two-argument tuple to the preprocessor only in the case where the 33 * value is defined to "1" 34 * ENABLED: _YYYY, <--- note comma! 35 * DISABLED: _XXXX 36 */ 37 #define _XXXX1 _YYYY, 38 39 /* Then we append an extra argument to fool the gcc preprocessor into 40 * accepting it as a varargs macro. 41 * arg1 arg2 arg3 42 * ENABLED: Z_IS_ENABLED3(_YYYY, 1, 0) 43 * DISABLED Z_IS_ENABLED3(_XXXX 1, 0) 44 */ 45 #define Z_IS_ENABLED2(one_or_two_args) Z_IS_ENABLED3(one_or_two_args 1, 0) 46 47 /* And our second argument is thus now cooked to be 1 in the case 48 * where the value is defined to 1, and 0 if not: 49 */ 50 #define Z_IS_ENABLED3(ignore_this, val, ...) val 51 52 /* Implementation of IS_EQ(). Returns 1 if _0 and _1 are the same integer from 53 * 0 to 4095, 0 otherwise. 54 */ 55 #define Z_IS_EQ(_0, _1) Z_HAS_COMMA(Z_CAT4(Z_IS_, _0, _EQ_, _1)()) 56 57 /* Used internally by COND_CODE_1 and COND_CODE_0. */ 58 #define Z_COND_CODE_1(_flag, _if_1_code, _else_code) \ 59 __COND_CODE(_XXXX##_flag, _if_1_code, _else_code) 60 #define Z_COND_CODE_0(_flag, _if_0_code, _else_code) \ 61 __COND_CODE(_ZZZZ##_flag, _if_0_code, _else_code) 62 #define _ZZZZ0 _YYYY, 63 #define __COND_CODE(one_or_two_args, _if_code, _else_code) \ 64 __GET_ARG2_DEBRACKET(one_or_two_args _if_code, _else_code) 65 66 /* Gets second argument and removes brackets around that argument. It 67 * is expected that the parameter is provided in brackets/parentheses. 68 */ 69 #define __GET_ARG2_DEBRACKET(ignore_this, val, ...) __DEBRACKET val 70 71 /* Used to remove brackets from around a single argument. */ 72 #define __DEBRACKET(...) __VA_ARGS__ 73 74 /* Used by IS_EMPTY() */ 75 /* reference: https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/ */ 76 #define Z_HAS_COMMA(...) \ 77 NUM_VA_ARGS_LESS_1_IMPL(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, \ 78 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 79 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 80 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) 81 #define Z_TRIGGER_PARENTHESIS_(...) , 82 #define Z_IS_EMPTY_(...) \ 83 Z_IS_EMPTY__( \ 84 Z_HAS_COMMA(__VA_ARGS__), \ 85 Z_HAS_COMMA(Z_TRIGGER_PARENTHESIS_ __VA_ARGS__), \ 86 Z_HAS_COMMA(__VA_ARGS__ (/*empty*/)), \ 87 Z_HAS_COMMA(Z_TRIGGER_PARENTHESIS_ __VA_ARGS__ (/*empty*/))) 88 #define Z_CAT4(_0, _1, _2, _3) _0 ## _1 ## _2 ## _3 89 #define Z_CAT5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4 90 #define Z_IS_EMPTY__(_0, _1, _2, _3) \ 91 Z_HAS_COMMA(Z_CAT5(Z_IS_EMPTY_CASE_, _0, _1, _2, _3)) 92 #define Z_IS_EMPTY_CASE_0001 , 93 94 /* Used by LIST_DROP_EMPTY() */ 95 /* Adding ',' after each element would add empty element at the end of 96 * list, which is hard to remove, so instead precede each element with ',', 97 * this way first element is empty, and this one is easy to drop. 98 */ 99 #define Z_LIST_ADD_ELEM(e) EMPTY, e 100 #define Z_LIST_DROP_FIRST(...) GET_ARGS_LESS_N(1, __VA_ARGS__) 101 #define Z_LIST_NO_EMPTIES(e) \ 102 COND_CODE_1(IS_EMPTY(e), (), (Z_LIST_ADD_ELEM(e))) 103 104 #define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__) 105 #define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__ 106 #define UTIL_CHECK_N(x, n, ...) n 107 #define UTIL_CHECK(...) UTIL_CHECK_N(__VA_ARGS__, 0,) 108 #define UTIL_NOT(x) UTIL_CHECK(UTIL_PRIMITIVE_CAT(UTIL_NOT_, x)) 109 #define UTIL_NOT_0 ~, 1, 110 #define UTIL_COMPL(b) UTIL_PRIMITIVE_CAT(UTIL_COMPL_, b) 111 #define UTIL_COMPL_0 1 112 #define UTIL_COMPL_1 0 113 #define UTIL_BOOL(x) UTIL_COMPL(UTIL_NOT(x)) 114 115 #define UTIL_EVAL(...) __VA_ARGS__ 116 #define UTIL_EXPAND(...) __VA_ARGS__ 117 #define UTIL_REPEAT(...) UTIL_LISTIFY(__VA_ARGS__) 118 119 /* Implementation details for NUM_VA_ARGS_LESS_1 */ 120 #define NUM_VA_ARGS_LESS_1_IMPL( \ 121 _ignored, \ 122 _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ 123 _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ 124 _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ 125 _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ 126 _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ 127 _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ 128 _61, _62, N, ...) N 129 130 /* Used by MACRO_MAP_CAT */ 131 #define MACRO_MAP_CAT_(...) \ 132 /* To make sure it works also for 2 arguments in total */ \ 133 MACRO_MAP_CAT_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) 134 #define MACRO_MAP_CAT_N_(N, ...) UTIL_CAT(MACRO_MC_, N)(__VA_ARGS__,) 135 #define MACRO_MC_0(...) 136 #define MACRO_MC_1(m, a, ...) m(a) 137 #define MACRO_MC_2(m, a, ...) UTIL_CAT(m(a), MACRO_MC_1(m, __VA_ARGS__,)) 138 #define MACRO_MC_3(m, a, ...) UTIL_CAT(m(a), MACRO_MC_2(m, __VA_ARGS__,)) 139 #define MACRO_MC_4(m, a, ...) UTIL_CAT(m(a), MACRO_MC_3(m, __VA_ARGS__,)) 140 #define MACRO_MC_5(m, a, ...) UTIL_CAT(m(a), MACRO_MC_4(m, __VA_ARGS__,)) 141 #define MACRO_MC_6(m, a, ...) UTIL_CAT(m(a), MACRO_MC_5(m, __VA_ARGS__,)) 142 #define MACRO_MC_7(m, a, ...) UTIL_CAT(m(a), MACRO_MC_6(m, __VA_ARGS__,)) 143 #define MACRO_MC_8(m, a, ...) UTIL_CAT(m(a), MACRO_MC_7(m, __VA_ARGS__,)) 144 #define MACRO_MC_9(m, a, ...) UTIL_CAT(m(a), MACRO_MC_8(m, __VA_ARGS__,)) 145 #define MACRO_MC_10(m, a, ...) UTIL_CAT(m(a), MACRO_MC_9(m, __VA_ARGS__,)) 146 #define MACRO_MC_11(m, a, ...) UTIL_CAT(m(a), MACRO_MC_10(m, __VA_ARGS__,)) 147 #define MACRO_MC_12(m, a, ...) UTIL_CAT(m(a), MACRO_MC_11(m, __VA_ARGS__,)) 148 #define MACRO_MC_13(m, a, ...) UTIL_CAT(m(a), MACRO_MC_12(m, __VA_ARGS__,)) 149 #define MACRO_MC_14(m, a, ...) UTIL_CAT(m(a), MACRO_MC_13(m, __VA_ARGS__,)) 150 #define MACRO_MC_15(m, a, ...) UTIL_CAT(m(a), MACRO_MC_14(m, __VA_ARGS__,)) 151 152 /* Used by Z_IS_EQ */ 153 #include "util_internal_is_eq.h" 154 155 /* 156 * Generic sparse list of odd numbers (check the implementation of 157 * GPIO_DT_RESERVED_RANGES_NGPIOS as a usage example) 158 */ 159 #define Z_SPARSE_LIST_ODD_NUMBERS \ 160 EMPTY, 1, EMPTY, 3, EMPTY, 5, EMPTY, 7, \ 161 EMPTY, 9, EMPTY, 11, EMPTY, 13, EMPTY, 15, \ 162 EMPTY, 17, EMPTY, 19, EMPTY, 21, EMPTY, 23, \ 163 EMPTY, 25, EMPTY, 27, EMPTY, 29, EMPTY, 31, \ 164 EMPTY, 33, EMPTY, 35, EMPTY, 37, EMPTY, 39, \ 165 EMPTY, 41, EMPTY, 43, EMPTY, 45, EMPTY, 47, \ 166 EMPTY, 49, EMPTY, 51, EMPTY, 53, EMPTY, 55, \ 167 EMPTY, 57, EMPTY, 59, EMPTY, 61, EMPTY, 63 168 169 /* 170 * Generic sparse list of even numbers (check the implementation of 171 * GPIO_DT_RESERVED_RANGES_NGPIOS as a usage example) 172 */ 173 #define Z_SPARSE_LIST_EVEN_NUMBERS \ 174 0, EMPTY, 2, EMPTY, 4, EMPTY, 6, EMPTY, \ 175 8, EMPTY, 10, EMPTY, 12, EMPTY, 14, EMPTY, \ 176 16, EMPTY, 18, EMPTY, 20, EMPTY, 22, EMPTY, \ 177 24, EMPTY, 26, EMPTY, 28, EMPTY, 30, EMPTY, \ 178 32, EMPTY, 34, EMPTY, 36, EMPTY, 38, EMPTY, \ 179 40, EMPTY, 42, EMPTY, 44, EMPTY, 46, EMPTY, \ 180 48, EMPTY, 50, EMPTY, 52, EMPTY, 54, EMPTY, \ 181 56, EMPTY, 58, EMPTY, 60, EMPTY, 62, EMPTY 182 183 /* Used by UTIL_INC */ 184 #include "util_internal_util_inc.h" 185 186 /* Used by UTIL_DEC */ 187 #include "util_internal_util_dec.h" 188 189 /* Used by UTIL_X2 */ 190 #include "util_internal_util_x2.h" 191 192 #endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */ 193