一直想分享点方法,却又不知从何入手;正好老大让统计工程有效代码行数,就分享一下相关的经验。前后总共尝试了3种方案
(1)VS2010直接统计
在如下对话框中输入:^:b*[^:b#/]+.*$
(2)sourceinsight 总计
选择Project->Project Report(勾选如下图),点ok即可
(3)自己写个脚本
中秋节熬了一个通宵用perl写了一个脚本,当然主要是perl本身用的也不是很好,带有尝试性的写写,所以可能还有一些问题,但好在此次统计中感觉结果还是很靠谱的,所以本着学习的态度暂且拿出来分享,如有不妥请指正。
</pre><pre name="code" class="html"># function:本脚本用于统计c/c++代码的有效行数;其他语言暂不支持
# author :MoreSpeech
# date :2016/9/17
#参数1:输入代码存放路径
#参数2:输出log文件名
#! /user/bin/perl
use warnings;
use strict;
if(@ARGV != 2)
{
die"Usage: statistical_line_num.pl src_path info.log\n";
}
my $src_path=$ARGV[0];
my $log_file_name = $ARGV[1];
##支持文件格式
my %formatHash = ('.cpp', 1, '.c', 1, '.h',1, '.hpp', 1,'.cc', 1,);
my %dest_file_hash;
ransack($src_path, \%formatHash, \%dest_file_hash);
my %linenum2file;
my $sumValidline = 0;
while( my ($onefile, $val) = each( %dest_file_hash))
{
my $validN = processOneFile($onefile);
$sumValidline += $validN;
$linenum2file{$onefile} = $validN;
}
writeLog($log_file_name, %linenum2file);
print "$sumValidline\n";
###############sub_function#######################
sub writeLog{
my ($log_name, %linen2file) = @_;
open (Handle, ">$log_name") or die "can't create the $log_name\n";
my %hash=();
my @key = sort {$linen2file{$a}<=>$linen2file{$b}} keys %linen2file;
foreach my $key(@key)
{
print Handle"$key, $linen2file{$key}\n";
}
close(Handle);
}
sub ransack
{
my ($dir, $format, $files) = @_;
my @array=glob( "$dir\\* ");
foreach my $item (@array)
{
if(-d $item)
{
ransack($item, $format, $files);
}
elsif( $item =~ /(.\w{1,10})$/)
{
if( exists $format->{$1})
{
$files->{$item} = 1;
}
}
}
}
sub ParseCommentBegin{
my $InString = shift;
my $validchar = shift;
my $beginchar = "/*";
my $endchar = "*/";
my $beginPos = index($InString, $beginchar);
my $endPos = index($InString, $endchar);
my $flag = 0;
if( $beginPos > $endPos && $endPos >= 0) ##another "*/", so skip it
{
$endPos = index($InString, $endchar, $endPos + length($endchar));
$flag = 1;
}
if($beginPos > 0 && !$flag)
{
my $str = substr($InString, 0, $beginPos);
$$validchar .= $str;
}
my $retval = 0;
if( $beginPos >= 0 && $endPos > 0 )
{
my $subString = substr($InString, $endPos + length($endchar));
my $len = length($subString);
if( $len > 0)
{
return ParseCommentBegin($subString, $validchar);
}
}
elsif($beginPos <0 && $endPos< 0)
{
$$validchar .= $InString;
return 0;
}
elsif($endPos < 0)
{
return 1; ##wait for end
}
else{
print "Error: without this situation\n"
}
return 0;
}
sub ParseCommentEnd{
my $InString = shift;
my $validchar = shift;
my $endchar = "*/";
my $endPos = index($InString, $endchar);
if( $endPos < 0 )
{
return;
}
my $subString = substr($InString, $endPos + length($endchar));
my $tmpStr = $subString;
$tmpStr =~ s/[\s|\t]*//g;
if( length($tmpStr) > 0 )
{
$$validchar .= $subString;
ParseCommentEnd($subString, $validchar);
}
}
sub ParseArrayBegin{
my $InString = shift;
my $beginchar = "[";
my $endchar = "]";
my $beginPos = index($InString, $beginchar);
my $endPos = index($InString, $endchar);
my $searchPos = $endPos + 1;
my $retval = 0; ##ordinary
if( $beginPos && ($endPos > $beginPos) ) ##array[]
{
if( !(index($InString, "=", $searchPos ) < 0) )
{
$searchPos += 1;
if( !(index($InString ,"{", $searchPos) < 0) )
{
$searchPos += 1;
if( index($InString, "}", $searchPos) < 0 )
{
$retval = 1; ##wait for "}"
}
}
else
{
$retval = 2; ###wait for "{"
}
}
elsif( index($InString, ";", $searchPos))
{
$retval = 0; ##get array end symbol";"
}
else
{
$retval = 3; ##wait for "="
}
}
return $retval;
}
##校验查到结果是否有效
sub CheckValidFind
{
my $InString = shift;
my $forestr = shift;
my $backstr = shift;
my $forePos = index($InString, $forestr);
my $backPos = index($InString, $backstr); ##dest string
if(($forePos < $backPos) && ($forePos>=0)) ##pairing
{
my $subString = substr($InString, $backPos+length($backstr));
if(CheckValidString($subString))
{
return CheckValidFind($subString, $forestr, $backstr);
}
}
elsif( $backPos >= 0 )
{
return 1; ##valid: just one
}
else
{
# die "Error: without this situation\n";
}
return 0; ##invalid
}
sub FindInFile{
*FILE = shift;
my $flag = shift;
my $deststr = shift;
my $nline = 0;
while( my $line = <FILE> )
{
chomp($line);
if(!CheckValidString($line))
{
next;
}
$nline++;
if( $line =~ /$deststr/)
{
if($flag == 1)
{
if(CheckValidFind($line, "{", "}"))
{
last; ##find the valid "}"
}
}
else
{
last;
}
}
}
return 1;
}
sub ParseArrayEnd{
*FileHandle= shift;
my $InFlag = shift;
#print "$InFlag\n";
my $sumLine = 0;
while( my $line = <FileHandle>)
{
chomp($line);
if( $InFlag == 3)
{
$sumLine += FindInFile( *FileHandle, $InFlag, "=");
$InFlag = 2;
}
elsif( $InFlag == 2 )
{
$sumLine += FindInFile(*FileHandle ,$InFlag, "{");
$InFlag = 1;
}
elsif( $InFlag == 1 )
{
$sumLine += FindInFile(*FileHandle, $InFlag, "}");
last;
}
}
return $sumLine;
}
sub CheckValidString{
my $string = shift;
$string =~ s/[\s|\t]*//g;
if( length($string) > 0) #valid string
{
return 1;
}
else
{
return 0;
}
}
sub processOneFile
{
my $file_name = shift;
open(curHandle, "<$file_name") or die "can't open the $file_name\n";
my $validlineN = 0;
my $nLine = 0;
my $waitforend = 0;
while(my $line = <curHandle> )
{
chomp($line);
my $validstring="";
if( $line =~ /^[\s|\t]*\/\//) #"//"
{
#print "$line";
}
elsif( $line =~ /\/\*/) #"/*" :begin of comment
{
if(ParseCommentBegin($line, \$validstring))
{
$waitforend = 1;
}
else
{
$waitforend = 0; ##get "*/"
}
if( CheckValidString($validstring) )
{
$validlineN++;
}
}
elsif( $line =~ /\*\//) #"*/": end of comment
{
ParseCommentEnd($line, \$validstring);
if( CheckValidString($validstring))
{
$validlineN++;
}
$waitforend = 0;
}
elsif( !$waitforend )
{
if( $line =~ /\[/)
{
my $retval = ParseArrayBegin($line);
if( $retval )
{
$validlineN += ParseArrayEnd(*curHandle, $retval);
}
}
if(CheckValidString($line))
{
$validlineN++;
}
}
}
close(curHandle);
return $validlineN;
}