Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Yet another code counter

by rinceWind (Monsignor)
on Mar 01, 2002 at 14:27 UTC ( [id://148569]=sourcecode: print w/replies, xml ) Need Help??
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);

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://148569]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-04-24 12:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found