eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
    & eval 'exec perl -S $0 $argv:q'
    if 0;

# cvslog,v 4.4 1999/08/24 15:38:17 levine Exp
#
# Wraps cvs log, and substitutes messages of form "ChangeLogTag"
# with their corresponding ChangeLog entries.
#
# Authors:  Luther J. Baker and David L. Levine

####
#### global
####
use strict;
my $dir_sep = $^O eq 'MSWin32'  ?  '\\'  :  '/';
my $cvs_log_options = '';
my @changelogs = ();
my %changelog_hash = ();


####
#### main (I do this for reading clarity)
####
{
  ####
  #### Save any command line options (beginning with -), to pass to cvs log.
  ####
  while ($#ARGV >= $[  &&  $ARGV[0] =~ /^-/) {
    $cvs_log_options .= $cvs_log_options  ?  " " . shift  :  shift;
  }

  ####
  #### Build up the array of ChangeLog files to search,
  ####
  &find_changelogs($ARGV[0]);

  ####
  #### Build the hash table of key=tags value=entry
  ####
  &build_changelog_hash();


  ####
  #### Print the cvs log for each filename argument.
  #### Inserting expanded entries after ChangeLog tags
  ####
  foreach my $arg (@ARGV) {
    &print_log ($arg);
  }
}


####
#### Function surrounding cvs log
####
sub print_log () {
  my $file = shift;

  open (CVSLOG, "cvs log $cvs_log_options $file |")  ||
    die "$0: unable to open cvs log\n";

  while (<CVSLOG>) {

    if (/ChangeLog(Tag)?: *(.*)/i  ||
        /ChangeLog( *Entry)?: *(.*)/i) {

      chomp;
      print "$_:\n";

      # An array reference HAS to be defined, the following will NOT work
      # print "$changelog_hash{$2})" || "ChangeLogTag NOT FOUND!!!!\n";

      if (defined $changelog_hash{$2}) {
        print "@{$changelog_hash{$2}}";
      } else {
        print "\n\tChangeLogTag \"$2\" NOT FOUND!!!!\n\n";
      }

    } else {
      print;
    }
  }

  close CVSLOG;
}


####
#### Build the hash
####
sub build_changelog_hash () {
  my $key = 0;
  my @entry = ();

  foreach my $changelog_file (@changelogs) {

    open (CHANGELOG, $changelog_file)  ||
      die "$0: unable to open '$changelog_file'\n";

    while (<CHANGELOG>) {
      if (/^\w/) {
        if ($key) {
          if (defined $changelog_hash{$key}) {
            #### Deal with multiple identical ChangeLogTags.
            push @{$changelog_hash{$key}}, @entry;
          } else {
            $changelog_hash{$key} = [ @entry ];
          }
        }
        @entry = ();
        chomp;
        $key = $_;
      }
      else {
        push @entry, $_;
      }
    }

    close CHANGELOG;
  }
}


####
#### Find the ChangeLog(s) associated with the file.
####
sub find_changelogs () {
  my $file = shift;

  if ($#changelogs >= 0) {
    @changelogs;
  } else {
    my $pwd = &basename ($file)  ||  '.';

    #### The [C] ensures that the glob will actually look for the file.
    while (! (@changelogs =
              glob ("$pwd/[C]hangeLog " .
                    "$pwd/[C]hangeLog-97 " .   #### ACE_wrappers/TAO
                    "$pwd/[C]hangeLog-97b " .  #### ACE_wrappers
                    "$pwd/ChangeLog-9[89]* " .
                    "$pwd/ChangeLog-0*"))) {
      if ($pwd !~ m%^${dir_sep}%) {
        #### We're starting with a relative path.  Get the
        #### absolute path.
        chomp ($pwd = `pwd`);
        $pwd .= "/$file";
      }

      $pwd = &basename ($pwd);

      if ($pwd eq '') {
        warn "$0: ChangeLog NOT FOUND for '$file'!!!!\n";
        return ();
      }
    }
  }
}


####
#### Return directory component of a filename, without trailing $dir_sep.
#### Return '' if there is no directory component.
####
sub basename () {
  my $filename = shift;

  $filename =~ s%[${dir_sep}][^${dir_sep}]+$%%  ?  $filename  :  '';
}
