一直想分享点方法,却又不知从何入手;正好老大让统计工程有效代码行数,就分享一下相关的经验。前后总共尝试了3种方案
(1)VS2010直接统计
在如下对话框中输入:^:b*[^:b#/]+.*$
(2)sourceinsight 总计
选择Project->Project Report(勾选如下图),点ok即可
(3)自己写个脚本
中秋节熬了一个通宵用perl写了一个脚本,当然主要是perl本身用的也不是很好,带有尝试性的写写,所以可能还有一些问题,但好在此次统计中感觉结果还是很靠谱的,所以本着学习的态度暂且拿出来分享,如有不妥请指正。
# 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 =) { 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 = ) { 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 = ) { 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; }