如何从C代码生成#define值列表?
我的代码有很多复杂的#define错误代码,这些代码不容易解码,因为它们嵌套在几个级别。
有没有优雅的方法我可以获得#defines列表及其最终数值(或者他们可能是什么)?
举个例子:
#define CREATE_ERROR_CODE(class, sc, code) ((class << 16) & (sc << 8) & code) #define EMI_MAX 16 #define MI_1 EMI_MAX #define MODULE_ERROR_CLASS MI_1 #define MODULE_ERROR_SUBCLASS 1 #define ERROR_FOO CREATE_ERROR_CODE(MODULE_ERROR_CLASS, MODULE_ERROR_SUBCLASS, 1)
我会有大量类似的#defines匹配ERROR _ [\ _ W _] +,我想枚举,以便我总是有一个程序可以输出的错误代码的当前列表。 我需要数值,因为这是所有程序将打印出来的(不,它不是打印出字符串的选项)。
对gcc或任何其他编译器的建议会有所帮助。
我认为解决方案是@nmichaels和@aschepler的答案的组合。
使用gcc的-dM选项获取宏列表。 使用perl或awk或其他任何方法从此列表中创建2个文件:
1)Macros.h,只包含#defines。
2)Codes.c,其中包含
#include "Macros.h" ERROR_FOO = "ERROR_FOO" ERROR_BAR = "ERROR_BAR"
(即:将每个#define ERROR_x
提取到一个包含宏和字符串的行中。
现在运行gcc -E Codes.c
。 这应该创建一个扩展了所有宏的文件。 输出应该看起来像
1 = "ERROR_FOO" 2 = "ERROR_BAR"
我没有gcc方便,所以没有测试过这个……
GCC的-dM
预处理器选项可以为您提供所需的function。
程序’coan’看起来像你正在使用的工具。 它有’defs’子命令,描述如下:
defs [OPTION …] [file …] [目录…]
根据选项从输入文件中选择
#define
和#undef
指令,并根据选项在标准输出上报告它们。
有关这些选项的更多信息,请参阅引用的URL。 在这里获取代码。
如果您有一个想要查看的宏的完整列表,并且都是数字的,那么您可以为此目的编译并运行一个简短的程序:
#include #include #define SHOW(x) printf(#x " = %lld\n", (long long int) x) int main(void) { SHOW(ERROR_FOO); /*...*/ return 0; }
正如@nmichaels所提到的,gcc的-d
标志可能有助于获得要显示的宏列表。
这是一个有点创意的解决方案:
编写一个程序,将所有标识符与正则表达式匹配(如\#define :b+(?
in .NET),然后让它创建另一个只有匹配名称的C文件:
void main() { /*my_define_1*/ my_define_1; /*my_define_2*/ my_define_2; //... }
然后使用/ C / P选项(对于VC ++)预处理文件,并且应该将所有这些替换为值。 然后使用另一个正则表达式来交换周围的东西,并将注释放在#define
格式的值之前 – 现在你有了#define
的列表!
(你可以用GCC做类似的事情。)
有没有任何优雅的方式我可以获得#defines列表及其最终数值
对于各种级别的优雅,有点。
#!/bin/bash file="mount.c"; for macro in $(grep -Po '(?<=#define)\s+(\S+)' "$file"); do echo -en "$macro: "; echo -en '#include "'"$file"'"\n'"$macro\n" | \ cpp -E -P -xc ${CPPFLAGS} - | tail -n1; done;
不是万无一失( #define \ \n macro(x) ...
不会被抓住 - 但我见过的风格没有这样做 )。