如何在用sed或awk预处理C/C++代码时可靠地定位函数

how to target reliably functions when pre-processing C/C++ code with sed or awk?

本文关键字:代码 C++ 函数 定位 sed 预处理 awk      更新时间:2023-10-16

我想通过使用sed/awk预处理源文件来直接插入我的代码。我不能使用其他方法,如调试器跟踪或gcc选项-finstrument-functions。在最后一种情况下,地址以某种我无法管理的方式重新设置,并且我错过了与符号表的对应关系。这里介绍的其他方法(ptrace、etrace、callgraph等)或这里介绍的方法在一个简单的例子中效果很好,但在我的真实项目中却没有。

问题是,在处理大型开源项目时,函数的编写标准不同,不仅在C和C++文件之间,而且通常在同一个文件中。{可能在参数列表的末尾,或者在另一行,结构或赋值可能使用起始{,使得简单函数解析为false。

因此,上述链接中提出的在函数定义的开头插入宏的解决方案通常不起作用,而且用千行代码(KLOC)进行纠正是不可行的。

sed 's/^{/{ENTRY/'

那么,如何用sed或awk中可用的正则表达式可靠地针对C/C++代码中的函数定义呢?可能是通过使用gcc预编译器代码的一部分?我正在找一些可能是现成的东西。

sedawk(或任何纯文本方法)是可靠处理C代码的错误工具(您可能应该处理预处理的表单)。

您想要处理某种形式的编译器的AST。当然,编译器内部的内部表示是特定于编译器的(甚至可能是特定于它的版本)。

如果使用最近的GCC,您可以使用MELT进行自定义(并将您的通行证添加到GCC),或者使用C++中自己的插件。

如果使用Clang/LLVM,您也可以通过添加通行证进行自定义。

Coccinelle工具也可能是相关的。

任何这样的方法都需要大量的工作(可能需要数周),因为您需要详细了解正在使用的特定编译器的内部表示。C足够复杂,可以使它变得不平凡。

您不能使用任何不了解代码所用C的特定版本的工具(例如C++、ANSI-C或C-99)来执行此操作。作为一个琐碎的例子,"//"在"C函数"中是什么意思?如果它在一个字符串中,它是一对斜杠,如果它在字符串之外,如果代码是C++或C-99,它可能是注释的开始,但它不是ANSI-C中注释的开始。如果它在/* ... // ... */里面呢?如果一个函数定义后面跟着一个"//",那真的是一个函数吗?

你没有说你想做什么("预处理代码"并不能告诉我们任何事情),但你应该考虑使用我在Remove multi-line comments上发布的东西,使用gcc来去除代码中的注释,然后使用C美化器,如"indent"或"cb"来一致地重新格式化代码,和/或如果你只是在寻找列出函数的工具,请查看"cscope"或"ccalls"。