我的代码有很多复杂的#define错误代码,因为它们嵌套在几个层次上,因此不容易解码。
有没有优雅的方法可以获得#defines列表及其最终数值(或其他任何可能的值)?
举个例子:
<header1.h>
#define CREATE_ERROR_CODE(class, sc, code) ((class << 16) & (sc << 8) & code)
#define EMI_MAX 16
<header2.h>
#define MI_1 EMI_MAX
<header3.h>
#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或任何其他编译器的建议会有所帮助。
答案 0 :(得分:7)
海湾合作委员会-dM
preprocessor option可能会得到你想要的东西。
答案 1 :(得分:4)
我认为解决方案是@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方便,所以没有测试过这个......
答案 2 :(得分:2)
程序'coan'看起来像你正在使用的工具。它有'defs'子命令,描述如下:
defs [OPTION ...] [file ...] [directory ...]
根据选项从输入文件中选择
#define
和#undef
指令,并根据选项在标准输出上报告。
有关选项的更多信息,请参阅引用的URL。获取代码here。
答案 3 :(得分:1)
如果您有一个想要查看的宏的完整列表,并且都是数字的,那么您可以为此目的编译并运行一个简短的程序:
#include <header3.h>
#include <stdio.h>
#define SHOW(x) printf(#x " = %lld\n", (long long int) x)
int main(void) {
SHOW(ERROR_FOO);
/*...*/
return 0;
}
正如@nmichaels所提到的,gcc的-d
标志可能有助于获得要显示的宏列表。
答案 4 :(得分:1)
这是一个有点创意的解决方案:
编写一个程序,使所有标识符与正则表达式匹配(如.NET中的\#define :b+(?<NAME>[0-9_A-Za-z]+):b+(?<VALUE>[^(].+)$
),然后让它创建另一个只有匹配名称的C文件:
void main() {
/*my_define_1*/ my_define_1;
/*my_define_2*/ my_define_2;
//...
}
然后使用/ C / P选项(对于VC ++)预处理文件,您应该将所有这些替换为值。然后使用另一个正则表达式来交换周围的事物,并将评论放在#define
格式的值之前 - 现在你有了#define
的列表!
(你可以和GCC做类似的事情。)
答案 5 :(得分:0)
有没有优雅的方法可以获得#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 -x c ${CPPFLAGS} - | tail -n1;
done;
不是万无一失(#define \ \n macro(x) ...
不会被抓住 - 但我见过没有 的样式。