我在C(Linux OS)中编程。我必须读取一个文件,检查该文件中的函数并打印相应的函数名称。到目前为止,我已经编程使用'{'的深度计算来识别函数。我知道__FUNCTION__
预处理程序指令用于打印当前文件的函数名称。同样,是否有任何预处理器指令用于查找我们读取的文件的函数名称?我不关心任何具体的工具。我想让它编程。请指导我。提前谢谢。
我试图实现这个代码。这个函数将行(在'{'之前)作为参数。
void ffname(char line[100])
{
int i,j,m,n,f=0;
char dt[10],fname[28];
char s[5][10]={"int","void","struct","char","float"};
dt = strtok(line," ");
for(i=0;i<5;i++)
{
m=strcmp(dt,s[i]);
if(m==0)
{
f=1;
n=strlen(dt);
}
}
if(f)
{
for(i=n+2,j=0;i<strlen(line);i++,j++)
{
if(line[i] == '*')
i++;
while(line[i] != '(')
{
fname[j]=line[i];
}
}
}
}
我不知道这段代码是否正确。我应该用这种方式吗?有没有找到功能名称的选项?
答案 0 :(得分:3)
我假设您正在阅读的文件是C源文件。
如果您想要正确地执行此操作(这意味着,如果您可靠地想要识别所有功能),这不是一项微不足道的任务。有关其他信息,请参阅Listing C/C++ functions (Code analysis in Unix)。
我并不关心任何特定的工具。我想让它编程。
这当然是可能的,但基本上你最终会得到C的扫描器/解析器前端,类似于Doxygen或Synopsis等工具中已实现的内容。您可以稍微简化它并使用一些启发式方法,例如,您不需要解析完整的代码(例如,您可以跳过{
和}
之间的任何内容。
如果您仍想实施自己的方法,我会按照以下步骤操作:
(6.9.1) function-definition
是你应该开始的生产术语。答案 1 :(得分:2)
我使用Simple C代码来查找函数的名称。
#include <stdio.h>
#include <string.h>
#define SIZE 1024
void ffname(char *line)
{
int i=1,j=0;
char *dt;
char name[SIZE];
strtok(line,"(");
dt = strchr(line,' ');
if(dt[i] == '*')
i++;
while(dt[i] != '\0')
{
name[j]=dt[i];
i++;
j++;
}
name[j] ='\0';
printf("Function name is: %s\n", name);
}
int main(int argc, char **argv)
{
if(argc < 2)
{
printf("Give the filename \n");
printf("Usage: %s filename\n", argv[0]);
return -1;
}
int i, lines =0, funlines =0,count =0, fn =0, flag =0;
char c[SIZE],b[SIZE];
FILE *fd;
fd = fopen(argv[1],"r");
while(fgets(c,SIZE,fd))
{
lines++;
i=0;
for(i=0;i<strlen(c);i++)
{
while( c[i] =='\t' || c[i] == ' ')
{
i++;
}
if( c[i] == '{')
{
count++;
if(flag)
{
funlines++;
}
if(count == 1)
{
fn++;
printf("Function %d is Started..............\n", fn);
flag = 1;
ffname(b);
}
break;
}
else if( c[i] == '}')
{
count--;
if(!count)
{
flag = 0;
printf("No of lines in the function %d is: %d\n", fn, funlines);
printf("Function %d is finished..........\n", fn);
funlines = 0;
}
else
{
funlines++;
}
break;
}
else if(flag)
{
funlines++;
break;
}
}
strcpy(b,c);
}
printf("Total no of function%d\n",fn);
printf("Total no of lines%d\n",lines);
return 0;
}
答案 2 :(得分:1)
这很难正确完成。基本上,您需要实现一个c编译器来正确执行此操作。这正是c编译器所做的,并且需要一个正确的语法定义和预处理器来执行此操作。
答案 3 :(得分:1)
为C编写解析器很困难(并非不可能,很难),因为C支持如此多的语法。
您可以使用
定义一个功能gcc -S
以了解语法)我已经使用这个方法创建了一些占位符函数。因此,您可以更轻松地解析汇编文件,而不是解析C文件。
E.g。 gcc -S
转换C函数定义如下:
.globl someFnName
.type someFnName, @function
someFnName:
...function-body related code...
如果你只需要函数名列表(即不需要参数/返回值等),你可以轻松解析汇编中的上述3行代码,与C文件相比。
如果您还添加了-g
切换以及-s
,那么您还可以获得一些行号信息。
优点:
.globl someFnName
”行是否存在,您可以隔离静态函数。缺点:
答案 4 :(得分:1)
我认为flex
和bison
会帮助您解决问题,以下是一些链接:c grammar(lex),c grammar(bison)
答案 5 :(得分:1)
简单的方法,如果你愿意做一些假设,请阅读源代码,然后:
删除所有的prerosessor指令(假设您不想要包含文件的函数,并且不想处理可能与函数相关的任何不稳定的#define
宏,请注意多行#define
s继续\
在行尾。)
删除所有评论(请注意嵌套/*
评论)。
将所有字符串转换为""
(请注意转义\"
和多行字符串)。
将任何字符转换为' '
或其他内容(以摆脱'{'
等,请注意转义\'
以及其他转义符。
将所有(嵌套,多行)代码块转换为“顶级”{}
对。
重新格式化文字,仅在;
和}
之后设置换行符,除非在前一行的行中加入单独的;
,以防它实际上属于{ {1}}不是函数定义。
删除以};
除非我遗漏了某些内容,否则现在应该留下所有函数定义,每行一个,函数体替换为;
。
答案 6 :(得分:0)
我想你可以试试 正则表达式,用于查找目标函数名称是否存在。
您可以在这篇文章中找到有关正则表达式的更多信息。 Regular expressions in C: examples?
答案 7 :(得分:0)
你读过什么样的文件?它是一些任意的C源文件吗?如果是,它可以以许多不同的方式定义功能,例如,通过预处理器宏。例如
#define DF(Nam) void Nam##print(void) {puts(#Nam);}
一个C文件可能有DF(foo)
并定义了函数fooprint
(源代码中没有出现fooprint
)。
如果要处理编译器看到的函数名称集,可以更好地开发编译器扩展或插件。使用GCC,您可以使用MELT(特定于域的语言来扩展GCC)。
如果要查找某个目标文件*.o
定义的[global]函数,可以在Linux上使用nm
命令。也许还要考虑dlopen(3) - 共享对象文件*.so
当然,所有这些都可能是编译器和系统特定的。
答案 8 :(得分:0)
如果你可以使用gcc:
gcc -nostdinc -aux-info output demo.c
仅输出文件函数(不包括标准库)
注意:-nostdinc导致编译错误
您可以使用sed
来避免编译错误gcc -aux-info output demo.c
sed '/include/d' output