#!/usr/bin/perl -w

# $HeadURL$
# $LastChangedDate$
# $LastChangedBy$
# $LastChangedRevision$

use strict;
use Carp;

&usage("$0: too few arguments") if @ARGV < 1;
&usage("$0: too many arguments") if @ARGV > 1;

my $file_or_dir = shift;

unless (-e $file_or_dir)
  {
    die "$0: file or directory `$file_or_dir' does not exist.\n";
  }

# Get all the revisions that this file or directory changed.  This
# gets the revisions in latest to oldest order.
my @revs = map { m/^rev (\d+)/ } read_from_process('svn', 'log', $file_or_dir);

# Run all the diffs.
while (@revs > 1) {
  my $new_rev = shift @revs;
  my $old_rev = $revs[0];
  print join("\n", read_from_process('svn', 'diff',
                                     "-r$old_rev:$new_rev", $file_or_dir),
                   "\n");  
}

exit 0;

sub usage
{
  warn "@_\n" if @_;
  die "usage: $0 file_or_dir\n";
}

# Start a child process safely without using /bin/sh.
sub safe_read_from_pipe
{
  unless (@_)
    {
      croak "$0: safe_read_from_pipe passed no arguments.\n";
    }
  print "Running @_\n";
  my $pid = open(SAFE_READ, '-|');
  unless (defined $pid)
    {
      die "$0: cannot fork: $!\n";
    }
  unless ($pid)
    {
      open(STDERR, ">&STDOUT")
        or die "$0: cannot dup STDOUT: $!\n";
      exec(@_)
        or die "$0: cannot exec `@_': $!\n";
    }
  my @output;
  while (<SAFE_READ>)
    {
      chomp;
      push(@output, $_);
    }
  close(SAFE_READ);
  my $result = $?;
  my $exit   = $result >> 8;
  my $signal = $result & 127;
  my $cd     = $result & 128 ? "with core dump" : "";
  if ($signal or $cd)
    {
      warn "$0: pipe from `@_' failed $cd: exit=$exit signal=$signal\n";
    }
  if (wantarray)
    {
      return ($result, @output);
    }
  else
    {
      return $result;
    }
}

# Use safe_read_from_pipe to start a child process safely and exit the
# script if the child failed for whatever reason.
sub read_from_process
  {
  unless (@_)
    {
      croak "$0: read_from_process passed no arguments.\n";
    }
  my ($status, @output) = &safe_read_from_pipe(@_);
  if ($status)
    {
      die "$0: @_ failed with this output:\n", join("\n", @output), "\n";
    }
  else
    {
      return @output;
    }
}

# local variables:
# eval: (load-file "../dev/svn-dev.el")
# end:
