我正在开展一项关于extremely long and complicated functions in the Linux kernel的小型学术研究。我试图找出是否有充分的理由来编写600或800行长的函数。
为此,我想找到一个可以从.c文件中提取函数的工具,这样我就可以在函数上运行一些自动化测试。
例如,如果我在文件connect.c
中有函数cifs_parse_mount_options()
,我正在寻找一个大致类似的解决方案:
extract /fs/cifs/connect.c cifs_parse_mount_options
并返回函数的523行代码(!),从开括号到结束括号。
当然,任何操纵现有软件包(如gcc
)的方法都是最有帮助的。
谢谢,
乌迪
编辑: Regex to pull out C function prototype declarations?的答案使我确信正则表达式匹配的函数声明远非微不足道。
答案 0 :(得分:3)
为什么不编写一个小的PERL / PHP / Python脚本,甚至是一个小的C ++,Java或C#程序呢?
我不知道有任何已经制作的工具,但是编写代码来解析文本文件并从C ++代码文件中提取函数体不应该超过20行代码。 难以部分将定位函数的开头,这应该是使用RegEx的相对简单的任务。之后,您只需要遍历文件的其余部分,跟踪打开和关闭花括号,当您到达函数体关闭括号时,您就完成了。
答案 1 :(得分:1)
缩进-kr代码-o code.out
awk -f split.awk code.out
你必须适应一点split.awk,这有点特定于我的代码和重构需求(例如y有这样的struct不是typedef
我相信你可以制作一个更好的剧本: - )
--
BEGIN { line=0; FS="";
out=ARGV[ARGC-1] ".out";
var=ARGV[ARGC-1] ".var";
ext=ARGV[ARGC-1] ".ext";
def=ARGV[ARGC-1] ".def";
inc=ARGV[ARGC-1] ".inc";
typ=ARGV[ARGC-1] ".typ";
system ( rm " " -f " " out " " var " " ext " " def " " inc " " typ );
}
/^[ ]*\/\/.*/ { print "comment :" $0 "\n"; print $0 >> out ; next ;}
/^#define.*/ { print "define :" $0 ; print $0 >>def ; next;}
/^#include.*/ { print "define :" $0 ; print $0 >>inc ; next;}
/^typedef.*{$/ { print "typedef var :" $0 "\n"; decl="typedef";print $0 >> typ;infile="typ";next;}
/^extern.*$/ { print "extern :" $0 "\n"; print $0 >> ext;infile="ext";next;}
/^[^ }].*{$/ { print "init var :" $0 "\n";decl="var";print $0 >> var; infile="vars";
print $0;
fout=gensub("^([^ \\*])*[ ]*([a-zA-A0-9_]*)\\[.*","\\2","g") ".vars";
print "var decl : " $0 "in file " fout;
print $0 >fout;
next;
}
/^[^ }].*)$/ { print "func :" $0 "\n";decl="func"; infile="func";
print $0;
fout=gensub("^.*[ \\*]([a-zA-A0-9_]*)[ ]*\\(.*","\\1","g") ".func";
print "function : " $0 "in file " fout;
print $0 >fout;
next;
}
/^}[ ]*$/ { print "end of " decl ":" $0 "\n";
if(infile=="typ") {
print $0 >> typ;
}else if (infile=="ext"){
print $0 >> ext;
}else if (infile=="var") {
print $0 >> var;
}else if ((infile=="func")||(infile=="vars")) {
print $0 >> fout;
fflush (fout);
close (fout);
}else if (infile=="def") {
print $0 >> def;
}else if (infile=="inc"){
print $0 >> inc;
}else print $0 >> out;
next;
}
/^[a-zA-Z_]/ { print "extern :" $0 "\n"; print $0 >> var;infile="var";next;}
{ print "other :" $0 "\n" ;
if(infile=="typ") {
print $0 >> typ;
}else if (infile=="ext"){
print $0 >> ext;
}else if (infile=="var") {
print $0 >> var;
}else if ((infile=="func")||(infile=="vars")){
print $0 >> fout;
}else if (infile=="def") {
print $0 >> def;
}else if (infile=="inc"){
print $0 >> inc;
}else print $0 >> out;
next;
}
答案 2 :(得分:0)
如果您发现难以提取函数名称:
1>使用ctags(程序)来提取函数名称。 ctags -x --c-kinds = fp path_to_file。 2 - ;一旦你得到了函数名,就编写一个简单的perl脚本,通过传递上述函数的脚本名来提取函数的内容。