Subject: | gcov2perl fails for "gcov -l" include files (patch) |
When a source a.cpp includes an include b.hpp and gcov is used with
option -l (--long-file-names) the resulting gcov file is called
a.cpp##b.hpp.gcov. For those gcov files gcov2perl tries to find the
source a.cpp##b.hpp (and fails of course).
The fix described in the patch to ticket 29362 uses the right idea to
fix the problem (take the source name from the first line of the gcov
file), but
a) it only works when the current directory is the directory with the
gcov file as the paths therein may be relative (and when I use an easy
"find -name '*.gcov' | xargs gcov2perl" I'm not in right directory)
b) it doesn't handle the case when the source still can't be found
c) I'm not sure, if $run{digests}{$f} shouldn't be set directly after
finding the correct source
See the attachment for a patch for version 0.64 solving all these topics
(and hopefully breaking nothing else ;-).
PS: For the error handling maybe a "last" instead of the
"close/chdir/return" is an alternative.
Subject: | gcov2perl-0.64.patch |
--- gcov2perl.org 2008-04-10 13:57:39.000000000 +0200
+++ gcov2perl 2009-04-08 09:24:24.106116000 +0200
@@ -17,6 +17,7 @@
use Devel::Cover::DB 0.64;
use File::Path;
+use File::Spec;
use Getopt::Long;
use Pod::Usage;
@@ -44,7 +45,11 @@
sub add_cover
{
- my ($file) = @_;
+ my ($path) = @_;
+ my ($vol, $dir, $file) = File::Spec->splitpath(File::Spec->rel2abs($path));
+ $dir = File::Spec->catpath($vol, $dir);
+ my $olddir = File::Spec->rel2abs(File::Spec->curdir());
+ chdir $dir or die "Can't chdir to $dir: $!\n";
my $f = $file;
$f =~ s/.gcov$//;
@@ -53,11 +58,22 @@
$run{collected} = ["statement"];
my $structure = Devel::Cover::DB::Structure->new;
$structure->add_criteria("statement");
- $run{digests}{$f} = $structure->set_file($f);
- open F, $file or die "Can't open $file: $!\n";
+ open F, $file or die "Can't open $path: $!\n";
while (<F>)
{
+ $f = $1 if m|^[^:]+:[^:]+:Source:(.*)$|;
+ unless (defined $run{digests}{$f})
+ {
+ unless (-f $f)
+ {
+ warn "no source $f found for $file in $dir\n";
+ close F or die "Can't close $path: $!\n";
+ chdir $olddir or die "Can't chdir to $olddir: $!\n";
+ return;
+ }
+ $run{digests}{$f} = $structure->set_file($f);
+ }
next unless my ($count, $line) = /(.{9}):\s*(\d+):/;
$count =~ s/\s+//g;
next if $count eq "-";
@@ -67,7 +83,7 @@
push @{$run{count}{$f}{statement}}, $count;
$structure->add_statement($f, $line);
}
- close F or die "Can't close $file: $!\n";
+ close F or die "Can't close $path: $!\n";
my $run = time . ".$$." . sprintf "%05d", rand 2 ** 16;
my $db = $Options->{db};
@@ -86,6 +102,8 @@
print STDOUT "gcov2perl: Writing coverage database to $db\n";
$cover->write;
+
+ chdir $olddir or die "Can't chdir to $olddir: $!\n";
}
sub main