#! /usr/bin/env perl # -*- Mode: perl; -*- # # This script merges output from two files that should be applied to the # same source file. This is needed for MPICH on systems that support # gcov but do not support weak symbols. This script is invoked by # the coverage target in the Makefiles generated by automake. # $debug = 0; if ($#ARGV != 1) { print STDERR "gcovmerge.pl file1 file2 Merge the gcov output of file1 and file 2 and write the result to stdout "; exit(1); } $f1 = $ARGV[0]; $f2 = $ARGV[1]; open (I1, "<$f1" ) || die "Cannot open $f1"; open (I2, "<$f2" ) || die "Cannot open $f2"; while (!eof(I1) && !eof(I2)) { $s1 = ; $s2 = ; # The following apply to the preceeding line, and in the case of # a macro, there may be multiple lines. In the merge case, # we don't have a good way to interpret these, so we skip them # ^\s*branch\s+\d+\s+never executed # ^\s*call\s+\d+\s+never executed do { $foundSkip = 0; if ($s1 =~ /^\s*branch\s+\d+\s+never executed/ || $s1 =~ /^\s*call\s+\d+\s+never executed/) { $s1 = ; $foundSkip = 1; } if ($s2 =~ /^\s*branch\s+\d+\s+never executed/ || $s2 =~ /^\s*call\s+\d+\s+never executed/) { $s2 = ; $foundSkip = 1; } # Other cases: If text, then compare and output if ($s1 =~ /^\s*[A-za-z]+/) { $foundSkip = 1; if ($s1 eq $s2) { print $s1; $s1 = ; $s2 = ; } else { $s1 = ; } } if ($s2 =~ /^\s*[A-za-z]+/) { $foundSkip = 1; $s2 = ; } } while ($foundSkip); print "Comparing >$s1< and >$s2<\n" if $debug; $out = ""; if ($s1 ne $s2) { # See if these are in expected format: # ^\s*#####:\s*\d+:.* or # ^\s*\d+:\s*d+:.* or # ^\s*-:\s*d+:.* if ($s1 =~ /^\s*#+:\s*(\d+):(.*)/) { $s1count = -1; $s1linenum = $1; $s1line = $2; } elsif ($s1 =~ /^\s*(\d+):\s*(\d+):(.*)/) { $s1count = $1; $s1linenum = $2; $s1line = $3; } elsif ($s1 =~ /^\s*-:\s*(\d+):(.*)/) { $s1count = -1; $s1linenum = $1; $s1line = $2; } else { print "Unrecognized format for s1\n"; } if ($s2 =~ /^\s*#+:\s*(\d+):(.*)/) { $s2count = -1; $s2linenum = $1; $s2line = $2; } elsif ($s2 =~ /^\s*(\d+):\s*(\d+):(.*)/) { $s2count = $1; $s2linenum = $2; $s2line = $3; } elsif ($s2 =~ /^\s*-:\s*(\d+):(.*)/) { $s2count = -1; $s2linenum = $1; $s2line = $2; } else { print "Unrecognized format for s2\n"; } if ($s1line eq $s2line && $s1linenum == $s2linenum) { $nlines = 0; if ($s1count > 0) { $nlines += $s1count; } if ($s2count > 0) { $nlines += $s2count; } # Format line: number of characters in leader (9:5:.*) if ($nlines == 0) { $nlineTxt = " #####"; } else { $nlineTxt = sprintf( "%9d", $nlines ); } $linenumTxt = sprintf( "%5d", $s1linenum ); $out = "$nlineTxt:$linenumTxt:$s1line\n"; #$out = "$nlines:$s1linenum:$s1line\n"; } else { # This outputs both lines $out = $s1 . $s2; } } else { $out = $s1; } print $out; } # One of the two files has reached the EOF. Copy out the rest of the other file while (!eof(I1)) { $s1 = ; print $s1; } while (!eof(I2)) { $s2 = ; print $s2; }