Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 101 additions & 53 deletions bin/genhtml
Original file line number Diff line number Diff line change
Expand Up @@ -2544,10 +2544,6 @@ sub new
$diffMap, $verbose)
if ($lcovutil::func_coverage);

while (my ($lineNo, $deleted) = each(%{$self->[DELETED_LINE_LEADER]})) {
@$deleted =
sort({ $a->lineNo('base') <=> $b->lineNo('base') } @$deleted);
}
return $self;
}

Expand Down Expand Up @@ -2813,6 +2809,12 @@ sub _categorizeLineCov
my $val = $lineCovBase->value($bline);
$linedata->base_count($val);
}
# walk the diff data here to mark deleted regions so we can highlight
# them in the source view
my $deletedLineData = $diffMap->compute_deleted_lines($filename);
$self->[DELETED_LINE_LEADER] = $deletedLineData
if $deletedLineData;

if ($verbose) {
print(" line data map:\n");
foreach my $line (sort keys %$lineDataMap) {
Expand Down Expand Up @@ -2946,14 +2948,14 @@ sub _categorizeBranchCov
} else {
# the line has been deleted...just record the data
my $deleteKey = "<<<" . $base_line;
$branchCovLines{$deleteKey} = 1;
}
my $baseBranchData = $branchBaseline->value($base_line);
$data->baseline_branch($baseBranchData, $filename);
} # foreach line in baseline data

# go through all the branch data for each line, and categorize everything
foreach my $line (keys(%branchCovLines)) {
next if ($line <= 0); # ignore bogus
my $data = $self->lineMap()->{$line};
my $type = $data->type();
my $curr = $data->current_branch();
Expand Down Expand Up @@ -3119,6 +3121,7 @@ sub _categorizeMcdcCov
} else {
# the line has been deleted...just record the data
my $deleteKey = "<<<" . $base_line;
$mcdcCovLines{$deleteKey} = 1;
}
my $baseMcdcData = $mcdcBaseline->value($base_line);
$data->baseline_mcdc($baseMcdcData, $filename);
Expand Down Expand Up @@ -3583,16 +3586,35 @@ sub recreateBaseline

my $deleted = $self->[BASELINE]->{$self->findName($filename)};
my @lines;
my $didWarn = 0;
foreach my $chunk (@$diffs) {
if ($chunk->[TYPE] eq 'equal') {
my ($from, $to) = @{$chunk->[NEW]};
push(@lines, @{$currentSrcLines}[($from - 1) .. ($to - 1)]);
my $f = $from - 1;
my $t = $to - 1;
if ($t <= $#$currentSrcLines) {
push(@lines, @{$currentSrcLines}[$f .. $t]);
} else {
lcovutil::ignorable_error(
$lcovutil::ERROR_INCONSISTENT_DATA,

"$filename: inconsistent diff data vs current source code: diff refers to 'current' line range [$f:$t] but source code has only "
. scalar(@$currentSrcLines)
. " lines") unless $didWarn;
$didWarn = 1;
# if error is ignored, then append up to the data we have
while ($f <= $#$currentSrcLines) {
push(@lines, $currentSrcLines->[$f++]);
}
}
} elsif ($chunk->[TYPE] eq 'delete') {
my $r = $chunk->[OLD];
for (my $i = $r->[_START]; $i <= $r->[_END]; ++$i) {
die("missing baseline line $i")
unless defined($deleted) && exists($deleted->{$i});
push(@lines, $deleted->{$i});
my $d = $deleted->{$i};
die("undef deleted line $filename:$i") unless defined($d);
push(@lines, $d);
}
}
# else 'insert': nothing to do/those lines are not in baseline
Expand Down Expand Up @@ -3672,6 +3694,21 @@ sub type
return $chunk->[TYPE];
}

sub compute_deleted_lines
{
my ($self, $filename) = @_;
my $file = $self->findName($filename);
my $lineMap = $self->[LINEMAP]->{$file};
return undef unless defined($lineMap);
my %hash;
foreach my $chunk (@$lineMap) {
next unless $chunk->[TYPE] eq 'delete';

$hash{$chunk->[NEW]->[_START]} = $chunk->[OLD];
}
return %hash ? \%hash : undef;
}

sub baseline_file_name
{
# file may have been moved between baseline and current...
Expand Down Expand Up @@ -3965,7 +4002,7 @@ sub _read_udiff
}
foreach ($line) {
/^Git Root: (.+)$/ && do {
$self->[DIFF_ROOT] = $1;
$self->[DIFF_ROOT] = ReadCurrentSource::resolve_path($1, 1);
last;
};

Expand Down Expand Up @@ -4637,29 +4674,34 @@ sub _countBranchTlaData
my %foundBranchTlas;
my ($src_age, $developer, $srcLine);
my $lineTla = $lineData->tla();
$srcLine = $self->line($line);
if (!defined($srcLine)) {
lcovutil::ignorable_error($lcovutil::ERROR_UNMAPPED_LINE,

if ($SummaryInfo::tlaLocation{$lineTla} & 0x1) {
# skip check if line was deleted - no age/owner data for deleted code
$srcLine = $self->line($line);
if (!defined($srcLine)) {
lcovutil::ignorable_error($lcovutil::ERROR_UNMAPPED_LINE,
"no data for 'branch' line:$line, file:" . $self->path())
if (!$lcovutil::warn_once_per_file ||
lcovutil::warn_once($lcovutil::ERROR_UNMAPPED_LINE, $self->path()));
} else {
$srcLine->branchElem($differentialData);
if (@SourceFile::annotateScript &&
!grep(/^$lineTla$/, ('DUB', 'DCB'))) {
# deleted lines don't have owner data...
# if this line is not in the project (e.g., from some 3rd party
# library - then we might not have file history for it.
$src_age = $srcLine->age();
$developer = $srcLine->owner();

if (defined($developer)) {
my $shash = $self->[BRANCH_OWNERS];
if (!exists($shash->{$developer})) {
$shash->{$developer} = {};
$shash->{$developer}->{lines} = [];
if (!$lcovutil::warn_once_per_file ||
lcovutil::warn_once($lcovutil::ERROR_UNMAPPED_LINE,
$self->path()));
} else {
$srcLine->branchElem($differentialData);
if (@SourceFile::annotateScript &&
!grep(/^$lineTla$/, ('DUB', 'DCB'))) {
# deleted lines don't have owner data...
# if this line is not in the project (e.g., from some 3rd party
# library - then we might not have file history for it.
$src_age = $srcLine->age();
$developer = $srcLine->owner();

if (defined($developer)) {
my $shash = $self->[BRANCH_OWNERS];
if (!exists($shash->{$developer})) {
$shash->{$developer} = {};
$shash->{$developer}->{lines} = [];
}
push(@{$shash->{$developer}->{lines}}, $line);
}
push(@{$shash->{$developer}->{lines}}, $line);
}
}
}
Expand Down Expand Up @@ -4756,29 +4798,33 @@ sub _countMcdcTlaData
my %foundMcdcTlas;
my ($src_age, $developer, $srcLine);
my $lineTla = $lineData->tla();
$srcLine = $self->line($line);
if (!defined($srcLine)) {
lcovutil::ignorable_error($lcovutil::ERROR_UNMAPPED_LINE,
if ($SummaryInfo::tlaLocation{$lineTla} & 0x1) {
# skip check if line was deleted - no age/owner data for deleted code
$srcLine = $self->line($line);
if (!defined($srcLine)) {
lcovutil::ignorable_error($lcovutil::ERROR_UNMAPPED_LINE,
"no data for 'MC/DC' line:$line, file:" . $self->path())
if (!$lcovutil::warn_once_per_file ||
lcovutil::warn_once($lcovutil::ERROR_UNMAPPED_LINE, $self->path()));
} else {
$srcLine->mcdcElem($differentialData);
if (@SourceFile::annotateScript &&
!grep(/^$lineTla$/, ('DUB', 'DCB'))) {
# deleted lines don't have owner data...
# if this line is not in the project (e.g., from some 3rd party
# library - then we might not have file history for it.
$src_age = $srcLine->age();
$developer = $srcLine->owner();

if (defined($developer)) {
my $shash = $self->[MCDC_OWNERS];
if (!exists($shash->{$developer})) {
$shash->{$developer} = {};
$shash->{$developer}->{lines} = [];
if (!$lcovutil::warn_once_per_file ||
lcovutil::warn_once($lcovutil::ERROR_UNMAPPED_LINE,
$self->path()));
} else {
$srcLine->mcdcElem($differentialData);
if (@SourceFile::annotateScript &&
!grep(/^$lineTla$/, ('DUB', 'DCB'))) {
# deleted lines don't have owner data...
# if this line is not in the project (e.g., from some 3rd party
# library - then we might not have file history for it.
$src_age = $srcLine->age();
$developer = $srcLine->owner();

if (defined($developer)) {
my $shash = $self->[MCDC_OWNERS];
if (!exists($shash->{$developer})) {
$shash->{$developer} = {};
$shash->{$developer}->{lines} = [];
}
push(@{$shash->{$developer}->{lines}}, $line);
}
push(@{$shash->{$developer}->{lines}}, $line);
}
}
}
Expand Down Expand Up @@ -11313,12 +11359,14 @@ sub write_source_line(*$$$$$$$)
my $lineNumTag = 'lineNum';
my $lineNumTitle = '';
if (defined($deletedLines)) {
my $first = $deletedLines->[0]->lineNo('base');
my $last = $deletedLines->[-1]->lineNo('base');
my $first = $deletedLines->[0];
my $last = $deletedLines->[1];
die("invalid deleted lines array") unless $first <= $last;
my $count = $last - $first + 1;
$lineNumTitle = ' title="'
.
(($first != $last) ? "removed lines [$first:$last]" :
(($first != $last) ?
"removed $count lines ([$first:$last] inclusive)" :
"removed line $first") .
' from baseline version"';
$lineNumTag = 'lineNumWithDelete';
Expand Down
14 changes: 11 additions & 3 deletions example/README
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
To see some examples of LCOV generated HTML coverage reports,
and point a web browser into the resulting reports:
To see some examples of LCOV generated HTML coverage reports, run

$ make

in the .../examples directory, review the 'make' log and the generated
data, and then point a web browser into the resulting reports.

The example builds with GCC by default.
You will need to make a few changes if you want to use LLVM instead.


Default view:

Expand Down Expand Up @@ -40,7 +48,7 @@ Differential coverage:
Code review:

- point your browser to
exampleRepo/differential/index.html
exampleRepo/review/index.html

- This example builds on the "Differential coverage" example, above
to emulate a possible code review methodology in which adds code
Expand Down
7 changes: 4 additions & 3 deletions scripts/select.pm
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,12 @@ sub save
sub restore
{
my ($self, $data) = @_;
$self->[TOTAL] += $data->[TOTAL];
foreach my $i (0 .. $#$data) {
$self->[TOTAL] += $data->[0];
my $d = $data->[1];
foreach my $i (0 .. $#$d) {
my $l = $self->[COUNTS]->[$i];
foreach my $j (0 .. $#$l) {
$l->[$j] += $data->[$i]->[$j];
$l->[$j] += $d->[$i]->[$j];
}
}
}
Expand Down
26 changes: 24 additions & 2 deletions tests/gendiffcov/simple/script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -654,15 +654,37 @@ for opt in "" "--show-details" "--hier"; do
for o in "" $opt ; do
OPTS="$TEST_OPTS $o"
outdir=./differential${EXT}${o}
outFile=differential${EXT}${o}.log
echo ${LCOV_HOME}/bin/genhtml $OPTS --baseline-file ./baseline.info --diff-file diff.txt --annotate-script `pwd`/annotate.sh --show-owners all --ignore-errors source -o $outdir ./current.info $IGNORE $POPUP
$COVER ${GENHTML_TOOL} $OPTS --baseline-file ./baseline.info --diff-file diff.txt --annotate-script `pwd`/annotate.sh --show-owners all --ignore-errors source -o $outdir ./current.info $GENHTML_PORT $IGNORE $POPUP
if [ 0 != $? ] ; then
$COVER ${GENHTML_TOOL} $OPTS --baseline-file ./baseline.info --diff-file diff.txt --annotate-script `pwd`/annotate.sh --show-owners all --ignore-errors source -o $outdir ./current.info $GENHTML_PORT $IGNORE $POPUP 2>&1 | tee $outFile
if [ 0 != ${PIPESTATUS[0]} ] ; then
echo "ERROR: genhtml $outdir failed (2)"
status=1
if [ 0 == $KEEP_GOING ] ; then
exit 1
fi
fi
# expect to see non-zero deleted branch count
for tla in DUB DCB ; do
grep -E branch:.+$(tla):1 $outFile
if [ 0 != $? ] ; then
echo "ERROR: did not find expected $tla branches"
status = 1
if [ 0 != $KEEP_GOING ] ; then
exit 1
fi
fi
if [ "$ENABLE_MCDC" == '1' ] ; then
grep -E mcdc:.+$(tla):1 $outFile
if [ 0 != $? ] ; then
echo "ERROR: did not find expected $tla branches"
status = 1
if [ 0 != $KEEP_GOING ] ; then
exit 1
fi
fi
fi
done

if [[ $OPTS =~ "show-details" ]] ; then
found=0
Expand Down
2 changes: 1 addition & 1 deletion tests/gendiffcov/simple/simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ main(int ac, char ** av)
#endif
std::cout << " this code will be DUB" << std::endl;
}
if (cond == 1)
if (1 == cond)
std::cout << "cond == " << cond << "... code exercised" << std::endl;// LBC
else if (cond == 2)
std::cout << "cond == " << cond << "... code not exercised" << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion tests/gendiffcov/simple/simple2.cpp.annotated
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
1|henry.cox|274| std::cout << " this code will be EUB" << std::endl;
1|henry.cox|274|#endif
1|henry.cox|274| }
1|henry.cox|274| if (cond == 1)
1|henry.cox|3| if (1 == cond)
7|roderick.glossop|122| std::cout << "cond == " << cond << "... code exercised" << std::endl;// LBC
1|henry.cox|274| else if (cond == 2)
1|henry.cox|274| std::cout << "cond == " << cond << "... code exercised" << std::endl;
Expand Down