247 lines
7.1 KiB
Perl
247 lines
7.1 KiB
Perl
# Synopsis: generate a list of highest metrics for files. (C/C++)
|
|
#
|
|
# Requires one existing Understand for C++ databases
|
|
#
|
|
# Categories: Project Report
|
|
#
|
|
# Languages: C
|
|
#
|
|
# Usage:
|
|
sub usage($)
|
|
{
|
|
return << "END_USAGE";
|
|
${ \( shift @_ ) }
|
|
Usage: c_highestmetrics_files.pl -db database -root_path path -maxcount maxcount -min_line line -min_linecode linecode -min_classes classes -output_file file
|
|
-db database Specify Understand database (required for uperl, inherited from Understand)
|
|
-root_path path Specify a path for files to into account ()
|
|
-maxcount maxcount Specify the max number of functions per categories (default=10)
|
|
-min_line linecode Specify the min number of lines (default=750)
|
|
-min_linecode line Specify the min number of lines of code (default=1000)
|
|
-min_classes classes Specify the min number of declared classes (default=20)
|
|
-output_file file Specify the name of the output file
|
|
END_USAGE
|
|
}
|
|
|
|
# For the latest Understand perl API documentation, see
|
|
# http://www.scitools.com/perl.html
|
|
#
|
|
use Understand;
|
|
use Tie::RefHash;
|
|
use Getopt::Long;
|
|
use strict;
|
|
|
|
my $dbPath;
|
|
my $help;
|
|
my $maxcount = 10;
|
|
my $root_path = "";
|
|
my $countLine_Threshold = 1000;
|
|
my $countLineCode_Threshold = 750;
|
|
my $countDeclClass_Threshold = 20;
|
|
my $output_file = "";
|
|
|
|
# if option is not found in the command line, corresponding variable is not changed, and use the initialized value.
|
|
GetOptions(
|
|
"db=s" => \$dbPath,
|
|
"maxcount=s" => \$maxcount,
|
|
"root_path=s" => \$root_path,
|
|
"min_line=s" => \$countLine_Threshold,
|
|
"min_linecode=s" => \$countLineCode_Threshold,
|
|
"min_classes=s" => \$countDeclClass_Threshold,
|
|
"output_file=s" => \$output_file,
|
|
"help" => \$help,
|
|
);
|
|
|
|
|
|
# open the database
|
|
my $db=openDatabase($dbPath);
|
|
|
|
my $title = "Files";
|
|
my $kindFiles = "File";
|
|
my $kindCodeFiles = "Code File";
|
|
my $kindHeaderFiles = "Header File";
|
|
my $fh;
|
|
my $writeInFile = 0;
|
|
|
|
prepareOutput();
|
|
|
|
display("-------------------------------------------------------\n");
|
|
display("Highest metrics for files\n\n");
|
|
display("Database : ".$dbPath."\n");
|
|
display("maxcount : ".$maxcount."\n");
|
|
display("root_path : ".$root_path."\n");
|
|
display("min_line : ".$countLine_Threshold."\n");
|
|
display("min_linecode : ".$countLineCode_Threshold."\n");
|
|
display("min_classes : ".$countDeclClass_Threshold."\n");
|
|
display("output_file : ".$output_file."\n");
|
|
display("\n");
|
|
|
|
generateHighestMetrics($db, $title, $kindFiles, lc $root_path, "CountLine", $countLine_Threshold, $maxcount);
|
|
generateHighestMetrics($db, $title, $kindCodeFiles, lc $root_path, "CountLineCode", $countLineCode_Threshold, $maxcount);
|
|
generateHighestMetrics($db, $title, $kindHeaderFiles, lc $root_path, "CountDeclClass", $countDeclClass_Threshold, $maxcount);
|
|
|
|
display("-------------------------------------------------------\n");
|
|
|
|
closeDatabase($db);
|
|
|
|
closeOutput();
|
|
|
|
# ------------------------------------------------------------------------------------------
|
|
# ------------------------------------------------------------------------------------------
|
|
# subroutines
|
|
# ------------------------------------------------------------------------------------------
|
|
# ------------------------------------------------------------------------------------------
|
|
|
|
sub openDatabase($)
|
|
{
|
|
my ($dbPath) = @_;
|
|
|
|
my $db = Understand::Gui::db();
|
|
|
|
# path not allowed if opened by understand
|
|
if ($db && $dbPath) {
|
|
die "database already opened by GUI, don't use -db option\n";
|
|
}
|
|
|
|
# open database if not already open
|
|
if (!$db) {
|
|
my $status;
|
|
die usage("Error, database not specified\n\n") unless ($dbPath);
|
|
($db,$status)=Understand::open($dbPath);
|
|
die "Error opening database: ",$status,"\n" if $status;
|
|
}
|
|
return($db);
|
|
}
|
|
|
|
sub closeDatabase($)
|
|
{
|
|
my ($db)=@_;
|
|
|
|
# close database only if we opened it
|
|
$db->close() if ($dbPath);
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------------------
|
|
# ------------------------------------------------------------------------------------------
|
|
sub prepareOutput {
|
|
if($output_file eq "") {
|
|
$writeInFile = 0;
|
|
} else {
|
|
if(open($fh, '>', $output_file)) {
|
|
$writeInFile = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------------------
|
|
# ------------------------------------------------------------------------------------------
|
|
sub closeOutput {
|
|
if($writeInFile) {
|
|
close $fh;
|
|
}
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------------------
|
|
# Parameters
|
|
# - db
|
|
# - title
|
|
# - kind
|
|
# - threshold name
|
|
# - metrics name
|
|
# - max result count
|
|
# ------------------------------------------------------------------------------------------
|
|
sub generateHighestMetrics {
|
|
my ($db, $title, $kind, $root_path, $metrics, $threshold, $maxcount) = @_;
|
|
|
|
# retrieve threshold option value
|
|
$threshold = 1 if ($threshold < 1);
|
|
|
|
# build hash of matching entities
|
|
tie my %ents, 'Tie::RefHash';
|
|
my $ents;
|
|
foreach my $file ($db->ents($kind)) {
|
|
# keep file if not in excluded path and if metrics > threshold
|
|
my $val = $file->metric($metrics);
|
|
if ($val >= $threshold) {
|
|
if(index(lc $file->longname(), $root_path) != -1) {
|
|
$ents{$file} = $val;
|
|
}
|
|
}
|
|
}
|
|
|
|
printTitleMetric($title, $metrics, $threshold);
|
|
|
|
# output, sorted by value, then by name
|
|
my $cur = 1;
|
|
foreach my $file (sort {
|
|
$ents{$b} <=> $ents{$a}
|
|
|| lc($b->longname()) cmp lc($a->longname());
|
|
} keys %ents) {
|
|
if($cur <= $maxcount) {
|
|
printOneResult($file, $ents{$file});
|
|
}
|
|
$cur++;
|
|
}
|
|
display("\n");
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------------------
|
|
# Parameters
|
|
# - report
|
|
# - title
|
|
# - metrics name
|
|
# - threshold
|
|
# ------------------------------------------------------------------------------------------
|
|
sub printTitleMetric {
|
|
my ($title, $metrics, $threshold) = @_;
|
|
|
|
display("-------------------------------------------------------\n");
|
|
display($title);
|
|
display(" with highest metric ");
|
|
display($metrics);
|
|
display(" ( > ");
|
|
display($threshold);
|
|
display(" ) :\n");
|
|
display("-------------------------------------------------------\n");
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------------------
|
|
# Parameters
|
|
# - report
|
|
# - entity
|
|
# - metric value
|
|
# ------------------------------------------------------------------------------------------
|
|
sub printOneResult {
|
|
my ($entity, $value) = @_;
|
|
|
|
#value in red
|
|
my $str = sprintf("%5d " ,$value);
|
|
display($str);
|
|
|
|
# entity
|
|
my $length = length($entity->longname());
|
|
$str = $entity->longname();
|
|
# if entity is not a file, print its kind
|
|
if($entity->kindname() eq "File")
|
|
{}
|
|
else {
|
|
$str .= sprintf("%*s" , 60 - $length , "(");
|
|
$str .= $entity->kindname();
|
|
$str .= ")";
|
|
}
|
|
display($str);
|
|
display("\n");
|
|
}
|
|
|
|
# ------------------------------------------------------------------------------------------
|
|
# Parameters
|
|
# - text
|
|
# ------------------------------------------------------------------------------------------
|
|
sub display {
|
|
my ($text) = @_;
|
|
|
|
if($writeInFile) {
|
|
print $fh $text;
|
|
} else {
|
|
print $text;
|
|
}
|
|
}
|