Skip to content

Commit 9be341e

Browse files
committed
[nrf fromlist] sys: util_macro: Add IS_ENABLED_ALL and IS_ENABLED_ANY
-Added macro IS_ENABLED_ALL to check multiple macro definitions to see if ALL of them are define and set to 1. The result of calling this macro is compiler-visible expressions resolving to "1" if true, otherwise "0". -Added macro IS_ENABLED_ANY to check multiple macro definitions to see if ANY of them are defined and set to 1. The result of calling this macro is compiler-visible expressions resolving to "1" if true, otherwise "0". -Added unit tests for IS_ENABLED -Added unit tests for IS_ENABLED_ALL and IS_ENABLED_ANY Both macros utilize the same strategy as the IS_ENABLED macro, but supports variable number of arguments Signed-off-by: Frank Audun Kvamtrø <[email protected]> (cherry picked from commit a17af065ae9ae16fd8e38392e6efeff0d20692dd)
1 parent dc536c6 commit 9be341e

File tree

3 files changed

+229
-0
lines changed

3 files changed

+229
-0
lines changed

include/zephyr/sys/util_internal.h

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,82 @@
4949
*/
5050
#define Z_IS_ENABLED3(ignore_this, val, ...) val
5151

52+
/* Helper macro for IS_ENABLED_ALL */
53+
#define Z_IS_ENABLED_ALL(...) \
54+
Z_IS_ENABLED_ALL_N(NUM_VA_ARGS(__VA_ARGS__), __VA_ARGS__)
55+
#define Z_IS_ENABLED_ALL_N(N, ...) UTIL_CAT(Z_IS_ENABLED_ALL_, N)(__VA_ARGS__)
56+
#define Z_IS_ENABLED_ALL_0(...)
57+
#define Z_IS_ENABLED_ALL_1(a, ...) COND_CODE_1(a, (1), (0))
58+
#define Z_IS_ENABLED_ALL_2(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_1(__VA_ARGS__,)), (0))
59+
#define Z_IS_ENABLED_ALL_3(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_2(__VA_ARGS__,)), (0))
60+
#define Z_IS_ENABLED_ALL_4(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_3(__VA_ARGS__,)), (0))
61+
#define Z_IS_ENABLED_ALL_5(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_4(__VA_ARGS__,)), (0))
62+
#define Z_IS_ENABLED_ALL_6(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_5(__VA_ARGS__,)), (0))
63+
#define Z_IS_ENABLED_ALL_7(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_6(__VA_ARGS__,)), (0))
64+
#define Z_IS_ENABLED_ALL_8(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_7(__VA_ARGS__,)), (0))
65+
#define Z_IS_ENABLED_ALL_9(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_8(__VA_ARGS__,)), (0))
66+
#define Z_IS_ENABLED_ALL_10(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_9(__VA_ARGS__,)), (0))
67+
#define Z_IS_ENABLED_ALL_11(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_10(__VA_ARGS__,)), (0))
68+
#define Z_IS_ENABLED_ALL_12(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_11(__VA_ARGS__,)), (0))
69+
#define Z_IS_ENABLED_ALL_13(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_12(__VA_ARGS__,)), (0))
70+
#define Z_IS_ENABLED_ALL_14(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_13(__VA_ARGS__,)), (0))
71+
#define Z_IS_ENABLED_ALL_15(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_14(__VA_ARGS__,)), (0))
72+
#define Z_IS_ENABLED_ALL_16(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_15(__VA_ARGS__,)), (0))
73+
#define Z_IS_ENABLED_ALL_17(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_16(__VA_ARGS__,)), (0))
74+
#define Z_IS_ENABLED_ALL_18(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_17(__VA_ARGS__,)), (0))
75+
#define Z_IS_ENABLED_ALL_19(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_18(__VA_ARGS__,)), (0))
76+
#define Z_IS_ENABLED_ALL_20(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_19(__VA_ARGS__,)), (0))
77+
#define Z_IS_ENABLED_ALL_21(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_20(__VA_ARGS__,)), (0))
78+
#define Z_IS_ENABLED_ALL_22(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_21(__VA_ARGS__,)), (0))
79+
#define Z_IS_ENABLED_ALL_23(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_22(__VA_ARGS__,)), (0))
80+
#define Z_IS_ENABLED_ALL_24(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_23(__VA_ARGS__,)), (0))
81+
#define Z_IS_ENABLED_ALL_25(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_24(__VA_ARGS__,)), (0))
82+
#define Z_IS_ENABLED_ALL_26(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_25(__VA_ARGS__,)), (0))
83+
#define Z_IS_ENABLED_ALL_27(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_26(__VA_ARGS__,)), (0))
84+
#define Z_IS_ENABLED_ALL_28(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_27(__VA_ARGS__,)), (0))
85+
#define Z_IS_ENABLED_ALL_29(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_28(__VA_ARGS__,)), (0))
86+
#define Z_IS_ENABLED_ALL_30(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_29(__VA_ARGS__,)), (0))
87+
#define Z_IS_ENABLED_ALL_31(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_30(__VA_ARGS__,)), (0))
88+
#define Z_IS_ENABLED_ALL_32(a, ...) COND_CODE_1(a, (Z_IS_ENABLED_ALL_31(__VA_ARGS__,)), (0))
89+
90+
/* Helper macro for IS_ENABLED_ANY */
91+
#define Z_IS_ENABLED_ANY(...) \
92+
Z_IS_ENABLED_ANY_N(NUM_VA_ARGS(__VA_ARGS__), __VA_ARGS__)
93+
#define Z_IS_ENABLED_ANY_N(N, ...) UTIL_CAT(Z_IS_ENABLED_ANY_, N)(__VA_ARGS__)
94+
#define Z_IS_ENABLED_ANY_0(...)
95+
#define Z_IS_ENABLED_ANY_1(a, ...) COND_CODE_1(a, (1), (0))
96+
#define Z_IS_ENABLED_ANY_2(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_1(__VA_ARGS__,)))
97+
#define Z_IS_ENABLED_ANY_3(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_2(__VA_ARGS__,)))
98+
#define Z_IS_ENABLED_ANY_4(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_3(__VA_ARGS__,)))
99+
#define Z_IS_ENABLED_ANY_5(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_4(__VA_ARGS__,)))
100+
#define Z_IS_ENABLED_ANY_6(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_5(__VA_ARGS__,)))
101+
#define Z_IS_ENABLED_ANY_7(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_6(__VA_ARGS__,)))
102+
#define Z_IS_ENABLED_ANY_8(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_7(__VA_ARGS__,)))
103+
#define Z_IS_ENABLED_ANY_9(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_8(__VA_ARGS__,)))
104+
#define Z_IS_ENABLED_ANY_10(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_9(__VA_ARGS__,)))
105+
#define Z_IS_ENABLED_ANY_11(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_10(__VA_ARGS__,)))
106+
#define Z_IS_ENABLED_ANY_12(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_11(__VA_ARGS__,)))
107+
#define Z_IS_ENABLED_ANY_13(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_12(__VA_ARGS__,)))
108+
#define Z_IS_ENABLED_ANY_14(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_13(__VA_ARGS__,)))
109+
#define Z_IS_ENABLED_ANY_15(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_14(__VA_ARGS__,)))
110+
#define Z_IS_ENABLED_ANY_16(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_15(__VA_ARGS__,)))
111+
#define Z_IS_ENABLED_ANY_17(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_16(__VA_ARGS__,)))
112+
#define Z_IS_ENABLED_ANY_18(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_17(__VA_ARGS__,)))
113+
#define Z_IS_ENABLED_ANY_19(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_18(__VA_ARGS__,)))
114+
#define Z_IS_ENABLED_ANY_20(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_19(__VA_ARGS__,)))
115+
#define Z_IS_ENABLED_ANY_21(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_20(__VA_ARGS__,)))
116+
#define Z_IS_ENABLED_ANY_22(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_21(__VA_ARGS__,)))
117+
#define Z_IS_ENABLED_ANY_23(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_22(__VA_ARGS__,)))
118+
#define Z_IS_ENABLED_ANY_24(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_23(__VA_ARGS__,)))
119+
#define Z_IS_ENABLED_ANY_25(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_24(__VA_ARGS__,)))
120+
#define Z_IS_ENABLED_ANY_26(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_25(__VA_ARGS__,)))
121+
#define Z_IS_ENABLED_ANY_27(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_26(__VA_ARGS__,)))
122+
#define Z_IS_ENABLED_ANY_28(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_27(__VA_ARGS__,)))
123+
#define Z_IS_ENABLED_ANY_29(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_28(__VA_ARGS__,)))
124+
#define Z_IS_ENABLED_ANY_30(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_29(__VA_ARGS__,)))
125+
#define Z_IS_ENABLED_ANY_31(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_30(__VA_ARGS__,)))
126+
#define Z_IS_ENABLED_ANY_32(a, ...) COND_CODE_1(a, (1), (Z_IS_ENABLED_ANY_31(__VA_ARGS__,)))
127+
52128
/* Implementation of IS_EQ(). Returns 1 if _0 and _1 are the same integer from
53129
* 0 to 4096, 0 otherwise.
54130
*/

include/zephyr/sys/util_macro.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,52 @@ extern "C" {
144144
* recursive expansion does not work.
145145
*/
146146

147+
/**
148+
* @brief Check multiple macro definitions to see if all are set in
149+
* compiler-visible expressions
150+
*
151+
* This utilizes the same methodology as @ref IS_ENABLED but on an variable number
152+
* of argument. It will resolve as true (1) if all of the arguments in the input
153+
* are defined to 1.
154+
*
155+
* Example usage:
156+
*
157+
* if (IS_ENABLED_ALL(CONFIG_FOO, CONFIG_BAR)) {
158+
* do_something_if_all_of_these
159+
* }
160+
*
161+
* This is cleaner since the compiler can generate errors and warnings
162+
* for @p do_something_if_all_of_these even when @p CONFIG_FOO and/or
163+
* @p CONFIG_BAR is undefined.
164+
*
165+
* @param ... Arguments to check if all are defined to 1
166+
* @return 1 if all params in @p ... are defined to 1, otherwise 0
167+
*/
168+
#define IS_ENABLED_ALL(...) Z_IS_ENABLED_ALL(__VA_ARGS__)
169+
170+
/**
171+
* @brief Check multiple macro definitions to see if any is set in
172+
* compiler-visible expressions
173+
*
174+
* This utilizes the same methodology as @ref IS_ENABLED but on an variable number
175+
* of argument. It will resolve as true (1) if any of the arguments in the input
176+
* are defined to 1.
177+
*
178+
* Example usage:
179+
*
180+
* if (IS_ENABLED_ANY(CONFIG_FOO, CONFIG_BAR)) {
181+
* do_something_if_any_of_these
182+
* }
183+
*
184+
* This is cleaner since the compiler can generate errors and warnings
185+
* for @p do_something_if_any_of_these even when @p CONFIG_FOO and/or
186+
* @p CONFIG_BAR is undefined.
187+
*
188+
* @param ... Arguments to check if at least one is defined to 1
189+
* @return 1 if at least one param in @p ... is defined to 1, otherwise 0
190+
*/
191+
#define IS_ENABLED_ANY(...) Z_IS_ENABLED_ANY(__VA_ARGS__)
192+
147193
/**
148194
* @brief Insert code depending on whether @p _flag expands to 1 or not.
149195
*

tests/unit/util/main.c

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,113 @@ ZTEST(util, test_sign_extend_64) {
101101
zassert_equal(sign_extend_64(u64, 60), 0xfffffffffffffff);
102102
}
103103

104+
ZTEST(util, test_IS_ENABLED) {
105+
#define TEST_FLAG_A 1
106+
#define TEST_FLAG_B 0
107+
108+
if (IS_ENABLED(TEST_FLAG_A)) {
109+
goto skipped;
110+
}
111+
112+
/* location should be skipped (TEST_FLAG_A is 1). */
113+
zassert_false(true, "location should be skipped");
114+
skipped:
115+
if (IS_ENABLED(TEST_FLAG_B)) {
116+
zassert_false(true, "IS_ENABLED should not be emitted (invalid)");
117+
}
118+
119+
zassert_true(true, "");
120+
121+
#undef TEST_FLAG_A
122+
#undef TEST_FLAG_B
123+
}
124+
125+
ZTEST(util, test_IS_ENABLED_ALL) {
126+
#define TEST_FLAG_A 1
127+
#define TEST_FLAG_B 1
128+
#define TEST_FLAG_C 0
129+
#define TEST_FLAG_D 0
130+
131+
if (IS_ENABLED_ALL(TEST_FLAG_A, TEST_FLAG_B)) {
132+
goto skipped;
133+
}
134+
135+
/* location should be skipped (TEST_FLAG_A/B are 1). */
136+
zassert_false(true, "location should be skipped");
137+
skipped:
138+
if (IS_ENABLED_ALL(TEST_FLAG_A)) {
139+
goto skipped_1;
140+
}
141+
142+
/* location should be skipped (TEST_FLAG_A is 1). */
143+
zassert_false(true, "location should be skipped (single valid)");
144+
skipped_1:
145+
if (IS_ENABLED_ALL(TEST_FLAG_C)) {
146+
zassert_false(
147+
false,
148+
"IS_ENABLED_ALL should not emit (single invalid)");
149+
}
150+
151+
if (IS_ENABLED_ALL(TEST_FLAG_A, TEST_FLAG_C)) {
152+
zassert_false(true, "IS_ENABLED_ALL should not emit (one invalid)");
153+
}
154+
155+
156+
if (IS_ENABLED_ALL(TEST_FLAG_C, TEST_FLAG_D)) {
157+
zassert_false(true, "IS_ENABLED_ALL should not emit (no valid)");
158+
}
159+
160+
zassert_true(true, "");
161+
162+
#undef TEST_FLAG_A
163+
#undef TEST_FLAG_B
164+
#undef TEST_FLAG_C
165+
#undef TEST_FLAG_D
166+
}
167+
168+
ZTEST(util, test_IS_ENABLED_ANY) {
169+
#define TEST_FLAG_A 1
170+
#define TEST_FLAG_B 1
171+
#define TEST_FLAG_C 0
172+
#define TEST_FLAG_D 0
173+
174+
if (IS_ENABLED_ANY(TEST_FLAG_A, TEST_FLAG_B)) {
175+
goto skipped;
176+
}
177+
178+
/* location should be skipped (TEST_FLAG_A/B are 1). */
179+
zassert_false(true, "location should be skipped");
180+
skipped:
181+
if (IS_ENABLED_ANY(TEST_FLAG_A)) {
182+
goto skipped_1;
183+
}
184+
185+
/* Location should be skipped (TEST_FLAG_A is 1)*/
186+
zassert_false(true, "location should be skipped (single valid)");
187+
skipped_1:
188+
if (IS_ENABLED_ANY(TEST_FLAG_C)) {
189+
zassert_false(true,
190+
"IS_ENABLED_ANY should not emit (single invalid)");
191+
}
192+
193+
if (IS_ENABLED_ANY(TEST_FLAG_A, TEST_FLAG_C)) {
194+
zassert_true(true,
195+
"IS_ENABLED_ANY should emit (single valid)");
196+
}
197+
198+
if (IS_ENABLED_ANY(TEST_FLAG_C, TEST_FLAG_D)) {
199+
zassert_false(true,
200+
"IS_ENABLED_ANY should not emit (no valid)");
201+
}
202+
203+
zassert_true(true, "");
204+
205+
#undef TEST_FLAG_A
206+
#undef TEST_FLAG_B
207+
#undef TEST_FLAG_C
208+
#undef TEST_FLAG_D
209+
}
210+
104211
ZTEST(util, test_COND_CODE_1) {
105212
#define TEST_DEFINE_1 1
106213
#define TEST_DEFINE_0 0

0 commit comments

Comments
 (0)