1*0Sstevel@tonic-gate#!/usr/perl5/5.8.4/bin/perl 2*0Sstevel@tonic-gate# 3*0Sstevel@tonic-gate# Copyright 2004 Sun Microsystems, Inc. All rights reserved. 4*0Sstevel@tonic-gate# Use is subject to license terms. 5*0Sstevel@tonic-gate# 6*0Sstevel@tonic-gate#ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate# 8*0Sstevel@tonic-gate# This script works out which files from a stock Perl 5.8.3 distribution need 9*0Sstevel@tonic-gate# to be integrated into ON. It MUST be run inside a stock perl distribution 10*0Sstevel@tonic-gate# directory AFTER the InstallPerl script has been run, as it uses the contents 11*0Sstevel@tonic-gate# of the MANIFEST, build.touched, test.log and install.packlist files to figure 12*0Sstevel@tonic-gate# out which files are needed in ON. The parameter for this script is the name 13*0Sstevel@tonic-gate# of the output CSV file, which can be viewed in StarOffice. 14*0Sstevel@tonic-gate# 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gateuse strict; 17*0Sstevel@tonic-gateuse warnings; 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gate# 20*0Sstevel@tonic-gate# Compare two files, return 0 for different, 1 for the same. 21*0Sstevel@tonic-gate# 22*0Sstevel@tonic-gatesub file_cmp 23*0Sstevel@tonic-gate{ 24*0Sstevel@tonic-gate my ($f1, $f2) = @_; 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate # Quick check - they must exist and be the same size. 27*0Sstevel@tonic-gate return (0) unless (-e $f1 && -e $f2 && -s $f1 == -s $f2); 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate # Open the files. 30*0Sstevel@tonic-gate my ($fh1, $fh2); 31*0Sstevel@tonic-gate open($fh1, '<', $f1) || return (0); 32*0Sstevel@tonic-gate open($fh2, '<', $f2) || return (0); 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate # Compare. 35*0Sstevel@tonic-gate my ($len1, $len2); 36*0Sstevel@tonic-gate while (1) { 37*0Sstevel@tonic-gate my ($buf1, $buf2); 38*0Sstevel@tonic-gate $len1 = sysread($fh1, $buf1, 4096); 39*0Sstevel@tonic-gate $len2 = sysread($fh2, $buf2, 4096); 40*0Sstevel@tonic-gate last if ($len1 == 0 && $len2 == 0); 41*0Sstevel@tonic-gate if ($len1 != $len2 || $buf1 ne $buf2) { 42*0Sstevel@tonic-gate $len1 = -1; 43*0Sstevel@tonic-gate $len2 = -2; 44*0Sstevel@tonic-gate last; 45*0Sstevel@tonic-gate } 46*0Sstevel@tonic-gate } 47*0Sstevel@tonic-gate close($fh1) || return (0); 48*0Sstevel@tonic-gate close($fh2) || return (0); 49*0Sstevel@tonic-gate return ($len1 == $len2 ? 1 : 0); 50*0Sstevel@tonic-gate} 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate# 53*0Sstevel@tonic-gate# Main. 54*0Sstevel@tonic-gate# 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate# %file is indexed by (path, filename) 57*0Sstevel@tonic-gatemy ($infh, $outfh, $line, %file); 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate# Check args. 60*0Sstevel@tonic-gatedie("Args are <output.csv>\n") unless (@ARGV == 1); 61*0Sstevel@tonic-gatemy ($outf) = @ARGV; 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate# Check cwd is a valid perl build dir. 64*0Sstevel@tonic-gatedie("Must be run from a perl build directory\n") 65*0Sstevel@tonic-gate unless (-f 'config.over' && -f 'MANIFEST' && -f 'Configure' && 66*0Sstevel@tonic-gate -f 'libperl.so' && -f 'build.touched' && -f 'install.packlist'); 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate# Open output CSV file. 69*0Sstevel@tonic-gateopen($outfh, '>', $outf) || die("Can't open $outf: $!\n"); 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate# Read the MANIFEST. 72*0Sstevel@tonic-gateopen($infh, '<', 'MANIFEST') || die("Can't open MANIFEST: $!\n"); 73*0Sstevel@tonic-gatewhile (defined($line = <$infh>)) { 74*0Sstevel@tonic-gate chomp($line); 75*0Sstevel@tonic-gate $line = (split(m{\s+}, $line, 2))[0]; 76*0Sstevel@tonic-gate my ($p, $f); 77*0Sstevel@tonic-gate if ($line =~ m{/}) { 78*0Sstevel@tonic-gate ($p, $f) = $line =~ m{^(.*)/(.*)$}; 79*0Sstevel@tonic-gate } else { 80*0Sstevel@tonic-gate $p = ''; 81*0Sstevel@tonic-gate $f = $line; 82*0Sstevel@tonic-gate } 83*0Sstevel@tonic-gate $file{$p}{$f}{mfst} = 'X'; 84*0Sstevel@tonic-gate} 85*0Sstevel@tonic-gateclose($infh); 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate# Read build.touched. 88*0Sstevel@tonic-gateopen($infh, '<', 'build.touched') || die("Can't open build.touched: $!\n"); 89*0Sstevel@tonic-gatewhile (defined($line = <$infh>)) { 90*0Sstevel@tonic-gate chomp($line); 91*0Sstevel@tonic-gate my ($p, $f); 92*0Sstevel@tonic-gate if ($line =~ m{/}) { 93*0Sstevel@tonic-gate ($p, $f) = $line =~ m{^(.*)/(.*)$}; 94*0Sstevel@tonic-gate } else { 95*0Sstevel@tonic-gate $p = ''; 96*0Sstevel@tonic-gate $f = $line; 97*0Sstevel@tonic-gate } 98*0Sstevel@tonic-gate $file{$p}{$f}{bld} = 'X'; 99*0Sstevel@tonic-gate} 100*0Sstevel@tonic-gateclose($infh); 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate# Read test.log. 103*0Sstevel@tonic-gateopen($infh, '<', 'test.log') || die("Can't open test.log: $!\n"); 104*0Sstevel@tonic-gatemy %test; 105*0Sstevel@tonic-gatewhile (defined($line = <$infh>)) { 106*0Sstevel@tonic-gate chomp($line); 107*0Sstevel@tonic-gate if ($line =~ m{^([\w/-]+)\.{2,}} && $line !~ /\.skipping test/) { 108*0Sstevel@tonic-gate my $file = $1; 109*0Sstevel@tonic-gate if (-f ($_ = "$file.t")) { 110*0Sstevel@tonic-gate $test{$_} = 1; 111*0Sstevel@tonic-gate } elsif ($file =~ m{/test$} && -f ($_ = "$file.pl")) { 112*0Sstevel@tonic-gate $test{$_} = 1; 113*0Sstevel@tonic-gate } 114*0Sstevel@tonic-gate } 115*0Sstevel@tonic-gate} 116*0Sstevel@tonic-gateclose($infh); 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate# Read install.packlist and build a hash indexed by (filename, path). 119*0Sstevel@tonic-gatemy %inst; 120*0Sstevel@tonic-gateopen($infh, '<', 'install.packlist') 121*0Sstevel@tonic-gate || die("Can't open install.packlist: $!\n"); 122*0Sstevel@tonic-gate$line = <$infh>; 123*0Sstevel@tonic-gatechomp($line); 124*0Sstevel@tonic-gatemy $inst_pfx; 125*0Sstevel@tonic-gatedie("Invalid install.packlist\n") 126*0Sstevel@tonic-gate unless (($inst_pfx) = $line =~ /^PREFIX:\s+(.*)$/); 127*0Sstevel@tonic-gatewhile (defined($line = <$infh>)) { 128*0Sstevel@tonic-gate # Skip manpages and bin/perlX.Y.Z 129*0Sstevel@tonic-gate #next if ($line =~ m{^(?:man/man\d+/|bin/perl\d+\.\d+\.\d+)}); 130*0Sstevel@tonic-gate chomp($line); 131*0Sstevel@tonic-gate my ($p, $f); 132*0Sstevel@tonic-gate if ($line =~ m{/}) { 133*0Sstevel@tonic-gate ($p, $f) = $line =~ m{^(.*)/(.*)$}; 134*0Sstevel@tonic-gate } else { 135*0Sstevel@tonic-gate $p = ''; 136*0Sstevel@tonic-gate $f = $line; 137*0Sstevel@tonic-gate } 138*0Sstevel@tonic-gate $inst{$f}{$p} = 1; 139*0Sstevel@tonic-gate} 140*0Sstevel@tonic-gateclose($infh); 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate# Go through the MANIFEST files, trying to match to installed files. 143*0Sstevel@tonic-gateforeach my $p (keys(%file)) { 144*0Sstevel@tonic-gate foreach my $f (keys(%{$file{$p}})) { 145*0Sstevel@tonic-gate my $v = $file{$p}{$f}; 146*0Sstevel@tonic-gate next unless (exists($v->{mfst})); 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate # 149*0Sstevel@tonic-gate # Easy cases: Files that map directly into the install tree 150*0Sstevel@tonic-gate # 151*0Sstevel@tonic-gate if (exists($inst{$f}{$p})) { 152*0Sstevel@tonic-gate $v->{inst} = 'X'; 153*0Sstevel@tonic-gate delete($inst{$f}{$p}); 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate # 156*0Sstevel@tonic-gate # Brute force: Compare the manifest file against each file with 157*0Sstevel@tonic-gate # the same name in the install tree. 158*0Sstevel@tonic-gate # 159*0Sstevel@tonic-gate } else { 160*0Sstevel@tonic-gate foreach my $ip (keys(%{$inst{$f}})) { 161*0Sstevel@tonic-gate my ($mfst, $inst); 162*0Sstevel@tonic-gate $mfst = "$p/" if ($p ne ''); 163*0Sstevel@tonic-gate $mfst .= $f; 164*0Sstevel@tonic-gate $inst = $inst_pfx; 165*0Sstevel@tonic-gate $inst .= "/$ip" if ($ip); 166*0Sstevel@tonic-gate $inst .= "/$f"; 167*0Sstevel@tonic-gate if (file_cmp($mfst, $inst)) { 168*0Sstevel@tonic-gate $v->{inst} = 'X'; 169*0Sstevel@tonic-gate delete($inst{$f}{$p}); 170*0Sstevel@tonic-gate } 171*0Sstevel@tonic-gate } 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate } 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate} 176*0Sstevel@tonic-gateundef(%inst); 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate# Intuit where we think the 5.8.x files should go in S10. 179*0Sstevel@tonic-gateforeach my $p (keys(%file)) { 180*0Sstevel@tonic-gate foreach my $f (keys(%{$file{$p}})) { 181*0Sstevel@tonic-gate my $v = $file{$p}{$f}; 182*0Sstevel@tonic-gate my $pf = ($p ne '' ? "$p/" : $p) . $f; 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate # 185*0Sstevel@tonic-gate # Some directories and files we can ignore completely, 186*0Sstevel@tonic-gate # for example other architectures. 187*0Sstevel@tonic-gate # 188*0Sstevel@tonic-gate if ($p =~ m{^(?:Cross|NetWare|apollo|beos|cydwin|djgpp|emacs| 189*0Sstevel@tonic-gate epoc|jpl|mint|mpeix|os2|plan9|qnx|uts|vmesa|vms|vos|win32| 190*0Sstevel@tonic-gate wince|t/win32|lib/Thread|ext/threads)}x || 191*0Sstevel@tonic-gate $f =~ m{Makefile.SH|Thread.pm}) { 192*0Sstevel@tonic-gate $v->{s10} = 'skip'; 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate # 195*0Sstevel@tonic-gate # Stuff that we don't want from the top-level directory. 196*0Sstevel@tonic-gate # 197*0Sstevel@tonic-gate } elsif ($p eq '' && 198*0Sstevel@tonic-gate $f =~ m{^(?:[Cc]onfigure.*|Makefile\.SH|Policy_sh.SH| 199*0Sstevel@tonic-gate cflags\.SH|makeaperl\.SH|makedepend\.SH|makedir\.SH| 200*0Sstevel@tonic-gate mv-if-diff)$}x) { 201*0Sstevel@tonic-gate $v->{s10} = 'skip'; 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate # 204*0Sstevel@tonic-gate # We don't want README and other such files. 205*0Sstevel@tonic-gate # 206*0Sstevel@tonic-gate } elsif (($f =~ m{^(?:(?:readme|change|notes|patching).*| 207*0Sstevel@tonic-gate manifest)$}ix && $f !~ m{\.e2x$}) || 208*0Sstevel@tonic-gate ($f =~ m{^todo}i && $p !~ m{^t/|/t/|/t$})) { 209*0Sstevel@tonic-gate $v->{s10} = 'skip'; 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate # 212*0Sstevel@tonic-gate # Pod files need a little finesse. 213*0Sstevel@tonic-gate # We don't want any that are links to README files in the 214*0Sstevel@tonic-gate # top-level directory, unless they are the Solaris or Unicode 215*0Sstevel@tonic-gate # ones. We also exclude some others that aren't relevant, 216*0Sstevel@tonic-gate # and include some that would otherwise be missed. 217*0Sstevel@tonic-gate # 218*0Sstevel@tonic-gate } elsif (($_) = $f =~ m{(\w+)\.pod$}) { 219*0Sstevel@tonic-gate $_ =~ s{^perl}{}; 220*0Sstevel@tonic-gate if (exists($file{''}{"README.$_"})) { 221*0Sstevel@tonic-gate if ($_ =~ m{^(?:solaris|cn|jp|ko|tw)$}) { 222*0Sstevel@tonic-gate $v->{s10} = 'distrib'; 223*0Sstevel@tonic-gate } else { 224*0Sstevel@tonic-gate $v->{s10} = 'skip'; 225*0Sstevel@tonic-gate } 226*0Sstevel@tonic-gate } elsif (($v->{mfst} && ($v->{bld} || $v->{inst})) && 227*0Sstevel@tonic-gate $_ !~ m{^(?:Config|fork|othrtut|thrtut|pumpkin| 228*0Sstevel@tonic-gate Win32|repository)$}x) { 229*0Sstevel@tonic-gate $v->{s10} = 'distrib'; 230*0Sstevel@tonic-gate # perldelta.pod is a symlink, but we need to copy it. 231*0Sstevel@tonic-gate } elsif ($_ eq 'delta') { 232*0Sstevel@tonic-gate $v->{s10} = 'distrib'; 233*0Sstevel@tonic-gate } else { 234*0Sstevel@tonic-gate $v->{s10} = 'skip'; 235*0Sstevel@tonic-gate } 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate # 238*0Sstevel@tonic-gate # We only want test scripts that are actually run. 239*0Sstevel@tonic-gate # 240*0Sstevel@tonic-gate } elsif ($f =~ m{\.t$} || $f eq 'test.pl') { 241*0Sstevel@tonic-gate if (exists($test{$pf}) || $pf eq 't/test.pl') { 242*0Sstevel@tonic-gate $v->{s10} = 'distrib'; 243*0Sstevel@tonic-gate } else { 244*0Sstevel@tonic-gate $v->{s10} = 'skip'; 245*0Sstevel@tonic-gate } 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate # 248*0Sstevel@tonic-gate # Anything in the MANIFEST and touched during the 249*0Sstevel@tonic-gate # build and install should be included. 250*0Sstevel@tonic-gate # 251*0Sstevel@tonic-gate } elsif ($v->{mfst} && ($v->{bld} || $v->{inst})) { 252*0Sstevel@tonic-gate $v->{s10} = 'distrib'; 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate } else { 255*0Sstevel@tonic-gate $v->{s10} = 'skip'; 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate} 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate# 262*0Sstevel@tonic-gate# Files that we need to treat specially. 263*0Sstevel@tonic-gate# 264*0Sstevel@tonic-gate$file{'..'}{'extract_config.sh'}{s10} = 'fwd'; 265*0Sstevel@tonic-gate$file{'..'}{'extract_makeext.sh'}{s10} = 'fwd'; 266*0Sstevel@tonic-gate$file{'..'}{'get_no_keywords.sh'}{s10} = 'fwd'; 267*0Sstevel@tonic-gate$file{'..'}{'Makefile'}{s10} = 'fwd'; 268*0Sstevel@tonic-gate$file{'..'}{'req.flg'}{s10} = 'fwd'; 269*0Sstevel@tonic-gate$file{'../contrib'}{'Makefile'}{s10} = 'fwd'; 270*0Sstevel@tonic-gate$file{''}{'config.sh'}{s10} = 'arch'; 271*0Sstevel@tonic-gate$file{''}{'installperl'}{s10} = 'distrib'; 272*0Sstevel@tonic-gate$file{''}{'utils.lst'}{s10} = 'distrib'; 273*0Sstevel@tonic-gate$file{''}{'Makefile'}{s10} = 'fwd'; 274*0Sstevel@tonic-gate$file{''}{'Makefile.lib'}{s10} = 'fwd'; 275*0Sstevel@tonic-gate$file{'pod'}{'Makefile'}{s10} = 'fwd'; 276*0Sstevel@tonic-gate$file{'utils'}{'Makefile'}{s10} = 'fwd'; 277*0Sstevel@tonic-gate$file{'x2p'}{'Makefile'}{s10} = 'fwd'; 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate# Write CSV contents. 280*0Sstevel@tonic-gateprint $outfh (qq{"Path","File","mfst","bld","inst","s10"\n}); 281*0Sstevel@tonic-gateforeach my $p (sort(keys(%file))) { 282*0Sstevel@tonic-gate foreach my $f (sort(keys(%{$file{$p}}))) { 283*0Sstevel@tonic-gate print $outfh (qq{"$p","$f"}); 284*0Sstevel@tonic-gate foreach my $c (qw{mfst bld inst s10}) { 285*0Sstevel@tonic-gate print $outfh (','); 286*0Sstevel@tonic-gate print $outfh (qq{"$file{$p}{$f}{$c}"}) 287*0Sstevel@tonic-gate if (defined($file{$p}{$f}{$c})); 288*0Sstevel@tonic-gate } 289*0Sstevel@tonic-gate print $outfh ("\n"); 290*0Sstevel@tonic-gate } 291*0Sstevel@tonic-gate} 292*0Sstevel@tonic-gateclose($outfh); 293