📄 cov2html.in
字号:
#! /usr/bin/perl# -*- Mode:perl ; -*-## This file converts a coverate data file, produced by the simple coverage# package, into an html file showing the covered and uncovered parts of the # code.## The format of the simple coverage package data is# routine \t nargs \t #calls \t sourcefile \t first-line \t last-line \n# sorted by routine name and number of arguments.## NOT YET WRITTEN# This program reads the data file; then takes each different source file# and creates a simple HTML version, using color to accent uncovered and# covered code## First step:# read file. Save data as# %SourceFiles{ name } => internal hash name# %internalhashname{ firstline } => "lastline:routine:argcount:ncall"## Then we can sort on the keys and the use that for "next line with covered"## Reading the source code, we check each# COVERAGE_BEGIN/END# for a corresponding entry in the data (in internalhashname). Surround# the block with pale green or red if covered or uncovered.# sub ReadCovData { my $filename = $_[0]; my $srccnt = 0; open FD, "<$filename" || die "Could not open coverage file $filename\n"; while (<FD>) { chomp; my ($routine,$argcnt,$callcnt,$srcfile,$firstline,$lastline) = split(/\t/,$_); if (!defined($SourceFiles{$srcfile})) { $srccnt++; $srchash = "srchash$srccnt"; $SourceFiles{$srcfile} = $srchash; } else { $srchash = $SourceFiles{$srcfile}; } $$srchash{$firstline} = "$lastline\t$routine\t$argcnt\t$callcnt"; } close FD;}# For debuggingsub DebugWriteCovData { foreach my $srcfile (keys(%SourceFiles)) { my $srchash = $SourceFiles{$srcfile}; print "srchash = $srchash\n"; foreach my $line (sort(keys(%$srchash))) { print "$line\t$$srchash{$line}\n"; } }}# Read a source file and annotate it based on the information in the# srchash## There are three states for the annoted file:# nocode - not within a coverage block# incov - within AND covered# uncov - within and NOT covered#%annotecolors = ( "nocode" => "white", "incov" => "lightgreen", "uncov" => "red", );# Save routine => file:line%coveredRoutines = ();%uncoveredRoutines = ();sub ReadAndAnnoteSrcfile { my $srcfile = $_[0]; my $srchash = $_[1]; # *name* of the source hash my $annotefile = $_[2]; my $linecount = 0; my $state = "nocode", $newstate; my $bgcolor, $newcolor; $bgcolor = $annotecolors{$state}; open FD, "<$srcfile" || die "Cannot open source file $srcfile\n"; open OUTFD, ">$annotefile" || die "Cannot open annotation file $annotefile\n"; &WriteHTMLHeader( OUTFD, "Coverage file for $srcfile" ); print OUTFD "<TABLE WIDTH=100%><TR><TD BGCOLOR=$bgcolor><PRE>"; while (<FD>) { $linecount ++; if (/COVERAGE_START\(([^,]*),([^\)]*)\)/) { my $routine = $1; my $argcnt = $2; my $rname = "$routine-$argcnt"; if (defined($$srchash{$linecount})) { $newstate = "incov"; $coveredRoutines{$rname} = "$srcfile:$linecount"; } else { $newstate = "uncov"; $uncoveredRoutines{$rname} = "$srcfile:$linecount"; } } elsif (/COVERAGE_END/) { $newstate = "nocode"; print OUTFD &HTMLify( $_ ); } if ($newstate eq $state) { print OUTFD &HTMLify( $_ ); } else { # State transitions happen at either the beginning or the # If at the end, the line has already been output. print OUTFD "</PRE></TD></TR></TABLE>\n"; $state = $newstate; $bgcolor = $annotecolors{$state}; print OUTFD "<TABLE WIDTH=100%><TR><TD BGCOLOR=\"$bgcolor\"><PRE>"; if ($newstate ne "nocode") { print OUTFD &HTMLify( $_ ); } } } # Finish off the last table. print OUTFD "</PRE></TD></TR></TABLE>\n"; close FD; &WriteHTMLTrailer( OUTFD ); close OUTFD;}# Summary report# TODO : compare the routines found to a master list of all routines.# generate a third list of unseen routines$maxcol = 4;sub CoverageSummary { my ($filename) = @_; my $col; my %unseenRoutines = %allRoutines; open FD, ">$filename" || die "Cannot open summary file $filename\n"; &WriteHTMLHeader( FD, "Coverage Summary" ); print FD "<h2>Covered routines</h2>\n"; print FD "<TABLE WIDTH=100%>"; $col = 1; foreach $name (sort(keys(%coveredRoutines))) { if ($col == 1) { print FD "<TR>"; } my ($routine,$argcnt) = split(/-/,$name); print FD "<TD>$routine</TD>"; if (defined($unseenRoutines{$routine})) { delete $unseenRoutines{$routine}; } if ($col++ == $maxcol) {$col = 1; print FD "</TR>\n"; } } while ($col != 1) { print FD "<TD></TD>"; if ($col++ == $maxcol) {$col = 1; print FD "</TR>\n"; } } print FD "</TABLE>\n"; print FD "<h2>Uncovered routines</h2>\n"; print FD "<TABLE WIDTH=100%>"; $col = 1; foreach $name (sort(keys(%uncoveredRoutines))) { if ($col == 1) { print FD "<TR>"; } my ($routine,$argcnt) = split(/-/,$name); my $where = $uncoveredRoutines{$name}; $where =~ s/.*\///; print FD "<TD>$routine($where)</TD>"; if ($col++ == $maxcol) {$col = 1; print FD "</TR>\n"; } if (defined($unseenRoutines{$routine})) { delete $unseenRoutines{$routine}; } } while ($col != 1) { print FD "<TD></TD>"; if ($col++ == $maxcol) {$col = 1; print FD "</TR>\n"; } } print FD "</TABLE>\n"; print FD "<h2>Unseen routines</h2>\n"; print FD "<TABLE WIDTH=100%>"; $col = 1; foreach $name (sort(keys(%unseenRoutines))) { if ($col == 1) { print FD "<TR>"; } my $routine = $name; print FD "<TD>$routine</TD>"; if ($col++ == $maxcol) {$col = 1; print FD "</TR>\n"; } } while ($col != 1) { print FD "<TD></TD>"; if ($col++ == $maxcol) {$col = 1; print FD "</TR>\n"; } } print FD "</TABLE>\n"; &WriteHTMLTrailer( FD ); close FD;}%coveredRoutines = ();%uncoveredRoutines = ();%allRoutines = (); # Not yet usedsub ReadAllList { my $filename = $_[0]; open FD, "<$filename" || return 0; while (<FD>) { chomp; s/\r//; $allRoutines{$_} = 1; } close FD;}# --------------------------------------------------------------------------sub WriteHTMLHeader { my ($FD,$title) = @_; print $FD "<HTML>\n<HEAD>\n<TITLE>$title</TITLE></HEAD>\n"; print $FD "<BODY BGCOLOR=\"FFFFFF\">\n";}sub WriteHTMLTrailer { my $FD = $_[0]; print $FD "</BODY>\n</HTML>\n";}# HTMLify# Take an input line and make it value HTMLsub HTMLify { my $line = $_[0]; $line =~ s/\&/--AMP--/g; $line =~ s/>/>/g; $line =~ s/</</g; $line =~ s/--AMP--/&/g; return $line;}# --------------------------------------------------------------------------## Temp for testing&ReadAllList( "mpi.dat" );# Remove those deprecated MPI routines that are not in the C++ binding# FIXME: Check that C++ binding does not include theseforeach my $oldname ("Type_ub", "Type_lb", "Attr_delete", "Attr_get", "Attr_put", "Keyval_free", "Keyval_create", "Errhandler_get", "Errhandler_set", "Errhandler_create", "Address", "Type_struct", "Type_extent", "Type_hvector", "Type_hindexed" ) { delete $allRoutines{$oldname};}&ReadCovData( "cov.dat" );# Generate the outputforeach $srcfile (keys(%SourceFiles)) { my $srchash = $SourceFiles{$srcfile}; my $annotefile; $annotefile = $srcfile; # Still needed: A way to update the directory paths. This # simply removes -all- directories. We may instead # want a way to remove a prefix only $annotefile =~ s/.*\///g; $annotefile .= ".htm"; print "annote file = $annotefile\n"; &ReadAndAnnoteSrcfile( $srcfile, $srchash, $annotefile );}&CoverageSummary( "cov.sum.htm" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -