LCOV - code coverage report
Current view: top level - zephyr/sys - util_internal.h Hit Total Coverage
Test: new.info Lines: 1 33 3.0 %
Date: 2024-12-22 00:14:23

          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 1.14