18852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#! @PERL@
28852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
38852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry##--------------------------------------------------------------------##
48852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry##--- Cachegrind's differencer.                         cg_diff.in ---##
58852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry##--------------------------------------------------------------------##
68852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
78852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  This file is part of Cachegrind, a Valgrind tool for cache
88852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  profiling programs.
98852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#
108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  Copyright (C) 2002-2010 Nicholas Nethercote
118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#     njn@valgrind.org
128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#
138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  This program is free software; you can redistribute it and/or
148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  modify it under the terms of the GNU General Public License as
158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  published by the Free Software Foundation; either version 2 of the
168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  License, or (at your option) any later version.
178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#
188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  This program is distributed in the hope that it will be useful, but
198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  WITHOUT ANY WARRANTY; without even the implied warranty of
208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  General Public License for more details.
228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#
238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  You should have received a copy of the GNU General Public License
248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  along with this program; if not, write to the Free Software
258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  02111-1307, USA.
278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#
288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#  The GNU General Public License is contained in the file COPYING.
298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# This is a very cut-down and modified version of cg_annotate.
328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryuse warnings;
358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryuse strict;
368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Global variables
398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Version number
428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $version = "@VERSION@";
438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Usage message.
458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $usage = <<END
468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusage: cg_diff [options] <cachegrind-out-file1> <cachegrind-out-file2>
478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry  options for the user, with defaults in [ ], are:
498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    -h --help             show this message
508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    -v --version          show version
518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    --mod-filename=<expr> a Perl search-and-replace expression that is applied
528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                          to filenames, eg. --mod-filename='s/prog[0-9]/projN/'
538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    --mod-funcname=<expr> like --mod-filename, but applied to function names
548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry  cg_diff is Copyright (C) 2010-2010 Nicholas Nethercote.
568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry  and licensed under the GNU General Public License, version 2.
578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry  Bug reports, feedback, admiration, abuse, etc, to: njn\@valgrind.org.
588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                                                
598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryEND
608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry;
618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# --mod-filename expression
638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $mod_filename = undef;
648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# --mod-funcname expression
668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $mod_funcname = undef;
678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#-----------------------------------------------------------------------------
698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Argument and option handling
708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#-----------------------------------------------------------------------------
718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrysub process_cmd_line() 
728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my ($file1, $file2) = (undef, undef);
748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    for my $arg (@ARGV) { 
768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        if ($arg =~ /^-/) {
788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            # --version
798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            if ($arg =~ /^-v$|^--version$/) {
808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                die("cg_diff-$version\n");
818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            } elsif ($arg =~ /^--mod-filename=(.*)/) {
838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                $mod_filename = $1;
848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            } elsif ($arg =~ /^--mod-funcname=(.*)/) {
868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                $mod_funcname = $1;
878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            } else {            # -h and --help fall under this case
898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                die($usage);
908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            }
918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        } elsif (not defined($file1)) {
938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            $file1 = $arg;
948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        } elsif (not defined($file2)) {
968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            $file2 = $arg;
978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        } else {
998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            die($usage);
1008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        }
1018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    }
1028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    # Must have specified two input files.
1048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    if (not defined $file1 or not defined $file2) {
1058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        die($usage);
1068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    }
1078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    return ($file1, $file2);
1098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
1108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#-----------------------------------------------------------------------------
1128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Reading of input file
1138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#-----------------------------------------------------------------------------
1148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrysub max ($$) 
1158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
1168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my ($x, $y) = @_;
1178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    return ($x > $y ? $x : $y);
1188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
1198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Add the two arrays;  any '.' entries are ignored.  Two tricky things:
1218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# 1. If $a2->[$i] is undefined, it defaults to 0 which is what we want; we turn
1228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#    off warnings to allow this.  This makes things about 10% faster than
1238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#    checking for definedness ourselves.
1248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# 2. We don't add an undefined count or a ".", even though it's value is 0,
1258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#    because we don't want to make an $a2->[$i] that is undef become 0
1268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#    unnecessarily.
1278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrysub add_array_a_to_b ($$) 
1288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
1298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my ($a, $b) = @_;
1308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $n = max(scalar @$a, scalar @$b);
1328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    $^W = 0;
1338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    foreach my $i (0 .. $n-1) {
1348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        $b->[$i] += $a->[$i] if (defined $a->[$i] && "." ne $a->[$i]);
1358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    }
1368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    $^W = 1;
1378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
1388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrysub sub_array_b_from_a ($$) 
1408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
1418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my ($a, $b) = @_;
1428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $n = max(scalar @$a, scalar @$b);
1448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    $^W = 0;
1458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    foreach my $i (0 .. $n-1) {
1468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        $a->[$i] -= $b->[$i];       # XXX: doesn't handle '.' entries
1478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    }
1488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    $^W = 1;
1498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
1508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Add each event count to the CC array.  '.' counts become undef, as do
1528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# missing entries (implicitly).
1538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrysub line_to_CC ($$)
1548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
1558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my ($line, $numEvents) = @_;
1568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my @CC = (split /\s+/, $line);
1588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    (@CC <= $numEvents) or die("Line $.: too many event counts\n");
1598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    return \@CC;
1608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
1618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrysub read_input_file($) 
1638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
1648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my ($input_file) = @_;
1658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    open(INPUTFILE, "< $input_file") 
1678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry         || die "Cannot open $input_file for reading\n";
1688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    # Read "desc:" lines.
1708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $desc;
1718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $line;
1728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    while ($line = <INPUTFILE>) {
1738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        if ($line =~ s/desc:\s+//) {
1748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            $desc .= $line;
1758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        } else {
1768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            last;
1778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        }
1788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    }
1798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    # Read "cmd:" line (Nb: will already be in $line from "desc:" loop above).
1818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    ($line =~ s/^cmd:\s+//) or die("Line $.: missing command line\n");
1828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $cmd = $line;
1838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    chomp($cmd);    # Remove newline
1848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    # Read "events:" line.  We make a temporary hash in which the Nth event's
1868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    # value is N, which is useful for handling --show/--sort options below.
1878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    $line = <INPUTFILE>;
1888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    (defined $line && $line =~ s/^events:\s+//) 
1898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        or die("Line $.: missing events line\n");
1908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my @events = split(/\s+/, $line);
1918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $numEvents = scalar @events;
1928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $currFileName;
1948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $currFileFuncName;
1958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my %CCs;                    # hash("$filename#$funcname" => CC array)
1978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $currCC = undef;         # CC array
1988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $summaryCC;
2008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    # Read body of input file.
2028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    while (<INPUTFILE>) {
2038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        s/#.*$//;   # remove comments
2048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        if (s/^(\d+)\s+//) {
2058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            my $CC = line_to_CC($_, $numEvents);
2068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            defined($currCC) || die;
2078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            add_array_a_to_b($CC, $currCC);
2088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        } elsif (s/^fn=(.*)$//) {
2108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            defined($currFileName) || die;
2118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            my $tmpFuncName = $1;
2128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            if (defined $mod_funcname) {
2138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                eval "\$tmpFuncName =~ $mod_funcname";
2148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            }
2158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            $currFileFuncName = "$currFileName#$tmpFuncName";
2168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            $currCC = $CCs{$currFileFuncName};
2178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            if (not defined $currCC) {
2188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                $currCC = [];
2198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                $CCs{$currFileFuncName} = $currCC;
2208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            }
2218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        } elsif (s/^fl=(.*)$//) {
2238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            $currFileName = $1;
2248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            if (defined $mod_filename) {
2258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                eval "\$currFileName =~ $mod_filename";
2268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            }
2278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            # Assume that a "fn=" line is followed by a "fl=" line.
2288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            $currFileFuncName = undef;  
2298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        } elsif (s/^\s*$//) {
2318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            # blank, do nothing
2328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        
2338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        } elsif (s/^summary:\s+//) {
2348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            $summaryCC = line_to_CC($_, $numEvents);
2358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            (scalar(@$summaryCC) == @events) 
2368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry                or die("Line $.: summary event and total event mismatch\n");
2378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        } else {
2398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry            warn("WARNING: line $. malformed, ignoring\n");
2408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        }
2418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    }
2428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    # Check if summary line was present
2448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    if (not defined $summaryCC) {
2458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        die("missing final summary line, aborting\n");
2468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    }
2478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    close(INPUTFILE);
2498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    return ($cmd, \@events, \%CCs, $summaryCC);
2518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
2528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
2548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# "main()"
2558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
2568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Commands seen in the files.  Need not match.
2578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $cmd1;
2588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $cmd2;
2598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Events seen in the files.  They must match.
2618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $events1;
2628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $events2;
2638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Individual CCs, organised by filename/funcname/line_num.
2658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# hashref("$filename#$funcname", CC array)
2668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $CCs1;
2678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $CCs2;
2688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Total counts for summary (an arrayref).
2708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $summaryCC1;
2718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $summaryCC2;
2728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
2748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Read the input files
2758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
2768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy ($file1, $file2) = process_cmd_line();
2778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry($cmd1, $events1, $CCs1, $summaryCC1) = read_input_file($file1);
2788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry($cmd2, $events2, $CCs2, $summaryCC2) = read_input_file($file2);
2798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
2818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Check the events match
2828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
2838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrymy $n = max(scalar @$events1, scalar @$events2);
2848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry$^W = 0;    # turn off warnings, because we might hit undefs
2858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryforeach my $i (0 .. $n-1) {
2868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    ($events1->[$i] eq $events2->[$i]) || die "events don't match, aborting\n";
2878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
2888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry$^W = 1;
2898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
2918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Do the subtraction: CCs2 -= CCs1
2928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
2938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrywhile (my ($filefuncname, $CC1) = each(%$CCs1)) {
2948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my $CC2 = $CCs2->{$filefuncname};
2958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    if (not defined $CC2) {
2968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        $CC2 = [];
2978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        sub_array_b_from_a($CC2, $CC1);     # CC2 -= CC1
2988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        $CCs2->{$filefuncname} = $CC2;
2998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    } else {
3008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        sub_array_b_from_a($CC2, $CC1);     # CC2 -= CC1
3018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    }
3028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
3038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrysub_array_b_from_a($summaryCC2, $summaryCC1);
3048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
3068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry# Print the result, in CCs2
3078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#----------------------------------------------------------------------------
3088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprint("desc: Files compared:   $file1; $file2\n");
3098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprint("cmd:  $cmd1; $cmd2\n");
3108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprint("events: ");
3118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryfor my $e (@$events1) {
3128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    print(" $e");
3138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
3148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprint("\n");
3158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrywhile (my ($filefuncname, $CC) = each(%$CCs2)) {
3178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    my @x = split(/#/, $filefuncname);
3198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    (scalar @x == 2) || die;
3208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    print("fl=$x[0]\n");
3228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    print("fn=$x[1]\n");
3238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    print("0");
3258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    foreach my $n (@$CC) {
3268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry        print(" $n");
3278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    }
3288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    print("\n");
3298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
3308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprint("summary:");
3328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryforeach my $n (@$summaryCC2) {
3338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry    print(" $n");
3348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
3358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprint("\n");
3368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry##--------------------------------------------------------------------##
3388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry##--- end                                                          ---##
3398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry##--------------------------------------------------------------------##
3408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry