在 C 中生成跨多个文件的现有函数列表

Generate a list of existing functions across multiple files in C

由于需要填写文书工作,我需要知道整个 C 项目中有多少函数。

该项目分布在多个文件夹中,因此理想情况下我正在寻找的是您可以输入的内容:

FindAllTheFunctions --recursive /path/to/folder

结果写成这样:

/path.../filename: int foo(float bar)
.
.
.
/path.../final/filename: double foo2(int bar2)

我怎样才能得到这种性质的结果?

非常感谢!

感谢大家的宝贵意见!

最后,这就是我所做的: 我使用 ctags:

创建了 tags 文件
ctags --recurse=yes path/to/base/of/code

这会生成一个名为 tags

的输出文件

我使用 vim 作为文本编辑器。所以我打开 tags 文件并输入:

:v/f$/d

搜索文件中所有不以 f 结尾的行并删除它们。

我剩下的是代码中的所有函数。有多少功能?

wc -l tags

只有535个函数,现在我要把它们全部记录下来...

Moving/expanding来自评论,稍微笼统的一句话:

ctags -f - -R | cut -s -f 4- | grep -P '(^|\t)f($|\t)' | wc -l
  1. ctags -R 递归解析(...大部分...)当前目录中支持的文件; -f - 将其输出重定向到标准输出,而不是写入 tags 文件;
  2. 我们使用cut只提取我们感兴趣的字段;

    tags 文件格式由制表符分隔的字段组成(因此 cut 的默认分隔符已经可以);前三个字段具有固定的含义,我们不感兴趣,而后面的是 "extended fields",我们在其中寻找一个 f 来指示该行引用一个函数。

    -s 仅匹配带分隔符的行(= 跳过垃圾); -f 4-只输出从第四个字段到最后一个字段。

  3. 我们用grep寻找我们的寂寞f;无法保证 "extended fields" 的顺序 - 事实上,当通过 C++ 项目调用 ctags 时,我看到除了 f 之外还添加了额外的字段(特别是 class: 字段) .

    -P 使用 PCRE 正则表达式(只是因为查找制表符更容易,否则 egrep 就足够了); (^|\t)f($|\t) 查找被我们的分隔符(制表符)包围或被行的 start/end 包围的 f

  4. wc -l 计算结果行;结果应该是函数定义的数量。

ctags 的交叉引用功能可能对您有所帮助。

  1. 安装通用 ctags (https://ctags.io)
  2. 运行 查找 $dir --name '*.c' | ctags --kinds-C=f -x --_xformat='%F: %{C.properties} %t %N%S'
$ find ./main -name '*.c' | ./ctags --kinds-C=f -x --_xformat='%F: %{C.properties} %t %N%S' -L - | head
./main/args.c: extern Arguments * argNewFromArgv(char * const * const argv)
./main/args.c: extern Arguments * argNewFromFile(FILE * const fp)
./main/args.c: extern Arguments * argNewFromLineFile(FILE * const fp)
./main/args.c: extern Arguments * argNewFromString(const char * const string)
./main/args.c: extern bool argOff(const Arguments * const current)
./main/args.c: extern char * argItem(const Arguments * const current)
./main/args.c: extern void argDelete(Arguments * const current)
./main/args.c: extern void argForth(Arguments * const current)
./main/args.c: extern void argSetLineMode(Arguments * const current)
./main/args.c: extern void argSetWordMode(Arguments * const current)