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