1a66805b1SJerome Forissier /* SPDX-License-Identifier: Apache-2.0 */ 2a66805b1SJerome Forissier /* 3a66805b1SJerome Forissier * Copyright (c) 2017 Intel Corporation 4a66805b1SJerome Forissier * 5a66805b1SJerome Forissier */ 6a66805b1SJerome Forissier #ifndef __CONFIG_H_ 7a66805b1SJerome Forissier #define __CONFIG_H_ 8a66805b1SJerome Forissier 9a66805b1SJerome Forissier /** 10a66805b1SJerome Forissier * @brief Check for macro definition in compiler-visible expressions 11a66805b1SJerome Forissier * 12a66805b1SJerome Forissier * This trick was pioneered in Linux as the config_enabled() macro. 13a66805b1SJerome Forissier * The madness has the effect of taking a macro value that may be 14a66805b1SJerome Forissier * defined to "1" (e.g. CONFIG_MYFEATURE), or may not be defined at 15a66805b1SJerome Forissier * all and turning it into a literal expression that can be used at 16a66805b1SJerome Forissier * "runtime". That is, it works similarly to 17a66805b1SJerome Forissier * "defined(CONFIG_MYFEATURE)" does except that it is an expansion 18a66805b1SJerome Forissier * that can exist in a standard expression and be seen by the compiler 19a66805b1SJerome Forissier * and optimizer. Thus much ifdef usage can be replaced with cleaner 20a66805b1SJerome Forissier * expressions like: 21a66805b1SJerome Forissier * 22a66805b1SJerome Forissier * if (IS_ENABLED(CONFIG_MYFEATURE)) 23a66805b1SJerome Forissier * myfeature_enable(); 24a66805b1SJerome Forissier * 25a66805b1SJerome Forissier * INTERNAL 26a66805b1SJerome Forissier * First pass just to expand any existing macros, we need the macro 27a66805b1SJerome Forissier * value to be e.g. a literal "1" at expansion time in the next macro, 28a66805b1SJerome Forissier * not "(1)", etc... Standard recursive expansion does not work. 29a66805b1SJerome Forissier */ 30a66805b1SJerome Forissier #define IS_ENABLED(config_macro) Z_IS_ENABLED1(config_macro) 31a66805b1SJerome Forissier 32*d1a015feSEtienne Carriere /** 33*d1a015feSEtienne Carriere * @brief As IS_ENABLED() but to be used with _CFG_* internal switches 34*d1a015feSEtienne Carriere * to avoid triggering false positives with checkpatch. 35*d1a015feSEtienne Carriere */ 36*d1a015feSEtienne Carriere #define IS_ENABLED2(config_macro) IS_ENABLED(config_macro) 37*d1a015feSEtienne Carriere 38a66805b1SJerome Forissier /* Now stick on a "_XXXX" prefix, it will now be "_XXXX1" if config_macro 39a66805b1SJerome Forissier * is "1", or just "_XXXX" if it's undefined. 40a66805b1SJerome Forissier * ENABLED: Z_IS_ENABLED2(_XXXX1) 41a66805b1SJerome Forissier * DISABLED Z_IS_ENABLED2(_XXXX) 42a66805b1SJerome Forissier */ 43a66805b1SJerome Forissier #define Z_IS_ENABLED1(config_macro) Z_IS_ENABLED2(_XXXX##config_macro) 44a66805b1SJerome Forissier 45a66805b1SJerome Forissier /* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string 46a66805b1SJerome Forissier * with a trailing comma), so it has the effect of making this a 47a66805b1SJerome Forissier * two-argument tuple to the preprocessor only in the case where the 48a66805b1SJerome Forissier * value is defined to "1" 49a66805b1SJerome Forissier * ENABLED: _YYYY, <--- note comma! 50a66805b1SJerome Forissier * DISABLED: _XXXX 51a66805b1SJerome Forissier */ 52a66805b1SJerome Forissier #define _XXXX1 _YYYY, 53a66805b1SJerome Forissier 54a66805b1SJerome Forissier /* Then we append an extra argument to fool the gcc preprocessor into 55a66805b1SJerome Forissier * accepting it as a varargs macro. 56a66805b1SJerome Forissier * arg1 arg2 arg3 57a66805b1SJerome Forissier * ENABLED: Z_IS_ENABLED3(_YYYY, 1, 0) 58a66805b1SJerome Forissier * DISABLED Z_IS_ENABLED3(_XXXX 1, 0) 59a66805b1SJerome Forissier */ 60a66805b1SJerome Forissier #define Z_IS_ENABLED2(one_or_two_args) \ 61a66805b1SJerome Forissier Z_IS_ENABLED3(one_or_two_args true, false) 62a66805b1SJerome Forissier 63a66805b1SJerome Forissier /* And our second argument is thus now cooked to be 1 in the case 64a66805b1SJerome Forissier * where the value is defined to 1, and 0 if not: 65a66805b1SJerome Forissier */ 66a66805b1SJerome Forissier #define Z_IS_ENABLED3(ignore_this, val, ...) val 67a66805b1SJerome Forissier 68a66805b1SJerome Forissier #endif // __CONFIG_H_ 69