cloc是一个基于perl的、十分好用的代码统计工具(http://cloc.sourceforge.net/),它所支持的语言还算十分丰富。不过,还是有很多用的较少的语言是不支持的。
项目中的一些功能模块用到re2c来实现字符匹配,因此,这些.re文件是cloc无法统计的。
不过还好,cloc提供了用户定制功能,使得我们还是可以实现对.re文件进行代码行统计。
定制方法很简单,基本有步骤如下:
1. 导出默认支持语言类型相关配置到一个文件中,命令:
cloc.pl --write-lang-def=langs.txt
2. 参考其他语言的格式,修改langs.txt,添加所要统计语言源码文件的后缀名(这里参考了C语言):
re2c filter remove_matches ^\s*// filter call_regexp_common C filter remove_inline //.*$ extension re
3. 使用新定义的语言文件langs.txt运行cloc:
cloc.pl --read-lang-def=langs.txt [源文件|目录]
但是还是有问题,用过re2c的人都知道,re2c是以/*!re2c [代码] */的形式将代码嵌在C代码中,这与C语言的注释相冲突,因此,上面操作后,cloc依然区分不开re2c内嵌代码和注释,因此,会把这部分代码识别为注释,而与实际不符。
对于这个问题,我一开始也是在尝试通过修改langs.txt文件的方法来进行支持,很遗憾,一直到现在没能找到。所以,我参考cloc.pl中python对于docstring的处理方式以及处理函数docstrings_to_C,也在cloc.pl中添加了一个新函数re_to_C,将/*!re2c [代码]*/的形式改成!re2c[代码]!re2c,这样就与C语言的注释语句格式区分开了,再修改langs.txt文件,让cloc.pl在统计前,先进行re_to_C处理,再按C语言的方式进行处理,最终,实现了对re2c文件的正确统计(呵呵,至少目前来看是正确的)。
最终langs.txt中re2c的内容如下:
re2c filter re_to_C filter remove_matches ^\s*// filter call_regexp_common C filter remove_inline //.*$ extension re
新增的re_to_C代码如下(呵呵,没学习perl,完全是照猫画虎呀):
sub re_to_C { # {{{1 my ($ra_lines, ) = @_; # Converts Python docstrings to C comments. print "-> re_to_C()\n" if $opt_v > 2; my $in_re = 0; foreach (@{$ra_lines}) { if (!$in_re) { while (/\/\*!re2c/) { s{\/\*!re2c}{!re2c}; $in_re = 1; } } else { while (/\*\//) { s{\*\/}{!re2c}; $in_re = 0; } } } print "<- re_to_C\n" if $opt_v > 2; return @{$ra_lines}; } # 1}}}
其他的语言应该也可以通过类似的方法定制吧。