提取C/C++函数原型

28

我想要做到这个:

extract_prototypes file1.c file2.cpp file3.c

我希望有一个脚本/程序可以打印给定C/C++文件中定义的所有函数原型的清单,它必须能够很好地处理多行声明。

是否有可以完成此工作的程序? 越简单越好。

编辑:尝试编译两个C程序后,最好使用{perl、python、ruby}之一的东西来实现。

11个回答

39
我使用ctags
# p = function declaration, f = function definition
ctags -x --c-kinds=fp /usr/include/hal/libhal.h

同样适用于C++。

ctags -x --c++-kinds=pf --language-force=c++ /usr/include/c++/4.4.1/bits/deque.tcc
请注意,您可能需要添加包含路径,可以使用 -I /path/to/includes 来完成此操作。

很遗憾,您需要过滤结果。否则它本来会完美无缺的。结果以...的形式呈现。 - rxantos
当我尝试使用这个时,我收到了错误信息:“ctags: 无法识别选项 '--c-kinds=fp'”。我正在Windows上使用ctags.exe。您有任何想法为什么会出现这个错误吗? - mashrur
1
只有在声明没有分散到多行的情况下才能正常工作,至少对于Exuberant Ctags 5.8而言。 - mondaugen

15

工具cproto可以满足您的需求,并且允许调整输出以适应您的要求。

注意:此工具仅适用于C文件。


哎呀,今晚编译东西好像有些麻烦(在Mac上)。不过看起来还不错... - Peter
2
不是独立的工具。它需要安装gcc(在Windows上尝试过)。 - rxantos
1
请注意,由于gcc处理缺少头文件的方式发生了变化,因此cproto在gcc 4.5或更高版本上不再能正常工作。(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55115) - Haydentech

4

我使用ctagsjq

ctags --output-format=json --totals=no --extras=-F --fields=nP file1.c |
jq -sr 'sort_by(.line) | .[].pattern | ltrimstr("/^") | rtrimstr("$/") | . + ";"'

3
如果您安装了universal-ctags (https://ctags.io),--_xformat选项可能会很有用,不过需要使用sed和tr命令才能获得所需内容。
$ cat input.c 
struct object *new_object (struct
                           /* COMMENT */
                           param
                           /* IGNORE ME */
                           *p)
{
    return NULL;
}
int main (void)
{
    return 0;
}
$ ./ctags -o - --kinds-C=f --kinds-C++=f -x --_xformat='%{typeref} %{name} %{signature};' input.c | tr ':' ' ' | sed -e 's/^typename //'
struct object * new_object (struct param * p);
int main (void);
$

这类似于Steve Ward发布的答案,但这个需要使用sed和tr而不是jq。

2

如果有用的话,这里是一条稍微有点用处的信息... http://pastie.org/655762 - Peter
谢谢。我已经修复了那个 bug,并上传了一个新版本到 Sourceforge。我在使用 Sourceforge 的管理界面时遇到了一些问题,所以我不确定它是否会成为默认的下载。不过文件应该都在那里。 - user181548
新版本似乎已经在sourceforge上发布了。如果你有时间和耐心再次尝试,请告诉我是否发现了更多问题。Google群组链接为http://groups.google.com/group/cfunctions。 - user181548
非常不幸,我仍然无法在C++中使其正常工作。 - Peter
这个项目似乎已经死了。有人知道在哪里可以找到它吗? - kvantour

1
在更新的GCC版本中,您还可以在编写C代码时使用-aux-info来获取此信息。请参见这里
以下是输出样例:
/* src/main.c:30:NC */ static void usage (const char *);
/* src/main.c:32:NF */ extern int main (int argc, char **argv); /* (argc, argv) int argc; char **argv; */
/* src/main.c:57:NF */ static void usage (const char *prog_name); /* (prog_name) const char *prog_name; */

1

我曾经使用doxygen为我的C++代码生成文档。虽然我不是专家,但我认为你可以使用doxygen生成一些函数原型的索引文件。

这里有一个thread,有人问了类似的问题。


啊,被抢先了。不过我同意 :-) - Jon Cage

1
如果您适当地格式化您的注释,您可以尝试使用DOxygen。实际上,如果您以前没有尝试过它,我建议您尝试一下 - 它将生成继承图以及完整的成员函数列表和描述(从您的注释中)。

是的,我已经走过Doxygen这条路了,但对于这个任务,我需要更简单的东西。(关于Doxygen的优点的讨论,我会留到另一个主题中。) - Peter
你其实不需要注释任何东西。只需确保您的Doxyfile已打开为所有成员生成文档的选项即可。但是同意,这是相当复杂的工作,尽管我记得有一个XML输出选项,您可以尝试解析。 - blwy10

1

gccxml 很有趣,但它只打印一个 XML 树。你需要提取关于类、函数、类型甚至是类和函数的专业模板的信息。gccxml 使用 GCC 的解析器,因此你不需要做最糟糕的工作,即解析 C++ 文件,并且你可以100%确定这是最好的编译器所理解的。


0

你可以通过这个程序运行源文件:

/* cproto_parser.c */
#include <stdio.h>                           
int main (void)                              
{                                            
    int c;                                   
    int infundef = 0;                        
    int nb = 0,                              
        np = 0;                              
    while((c=getc(stdin))!=EOF){             
        if(c=='{'){                          
            if((np==0)&&(nb==0)){infundef=1;}
            nb++;                            
        }                                    
        if (infundef==0) {putc(c,stdout);}   
        if(c=='}'){                          
            if((np==0)&&(nb==1)){infundef=0;}
            nb--;                            
        }                                    
        if(c=='('){np++;}                    
        if(c==')'){np--;}                    
    }                                        
    return 0;                                
}                    

运行预处理器以去除注释。如果由于 #ifdefs 导致大括号不匹配,则必须设置定义、包含文件以使其不那么复杂。

例如,cc cproto_parser.c -o cproto_parser; cc -E your_source_file.c|./cproto_parser


随意将此移植到更适合的语言。 - mondaugen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接