File indexing completed on 2024-12-15 05:11:24

0001 #!/usr/bin/perl -w
0002 
0003 # Simple Source metrics for C++
0004 # Started by Taj Sun Apr 26 03:31:00 EST 1998
0005 # $Id$
0006 
0007 use strict;
0008 
0009 our $bigblank = 0;
0010 our $bigcommt = 0;
0011 our $bigstrcount = 0;
0012 our $bigstrsize = 0;
0013 our $bigtotal = 0;
0014 our $numfiles = 0;
0015 
0016 our $blocklen = 0;
0017 our $numblocks = 0;
0018 our $blockdepth = 0;
0019 our $blockstart = 0;
0020 our $blockmin = -1;
0021 our $blockmax = 0;
0022 our @blenlist = ();
0023 our @extensions = ( ".cpp", ".cc", ".c", ".cxx", ".c++", ".h", ".hh", ".hpp", ".hxx", ".tcc" );
0024 our %byExt = ();
0025 
0026 sub processFile
0027 {
0028     our ( $file ) = @_;
0029     our $blank  = 0;
0030     our $comment  = 0;
0031     our $total  = 0;
0032     our $incomment  = 0;
0033     our $strcount = 0;
0034     our $strsize = 0;
0035 
0036     open( SOURCE, "$file" ) || 
0037         die "cxxmetric: Couldn't read from $file.\n";
0038 
0039     while( <SOURCE> ) {
0040         $total++;
0041 
0042         if ( /^\s*$/ ) {
0043             $blank++;
0044             next;
0045         }
0046 
0047         if ( m#^\s*//# ) {
0048             $comment++;
0049             next;
0050         }
0051 
0052         if ( /{/ ) {
0053             # block start
0054             $blockdepth += s/{/{/g;
0055 
0056             $blockstart = $. if $blockdepth  == 1;
0057         }
0058 
0059         if ( /}/ ) {
0060             # block end
0061 
0062             $blockdepth -= s/}/}/g;
0063 
0064             if( $blockdepth == 0 ) {
0065                 my $thisblocklen = $. - $blockstart;
0066                 push @blenlist, $thisblocklen;
0067                 
0068                 $blocklen += $thisblocklen;
0069                 $numblocks++;
0070 
0071                 if( $blockmax < $thisblocklen ) {
0072                     $blockmax = $thisblocklen;
0073                 }
0074 
0075                 if ( $blockmin == -1 
0076                     || $blockmin > $thisblocklen ) {
0077                     $blockmin = $thisblocklen;
0078                 }
0079             }
0080         }   
0081 
0082         my $start = 0;
0083         my $stop  = 0;
0084 
0085         if ( m#/\*# ) {
0086             $start = 1;
0087         }
0088         
0089         if( m#\*/# ) {
0090             $stop = 1;
0091         }
0092 
0093         if( $start ) {
0094             $incomment = 1 unless $stop;
0095             $comment++;
0096         }
0097         elsif ( $stop ) {
0098             $comment++;
0099             $incomment = 0;
0100         }
0101         elsif ( $incomment ) {
0102                 $comment++;
0103         }
0104         else {
0105                 my $line = $_;
0106                 countStrings( $line );
0107         }
0108     }
0109 
0110     our $code = $total - ($comment + $blank );
0111     $bigtotal += $total;
0112     $bigcommt += $comment;
0113     $bigblank += $blank;
0114     $bigstrcount += $strcount;
0115     $bigstrsize += $strsize;
0116     
0117     our $stravglen = $strcount ? ($strsize / $strcount) : 0;
0118 
0119     write;
0120 }
0121 
0122 sub buildFileList {
0123   my ( $dir ) = @_;
0124   my @fileList = glob( "'$dir/*'" );
0125   my @cxxList;
0126 
0127   foreach my $file (@fileList) {
0128 
0129     if( -d $file ) {
0130       push @cxxList, buildFileList( $file );
0131     }
0132     else {
0133       foreach my $extension (@extensions) {
0134         # Case-insensitive "endsWith"
0135         if( uc( substr( $file, length( $file ) - length( $extension ) ) ) eq uc ( $extension ) ) {
0136            $byExt{$extension} += 1;
0137            push @cxxList, $file;
0138         }
0139       }
0140     }
0141   }
0142 
0143   return @cxxList;
0144 }
0145 
0146 sub countStrings
0147 {
0148         my $line = shift;
0149 
0150         foreach my $string ( split( /("[^"]*)\"/, $line ) ) {
0151                 next unless $string =~ /^\"/;
0152 
0153                 our $strcount++;
0154                 our $strsize += length( $string ) - 1;
0155         }
0156 }
0157 
0158 sub pct
0159 {
0160     my( $top, $bottom ) = @_;
0161 
0162     return 0 if $bottom == 0;
0163 
0164     return int(( $top * 100 ) / $bottom);
0165 }
0166 
0167 our @files;
0168 
0169 if( @ARGV == 0 ) {
0170   @files = buildFileList(".");
0171 }
0172 else {
0173     foreach my $arg ( @ARGV ) {
0174         push @files, buildFileList($arg);
0175     }
0176 }
0177 
0178 foreach my $file ( @files ) {
0179     processFile( $file );
0180     ++$numfiles;
0181 }
0182 
0183 our $total =  $bigtotal;
0184 our $comment = $bigcommt;
0185 our $blank = $bigblank;
0186 our $code  = $bigtotal - ($bigcommt + $bigblank );
0187 our $file = "Total";
0188 
0189 print "\n";
0190 write;
0191 
0192 print "\nPercentage Code:\t" , pct( $code, $total ),"%\n";
0193 print "Percentage Comment:\t" , pct( $comment, $total ),"%\n";
0194 print "Percentage Blank:\t" , pct( $blank, $total ),"%\n";
0195 print "Ratio Comment/Code:\t" , pct( $comment, $code + $comment ),"% Comment\n";
0196 print "Average Code/File:\t" , int($code/$numfiles)," lines\n" 
0197     unless $numfiles == 0;
0198 
0199 if ( $numblocks > 0 ) {
0200     my $avg = int( $blocklen / $numblocks );
0201     @blenlist = sort @blenlist;
0202     my $median = $blenlist[ int( $numblocks / 2 )];
0203 print<<EOF;
0204 
0205 Blocks:\t$numblocks
0206 \tLengths (lines):\tmin: $blockmin\tmax: $blockmax\tmed: $median\taverage: $avg
0207 EOF
0208 }
0209 
0210 our $bigstravglen = $bigstrcount ? int($bigstrsize / $bigstrcount) : 0;
0211 
0212 print<<EOF;
0213 Strings:\t$bigstrcount
0214 \tSize (bytes):\ttotal: $bigstrsize\taverage: $bigstravglen
0215 EOF
0216 
0217 print "Counts by file extension:\n";
0218 foreach my $ext (keys %byExt) {
0219   print "\t$ext\t" . $byExt{$ext} . "\n";
0220 }
0221 
0222 exit;
0223 
0224 format STDOUT_TOP =
0225  Lines  Code    Comment  Blank  Strs   AvgLen File
0226  ------ ------- -------- ------ ------ ------ ------
0227 
0228 .
0229 
0230 format STDOUT =
0231 @###### @###### @###### @###### @###### @###### @*
0232 $total, $code, $comment, $blank, our $strcount, our $stravglen, $file
0233 .