sys: util: Added separator to FOR_EACH_ macros

Added separator (e.g. comma or semicolon) parameter to FOR_EACH_ family.
Separator is added between macro execution for each argument and not at
the end.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2020-05-08 07:06:58 +02:00 committed by Carles Cufí
commit 1b4b9386e5
8 changed files with 56 additions and 46 deletions

View file

@ -121,7 +121,7 @@ struct z_app_region {
.bss_start = &Z_APP_BSS_START(name), \
.bss_size = (size_t) &Z_APP_BSS_SIZE(name) \
}; \
Z_APPMEM_PLACEHOLDER(name);
Z_APPMEM_PLACEHOLDER(name)
#else
#define K_APP_BMEM(ptn)

View file

@ -830,7 +830,7 @@ extern FUNC_NORETURN void k_thread_user_mode_enter(k_thread_entry_t entry,
* @param ... list of kernel object pointers
*/
#define k_thread_access_grant(thread, ...) \
FOR_EACH_FIXED_ARG(k_object_access_grant, thread, __VA_ARGS__)
FOR_EACH_FIXED_ARG(k_object_access_grant, (;), thread, __VA_ARGS__)
/**
* @brief Assign a resource memory pool to a thread

View file

@ -206,9 +206,9 @@ extern "C" {
#define _LOG_INTERNAL_3(_src_level, _str, _arg0, _arg1, _arg2) \
log_3(_str, (log_arg_t)(_arg0), (log_arg_t)(_arg1), (log_arg_t)(_arg2), _src_level)
#define __LOG_ARG_CAST(_x) (log_arg_t)(_x),
#define __LOG_ARG_CAST(_x) (log_arg_t)(_x)
#define __LOG_ARGUMENTS(...) FOR_EACH(__LOG_ARG_CAST, __VA_ARGS__)
#define __LOG_ARGUMENTS(...) FOR_EACH(__LOG_ARG_CAST, (,), __VA_ARGS__)
#define _LOG_INTERNAL_LONG(_src_level, _str, ...) \
do { \

View file

@ -408,7 +408,7 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
* @param ... list to be processed
*/
#define LIST_DROP_EMPTY(...) \
Z_LIST_DROP_FIRST(FOR_EACH(Z_LIST_NO_EMPTIES, __VA_ARGS__))
Z_LIST_DROP_FIRST(FOR_EACH(Z_LIST_NO_EMPTIES, (), __VA_ARGS__))
/* Adding ',' after each element would add empty element at the end of
* list, which is hard to remove, so instead precede each element with ',',
@ -959,16 +959,16 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
#define UTIL_LISTIFY(LEN, F, ...) UTIL_EVAL(UTIL_REPEAT(LEN, F, __VA_ARGS__))
/* Set of internal macros used for FOR_EACH series of macros. */
#define Z_FOR_EACH_IDX(count, n, macro, semicolon, fixed_arg0, fixed_arg1, ...)\
#define Z_FOR_EACH_IDX(count, n, macro, sep, fixed_arg0, fixed_arg1, ...)\
UTIL_WHEN(count) \
( \
UTIL_OBSTRUCT(macro) \
( \
fixed_arg0, fixed_arg1, n, GET_ARG1(__VA_ARGS__)\
)semicolon \
) COND_CODE_1(count, (), (__DEBRACKET sep)) \
UTIL_OBSTRUCT(Z_FOR_EACH_IDX_INDIRECT) () \
( \
UTIL_DEC(count), UTIL_INC(n), macro, semicolon, \
UTIL_DEC(count), UTIL_INC(n), macro, sep, \
fixed_arg0, fixed_arg1, \
GET_ARGS_LESS_1(__VA_ARGS__) \
) \
@ -992,10 +992,13 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
* @brief Calls macro F for each provided argument with index as first argument
* and nth parameter as the second argument.
*
* @note Separator argument must be in parentheses. It is required to enable
* providing comma as separator.
*
* Example:
*
* #define F(idx, x) int a##idx = x;
* FOR_EACH_IDX(F, 4, 5, 6)
* #define F(idx, x) int a##idx = x
* FOR_EACH_IDX(F, (;), 4, 5, 6);
*
* will result in following code:
*
@ -1005,11 +1008,12 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
*
* @param F Macro takes index and first argument and nth variable argument as
* the second one.
* @param sep Separator (e.g. comma or semicolon). Must be in parentheses.
* @param ... Variable list of argument. For each argument macro F is executed.
*/
#define FOR_EACH_IDX(F, ...) \
#define FOR_EACH_IDX(F, sep, ...) \
Z_FOR_EACH_IDX2(NUM_VA_ARGS_LESS_1(__VA_ARGS__, _), \
0, Z_FOR_EACH_SWALLOW_FIXED_ARG, /*no ;*/, \
0, Z_FOR_EACH_SWALLOW_FIXED_ARG, sep, \
F, 0, __VA_ARGS__)
/**
@ -1017,10 +1021,12 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
* and nth parameter as the second argument and fixed argument as the
* third one.
*
* @note Separator argument must be in parentheses. It is required to enable
* providing comma as separator.
* Example:
*
* #define F(idx, x, fixed_arg) int fixed_arg##idx = x;
* FOR_EACH_IDX_FIXED_ARG(F, a, 4, 5, 6)
* #define F(idx, x, fixed_arg) int fixed_arg##idx = x
* FOR_EACH_IDX_FIXED_ARG(F, (;), a, 4, 5, 6);
*
* will result in following code:
*
@ -1030,21 +1036,24 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
*
* @param F Macro takes index and first argument and nth variable argument as
* the second one and fixed argumnet as the third.
* @param sep Separator (e.g. comma or semicolon). Must be in parentheses.
* @param fixed_arg Fixed argument passed to F macro.
* @param ... Variable list of argument. For each argument macro F is executed.
*/
#define FOR_EACH_IDX_FIXED_ARG(F, fixed_arg, ...) \
#define FOR_EACH_IDX_FIXED_ARG(F, sep, fixed_arg, ...) \
Z_FOR_EACH_IDX2(NUM_VA_ARGS_LESS_1(__VA_ARGS__, _), \
0, Z_FOR_EACH_SWALLOW_NOTHING, /*no ;*/, \
0, Z_FOR_EACH_SWALLOW_NOTHING, sep, \
F, fixed_arg, __VA_ARGS__)
/**
* @brief Calls macro F for each provided argument.
*
* @note Separator argument must be in parentheses. It is required to enable
* providing comma as separator.
* Example:
*
* #define F(x) int a##x;
* FOR_EACH(F, 4, 5, 6)
* #define F(x) int a##x
* FOR_EACH(F, (;), 4, 5, 6);
*
* will result in following code:
*
@ -1053,23 +1062,25 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
* int a6;
*
* @param F Macro takes nth variable argument as the argument.
* @param sep Separator (e.g. comma or semicolon). Must be in parentheses.
* @param ... Variable list of argument. For each argument macro F is executed.
*/
#define FOR_EACH(F, ...) \
#define FOR_EACH(F, sep, ...) \
Z_FOR_EACH_IDX2(NUM_VA_ARGS_LESS_1(__VA_ARGS__, _), \
0, Z_FOR_EACH_SWALLOW_INDEX_FIXED_ARG, /*no ;*/, \
0, Z_FOR_EACH_SWALLOW_INDEX_FIXED_ARG, sep, \
F, 0, __VA_ARGS__)
/**
* @brief Calls macro F for each provided argument with additional fixed
* argument.
*
* After each iteration semicolon is added.
* @note Separator argument must be in parentheses. It is required to enable
* providing comma as separator.
*
* Example:
*
* static void func(int val, void *dev);
* FOR_EACH_FIXED_ARG(func, dev, 4, 5, 6)
* FOR_EACH_FIXED_ARG(func, (;), dev, 4, 5, 6);
*
* will result in following code:
*
@ -1079,12 +1090,13 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
*
* @param F Macro takes nth variable argument as the first parameter and
* fixed argument as the second parameter.
* @param sep Separator (e.g. comma or semicolon). Must be in parentheses.
* @param fixed_arg Fixed argument forward to macro execution for each argument.
* @param ... Variable list of argument. For each argument macro F is executed.
*/
#define FOR_EACH_FIXED_ARG(F, fixed_arg, ...) \
#define FOR_EACH_FIXED_ARG(F, sep, fixed_arg, ...) \
Z_FOR_EACH_IDX2(NUM_VA_ARGS_LESS_1(__VA_ARGS__, _), \
0, Z_FOR_EACH_SWALLOW_INDEX, ;, \
0, Z_FOR_EACH_SWALLOW_INDEX, sep, \
F, fixed_arg, __VA_ARGS__)
/**@brief Implementation details for NUM_VAR_ARGS */
@ -1120,13 +1132,13 @@ uint8_t u8_to_dec(char *buf, uint8_t buflen, uint8_t value);
*
* @deprecated Use FOR_EACH instead.
*
* @param ... Macro name to be used for argument processing followed by
* arguments to process. Macro should have following
* form: MACRO(argument).
* @param F Macro name to be used for argument processing Macro should have
* following form: MACRO(argument).
* @param ... Arguments to process.
*
* @return All arguments processed by given macro
*/
#define MACRO_MAP(...) __DEPRECATED_MACRO FOR_EACH(__VA_ARGS__)
#define MACRO_MAP(F, ...) __DEPRECATED_MACRO FOR_EACH(F, (), __VA_ARGS__)
/**
* @brief Mapping macro that pastes results together

View file

@ -27,7 +27,7 @@
*/
/* prepare the memory partition structures */
FOR_EACH(K_APPMEM_PARTITION_DEFINE, part0, part1, part2, part3, part4);
FOR_EACH(K_APPMEM_PARTITION_DEFINE, (;), part0, part1, part2, part3, part4);
/* prepare the memory domain structures */
struct k_mem_domain dom0, dom1, dom2;
/* each variable starts with a name defined in main.h

View file

@ -41,7 +41,7 @@ K_SEM_DEFINE(expect_fault_sem, 0, 1);
* ztest and this test suite. part1 is for
* subsequent test specifically for this new implementation.
*/
FOR_EACH(K_APPMEM_PARTITION_DEFINE, part0, part1);
FOR_EACH(K_APPMEM_PARTITION_DEFINE, (;), part0, part1);
/*
* Create memory domains. dom0 is for the ztest and this

View file

@ -627,7 +627,7 @@ void test_poll_grant_access(void)
&no_wait_signal, &wait_sem, &wait_fifo,
&cancel_fifo, &non_cancel_fifo,
&wait_signal, &test_thread,
&test_stack, &multi_sem, &multi_reply)
&test_stack, &multi_sem, &multi_reply);
}
void test_poll_zero_events(void)

View file

@ -219,12 +219,12 @@ static void test_z_max_z_min(void)
static void test_FOR_EACH(void)
{
#define FOR_EACH_MACRO_TEST(arg) *buf++ = arg;
#define FOR_EACH_MACRO_TEST(arg) *buf++ = arg
uint8_t array[3] = {0};
uint8_t *buf = array;
FOR_EACH(FOR_EACH_MACRO_TEST, 1, 2, 3)
FOR_EACH(FOR_EACH_MACRO_TEST, (;), 1, 2, 3);
zassert_equal(array[0], 1, "Unexpected value %d", array[0]);
zassert_equal(array[1], 2, "Unexpected value %d", array[1]);
@ -240,25 +240,25 @@ static void test_FOR_EACH_FIXED_ARG(void)
{
uint32_t sum = 0;
FOR_EACH_FIXED_ARG(fsum, &sum, 1, 2, 3)
FOR_EACH_FIXED_ARG(fsum, (;), &sum, 1, 2, 3);
zassert_equal(sum, 6, "Unexpected value %d", sum);
}
static void test_FOR_EACH_IDX(void)
{
#define FOR_EACH_IDX_MACRO_TEST(n, arg) uint8_t a##n = arg;
#define FOR_EACH_IDX_MACRO_TEST(n, arg) uint8_t a##n = arg
FOR_EACH_IDX(FOR_EACH_IDX_MACRO_TEST, 1, 2, 3)
FOR_EACH_IDX(FOR_EACH_IDX_MACRO_TEST, (;), 1, 2, 3);
zassert_equal(a0, 1, "Unexpected value %d", a0);
zassert_equal(a1, 2, "Unexpected value %d", a1);
zassert_equal(a2, 3, "Unexpected value %d", a2);
#define FOR_EACH_IDX_MACRO_TEST2(n, arg) array[n] = arg;
#define FOR_EACH_IDX_MACRO_TEST2(n, arg) array[n] = arg
uint8_t array[32] = {0};
FOR_EACH_IDX(FOR_EACH_IDX_MACRO_TEST2, 1, 2, 3, 4, 5, 6, 7, 8,
FOR_EACH_IDX(FOR_EACH_IDX_MACRO_TEST2, (;), 1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15);
for (int i = 0; i < 15; i++) {
zassert_equal(array[i], i + 1,
@ -266,10 +266,10 @@ static void test_FOR_EACH_IDX(void)
}
zassert_equal(array[15], 0, "Unexpected value: %d", array[15]);
#define FOR_EACH_IDX_MACRO_TEST3(n, arg) &a##n,
#define FOR_EACH_IDX_MACRO_TEST3(n, arg) &a##n
uint8_t *a[] = {
FOR_EACH_IDX(FOR_EACH_IDX_MACRO_TEST3, 1, 2, 3)
FOR_EACH_IDX(FOR_EACH_IDX_MACRO_TEST3, (,), 1, 2, 3)
};
zassert_equal(ARRAY_SIZE(a), 3, "Unexpected value:%d", ARRAY_SIZE(a));
@ -279,9 +279,9 @@ static void test_FOR_EACH_IDX_FIXED_ARG(void)
{
#undef FOO
#define FOO(n, arg, fixed_arg) \
uint8_t fixed_arg##n = arg;
uint8_t fixed_arg##n = arg
FOR_EACH_IDX_FIXED_ARG(FOO, a, 1, 2, 3)
FOR_EACH_IDX_FIXED_ARG(FOO, (;), a, 1, 2, 3);
zassert_equal(a0, 1, "Unexpected value %d", a0);
zassert_equal(a1, 2, "Unexpected value %d", a1);
@ -307,13 +307,11 @@ static void test_LIST_DROP_EMPTY(void)
*/
#define TEST_BROKEN_LIST EMPTY, Henry, EMPTY, Dorsett, Case,
#define TEST_FIXED_LIST LIST_DROP_EMPTY(TEST_BROKEN_LIST)
#define TEST_MKSTR(a) #a,
static const char *const arr[] = {
FOR_EACH(TEST_MKSTR, TEST_FIXED_LIST)
FOR_EACH(STRINGIFY, (,), TEST_FIXED_LIST)
};
zassert_equal(sizeof(arr) / sizeof(char *), 3,
"Failed to cleanup list");
zassert_equal(ARRAY_SIZE(arr), 3, "Failed to cleanup list");
zassert_equal(strcmp(arr[0], "Henry"), 0, "Failed at 0");
zassert_equal(strcmp(arr[1], "Dorsett"), 0, "Failed at 1");
zassert_equal(strcmp(arr[2], "Case"), 0, "Failed at 0");