1
1
openmpi/contrib/gen_stats.pl
2015-06-23 20:59:57 -07:00

276 строки
8.8 KiB
Perl
Исполняемый файл

#!/usr/bin/perl
# Currently, we implement only the directory option
# The following features have been requested for
#
# 1. Get the name of the directory and produce a
# statistic for all the files which have been touched
# in all the subdirectories starting from that
# directory
#
# 2. Since gcov spits out a statistic for all the header
# files included by all the source files, we need to
# aggregate them somehow into a single file. This might
# have to be done manually by going through all the lines
# which have been executed in that file since a header
# file may have multiple inclusions meaning that they
# might have multiple .gcov files in different directories
#
# 3. Support command line parsing of arguments
#
# 4. Support giving a listing of all the files which have
# been covered less than a certain percentage, say for
# eg., all files which have been covered less that 5%
#
use strict;
use Switch;
use File::Basename;
#global variables
my $index = 0;
my $num_args = scalar(@ARGV);
my $percentage = 0.0;
my $ret1 = 0;
my $ret2 = 0;
my $dir_list_given = 0;
my $req_list_given = 0;
$ret1 = open(DIR_FILE, "dir_list.txt");
$ret2 = open(REQ_FILE, "req_list.txt");
if ($ret1 < 0 || $ret2 < 0) {
print "ERROR: opening dir_list.txt or req_list.txt\n";
exit(3);
}
# check the error condition
if (0 == ($num_args % 2)) {
} else {
print "ERROR: the number of arguments has to be even\n";
exit(3);
}
# process the arguments
while($num_args > 0) {
switch ($ARGV[$index]) {
case "-d" {
print DIR_FILE $ARGV[$index+1];
$index += 2;
$num_args -= 2;
$dir_list_given = 1;
}
case "-f" {
my $filename = `find . -name $ARGV[$index+1]`;
print REQ_FILE $filename;
$index += 2;
$num_args -= 2;
$req_list_given = 1;
}
case "-p" {
$percentage = $ARGV[$index];
$index += 2;
$num_args -= 2;
}
else {
print "ERROR: Incorrect command line option\n";
exit(3);
}
}
}
close(DIR_FILE);
close(REQ_FILE);
# when nothing is specified, everything defaults to just "src"
if (0 == $dir_list_given && 0 == $req_list_given) {
print "WARN: No directory or file has been requested\ndefaulting to src directory\n";
system("echo src > dir_list.txt");
$dir_list_given = 1;
}
#Now, we have both the requested file list and the directory list
#So simply call the procedure generate_stats with the required arguments
if (1 == $dir_list_given) {
get_file_list("./dir_list.txt",
"touched_files.txt",
"untouched_files.txt");
generate_stats("touched_files.txt", # file_list
"coverage_stats.txt",# generic coverage numbers
"percent_stats.txt", # files below a certain %
$percentage, # percentage below which we report
1); # 1 to report
}
if (1 == $req_list_given) {
generate_stats("req_list.txt", # file_list
"req_stats.txt",# generic coverage
"", # no percentage coverage required
0, # not required
0); # 0 to not report percentages
}
sub get_file_list {
my ($input, $touched, $untouched) = @_;
my $ret = open(DIRFILES, "< $input");
if ($ret < 0) {
print "ERROR: could not open directory listing\n";
exit(3);
}
while(<DIRFILES>) {
chomp();
my $c_files = `find $_ -name \"*.c\"`;
my $cc_files = `find $_ -name \"*.cc\"`;
$cc_files =~ s/\.cc//g;
$c_files =~ s/\.c//g;
$c_files = $c_files . $cc_files;
my @C_FILES = split(/\n/, $c_files);
my $da_files = `find $_ -name \"*.da\" -o -name \"*.gcda\"`;
$da_files =~ s/\.gcda//g;
$da_files =~ s/\.da//g;
my @DA_FILES = split(/\n/, $da_files);
open (TEMP1, "> temp1");
open (TEMP2, "> temp2");
print TEMP1 $c_files;
print TEMP2 $da_files;
close(TEMP1);
close(TEMP2);
# Now do the manual diff
open(TEMP1, "< temp1");
open(UNTOUCHED_FILES, ">> $untouched");
open(TOUCHED_FILES, ">> $touched");
while(<TEMP1>) {
my $c_file = $_;
my $found = 0;
my $file_name;
my $dir_name;
my $file_ext;
my $search_file;
($file_name, $dir_name, $file_ext) = fileparse($c_file, ('\.c') );
# For our libtool build, every .gcda and .gcno file lands in the .libs dir.
$search_file = $dir_name . ".libs/" . $file_name;
open(TEMP2, "< temp2");
while(<TEMP2>) {
if ($search_file eq $_) {
$found = 1;
}
}
close(TEMP2);
if ($found == 0) {
print UNTOUCHED_FILES $c_file;
} else {
chomp($c_file);
$c_file = $c_file . ".c\n";
print TOUCHED_FILES $c_file;
}
}
close(UNTOUCHED_FILES);
close(TOUCHED_FILES);
close(TEMP1);
system("rm temp1 temp2");
}
close(DIRFILES);
#Now to print the stats of all the files which are touched
system("sort $touched -o temp; uniq temp $touched");
system("sort $untouched -o temp; uniq temp $untouched");
}
# This is the function which generates the statistics and dumps it out
# to a file. Details are pretty straightforward at this point
sub generate_stats {
my ($input_file, $coverage_file, $percent_file, $percentage, $calculate) = @_;
my $k = 0;
my $l = 0;
open (INPUT, "< $input_file");
open (COVERAGE, "> $coverage_file");
if ($calculate == 1) {
open (PERCENT, "> percent_coverage.txt");
}
print COVERAGE "#Index Directory Filename Usage(%)\n";
print COVERAGE "#======================================================================================================\n";
if ($calculate == 1) {
print PERCENT "#Index Directory Filename Usage(%)\n";
print PERCENT "#======================================================================================================\n";
}
my $average = 0.0;
my $num_files = `wc -l touched_files.txt`;
print "num_files:", $num_files;
while (<INPUT>) {
#generate the gcov file for this particular file
#1. Get the directory name and filename seperately
#2. Invoke gcov on the file
#3. Print the statistic onto a file
chomp();
my $full_name = $_;
my $dir_name;
my $file_name;
my $file_ext;
my $file_gcda;
my $found_file;
($file_name, $dir_name, $file_ext) = fileparse($full_name, ('\.c') );
$file_gcda = $file_name . ".gcda";
open(RESULT, "cd $dir_name; gcov $file_gcda -o .libs 2> /dev/null | ");
while (<RESULT>) {
if (/Creating/) { $found_file = 0; }
else {
# print "check: ", $_;
# Do not check including the file_extension; might be .c or .cc or .C
if (/^File '$file_name/) {
# print "Found File:\n", $_;
$found_file = 1;
}
#Now we are doing the right line. Search for this file
if (/^Lines/ && $found_file == 1) {
# print "Found Lines:\n", $_;
s/([\s,0-9]*\.[0-9]+\%)\.*/$1/;
my $val = $1;
$average += $val;
$k++;
my $print_string = sprintf("%4d %40s %40s %3.2f\n", $k, $dir_name, $file_name, $val);
if ($calculate == 1) {
if ($val <= $percentage) {
$l++;
my $zero_string = sprintf("%4d %40s %40s %3.2f\n", $l, $dir_name, $file_name, $val);
print PERCENT $zero_string;
}
}
print COVERAGE $print_string;
# Need to detect the next round
$found_file = 0;
}
}
}
close(RESULT);
}
if ($num_files != 0){
print COVERAGE "==============================================================\n";
print COVERAGE "Average coverage was: ", $average/$num_files, " \n";
print COVERAGE "==============================================================\n";
}
close(INPUT);
close(COVERAGE);
if ($calculate == 1) {
close(PERCENT);
}
}