patternMinor
Calculating bytes of code
Viewed 0 times
codecalculatingbytes
Problem
I am new to Perl and I wrote this Perl script to calculate bytes of code and lines of code in a directory. I want to know if there are any improvements that can be made to it.
```
#!/usr/bin/perl
# codestats.pl
# A perl script to calculate the number of lines of code in a project
# and what type of lines those code are, such as comments, code, or
# newlines. This script is specific to C/C++, but it should work with any
# language that has the same commenting scheme, so it should probably work
# with java too.
#
# Henry J Schmale
# April 30, 2015
use strict;
use warnings;
my @srcext = (".cpp", ".c", ".h", ".hpp", ".ino", ".cxx", "*.cc");
my $commLines = 0; # Lines that start with a comment symbol
my $bothLines = 0; # Lines that have a comment and code
my $newLines = 0; # Lines that are just whitespace
my $codeLines = 0; # Lines of code - lines that don't fit in another space
my $totLines = 0; # Total lines of code
my $srcBytes = 0; # Total Number of bytes in src code
my $fCount = 0; # Number of files read
my $files;
for($a = 0; $a ;
for($b = 0; $b newLine
$newLines++;
next;
}
if(($lines[$b] =~ /^\s*\/\//) || # comments only lines
($lines[$b] =~ /^\s\/\/) ||
($lines[$b] =~ /^\s\/)){
$commLines++;
next;
}
# code + comments
if(($lines[$b] =~ /\/\//) ||
($lines[$b] =~ /\/\.\*\//)){
$bothLines++;
next;
}
$codeLines++;
}
close FILE;
}
sub calcPercent{
return ($_[0] / $_[1]) * 100.0;
}
sub printResults{
# print out the results
printf("Read %d Files\n", $fCount);
printf("Average Lines Per File: %d\n", $totLines / $fCount);
printf("Code : %09d ln. %06.3f", $codeLines, calcPercent($codeLines, $totLines));
print "%\n";
printf("Comment : %09d ln. %06.3f", $commLines, calcPercent($commLines, $totLines));
print "%\n";
printf("Blank : %09d ln. %0
```
#!/usr/bin/perl
# codestats.pl
# A perl script to calculate the number of lines of code in a project
# and what type of lines those code are, such as comments, code, or
# newlines. This script is specific to C/C++, but it should work with any
# language that has the same commenting scheme, so it should probably work
# with java too.
#
# Henry J Schmale
# April 30, 2015
use strict;
use warnings;
my @srcext = (".cpp", ".c", ".h", ".hpp", ".ino", ".cxx", "*.cc");
my $commLines = 0; # Lines that start with a comment symbol
my $bothLines = 0; # Lines that have a comment and code
my $newLines = 0; # Lines that are just whitespace
my $codeLines = 0; # Lines of code - lines that don't fit in another space
my $totLines = 0; # Total lines of code
my $srcBytes = 0; # Total Number of bytes in src code
my $fCount = 0; # Number of files read
my $files;
for($a = 0; $a ;
for($b = 0; $b newLine
$newLines++;
next;
}
if(($lines[$b] =~ /^\s*\/\//) || # comments only lines
($lines[$b] =~ /^\s\/\/) ||
($lines[$b] =~ /^\s\/)){
$commLines++;
next;
}
# code + comments
if(($lines[$b] =~ /\/\//) ||
($lines[$b] =~ /\/\.\*\//)){
$bothLines++;
next;
}
$codeLines++;
}
close FILE;
}
sub calcPercent{
return ($_[0] / $_[1]) * 100.0;
}
sub printResults{
# print out the results
printf("Read %d Files\n", $fCount);
printf("Average Lines Per File: %d\n", $totLines / $fCount);
printf("Code : %09d ln. %06.3f", $codeLines, calcPercent($codeLines, $totLines));
print "%\n";
printf("Comment : %09d ln. %06.3f", $commLines, calcPercent($commLines, $totLines));
print "%\n";
printf("Blank : %09d ln. %0
Solution
It's easy to write very ugly Perl code,
but this is pretty nicely written, so congrats.
Using barewords for file handles like this is discouraged:
The recommended way:
Some simplifications are possible.
For example instead of this:
I find this way a lot easier to type:
Another, bigger simplification is in the loops.
Instead of this:
You can iterate using
and instead of
which can be omitted from
like this:
but this is pretty nicely written, so congrats.
Using barewords for file handles like this is discouraged:
open(FILE, ";
# ...
close FILE;The recommended way:
open(my $fh, ";
# ...
close $fh;Some simplifications are possible.
For example instead of this:
my @srcext = ("*.cpp", "*.c");I find this way a lot easier to type:
my @srcext = qw/*.cpp *.c/;Another, bigger simplification is in the loops.
Instead of this:
my @lines = ;
for($b = 0; $b newLine
$newLines++;
next;
}
if(($lines[$b] =~ /^\s*\/\//) || # comments only lines
($lines[$b] =~ /^\s*\/\*/) ||
($lines[$b] =~ /^\s*\*/)){You can iterate using
for () { ... },and instead of
$lines[$b], benefit from the auto-variable $_,which can be omitted from
$lines[$b] =~ /.../ statements,like this:
for () {
$srcBytes += length($_);
$totLines++;
if(/^\s$/){ # is only whitespace ==> newLine
$newLines++;
next;
}
if(/^\s*\/\// || # comments only lines
/^\s*\/\*/ ||
/^\s*\*/){Code Snippets
open(FILE, "<$srcfile") or die "Couldn't open file: $!\n";
my @lines = <FILE>;
# ...
close FILE;open(my $fh, "<$srcfile") or die "Couldn't open file: $!\n";
my @lines = <$fh>;
# ...
close $fh;my @srcext = ("*.cpp", "*.c");my @srcext = qw/*.cpp *.c/;my @lines = <FILE>;
for($b = 0; $b < scalar(@lines); $b++){
$srcBytes += length($lines[$b]);
$totLines++;
if($lines[$b] =~ /^\s$/){ # is only whitespace ==> newLine
$newLines++;
next;
}
if(($lines[$b] =~ /^\s*\/\//) || # comments only lines
($lines[$b] =~ /^\s*\/\*/) ||
($lines[$b] =~ /^\s*\*/)){Context
StackExchange Code Review Q#94581, answer score: 7
Revisions (0)
No revisions yet.