Blob Blame History Raw
#! /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 = <I1>;
    $s2 = <I2>;
    # 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 = <I1>;
	    $foundSkip = 1;
	}
	if ($s2 =~ /^\s*branch\s+\d+\s+never executed/ ||
	    $s2 =~ /^\s*call\s+\d+\s+never executed/) {
	    $s2 = <I2>;
	    $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 = <I1>;
		$s2 = <I2>;
	    }
	    else {
		$s1 = <I1>;
	    }
	}
	if ($s2 =~ /^\s*[A-za-z]+/) {
	    $foundSkip = 1;
	    $s2 = <I2>;
	}
    } 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 = <I1>;
    print $s1;
}
while (!eof(I2)) {
    $s2 = <I2>;
    print $s2;
}