如何从 C 代码生成 #define 值列表?

发布于 2024-10-09 22:28:45 字数 631 浏览 4 评论 0原文

我的代码有很多复杂的 #define 错误代码,这些错误代码不容易解码,因为它们嵌套在多个级别中。

有没有什么优雅的方法可以让我获得 #define 列表及其最终数值(或其他任何值)?

举个例子:

<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 或任何其他编译器的建议会很有帮助。

I have code that has a lot of complicated #define error codes that are not easy to decode since they are nested through several levels.

Is there any elegant way I can get a list of #defines with their final numerical values (or whatever else they may be)?

As an example:

<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)

I would have a large number of similar #defines matching ERROR_[\w_]+ that I'd like to enumerate so that I always have a current list of error codes that the program can output. I need the numerical value because that's all the program will print out (and no, it's not an option to print out a string instead).

Suggestions for gcc or any other compiler would be helpful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

安静被遗忘 2024-10-16 22:28:45

GCC 的 -dM 预处理器选项 可能会帮助您你想要什么。

GCC's -dM preprocessor option might get you what you want.

够钟 2024-10-16 22:28:45

我认为解决方案是@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,所以还没有测试过这个...

I think the solution is a combo of @nmichaels and @aschepler's answers.

Use gcc's -dM option to get a list of the macros.
Use perl or awk or whatever to create 2 files from this list:

1) Macros.h, containing just the #defines.

2) Codes.c, which contains

#include "Macros.h"

ERROR_FOO = "ERROR_FOO"
ERROR_BAR = "ERROR_BAR"

(i.e: extract each #define ERROR_x into a line with the macro and a string.

now run gcc -E Codes.c. That should create a file with all the macros expanded. The output should look something like

1 = "ERROR_FOO"
2 = "ERROR_BAR"

I don't have gcc handy, so haven't tested this...

野却迷人 2024-10-16 22:28:45

该程序 'coan' 看起来像是您正在寻找的工具。它有“defs”子命令,描述为:

defs [选项...] [文件...] [目录...]

根据选项从输入文件中选择#define#undef指令,并根据选项在标准输出上报告它们。

有关选项的更多信息,请参阅引用的 URL。在此处获取代码。

The program 'coan' looks like the tool you are after. It has the 'defs' sub-command, which is described as:

defs [OPTION...] [file...] [directory...]

Select #define and #undef directives from the input files in accordance with the options and report them on the standard output in accordance with the options.

See the cited URL for more information about the options. Obtain the code here.

樱桃奶球 2024-10-16 22:28:45

如果您有想要查看的宏的完整列表,并且全部都是数字,您可以为此目的编译并运行一个简短的程序:

#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 标志可能会有所帮助获取要显示的宏列表。

If you have a complete list of the macros you want to see, and all are numeric, you can compile and run a short program just for this purpose:

#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;
}

As @nmichaels mentioned, gcc's -d flags may help get that list of macros to show.

不寐倦长更 2024-10-16 22:28:45

这是一个有点创意的解决方案:

编写一个程序,将所有标识符与正则表达式匹配(例如 \#define :b+(?[0-9_A-Za-z]+):b+(?[^(].+)$ in .NET),然后让它创建另一个名称匹配的 C 文件:

void main() {
    /*my_define_1*/ my_define_1;
    /*my_define_2*/ my_define_2;
    //...
}

然后使用 /C /P 选项预处理文件(对于 VC++ ),然后您应该将所有这些替换为值,然后使用另一个正则表达式来交换内容,并将注释放在 #define 格式的值之前 - 现在您有了 < 列表。 code>#define's!

(您可以使用 GCC 执行类似的操作。)

Here's a little creative solution:

Write a program to match all of your identifiers with a regular expression (like \#define :b+(?<NAME>[0-9_A-Za-z]+):b+(?<VALUE>[^(].+)$ in .NET), then have it create another C file with just the names matched:

void main() {
    /*my_define_1*/ my_define_1;
    /*my_define_2*/ my_define_2;
    //...
}

Then pre-process your file using the /C /P option (for VC++), and you should get all of those replaced with the values. Then use another regex to swap things around, and put the comments before the values in #define format -- now you have the list of #define's!

(You can do something similar with GCC.)

难得心□动 2024-10-16 22:28:45

有什么优雅的方式可以获取 #define 及其最终数值的列表

,以适应不同级别的优雅。

#!/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) ... 不会被捕获 - 但我见过的任何样式都不会这样做)。

Is there any elegant way I can get a list of #defines with their final numerical values

For various levels of elegance, sort of.

#!/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;

Not foolproof (#define \ \n macro(x) ... would not be caught - but no style I've seen does that).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文