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