--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/Read_me.txt Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,3 @@
+What's in this directory
+
+Various Perl scripts, generally about list processing and analysis
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/compare_7z_listings.pl Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Compare two 7z listings, looking for files present in both
+
+use strict;
+
+my %first_files;
+my $line;
+my $file_index = -1;
+
+while ($line=<>)
+ {
+
+ if ($line =~ /^Listing archive/)
+ {
+ $file_index++;
+ print "$file_index: Processing $line";
+ next;
+ }
+
+ # 2009-04-30 11:26:58 D.... 0 0 epoc32\cshlpcmp_template
+ # 2009-03-20 22:22:18 ..... 72192 16307 epoc32\cshlpcmp_template\cshelp2000.dot
+
+ next if (length($line) < 54);
+
+ my $dir_attribute = substr($line, 20, 1);
+ if ($dir_attribute eq ".")
+ {
+ chomp $line;
+ my $fullpath = substr($line, 53);
+
+ if ($file_index == 0)
+ {
+ # first file
+ $first_files{$fullpath} = $line;
+ next;
+ }
+ if (defined $first_files{$fullpath})
+ {
+ print "Duplicate filename: $fullpath\n";
+ print "\t$first_files{$fullpath}\n\t$line\n";
+ next
+ }
+ }
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/find_public_apis.pl Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,88 @@
+#!/usr/bin/perl
+
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Identify "Public APIs" - defined as
+# 1. Files in epoc32\include which are not in epoc32\include\platform,
+# 2. And contain either no Symbian API classification doxygen tags (Public by export)
+# 3. Or contain @publishedAll (Public by tag - now deprecated)
+
+use strict;
+my $debug = 0;
+
+sub is_public_api($$)
+ {
+ my ($file,$name) = @_;
+
+ if ($name =~ /^epoc32\/include\/platform\//)
+ {
+ # /epoc32/include/platform files are "Platform by export"
+ return 0; # Not public
+ }
+
+ open FILE, "<$file" or print "ERROR: Cannot open $file: $!\n" and return 1; # assume Public
+ my @lines = <FILE>; # they are all of a modest size
+ close FILE;
+
+ my @apitaglines = grep /\@published|\@internal/, @lines;
+ if (scalar @apitaglines == 0)
+ {
+ # no API classification tags - must be "Public by export"
+ return 1; # Public API
+ }
+
+ if ($debug)
+ {
+ print join("\n\t", $file, @apitaglines), "\n";
+ }
+ my @publishedAll = grep /\@publishedAll/, @apitaglines;
+ if (scalar @publishedAll == 0)
+ {
+ # the API classification tags are all @publishedPartner or @internal
+ return 0; # not public
+ }
+ # contains at least one @publishedAll element - must be "Public by tag"
+ return 1; # Public API
+ }
+
+sub scan_directory($$)
+ {
+ my ($path, $name) = @_;
+
+ opendir DIR, $path;
+ my @files = grep !/^\.\.?$/, readdir DIR;
+ closedir DIR;
+
+ foreach my $file (@files)
+ {
+ my $newpath = "$path/$file";
+ my $newname = "$name/$file";
+
+ if (-d $newpath)
+ {
+ scan_directory($newpath, $newname);
+ next;
+ }
+
+ if (is_public_api($newpath,$newname))
+ {
+ print "$newname\n";
+ }
+ else
+ {
+ # print "PARTNER\t$newname\n";
+ }
+ }
+ }
+
+scan_directory("/epoc32/include", "epoc32/include");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/sbs_findstr.pl Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,43 @@
+#! perl
+
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Filter an SBSv2 log to keep only recipes which match a specified RE
+
+use strict;
+
+my $expression = shift @ARGV;
+my $line;
+my $skipping = 1;
+
+while ($line =<>)
+ {
+ if (substr($line,0,9) eq "</recipe>")
+ {
+ print $line if ($skipping == 0);
+ $skipping = 1; # set this to 0 to get the "between recipes" stuff
+ next;
+ }
+ if (substr($line,0,8) eq "<recipe ")
+ {
+ if ($line =~ /$expression/io)
+ {
+ $skipping = 0;
+ }
+ else
+ {
+ $skipping = 1;
+ }
+ }
+ print $line if ($skipping == 0);
+ }
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/scan_antlogs.pl Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,216 @@
+#!/usr/bin/perl
+
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Parse "ant" logs from SBS build to determine missing source files
+
+my $pdk_src = "../.."; # path to sf tree - correct from "build/output"
+
+my %missing_files;
+my %damaged_components;
+my %excluded_things;
+my %abld_import;
+my %damaged_bldinfs;
+
+sub canonical_path($)
+ {
+ my ($path) = @_;
+ my @bits = split /\//, $path;
+ my @newbits = ();
+
+ foreach my $bit (@bits)
+ {
+ next if ($bit eq ".");
+ if ($bit eq "..")
+ {
+ pop @newbits;
+ next;
+ }
+ push @newbits, $bit;
+ }
+ return join("/", @newbits);
+ }
+
+sub excluded_thing($$$)
+ {
+ my ($path, $missing, $reason) = @_;
+ if (!defined $excluded_things{$path})
+ {
+ @{$excluded_things{$path}} = ();
+ }
+ push @{$excluded_things{$path}}, $missing;
+ # print "Missing $missing from excluded $path ($reason)\n";
+ }
+
+sub do_missing_file($$$)
+ {
+ my ($missing, $missing_from, $reason) = @_;
+
+ $missing = canonical_path($missing);
+ $missing_from = canonical_path($missing_from);
+
+ my $component = "??";
+ if ($missing_from ne "??")
+ {
+ my @dirs = split /\//, $missing_from;
+ shift @dirs if ($dirs[0] eq "sf");
+
+ $path = $pdk_src . "/sf/$dirs[0]/$dirs[1]";
+ if (!-e $path)
+ {
+ # no sign of the package
+ excluded_thing($path, $missing, $reason);
+ return;
+ }
+ $path .= "/$dirs[2]";
+ if (!-e $path)
+ {
+ # no sign of the collection
+ excluded_thing($path, $missing, $reason);
+ return;
+ }
+ $path .= "/$dirs[3]";
+ if (!-e $path)
+ {
+ # no sign of the component
+ excluded_thing($path, $missing, $reason);
+ return;
+ }
+ $component = join("/", $dirs[0], $dirs[1], $dirs[2], $dirs[3]);
+ }
+
+ $missing_files{$missing} = $reason if ($missing ne "??");
+
+ if (!defined $damaged_components{$component})
+ {
+ @{$damaged_components{$component}} = ();
+ }
+ push @{$damaged_components{$component}}, $missing;
+ }
+
+sub scan_logfile($)
+{
+ my ($logfile) = @_;
+
+ open FILE, "<$logfile" or print "Error: cannot open $logfile: $!\n" and return;
+
+ my $line;
+ while ($line = <FILE>)
+ {
+ # Could not export s:/sf/mw/classicui/commonuisupport/uikon/docs/Uikon_1.2_Caps_Lock_Extension.doc to s:/epoc32/engdoc/application_framework/uikon/uikon_1.2_caps_lock_extension.doc
+ if ($line =~ /^Could not export .*\/(sf\/.*) to .:\/(epoc32\/.*)$/)
+ {
+ my $source = $1;
+ my $exported = $2;
+ if (-e "m:/$exported")
+ {
+ $abld_import{$source} = $exported;
+ }
+ next;
+ }
+ # Source of export does not exist: s:/sf/mw/messagingmw/messagingfw/msgtests/group/msgerr.ra
+ # Source zip for export does not exist: s:/sf/os/deviceplatformrelease/S60LocFiles/data/96.zip
+ if ($line =~ /^Source (of|zip for) export does not exist.\s+.*\/(sf\/.*)$/)
+ {
+ do_missing_file($2, "??", "source of export");
+ next;
+ }
+ # No bld.inf found at sf/os/buildtools/toolsandutils/burtestserver/Group in s:/output/build/canonical_system_definition_GT_tb91sf.xml
+ # No bld.inf found at s:/sf/adaptation/stubs/licensee_tsy_stub/group in s:/output/build/canonical_system_definition_S60_5_1_clean.xml
+ if ($line =~ /No bld.inf found at (.*\/)?(sf\/.*) in /i)
+ {
+ my $bldinf = "$2/bld.inf";
+
+ do_missing_file($bldinf, $bldinf, "no bld.inf");
+ $damaged_bldinfs{"$bldinf\t(missing)"} = 1;
+ next;
+ }
+ # D:/Symbian/Tools/PDT_1.0/raptor/win32/mingw/bin/cpp.exe: s:/sf/os/networkingsrv/networksecurity/ipsec/group/bld.inf:19:42: ../eventmediator/group/bld.inf: No such file or directory
+ if ($line =~ /cpp.exe: .*\/(sf\/[^:]*):.*\s+([^:]+): No such file/)
+ {
+ my $parent = $1;
+ my $relative = $2;
+
+ if ($parent =~ /\.inf$/i)
+ {
+ my $parent = canonical_path($parent);
+ $damaged_bldinfs{"$parent\t$relative"} = 1;
+ }
+ do_missing_file("$parent/../$relative", $parent, "#include");
+ next;
+ }
+ }
+ close FILE;
+ }
+
+ my @logfiles = map(glob,@ARGV);
+ foreach my $logfile (@logfiles)
+ {
+ print "Scanning $logfile...\n";
+ scan_logfile($logfile);
+ }
+
+ printf "%d Excluded things\n", scalar keys %excluded_things;
+ foreach my $component (sort keys %excluded_things)
+ {
+ my @list = @{$excluded_things{$component}};
+ my %hash;
+ foreach my $missing (@list)
+ {
+ $hash{$missing} = 1;
+ }
+ printf "%s\t%d\n", $component, scalar keys %hash;
+ print "\t", join("\n\t", sort keys %hash), "\n";
+ }
+ print "\nDamaged components\n";
+ foreach my $component (sort keys %damaged_components)
+ {
+ my @list = @{$damaged_components{$component}};
+ my %hash;
+ foreach my $missing (@list)
+ {
+ $hash{$missing} = 1;
+ }
+ printf "%s\t%d\n", $component, scalar keys %hash;
+ print "\t", join("\n\t", sort keys %hash), "\n";
+ }
+ print "\nMissing files\n";
+ foreach my $missing (sort keys %missing_files)
+ {
+ my $exported = $abld_import{$missing};
+ $exported = "(not in PDK)" if (!defined $exported);
+ my $reason = $missing_files{$missing};
+ my @dirs = split /\//, $missing;
+ my $path = shift @dirs;
+ my $dir;
+
+ while ($dir = shift @dirs)
+ {
+ if (-e "$pdk_src/$path/$dir")
+ {
+ # still exists at this point
+ $path .= "/$dir";
+ next;
+ }
+ print "\t$reason\t$path\t\t", join("/", $dir,@dirs), "\t$exported\n";
+ last;
+ }
+ }
+
+ print "\nDamaged bld.infs\n";
+ print join("\n", sort keys %damaged_bldinfs, "");
+
+ print "\n\n";
+ printf "%d files missing from ", scalar keys %missing_files;
+ printf "%d damaged components\n", scalar keys %damaged_components;
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/scan_epocwind.pl Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,65 @@
+#! perl
+
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Summarise epocwind.out to identify repetitious and uninteresting comments
+
+use strict;
+
+my %count_by_word;
+my %unique_message;
+
+my $line;
+while ($line = <>)
+ {
+ chomp $line;
+
+ # 494.390 CTouchFeedbackImpl::SetFeedbackArea - Begin
+ my $message = substr($line, 10); # ignore the timestamp & the tab character
+ if (!defined $unique_message{$message})
+ {
+ $unique_message{$message} = 0;
+ }
+ $unique_message{$message} ++;
+
+ my ($junk,$count,$word) = split /\s+|:/, $line;
+ $word = $message if (!defined $word); # no spaces in the line at all
+
+ if (!defined $count_by_word{$word})
+ {
+ $count_by_word{$word} = 0;
+ }
+ $count_by_word{$word} ++;
+
+ }
+
+my @repeated_lines;
+foreach my $message (keys %unique_message)
+ {
+ my $count = $unique_message{$message};
+ next if ($count < 10);
+ push @repeated_lines, sprintf "%7d\t%s\n", $count, $message;
+ }
+
+print "Repeated lines\n", reverse sort @repeated_lines, "\n";
+
+my @repeated_words;
+foreach my $word (keys %count_by_word)
+ {
+ my $count = $count_by_word{$word};
+ next if ($count < 10);
+ push @repeated_words, sprintf "%7d\t%s\n", $count, $word;
+ }
+
+print "Repeated words (rest of the line may vary\n", reverse sort @repeated_words, "\n";
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/scan_sbs_makefile.pl Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,121 @@
+#!/usr/bin/perl
+
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Approximate "abld -what" from SBS Makefile.default and Makefile.export
+
+use strict;
+my $component = "";
+my $mmp = "";
+my $linkpath = "";
+my $target = "";
+my $targettype = "";
+my $exports = "";
+
+sub completed
+ {
+ if ($component ne "")
+ {
+ if ($exports eq "")
+ {
+ # Compilation makefile target
+ print "$component\t$mmp\t$linkpath/$target.$targettype\n";
+ }
+ else
+ {
+ # export makefile
+ my @exportpairs = split / /, $exports;
+ foreach my $pair (@exportpairs)
+ {
+ my ($dest,$src) = split /<-/, $pair;
+ $dest =~ s/^.:\///;
+ print "$component\texport\t$dest\n";
+ }
+ }
+ }
+ $component = "";
+ $mmp = "";
+ $linkpath = "";
+ $target = "";
+ $targettype = "";
+ $exports = "";
+ }
+
+sub scan_logfile($)
+ {
+ my ($logfile) = @_;
+
+ open FILE, "<$logfile" or print "Error: cannot open $logfile: $!\n" and return;
+
+ my $line;
+ while ($line = <FILE>)
+ {
+ # COMPONENT_META:=s:/sf/os/boardsupport/emulator/emulatorbsp/bld.inf
+ # PROJECT_META:=s:/sf/os/boardsupport/emulator/emulatorbsp/cakdwins.mmp
+ # LINKPATH:=winscw/udeb
+ # TARGET:=ekdata
+ # TARGETTYPE:=dll
+ # EXPORT:=s:/epoc32/tools/scanlog.pl<-s:/sf/os/buildtools/bldsystemtools/buildsystemtools/scanlog/scanlog.pl more...
+ # MAKEFILE_LIST:=
+
+ if ($line =~ /^(COMPONENT_META|PROJECT_META|LINKPATH|TARGET|REQUESTEDTARGETEXT|EXPORT|MAKEFILE_LIST):=(.*)$/o)
+ {
+ my $variable = $1;
+ my $value = $2;
+
+ if ($variable eq "MAKEFILE_LIST")
+ {
+ completed();
+ next;
+ }
+ if ($variable eq "COMPONENT_META")
+ {
+ $component = $value;
+ next;
+ }
+ if ($variable eq "PROJECT_META")
+ {
+ $mmp = $value;
+ next;
+ }
+ if ($variable eq "LINKPATH")
+ {
+ $linkpath = $value;
+ next;
+ }
+ if ($variable eq "TARGET")
+ {
+ $target = $value;
+ next;
+ }
+ if ($variable eq "REQUESTEDTARGETEXT")
+ {
+ $targettype = $value;
+ next;
+ }
+ if ($variable eq "EXPORT")
+ {
+ $exports = $value;
+ next;
+ }
+ }
+ }
+ close FILE;
+ }
+
+ my @logfiles = map(glob,@ARGV);
+ foreach my $logfile (@logfiles)
+ {
+ # print "Scanning $logfile...\n";
+ scan_logfile($logfile);
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/sfl_exports.pl Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,59 @@
+#!/usr/bin/perl
+
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Match list of "sfl" files in epoc32 tree with whatlog information
+
+use strict;
+
+my %sfl_files;
+my $line;
+
+while ($line = <>)
+ {
+ chomp $line;
+
+ # output of findstr /m /s /C:"www.symbianfoundation.org/legal/sfl-v" epoc32\*
+ # epoc32\data\z\private\101f7989\backup_registration.xml
+ if ($line =~ /^epoc32/)
+ {
+ $line =~ s/\\/\//g; # Unix directory separators please
+ $sfl_files{$line} = "unknown";
+ next;
+ }
+
+ # ..\/platform_MCL.PDK-3.8__winscw.whatlog_armv5.whatlog_multiple_threadWHAT_GT_tb91sf_compile.log(6824),
+ # sf/os/boardsupport/emulator/emulatorbsp/bld.inf,
+ # sf/os/boardsupport/emulator/emulatorbsp/specific/winscomm.h,
+ # export,
+ # epoc32/include/wins/winscomm.h,
+ # h
+ my ($log, $bldinf, $srcfile, $type, $epocfile, $extn) = split /,/, $line;
+
+ if (defined $sfl_files{$epocfile})
+ {
+ if ($type eq "export")
+ {
+ # direct export - should be easy to fix
+ $sfl_files{$epocfile} = $srcfile;
+ next;
+ }
+ $sfl_files{$epocfile} = "generated - $type";
+ next;
+ }
+ }
+
+foreach my $epocfile (sort keys %sfl_files)
+ {
+ print "$epocfile\t$sfl_files{$epocfile}\n";
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/sort_uniq.pl Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,27 @@
+#! perl
+
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Make up for lack of "sort | uniq" on Windows
+
+use strict;
+my $line;
+
+my %uniq;
+while ($line = <>)
+ {
+ $uniq{$line} = 1;
+ }
+
+print sort keys %uniq;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/williamr/summarise_rnd_binaries.pl Mon Jun 01 15:26:59 2009 +0100
@@ -0,0 +1,106 @@
+#! perl
+
+# Copyright (c) 2009 Symbian Foundation Ltd
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Symbian Foundation Ltd - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Perl script to summarise the R&D binaries listing
+
+use strict;
+
+my %grouped_by_basename;
+my $line;
+
+while ($line=<>)
+ {
+ # 2009-04-30 11:26:58 D.... 0 0 epoc32\cshlpcmp_template
+ # 2009-03-20 22:22:18 ..... 72192 16307 epoc32\cshlpcmp_template\cshelp2000.dot
+
+ next if (length($line) < 54);
+
+ my $dir_attribute = substr($line, 20, 1);
+ if ($dir_attribute eq ".")
+ {
+ chomp $line;
+ my $fullpath = substr($line, 53);
+ my $filename = substr($fullpath, rindex($fullpath,"\\")+1);
+ my $basename = lc substr($filename, 0, index($filename,"."));
+
+ if ($basename =~ /^(.*){[0-9a-f]+}$/)
+ {
+ # import library
+ $basename = $1;
+ }
+ elsif ($basename =~ /^(.*)_\d+$/)
+ {
+ # language variant in basename rather than extension
+ $basename = $1;
+ }
+ elsif ($basename =~ /^(.*)_(aif|reg)$/)
+ {
+ # Uikon file grouping
+ $basename = $1;
+ }
+
+ if (!defined $grouped_by_basename{$basename})
+ {
+ $grouped_by_basename{$basename} = ();
+ }
+ push @{$grouped_by_basename{$basename}}, $fullpath;
+ next;
+ }
+ }
+
+sub summarise_extensions(@)
+ {
+ my @files = @_;
+ my $resources = 0;
+ my $exes = 0;
+ my $dlls = 0;
+ my $libs = 0;
+ my $maps = 0;
+ my $headers = 0;
+ my $others = 0;
+ my %what_others;
+
+ foreach my $file (@files)
+ {
+ my $extension = substr($file,rindex($file, "."));
+
+ if ($extension =~ /^.r\d+$/io)
+ {
+ $what_others{".rNN"} += 1;
+ next;
+ }
+ if ($extension =~ /^.o\d+$/io)
+ {
+ $what_others{".oNNNN"} += 1;
+ next;
+ }
+ $what_others{$extension} += 1;
+ }
+ foreach my $extension (sort keys %what_others)
+ {
+ printf "%d %s, ", $what_others{$extension}, $extension;
+ }
+ print "\n";
+ }
+
+my $count = 0;
+foreach my $basename (sort keys %grouped_by_basename)
+ {
+ my @files = @{$grouped_by_basename{$basename}};
+ next if (! grep /winscw|tools/, @files); # ignore ARMV5 only for now...
+ printf "%6d\t%s\t", scalar @files, $basename;
+ summarise_extensions(@files);
+ $count++;
+ }
+printf "%d distinct missing basenames (from %d total)\n", $count, scalar keys %grouped_by_basename;