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 takes a file mapping CSV file as input (see flist_5.8.4_on10.csv 9*0Sstevel@tonic-gate# for an example), a perl build directory and a ON workspace and reports files 10*0Sstevel@tonic-gate# that are different in the build and ON directories. This show up any manual 11*0Sstevel@tonic-gate# edits that have been made during the integration process, useful for 12*0Sstevel@tonic-gate# identifying files that need to be preserved during future reintegrations. 13*0Sstevel@tonic-gate# Run with the '-d' option to produce a diff file suitable for applying with 14*0Sstevel@tonic-gate# gpatch. 15*0Sstevel@tonic-gate 16*0Sstevel@tonic-gateuse strict; 17*0Sstevel@tonic-gateuse warnings; 18*0Sstevel@tonic-gateuse POSIX qw(uname); 19*0Sstevel@tonic-gateuse Getopt::Std; 20*0Sstevel@tonic-gate 21*0Sstevel@tonic-gate# 22*0Sstevel@tonic-gate# Compare two files, return 0 for different, 1 for the same. 23*0Sstevel@tonic-gate# 24*0Sstevel@tonic-gatesub file_cmp 25*0Sstevel@tonic-gate{ 26*0Sstevel@tonic-gate my ($f1, $f2) = @_; 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate # Quick check - they must exist and be the same size. 29*0Sstevel@tonic-gate return (0) unless (-e $f1 && -e $f2 && -s $f1 == -s $f2); 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate # Open the files. 32*0Sstevel@tonic-gate my ($fh1, $fh2); 33*0Sstevel@tonic-gate open($fh1, '<', $f1) || return (0); 34*0Sstevel@tonic-gate open($fh2, '<', $f2) || return (0); 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate # Compare. 37*0Sstevel@tonic-gate my ($len1, $len2); 38*0Sstevel@tonic-gate while (1) { 39*0Sstevel@tonic-gate my ($buf1, $buf2); 40*0Sstevel@tonic-gate $len1 = sysread($fh1, $buf1, 4096); 41*0Sstevel@tonic-gate $len2 = sysread($fh2, $buf2, 4096); 42*0Sstevel@tonic-gate last if ($len1 == 0 && $len2 == 0); 43*0Sstevel@tonic-gate if ($len1 != $len2 || $buf1 ne $buf2) { 44*0Sstevel@tonic-gate $len1 = -1; 45*0Sstevel@tonic-gate $len2 = -2; 46*0Sstevel@tonic-gate last; 47*0Sstevel@tonic-gate } 48*0Sstevel@tonic-gate } 49*0Sstevel@tonic-gate close($fh1) || return (0); 50*0Sstevel@tonic-gate close($fh2) || return (0); 51*0Sstevel@tonic-gate return ($len1 == $len2 ? 1 : 0); 52*0Sstevel@tonic-gate} 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate# 55*0Sstevel@tonic-gate# Main. 56*0Sstevel@tonic-gate# 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate# Basic sanity checks. 59*0Sstevel@tonic-gateour $opt_d; 60*0Sstevel@tonic-gategetopts('d') && @ARGV == 3 || 61*0Sstevel@tonic-gate die("Usage is $0 [ -d ] <mapping file> <perl build dir> <workspace>\n"); 62*0Sstevel@tonic-gatemy ($mapfile, $bld, $ws) = @ARGV; 63*0Sstevel@tonic-gatedie("$bld is not a perl build dir\n") if (! -f "$bld/config.sh"); 64*0Sstevel@tonic-gatedie("$ws is not a workspace\n") if (! -d "$ws/Codemgr_wsdata"); 65*0Sstevel@tonic-gatemy ($fh, $line); 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate# Work out perl version. 68*0Sstevel@tonic-gateopen($fh, '<', "$bld/patchlevel.h") || die("$bld is not a perl build dir\n"); 69*0Sstevel@tonic-gatemy ($r, $v, $s); 70*0Sstevel@tonic-gatewhile (defined($line = <$fh>)) { 71*0Sstevel@tonic-gate ($line =~ /#define\s+PERL_REVISION\s+(\S+)/) && ($r = $1); 72*0Sstevel@tonic-gate ($line =~ /#define\s+PERL_VERSION\s+(\S+)/) && ($v = $1); 73*0Sstevel@tonic-gate ($line =~ /#define\s+PERL_SUBVERSION\s+(\S+)/) && ($s = $1); 74*0Sstevel@tonic-gate last if (defined($r) && defined($v) && defined ($s)); 75*0Sstevel@tonic-gate} 76*0Sstevel@tonic-gateclose($fh); 77*0Sstevel@tonic-gatedie("Can't find perl version\n") 78*0Sstevel@tonic-gate unless (defined($r) && defined($v) && defined($s)); 79*0Sstevel@tonic-gatemy $ver = "$r.$v.$s"; 80*0Sstevel@tonic-gateundef($r); 81*0Sstevel@tonic-gateundef($v); 82*0Sstevel@tonic-gateundef($s); 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate# Work out directory locations. 85*0Sstevel@tonic-gateour $ver_dst = "$ws/usr/src/cmd/perl/$ver"; 86*0Sstevel@tonic-gatemy $arch = ((uname())[4] eq 'i86pc') ? 'i386' : 'sparc'; 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate# Read in the mapping file. 89*0Sstevel@tonic-gatemy %file; 90*0Sstevel@tonic-gateopen($fh, '<', $mapfile) || die("Can't open $mapfile: $!\n"); 91*0Sstevel@tonic-gatewhile (defined($line = <$fh>) && $line !~ m{^"Path",}) { 92*0Sstevel@tonic-gate ; 93*0Sstevel@tonic-gate} 94*0Sstevel@tonic-gatewhile (defined($line = <$fh>)) { 95*0Sstevel@tonic-gate chomp($line); 96*0Sstevel@tonic-gate my @field; 97*0Sstevel@tonic-gate push(@field, $+) while $line =~ 98*0Sstevel@tonic-gate m{["']([^"'\\]*(?:\\.[^"'\\]*)*)["'],?|([^,]+),?|,}g; 99*0Sstevel@tonic-gate push(@field, undef) if (substr($line, -1, 1) eq ','); 100*0Sstevel@tonic-gate my $p = shift(@field); 101*0Sstevel@tonic-gate my $f = shift(@field); 102*0Sstevel@tonic-gate # We just want the s10 column. 103*0Sstevel@tonic-gate $file{$p}{$f} = defined($field[3]) ? $field[3] : ''; 104*0Sstevel@tonic-gate} 105*0Sstevel@tonic-gateclose($fh); 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate# Process the mappings. 108*0Sstevel@tonic-gateforeach my $p (sort(keys(%file))) { 109*0Sstevel@tonic-gate foreach my $f (sort(keys(%{$file{$p}}))) { 110*0Sstevel@tonic-gate my $d = $file{$p}{$f}; 111*0Sstevel@tonic-gate my $pf = ($p ne '' ? "$p/" : $p) . $f; 112*0Sstevel@tonic-gate my $cpf = ($p ne '' ? "$p/" : $p) . ",$f"; 113*0Sstevel@tonic-gate my ($src, $dst); 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate # If it has gone into the distrib directory. 116*0Sstevel@tonic-gate if ($d eq 'distrib') { 117*0Sstevel@tonic-gate $src = "$bld/$pf"; 118*0Sstevel@tonic-gate $dst = "$ver_dst/distrib/$pf"; 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate # If it has gone into the arch directory. 121*0Sstevel@tonic-gate } elsif ($d eq 'arch') { 122*0Sstevel@tonic-gate $src = "$bld/$pf"; 123*0Sstevel@tonic-gate $dst = "$ver_dst/$arch/$f"; 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate # If it is to be copied forwards from the last version. 126*0Sstevel@tonic-gate } elsif ($d eq 'fwd') { 127*0Sstevel@tonic-gate $dst = "$ver_dst/distrib/$pf"; 128*0Sstevel@tonic-gate } 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate # Short forms of the filenames. 132*0Sstevel@tonic-gate my ($ssrc, $sdst); 133*0Sstevel@tonic-gate if ($src) { 134*0Sstevel@tonic-gate $ssrc = $src; 135*0Sstevel@tonic-gate $ssrc =~ s{^$bld/}{}o; 136*0Sstevel@tonic-gate $ssrc =~ s{[^/]+/\.\./}{}g; 137*0Sstevel@tonic-gate } 138*0Sstevel@tonic-gate if ($dst) { 139*0Sstevel@tonic-gate $sdst = $dst; 140*0Sstevel@tonic-gate $sdst =~ s{^$ver_dst/}{}o; 141*0Sstevel@tonic-gate $sdst =~ s{[^/]+/\.\./}{}g; 142*0Sstevel@tonic-gate } 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate # New files. 145*0Sstevel@tonic-gate if (! $src && $dst) { 146*0Sstevel@tonic-gate if (! $opt_d) { 147*0Sstevel@tonic-gate print("New: $sdst\n"); 148*0Sstevel@tonic-gate } 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate # Modified files. 151*0Sstevel@tonic-gate } elsif ($src && $dst && ! file_cmp($src, $dst)) { 152*0Sstevel@tonic-gate if ($opt_d) { 153*0Sstevel@tonic-gate system("diff -u $src $dst | " . 154*0Sstevel@tonic-gate "sed -e 's!$src!$ssrc!g' " . 155*0Sstevel@tonic-gate "-e 's!$dst!$sdst!g'"); 156*0Sstevel@tonic-gate } else { 157*0Sstevel@tonic-gate print("Edited: $sdst\n"); 158*0Sstevel@tonic-gate } 159*0Sstevel@tonic-gate } 160*0Sstevel@tonic-gate } 161*0Sstevel@tonic-gate} 162