From 1b4b9386e5ad41ecacd2359ae7b5f106be0c6002 Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Fri, 8 May 2020 07:06:58 +0200 Subject: [PATCH] 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 --- include/app_memory/app_memdomain.h | 2 +- include/kernel.h | 2 +- include/logging/log_core.h | 4 +- include/sys/util.h | 60 +++++++++++-------- samples/userspace/shared_mem/src/main.c | 2 +- tests/kernel/mem_protect/userspace/src/main.c | 2 +- tests/kernel/poll/src/test_poll.c | 2 +- tests/unit/util/main.c | 28 ++++----- 8 files changed, 56 insertions(+), 46 deletions(-) diff --git a/include/app_memory/app_memdomain.h b/include/app_memory/app_memdomain.h index 40227d931ae..0b69359f363 100644 --- a/include/app_memory/app_memdomain.h +++ b/include/app_memory/app_memdomain.h @@ -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) diff --git a/include/kernel.h b/include/kernel.h index 0018d3663af..38f65eda548 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -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 diff --git a/include/logging/log_core.h b/include/logging/log_core.h index aa424ce6d71..7959b25ed7d 100644 --- a/include/logging/log_core.h +++ b/include/logging/log_core.h @@ -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 { \ diff --git a/include/sys/util.h b/include/sys/util.h index 8828c4d736b..797497981f1 100644 --- a/include/sys/util.h +++ b/include/sys/util.h @@ -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 diff --git a/samples/userspace/shared_mem/src/main.c b/samples/userspace/shared_mem/src/main.c index 24a91a65300..c4d1aea5d7e 100644 --- a/samples/userspace/shared_mem/src/main.c +++ b/samples/userspace/shared_mem/src/main.c @@ -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 diff --git a/tests/kernel/mem_protect/userspace/src/main.c b/tests/kernel/mem_protect/userspace/src/main.c index f2177d7ea0f..1e1cb11199f 100644 --- a/tests/kernel/mem_protect/userspace/src/main.c +++ b/tests/kernel/mem_protect/userspace/src/main.c @@ -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 diff --git a/tests/kernel/poll/src/test_poll.c b/tests/kernel/poll/src/test_poll.c index 1483c00ab81..880181a0cc3 100644 --- a/tests/kernel/poll/src/test_poll.c +++ b/tests/kernel/poll/src/test_poll.c @@ -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) diff --git a/tests/unit/util/main.c b/tests/unit/util/main.c index ba3f9a6f2b5..dc2c8af0161 100644 --- a/tests/unit/util/main.c +++ b/tests/unit/util/main.c @@ -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");