LCOV - code coverage report
Current view: top level - zephyr/sys - util_internal.h Coverage Total Hit
Test: new.info Lines: 3.0 % 33 1
Test Date: 2025-09-05 16:43:28

            Line data    Source code
       1            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 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 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            0 : #define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__)
     105            0 : #define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
     106            0 : #define UTIL_CHECK_N(x, n, ...) n
     107            0 : #define UTIL_CHECK(...) UTIL_CHECK_N(__VA_ARGS__, 0,)
     108            0 : #define UTIL_NOT(x) UTIL_CHECK(UTIL_PRIMITIVE_CAT(UTIL_NOT_, x))
     109            0 : #define UTIL_NOT_0 ~, 1,
     110            0 : #define UTIL_COMPL(b) UTIL_PRIMITIVE_CAT(UTIL_COMPL_, b)
     111            0 : #define UTIL_COMPL_0 1
     112            0 : #define UTIL_COMPL_1 0
     113            0 : #define UTIL_BOOL(x) UTIL_COMPL(UTIL_NOT(x))
     114              : 
     115            0 : #define UTIL_EVAL(...) __VA_ARGS__
     116            0 : #define UTIL_EXPAND(...) __VA_ARGS__
     117            0 : #define UTIL_REPEAT(...) UTIL_LISTIFY(__VA_ARGS__)
     118              : 
     119              : #define _CONCAT_0(arg, ...) arg
     120              : #define _CONCAT_1(arg, ...) UTIL_CAT(arg, _CONCAT_0(__VA_ARGS__))
     121              : #define _CONCAT_2(arg, ...) UTIL_CAT(arg, _CONCAT_1(__VA_ARGS__))
     122              : #define _CONCAT_3(arg, ...) UTIL_CAT(arg, _CONCAT_2(__VA_ARGS__))
     123              : #define _CONCAT_4(arg, ...) UTIL_CAT(arg, _CONCAT_3(__VA_ARGS__))
     124              : #define _CONCAT_5(arg, ...) UTIL_CAT(arg, _CONCAT_4(__VA_ARGS__))
     125              : #define _CONCAT_6(arg, ...) UTIL_CAT(arg, _CONCAT_5(__VA_ARGS__))
     126              : #define _CONCAT_7(arg, ...) UTIL_CAT(arg, _CONCAT_6(__VA_ARGS__))
     127              : 
     128              : /* Implementation details for NUM_VA_ARGS_LESS_1 */
     129              : #define NUM_VA_ARGS_LESS_1_IMPL(                                \
     130              :         _ignored,                                               \
     131              :         _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10,            \
     132              :         _11, _12, _13, _14, _15, _16, _17, _18, _19, _20,       \
     133              :         _21, _22, _23, _24, _25, _26, _27, _28, _29, _30,       \
     134              :         _31, _32, _33, _34, _35, _36, _37, _38, _39, _40,       \
     135              :         _41, _42, _43, _44, _45, _46, _47, _48, _49, _50,       \
     136              :         _51, _52, _53, _54, _55, _56, _57, _58, _59, _60,       \
     137            0 :         _61, _62, N, ...) N
     138              : 
     139              : /* Used by MACRO_MAP_CAT */
     140            0 : #define MACRO_MAP_CAT_(...)                                             \
     141              :         /* To make sure it works also for 2 arguments in total */       \
     142              :         MACRO_MAP_CAT_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__)
     143            0 : #define MACRO_MAP_CAT_N_(N, ...) UTIL_CAT(MACRO_MC_, N)(__VA_ARGS__,)
     144            0 : #define MACRO_MC_0(...)
     145            0 : #define MACRO_MC_1(m, a, ...)  m(a)
     146            0 : #define MACRO_MC_2(m, a, ...)  UTIL_CAT(m(a), MACRO_MC_1(m, __VA_ARGS__,))
     147            0 : #define MACRO_MC_3(m, a, ...)  UTIL_CAT(m(a), MACRO_MC_2(m, __VA_ARGS__,))
     148            0 : #define MACRO_MC_4(m, a, ...)  UTIL_CAT(m(a), MACRO_MC_3(m, __VA_ARGS__,))
     149            0 : #define MACRO_MC_5(m, a, ...)  UTIL_CAT(m(a), MACRO_MC_4(m, __VA_ARGS__,))
     150            0 : #define MACRO_MC_6(m, a, ...)  UTIL_CAT(m(a), MACRO_MC_5(m, __VA_ARGS__,))
     151            0 : #define MACRO_MC_7(m, a, ...)  UTIL_CAT(m(a), MACRO_MC_6(m, __VA_ARGS__,))
     152            0 : #define MACRO_MC_8(m, a, ...)  UTIL_CAT(m(a), MACRO_MC_7(m, __VA_ARGS__,))
     153            0 : #define MACRO_MC_9(m, a, ...)  UTIL_CAT(m(a), MACRO_MC_8(m, __VA_ARGS__,))
     154            0 : #define MACRO_MC_10(m, a, ...) UTIL_CAT(m(a), MACRO_MC_9(m, __VA_ARGS__,))
     155            0 : #define MACRO_MC_11(m, a, ...) UTIL_CAT(m(a), MACRO_MC_10(m, __VA_ARGS__,))
     156            0 : #define MACRO_MC_12(m, a, ...) UTIL_CAT(m(a), MACRO_MC_11(m, __VA_ARGS__,))
     157            0 : #define MACRO_MC_13(m, a, ...) UTIL_CAT(m(a), MACRO_MC_12(m, __VA_ARGS__,))
     158            0 : #define MACRO_MC_14(m, a, ...) UTIL_CAT(m(a), MACRO_MC_13(m, __VA_ARGS__,))
     159            0 : #define MACRO_MC_15(m, a, ...) UTIL_CAT(m(a), MACRO_MC_14(m, __VA_ARGS__,))
     160              : 
     161              : /* Used by Z_IS_EQ */
     162              : #include "util_internal_is_eq.h"
     163              : 
     164              : /*
     165              :  * Generic sparse list of odd numbers (check the implementation of
     166              :  * GPIO_DT_RESERVED_RANGES_NGPIOS as a usage example)
     167              :  */
     168              : #define Z_SPARSE_LIST_ODD_NUMBERS               \
     169              :         EMPTY,  1, EMPTY,  3, EMPTY,  5, EMPTY,  7, \
     170              :         EMPTY,  9, EMPTY, 11, EMPTY, 13, EMPTY, 15, \
     171              :         EMPTY, 17, EMPTY, 19, EMPTY, 21, EMPTY, 23, \
     172              :         EMPTY, 25, EMPTY, 27, EMPTY, 29, EMPTY, 31, \
     173              :         EMPTY, 33, EMPTY, 35, EMPTY, 37, EMPTY, 39, \
     174              :         EMPTY, 41, EMPTY, 43, EMPTY, 45, EMPTY, 47, \
     175              :         EMPTY, 49, EMPTY, 51, EMPTY, 53, EMPTY, 55, \
     176              :         EMPTY, 57, EMPTY, 59, EMPTY, 61, EMPTY, 63
     177              : 
     178              : /*
     179              :  * Generic sparse list of even numbers (check the implementation of
     180              :  * GPIO_DT_RESERVED_RANGES_NGPIOS as a usage example)
     181              :  */
     182              : #define Z_SPARSE_LIST_EVEN_NUMBERS              \
     183              :          0, EMPTY,  2, EMPTY,  4, EMPTY,  6, EMPTY, \
     184              :          8, EMPTY, 10, EMPTY, 12, EMPTY, 14, EMPTY, \
     185              :         16, EMPTY, 18, EMPTY, 20, EMPTY, 22, EMPTY, \
     186              :         24, EMPTY, 26, EMPTY, 28, EMPTY, 30, EMPTY, \
     187              :         32, EMPTY, 34, EMPTY, 36, EMPTY, 38, EMPTY, \
     188              :         40, EMPTY, 42, EMPTY, 44, EMPTY, 46, EMPTY, \
     189              :         48, EMPTY, 50, EMPTY, 52, EMPTY, 54, EMPTY, \
     190              :         56, EMPTY, 58, EMPTY, 60, EMPTY, 62, EMPTY
     191              : 
     192              : /* Used by UTIL_INC */
     193              : #include "util_internal_util_inc.h"
     194              : 
     195              : /* Used by UTIL_DEC */
     196              : #include "util_internal_util_dec.h"
     197              : 
     198              : /* Used by UTIL_X2 */
     199              : #include "util_internal_util_x2.h"
     200              : 
     201              : #endif /* ZEPHYR_INCLUDE_SYS_UTIL_INTERNAL_H_ */
        

Generated by: LCOV version 2.0-1