#!/usr/local/bin/perl # # file: tree-compare # purpose: given to directory trees, produces 3 lists: # files present in one tree and absent in another (files tree-compare.{12,21}, # and files that differ (stdout) # created: pasha feb 3-7 1999 # usage: (e.g.) tree-compare solaris/datlas sunos/datlas # use strict; use File::Basename; use File::Find; if (scalar @ARGV != 2) { print ("Usage: $0 \n"); exit (0); } my ($first_top_dir, $second_top_dir) = @ARGV; for ($first_top_dir, $second_top_dir) { if ($_ !~ /^\//) { print "$0: Full path names should be specified; $_ isn't\n"; exit (0); } if (!(-d $_)) { print "$0: $_ does not exists\n"; exit (0); } } # construct argument string for diff used to exclude # appropriate regexp's (in compare()) my $DIFF_ARG = ''; for ( '/\* [A-Za-z. ]* @(#)', '\ *\*/', '# SCCS information: ', '# SCCS info : @(#)', 'static char sccs.*\\[\\] = ' #'/\*.*SCCS information:.*\*/', #'/\*.*sccs information:.*\*/', #'/\*.*SCCS info:.*\*/', #'/\*.*SCCS id string.*\*/', #'/\*.*@(#).*\*/', #'/\*.*%W.*%G.*\*/', ) { $DIFF_ARG .= "-I \"$_\" "; } my $me = basename ($0); # first stage - run thru first tree producing list of files present # in the first tree and absent in the second one and list of files which differ open (F12, ">$me.12") || die ("cannot open $me.12 for write: $!"); print (F12 "list of files present in $first_top_dir\nand absent in $second_top_dir\n\n"); find (\&wanted1, $first_top_dir); close (F12); # second stage - run thru second tree producong list of files present # in the second tree and absent in the first one open (F21, ">$me.21") || die ("cannot open $me.21 for write: $!"); print (F21 "list of files present in $second_top_dir\nand absent in $first_top_dir\n\n"); find (\&wanted2, $second_top_dir); close (F21); exit (1); ##################################### # # # functions # # # ##################################### # # functions for find() # sub wanted1 { if (file_ok ($_)) { my $second_current_dir = $File::Find::dir; $second_current_dir =~ s/^$first_top_dir/$second_top_dir/o; if (-f "$second_current_dir/$_") { compare ("$File::Find::dir/$_", "$second_current_dir/$_"); } else { # file exists in first tree, but not in the second print (F12 "$File::Find::dir/$_\n"); } } return (1); } sub wanted2 { if (file_ok ($_)) { my $first_current_dir = $File::Find::dir; $first_current_dir =~ s/^$second_top_dir/$first_top_dir/o; if (!-f "$first_current_dir/$_") { # file exists in second tree, but not in the first print (F21 "$File::Find::dir/$_\n"); } } return (1); } sub file_ok ($) { my $f = $_[0]; # .lst and *_sel.[ch] produced from fast_parser; # .bk, .bck, .org, .orig, .save, .new, .tmp, .log, [ch]1 and ~ # is nothing else than various garbage left return ( -f $f && $_ !~ /\.(lst|com|bk|bck|org|save|new|tmp|log|[ch]1)$/ && $_ !~ /(_sel.[ch]|~)$/ ); } # # compare two files # arguments: file names # sub compare ($$) { my ($first, $second) = @_; my $out = `diff $DIFF_ARG $first $second 2>&1`; if ($? != 0) { print "OUCH! $first and $second differ:\n$out\n\n\n"; } return (1); }