Yarp.pl - Added manual XML parsing. Memory leaks using XML::Simple cause perl to run out of memory when parsing a large raptor log.
#!/usr/bin/perl
use strict;
#listdir_platform_MCL.PDK-3.5_baseline.log
#listdir_platform_MCL.PDK-3.5_post-clean.log
#listdir_platform_MCL.PDK-3.5_post-clean_delta.log
#listdir_platform_MCL.PDK-3.5_post-build-tools2.log
#listdir_platform_MCL.PDK-3.5_post-build-tools.log
#listdir_platform_MCL.PDK-3.5_post-build-main.log
#listdir_platform_MCL.PDK-3.5_s60-baseline.log
#listdir_platform_MCL.PDK-3.5_post-s60-clean.log
#listdir_platform_MCL.PDK-3.5_post-s60-clean_delta.log
#listdir_platform_MCL.PDK-3.5_post-s60-build-tools.log
#listdir_platform_MCL.PDK-3.5_post-s60-build-main.log
my $lowercase = 1;
my $useoutputfiles = 1;
my $path = shift @ARGV;
my $outputpath = shift @ARGV;
main();
sub main()
{
if($lowercase)
{
print "Running in lower case mode!\n";
}
my @listfiles = glob($path."listdir*");
my $gt_base;
my $gt_clean;
my $gt_main;
my $s60_base;
my $s60_clean;
my $s60_main;
foreach my $file (@listfiles)
{
if($file =~ m/s60/)
{
if($file =~ m/baseline/)
{
$s60_base = parsefile($file);
}
elsif($file =~ m/clean.log/)
{
$s60_clean = parsefile($file);
}
elsif($file =~ m/main.log/)
{
$s60_main = parsefile($file);
}
}
else
{
if($file =~ m/baseline/)
{
$gt_base = parsefile($file);
}
elsif($file =~ m/clean.log/)
{
$gt_clean = parsefile($file);
}
elsif($file =~ m/main.log/)
{
$gt_main = parsefile($file);
}
}
}
my $gt_try = diff($gt_base, $gt_clean);
my $gt_fail = diff($gt_base, $gt_main);
my $gt_built = diff($gt_try, $gt_fail);
# printgroup($gt_fail,'fail');
# printgroup($gt_built,'built');
my $s60_try = diff($s60_base, $s60_clean);
my $s60_fail = diff($s60_base, $s60_main);
my $s60_built = diff($s60_try, $s60_fail);
my $s60_add = diff($s60_main,$s60_base);
my $gt_add = diff($gt_main,$gt_base);
my $try = union($gt_try,$s60_try); # All the stuff we try to build
my $untouched = diff($gt_base,$try); # all the stuff we didn't try.
#printgroup($try,"try");
my $uptodate = finduptodate($path); # this is a bit dicey, 'cos it might get deleted/rebuilt by another part...
my $exported = findexported($path);
printgroup($exported,'exported');
$untouched = diff($untouched,union($exported,$uptodate));
printgroup($untouched,"untouched"); # 'clean' doesn't remove headers if they are 'uptodate'
#here's where the fun begins...
my $rebuildfail = intersect(union($gt_built,$gt_add), $s60_fail); #everything built in GT, minus stuff that failed in S60
my $rebuilt = intersect($gt_built, $s60_built); # everything built in both
my $built = diff(diff(union($gt_built, $s60_built),$rebuilt),$rebuildfail); # everything built, minus rebuilt, minus rebuildfail
my $fail = diff(union($gt_fail,$s60_fail),$rebuildfail); #everyhting that failed, minus the rebuild failures
my $added = diff(diff(union($gt_add,$s60_add),$exported),$rebuildfail); #all the stuff that got added, minus the stuff that filaed to rebuild
printgroup($built,"built");
printgroup($rebuilt,'rebuilt');
printgroup($rebuildfail,'rebuildfail');
printgroup($added,"added");
printgroup($fail,"failed");
$uptodate = diff($uptodate,union(union($added,$built),$exported)); #remove all stuff in other categories...'uptodate' was added late in the program
printgroup($uptodate,"uptodate"); # uptodate list isn't that good at the moment...put it last.
}
sub printgroup($$)
{
my $group = shift;
my $label = shift;
foreach my $key (sort keys %$group)
{
print $label." : ".$key."\t".$group->{$key}."\n";
}
if($useoutputfiles)
{
my $filename = $outputpath."results_$label.log";
open(FILE,">$filename") or die "Couldn't open $filename\n";
foreach my $key (sort keys %$group)
{
print FILE $key."\n";
}
close FILE;
}
}
sub diff($s1,$s2)
{
my $s1 = shift;
my $s2 = shift;
my %r;
foreach my $key (keys %$s1)
{
if(!defined $s2->{$key})
{
$r{$key} = $s1->{$key};
}
}
return \%r;
}
sub intersect($s1,$s2)
{
my $s1 = shift;
my $s2 = shift;
my %r;
foreach my $key (keys %$s1)
{
if(defined $s2->{$key})
{
$r{$key} = $s2->{$key};
}
}
return \%r;
}
sub union($s1,$s2)
{
my $s1 = shift;
my $s2 = shift;
my %r;
foreach my $key (keys %$s1)
{
$r{$key} = $s1->{$key};
}
foreach my $key (keys %$s2) #lazy
{
$r{$key} = $s2->{$key};
}
return \%r;
}
sub finduptodate($path)
{
my $path = shift;
my @files = glob($path."*compile.log");
my %results;
foreach my $file (@files)
{
print "Reading $file\n";
open(FILE,"<$file") or die "Cannot open $file\n";
while( my $line = <FILE>)
{
if($line =~ m/<info>Up-to-date:\s+(.+)<\/info>/)
{
my $str = $1;
$str =~ s/^\S:\///;
if($lowercase)
{
$str = lc($str);
}
$results{$str} = "";
# print $str;
}
}
close FILE;
}
return \%results;
}
sub findexported($)
{
my $path = shift;
my @files = glob($path."*compile.log");
my %results;
foreach my $file (@files)
{
print "Reading $file\n";
open(FILE,"<$file") or die "Cannot open $file\n";
while( my $line = <FILE>)
{
#<info>Copied u:/sf/app/conntools/emulatorlan/data/s60_32_default_snaps.xml to u:/epoc32/winscw/c/s60_32_default_snaps.xml</info>
if($line =~ m/<info>Copied\s+(\S+)\s+to\s+(\S+)<\/info>/)
{
my $str = $2; #we want the destination, not the source...
$str =~ s/^\S:\///;
if($lowercase)
{
$str = lc($str);
}
$results{$str} = "";
}
}
close FILE;
}
return \%results;
}
sub parsefile($file)
{
my $file = shift;
# my @results;
my %results;
print "Reading $file\n";
open(FILE,"<$file") or die "Couldn't open $file\n";
while(my $line = <FILE>)
{
$line =~ s/\n//;
if($line =~ m/\S+/)
{
if( $line !~/^epoc32/ ) #latest lists sometimes don't have this...
{
$line = "epoc32/".$line;
}
if( $line !~/epoc32\/build\// ) #ignore epoc32/build
{
if($lowercase)
{
$line = lc($line);
}
$results{$line} = "";
# $results{$line} = $file; #debugging
}
# push(@results,$line)
}
}
close FILE;
# return \@results;
return \%results;
}