Zephyr API Documentation
4.3.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
util_internal.h
Go to the documentation of this file.
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
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 4096, 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 COND_CASE_1(); supports up to 16 flag/value pairs */
75
#define Z_COND_CASE_1(...) \
76
Z_COND_CASE_1_CAT_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__)
77
78
#define Z_COND_CASE_1_CAT_N(count_minus_one, ...) \
79
UTIL_CAT(Z_COND_CASE_1_N_, count_minus_one)(__VA_ARGS__)
80
81
#define Z_COND_CASE_1_N_0(_default) __DEBRACKET _default
82
#define Z_COND_CASE_1_N_2(flag0, value0, _default) \
83
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (__DEBRACKET _default))
84
#define Z_COND_CASE_1_N_4(flag0, value0, ...) \
85
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_2(__VA_ARGS__)))
86
#define Z_COND_CASE_1_N_6(flag0, value0, ...) \
87
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_4(__VA_ARGS__)))
88
#define Z_COND_CASE_1_N_8(flag0, value0, ...) \
89
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_6(__VA_ARGS__)))
90
#define Z_COND_CASE_1_N_10(flag0, value0, ...) \
91
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_8(__VA_ARGS__)))
92
#define Z_COND_CASE_1_N_12(flag0, value0, ...) \
93
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_10(__VA_ARGS__)))
94
#define Z_COND_CASE_1_N_14(flag0, value0, ...) \
95
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_12(__VA_ARGS__)))
96
#define Z_COND_CASE_1_N_16(flag0, value0, ...) \
97
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_14(__VA_ARGS__)))
98
#define Z_COND_CASE_1_N_18(flag0, value0, ...) \
99
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_16(__VA_ARGS__)))
100
#define Z_COND_CASE_1_N_20(flag0, value0, ...) \
101
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_18(__VA_ARGS__)))
102
#define Z_COND_CASE_1_N_22(flag0, value0, ...) \
103
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_20(__VA_ARGS__)))
104
#define Z_COND_CASE_1_N_24(flag0, value0, ...) \
105
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_22(__VA_ARGS__)))
106
#define Z_COND_CASE_1_N_26(flag0, value0, ...) \
107
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_24(__VA_ARGS__)))
108
#define Z_COND_CASE_1_N_28(flag0, value0, ...) \
109
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_26(__VA_ARGS__)))
110
#define Z_COND_CASE_1_N_30(flag0, value0, ...) \
111
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_28(__VA_ARGS__)))
112
#define Z_COND_CASE_1_N_32(flag0, value0, ...) \
113
Z_COND_CODE_1(flag0, (__DEBRACKET value0), (Z_COND_CASE_1_N_30(__VA_ARGS__)))
114
115
/* Used by IS_EMPTY() */
116
/* reference: https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/ */
117
#define Z_HAS_COMMA(...) \
118
NUM_VA_ARGS_LESS_1_IMPL(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, \
119
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
120
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
121
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
122
#define Z_TRIGGER_PARENTHESIS_(...) ,
123
#define Z_IS_EMPTY_(...) \
124
Z_IS_EMPTY__( \
125
Z_HAS_COMMA(__VA_ARGS__), \
126
Z_HAS_COMMA(Z_TRIGGER_PARENTHESIS_ __VA_ARGS__), \
127
Z_HAS_COMMA(__VA_ARGS__ (
/*empty*/
)), \
128
Z_HAS_COMMA(Z_TRIGGER_PARENTHESIS_ __VA_ARGS__ (
/*empty*/
)))
129
#define Z_CAT4(_0, _1, _2, _3) _0 ## _1 ## _2 ## _3
130
#define Z_CAT5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4
131
#define Z_IS_EMPTY__(_0, _1, _2, _3) \
132
Z_HAS_COMMA(Z_CAT5(Z_IS_EMPTY_CASE_, _0, _1, _2, _3))
133
#define Z_IS_EMPTY_CASE_0001 ,
134
135
/* Used by LIST_DROP_EMPTY() */
136
/* Adding ',' after each element would add empty element at the end of
137
* list, which is hard to remove, so instead precede each element with ',',
138
* this way first element is empty, and this one is easy to drop.
139
*/
140
#define Z_LIST_ADD_ELEM(e) EMPTY, e
141
#define Z_LIST_DROP_FIRST(...) GET_ARGS_LESS_N(1, __VA_ARGS__)
142
#define Z_LIST_NO_EMPTIES(e) \
143
COND_CODE_1(IS_EMPTY(e), (), (Z_LIST_ADD_ELEM(e)))
144
145
#define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__)
146
#define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
147
#define UTIL_CHECK_N(x, n, ...) n
148
#define UTIL_CHECK(...) UTIL_CHECK_N(__VA_ARGS__, 0,)
149
#define UTIL_NOT(x) UTIL_CHECK(UTIL_PRIMITIVE_CAT(UTIL_NOT_, x))
150
#define UTIL_NOT_0 ~, 1,
151
#define UTIL_COMPL(b) UTIL_PRIMITIVE_CAT(UTIL_COMPL_, b)
152
#define UTIL_COMPL_0 1
153
#define UTIL_COMPL_1 0
154
#define UTIL_BOOL(x) UTIL_COMPL(UTIL_NOT(x))
155
156
#define UTIL_EVAL(...) __VA_ARGS__
157
#define UTIL_EXPAND(...) __VA_ARGS__
158
#define UTIL_REPEAT(...) UTIL_LISTIFY(__VA_ARGS__)
159
160
#define _CONCAT_0(arg, ...) arg
161
#define _CONCAT_1(arg, ...) UTIL_CAT(arg, _CONCAT_0(__VA_ARGS__))
162
#define _CONCAT_2(arg, ...) UTIL_CAT(arg, _CONCAT_1(__VA_ARGS__))
163
#define _CONCAT_3(arg, ...) UTIL_CAT(arg, _CONCAT_2(__VA_ARGS__))
164
#define _CONCAT_4(arg, ...) UTIL_CAT(arg, _CONCAT_3(__VA_ARGS__))
165
#define _CONCAT_5(arg, ...) UTIL_CAT(arg, _CONCAT_4(__VA_ARGS__))
166
#define _CONCAT_6(arg, ...) UTIL_CAT(arg, _CONCAT_5(__VA_ARGS__))
167
#define _CONCAT_7(arg, ...) UTIL_CAT(arg, _CONCAT_6(__VA_ARGS__))
168
169
/* Implementation details for NUM_VA_ARGS_LESS_1 */
170
#define NUM_VA_ARGS_LESS_1_IMPL( \
171
_ignored, \
172
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
173
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
174
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
175
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
176
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
177
_51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
178
_61, _62, N, ...) N
179
180
/* Used by MACRO_MAP_CAT */
181
#define MACRO_MAP_CAT_(...) \
182
/* To make sure it works also for 2 arguments in total */
\
183
MACRO_MAP_CAT_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__)
184
#define MACRO_MAP_CAT_N_(N, ...) UTIL_CAT(MACRO_MC_, N)(__VA_ARGS__,)
185
#define MACRO_MC_0(...)
186
#define MACRO_MC_1(m, a, ...) m(a)
187
#define MACRO_MC_2(m, a, ...) UTIL_CAT(m(a), MACRO_MC_1(m, __VA_ARGS__,))
188
#define MACRO_MC_3(m, a, ...) UTIL_CAT(m(a), MACRO_MC_2(m, __VA_ARGS__,))
189
#define MACRO_MC_4(m, a, ...) UTIL_CAT(m(a), MACRO_MC_3(m, __VA_ARGS__,))
190
#define MACRO_MC_5(m, a, ...) UTIL_CAT(m(a), MACRO_MC_4(m, __VA_ARGS__,))
191
#define MACRO_MC_6(m, a, ...) UTIL_CAT(m(a), MACRO_MC_5(m, __VA_ARGS__,))
192
#define MACRO_MC_7(m, a, ...) UTIL_CAT(m(a), MACRO_MC_6(m, __VA_ARGS__,))
193
#define MACRO_MC_8(m, a, ...) UTIL_CAT(m(a), MACRO_MC_7(m, __VA_ARGS__,))
194
#define MACRO_MC_9(m, a, ...) UTIL_CAT(m(a), MACRO_MC_8(m, __VA_ARGS__,))
195
#define MACRO_MC_10(m, a, ...) UTIL_CAT(m(a), MACRO_MC_9(m, __VA_ARGS__,))
196
#define MACRO_MC_11(m, a, ...) UTIL_CAT(m(a), MACRO_MC_10(m, __VA_ARGS__,))
197
#define MACRO_MC_12(m, a, ...) UTIL_CAT(m(a), MACRO_MC_11(m, __VA_ARGS__,))
198
#define MACRO_MC_13(m, a, ...) UTIL_CAT(m(a), MACRO_MC_12(m, __VA_ARGS__,))
199
#define MACRO_MC_14(m, a, ...) UTIL_CAT(m(a), MACRO_MC_13(m, __VA_ARGS__,))
200
#define MACRO_MC_15(m, a, ...) UTIL_CAT(m(a), MACRO_MC_14(m, __VA_ARGS__,))
201
202
/* Used by Z_IS_EQ */
203
#include "
util_internal_is_eq.h
"
204
205
/*
206
* Generic sparse list of odd numbers (check the implementation of
207
* GPIO_DT_RESERVED_RANGES_NGPIOS as a usage example)
208
*/
209
#define Z_SPARSE_LIST_ODD_NUMBERS \
210
EMPTY, 1, EMPTY, 3, EMPTY, 5, EMPTY, 7, \
211
EMPTY, 9, EMPTY, 11, EMPTY, 13, EMPTY, 15, \
212
EMPTY, 17, EMPTY, 19, EMPTY, 21, EMPTY, 23, \
213
EMPTY, 25, EMPTY, 27, EMPTY, 29, EMPTY, 31, \
214
EMPTY, 33, EMPTY, 35, EMPTY, 37, EMPTY, 39, \
215
EMPTY, 41, EMPTY, 43, EMPTY, 45, EMPTY, 47, \
216
EMPTY, 49, EMPTY, 51, EMPTY, 53, EMPTY, 55, \
217
EMPTY, 57, EMPTY, 59, EMPTY, 61, EMPTY, 63
218
219
/*
220
* Generic sparse list of even numbers (check the implementation of
221
* GPIO_DT_RESERVED_RANGES_NGPIOS as a usage example)
222
*/
223
#define Z_SPARSE_LIST_EVEN_NUMBERS \
224
0, EMPTY, 2, EMPTY, 4, EMPTY, 6, EMPTY, \
225
8, EMPTY, 10, EMPTY, 12, EMPTY, 14, EMPTY, \
226
16, EMPTY, 18, EMPTY, 20, EMPTY, 22, EMPTY, \
227
24, EMPTY, 26, EMPTY, 28, EMPTY, 30, EMPTY, \
228
32, EMPTY, 34, EMPTY, 36, EMPTY, 38, EMPTY, \
229
40, EMPTY, 42, EMPTY, 44, EMPTY, 46, EMPTY, \
230
48, EMPTY, 50, EMPTY, 52, EMPTY, 54, EMPTY, \
231
56, EMPTY, 58, EMPTY, 60, EMPTY, 62, EMPTY
232
233
/* Used by UTIL_INC */
234
#include "
util_internal_util_inc.h
"
235
236
/* Used by UTIL_DEC */
237
#include "
util_internal_util_dec.h
"
238
239
/* Used by UTIL_X2 */
240
#include "
util_internal_util_x2.h
"
241
242
#endif
/* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */
util_internal_is_eq.h
util_internal_util_dec.h
util_internal_util_inc.h
util_internal_util_x2.h
util_loops.h
Internals for looping macros.
zephyr
sys
util_internal.h
Generated on
for Zephyr API Documentation by
1.15.0