#!perl
# Usage:
# tree-diff [-w]
#
# Tree-diff looks at the RCS'ed version of this directory, then gives
# a list of all files that are writable, that are missing from the
# current directory, or are new to the current directory (has no RCS
# equivalent). Next to each file, it tells you which of those three
# ways the file is different -- "writeable", "deleted", or "new".
# If -w is specified, it only lists writeable files, and it doesn't
# use the word "writeable" next to them. The -w option is
# particularly useful for constructing complex commands, like
# "tree-diff -w | mass-diff"
# found_writeable(filename) -- Generate output declaring that filename
# is writeable.
sub found_writeable {
local($filename) = @_;
if ($writeable_files_only) {
print "$filename\n";
} else {
print "\twriteable\t$filename\n";
}
}
# found_deleted(filename) -- Check to see if the -w switch was
# specified, and if not, generate output saying that filename was
# deleted.
sub found_deleted {
local($filename) = @_;
if (!$writeable_files_only) {
print "\tdeleted\t\t$filename\n";
}
}
# found_new(filename) -- Check to see if the -w switch was specified,
# and if not, generate output saying that filename is new.
sub found_new {
local($filename) = @_;
if (!$writeable_files_only) {
print "\tnew\t\t$filename\n";
}
}
# examine(localfile, rcsfile) -- Compare localfile to its rcsfile, and
# output the appropriate message if not. (rcsfile must exist, but
# localfile might not, in which case the file was deleted)
sub examine {
local($localfile, $rcsfile) = @_;
if (-w $localfile) {
&found_writeable($localfile);
} elsif (! (-e $localfile)) {
&found_deleted($localfile);
}
}
# expand_fake_link(link_name) -- Expand our fake RCS sym-link.
sub expand_fake_link {
local($link_name) = @_;
open(LINKFILE, $link_name) || die("Can't find file $link_name");
$expanded_link = <LINKFILE>;
chop($expanded_link);
close(LINKFILE);
return $expanded_link;
}
# examine_rcs_files(localdir) -- Examine all files in localdir,
# generating appropriate output. Recursively visiting subdirs is left
# up to examine_directory.
sub examine_rcs_files {
local($localdir) = @_;
if (! -e "$localdir/RCS") {
return;
}
local($rcsdir) = &expand_fake_link("$localdir/RCS");
if (!opendir(DIR, $rcsdir)) {
print "-> Couldn't open dir $rcsdir\n";
return;
}
local(@allfiles) = readdir(DIR);
closedir(DIR);
local($file);
local(%rcsfiles);
foreach $file (@allfiles) {
if ($file =~ /,v$/) { # file ends in ",v"
local($localfile) = "$localdir/$file";
chop $localfile; chop $localfile; # remove ,v
&examine($localfile, "$rcsdir/$file");
$rcsfiles{$file} = 1;
}
}
opendir(DIR, $localdir) || die("Couldn't open local dir $localdir");
local(@all_local_files) = readdir(DIR);
closedir(DIR);
foreach $file (@all_local_files) {
if ($file ne "RCS" && $file ne "." && $file ne ".."
&& -f "$localdir/$file" && (! $rcsfiles{$file . ",v"})) {
# if normal file, not any of RCS, ., or .., and isn't a file
# that we saw in the RCS directory...
&found_new("$localdir/$file");
}
}
}
# examine_directory(local) -- Examines all files in and below that
# dir, generating appropriate output.
sub examine_directory {
local($dirname) = @_;
&examine_rcs_files($dirname);
opendir(DIR, $dirname) || die("Couldn't open $dirname.");
local(@allfiles) = readdir(DIR);
closedir(DIR);
local($file);
foreach $file (@allfiles) {
local($subdir) = "$dirname/$file";
if (-d $subdir && $file ne "RCS" && $file ne "." && $file ne "..") {
&examine_directory($subdir);
}
}
}
if ($#ARGV == 0 && $ARGV[0] eq '-w') {
$writeable_files_only = 1;
}
&examine_directory(".");
syntax highlighted by Code2HTML, v. 0.9.1