#!/mit/watchmaker/vaxbin/perl
        eval "exec /mit/watchmaker/vaxbin/perl -S $0 $*"
                if $running_under_some_shell;

# $Header: patdiff.SH,v 2.0.1.1 88/08/05 00:29:42 lwall Exp $
#
# $Log:	patdiff.SH,v $
# Revision 2.0.1.1  88/08/05  00:29:42  lwall
# patch1: now depends on perlpath
# 
# Revision 2.0  88/06/28  23:19:39  lwall
# Baseline.
# 
# 


$RCSEXT = ',v' unless $RCSEXT;

die "patdiff [files]\n" unless $#ARGV >= 0;

do readpackage();

system 'mkdir', 'bugs' unless -d 'bugs';

if (-f 'patchlevel.h') {
    open(PL,"patchlevel.h") || die "Can't open patchlevel.h\n";
    while (<PL>) {
        $bnum = $1 if /^#define\s+PATCHLEVEL\s+(\d+)/;
    }
    die "Malformed patchlevel.h file.\n" if $bnum eq '';
    ++$bnum;
}
else {
    $bnum=1;
}

$update = 1;
while ($ARGV[0] =~ /^-/) {
    $_ = shift;
    last if /--/;
    if ($_ eq '-n') {
        $update = 0;
    }
    elsif ($_ eq '-a') {
        $all++;
    }
    else {
        die "Unrecognized switch: $_\n";
    }
}

if ($all) {
    open(MANI,"MANIFEST.new") || die "No MANIFEST.new found.\n";
    @ARGV = ();
    while (<MANI>) {
        chop;
	($_) = split(' ');
        push(@ARGV,$_);
    }
    close MANI;
}

foreach $file (@ARGV) {
    if (! -f $file) {
	print "$file not found.\n";
    }
    else {
	$files = do rcsargs($file);
	@files = split(' ',$files);
	$new='';
	$revs=0;
	$rlog = `rlog -rlastpat- $files 2>&1`;
	($lastpat) = ($rlog =~ /lastpat: ([\d.]+)/);
	($revs) = ($rlog =~ /selected revisions: (\d+)/);
	if (!$revs) {
	    print "No cil has been done on $file.\n" ;;
	}
	elsif ($revs == 1) {
	    ($base) = ($rlog =~ /.*\nrevision\s+(\S+)/);
	    ($a,$b,$c,$d) = split(/\./,$base);
	    if ($d ne '') {
		if ($update) {
		    print "No changes in $file since last patch.  (Did you cil it?)\n";
		}
		else {
		    $new='foo';
		}
	    }
	    else {
		$revs=0;
		$rlog = `rlog -r$revbranch- $files 2>&1`;
		($revs) = ($rlog =~ /selected revisions: (\d+)/);
		if (!$revs) {
		    print "No changes in $file since base version.  (Did you cil it?)\n";
		}
		else {
		    ($new) = ($rlog =~ /\nrevision\s*(\d+\.\d+\.\d+\.\d+)/);
		}
	    }
	}
	else {
	    ($new) = ($rlog =~ /\nrevision\s*(\d+\.\d+\.\d+\.\d+)/);
	}
	if ($new ne '') {
	    ($fname = $file) =~ s|.*/||;
	    open(PATCH,">>bugs/$fname.$bnum") || die "Can't make patch";
	    print PATCH "\nIndex: $file\n";
	    open(CO,"co -p -rlastpat $files 2>/dev/null |");
	    while (<CO>) {
		if (/\$Header/) {
		    print PATCH "Prereq: $lastpat\n";
		    last;
		}
	    }
	    close CO;
	    if ($update) {
		if ($mydiff eq '') {
		    open(DIFF,"rcsdiff -c -rlastpat -r$new $files |") ||
			die "Can't run rcsdiff";
		    while (<DIFF>) {
			if ($. == 1) {s|\*\*\* \S+	|*** $file.old	|;}
			if ($. == 2) {s|--- \S+	|--- $file	|;}
			print PATCH;
		    }
		    close DIFF;
		    system 'rcs', "-Nlastpat:$new", @files;
		}
		else {
		    system "co -p -rlastpat $files >/tmp/pdo$$";
		    system "co -p -r$new $files >/tmp/pdn$$";
		    open(DIFF, "$mydiff /tmp/pdo$$ /tmp/pdn$$ |") ||
			die "Can't run $mydiff";
		    while (<DIFF>) {
			if ($. == 1) {s|\*\*\* \S+	|*** $file.old	|;}
			if ($. == 2) {s|--- \S+	|--- $file	|;}
			print PATCH;
		    }
		    close DIFF;
		    system 'rcs', "-Nlastpat:$new", @files;
		    unlink "/tmp/pdn$$", "/tmp/pdo$$";
		}
	    }
	    else {
		if ($mydiff eq '') {
		    open(DIFF,"rcsdiff -c -rlastpat $files |") ||
			die "Can't run rcsdiff";
		    while (<DIFF>) {
			if ($. == 1) {s|\*\*\* \S+	|*** $file.old	|;}
			if ($. == 2) {s|--- \S+	|--- $file	|;}
			print PATCH;
		    }
		    close DIFF;
		}
		else {
		    system "co -p -rlastpat $files >/tmp/pdo$$";
		    system "cp $file /tmp/pdn$$";
		    open(DIFF, "$mydiff /tmp/pdo$$ /tmp/pdn$$ |") ||
			die "Can't run $mydiff";
		    while (<DIFF>) {
			if ($. == 1) {s|\*\*\* \S+	|*** $file.old	|;}
			if ($. == 2) {s|--- \S+	|--- $file	|;}
			print PATCH;
		    }
		    close DIFF;
		    unlink "/tmp/pdn$$", "/tmp/pdo$$";
		}
	    }
	}
    }
}
unlink ".rlog$$";

sub readpackage {
    if (! -f '.package') {
        if (-f '../.package' || -f '../../.package') {
            die "Run in top level directory only.\n";
        }
        else {
            die "No .package file!  Run packinit.\n";
        }
    }
    open(package,'.package');
    while (<package>) {
        next if /^:/;
        next if /^#/;
        if (($var,$val) = /^\s*(\w+)=(.*)/) {
            $val = "\"$val\"" unless $val =~ /^['"]/;
            eval "\$$var = $val;";
        }
    }
    close package;
}

sub rcsargs {
    local($result) = '';
    local($_);
    while ($_ = shift(@_)) {
	if ($_ =~ /^-/) {
	    $result .= $_ . ' ';
	}
	elsif ($#_ >= 0 && do equiv($_,$_[0])) {
	    $result .= $_ . ' ' . $_[0] . ' ';
	    shift(@_);
	}
	else {
	    $result .= $_ . ' ' . do other($_) . ' ';
	}
    }
    $result;
}

sub equiv {
    local($s1, $s2) = @_;
    $s1 =~ s|.*/||;
    $s2 =~ s|.*/||;
    if ($s1 eq $s2) {
	0;
    }
    elsif ($s1 =~ s/$RCSEXT$// || $s2 =~ s/$RCSEXT$//) {
	$s1 eq $s2;
    }
    else {
	0;
    }
}

sub other {
    local($s1) = @_;
    ($dir,$file) = ('./',$s1) unless local($dir,$file) = ($s1 =~ m|(.*/)(.*)|);
    local($wasrcs) = ($file =~ s/$RCSEXT$//);
    if ($wasrcs) {
	`mkdir $dir` unless -d $dir;
	$dir =~ s|RCS/||;
    }
    else {
	$dir .= 'RCS/';
	`mkdir $dir` unless -d $dir;
	$file .= $RCSEXT;
    }
    "$dir$file";
}

