我有一个功能:
void srunner_free(SRunner *sr){
.......
}
我希望在原始函数体之前添加一些C代码,因此它变为:
void srunner_free(SRunner *sr){
//Some other random code, not necessary printfs, printf is just an example
printf("hello world");
.......
}
我该怎么做呢?我可以使用grep等工具吗?
感谢
答案 0 :(得分:1)
您应该可以使用coccinelle。这是一个专门修改源代码的工具。
使用以下测试输入非常快速地播放
$ cat test.c
int foo(int i)
{
return i+1;
}
void srunner_free(SRunner *sr)
{
int i;
foo(i);
return;
}
以及以下coccinelle脚本
$ cat test.cocci
@@
typedef SRunner;
statement S;
identifier sr;
@@
void srunner_free(SRunner *sr)
{
...
+ printf("hello world");
S
...
}
结果是
$ spatch -sp_file test.cocci test.c
init_defs_builtins: /usr/share/coccinelle/standard.h
HANDLING: test.c
diff =
--- test.c 2014-03-08 01:34:13.000000000 +0100
+++ /tmp/cocci-output-24589-dfa2db-test.c 2014-03-08 01:34:57.000000000 +0100
@@ -7,7 +7,9 @@ int foo(int i)
void srunner_free(SRunner *sr)
{
int i;
+ printf("hello world");
foo(i);
+ printf("hello world");
return;
}
$
这里的printf语句放在每个语句的前面,这不完全是你想要的,但结果并不是那么遥远。我不知道如何限制这个权利,但我认为我之前已经看过这个例子,所以它应该是可能的。
更新:我今天继续研究这个问题,修改内容相对容易 我最初建议完全是想要的解决方案。该脚本现在包含两个规则。
第一条规则只是一条匹配规则,不进行任何修改。它匹配两个相邻的语句,并将位置绑定到最后一个。所以这个规则将绑定一个 除了第一个语句之外,它位于函数内的所有语句中。
第二个规则然后通过排除rule1中某个位置绑定的任何语句,在第一个语句前插入printf语句(或其他)。
@rule1@
typedef SRunner;
statement S1, S2;
identifier sr;
position p;
@@
void srunner_free(SRunner *sr)
{
...
S1
S2@p
...
}
// typedefs are actually global, so no need to repeat
// (and doing so would in fact generate an error)
@rule2@
statement S;
identifier sr;
position p != rule1.p;
@@
void srunner_free(SRunner *sr)
{
...
+ printf("hello world");
S@p
...
}
答案 1 :(得分:0)
如果你想在每个函数或大量函数上正确地执行此操作,并且想要正确地执行此操作,则需要更改编译器或构建词法分析器(使用,例如{{1} })使用与C相同的规则,并输出额外的行。
如果你想为一些函数提供它,并为“无宏,普通格式化等”等标准做好准备,请使用脚本语言,如lex
和正则表达式。然而,这总是一个躲闪。