Category: | Text processing |
Author/Contact Info | rinceWind |
Description: | Here is a code counter that can handle languages other than Perl. It was required for sizing a rewrite project, and gave some useful metrics on code quality as a by-product.
It is easy to add other languages by populating the hashes %open_comment and %close_comment, and/or %line_comment. The code counts pod as comment, but bear it in mind that this script was not primarily designed for counting Perl. |
#!/usr/local/bin/perl -w use strict; my %open_comment = ( '.c' => '/*', '.h' => '/*', '.pas' => '{', ); my %close_comment = ( '.c' => '*/', '.h' => '*/', '.pas' => '}', ); my %line_comment = ( '.com' => '!', '.opt' => '!', '.mms' => '#', '.mar' => ';', '.pl' => '#', '.pm' => '#', '.sh' => '#', ); my $lincnt = 0; my $meatcnt = 0; my $tokencnt = 0; my $filcnt = 0; my $g_lincnt = 0; my $g_meatcnt = 0; my $g_tokencnt = 0; foreach my $filnam (@ARGV) { next if !open INFILE,$filnam; my $incomment = 0; my $inpod = 0; # Parse out filename extension. Needs to be portable # Note: VMS can have ;version on the end of the file name my $ext = $1 if $filnam =~ /(\.[^.;]+)(;|$)/; next if !$ext; # Get comment delimiters for extension my $lc = $line_comment{$ext}; my $oc = $open_comment{$ext}; my $cc = $close_comment{$ext}; while (defined ($_ = <INFILE>)) { # Line comment if ($lc) { s/\Q$lc\E.*//; } # Begin and end comment e.g. /* ... */ if ($oc) { $incomment = 0 if $incomment && s/.*?\Q$cc//; s/.*// if $incomment; s/\Q$oc\E.*?\Q$cc//g; $incomment++ if s/\Q$oc\E.*//; } # POD section $inpod++ if /^=/; $inpod = 0 if /^=cut/; s/.*// if $inpod; s/^=cut//; # Warning, does not handle token count for multi line # strings, \', regexs or <<FOO # but token count is only a rough guide s/(["'`]).*?\1/ string /g; s/^\s+//; my @tokens = /\w+\s*|.\s*/g; $lincnt++; $g_lincnt++; $meatcnt++,$g_meatcnt++ if $_; $g_tokencnt += @tokens; $tokencnt += @tokens; } close INFILE; printf("%s %d lines, %d non-commentary, %d tokens = %2.2f per line +\n", $filnam,$lincnt,$meatcnt,$tokencnt, $meatcnt ? ($tokencnt/$meatcnt) : 0); $lincnt = 0; $meatcnt = 0; $tokencnt = 0; $filcnt++; } printf("\nGrand total %d files, %d lines, %d non-commentary, %d tokens + = %2.2f per line\n", $filcnt,$g_lincnt,$g_meatcnt,$g_tokencnt, $g_meatcnt ? ($g_tokencnt/$g_meatcnt) : 0); |
|
---|
Back to
Code Catacombs