################################################################
# allsubs.pm
# Usage:
#   use allsubs;
# Locate and pre-declare all the subroutines in your file.
# (With caching.  I love caching.  Everything should be cached.)
#
# Retarded concept by Alex Davies (Alex.Davies@tiuk.ti.com)
# Idiotic module copyright 1998 M-J. Dominus (mjd-perl-allsubs@plover.com)
# Who is the greater pinhead?  You decide.
#

my $mainfile = (caller)[1];
my $H = $mainfile;
# print "H: $H\n";
$H =~ s/\.[^.]*$//;    # foo.xy.pl => foo.xy.h.  
$H .= '.h';            # Would     => foo.h  have been better?
eval { require $H };
my $err = $@;
my $ood = 0;

return if $H_FROZEN;

if (!$err) {
  my $hfile = $INC{$H};
  my $main_mtime = (stat $mainfile)[9];
  my $h_mtime = (stat $H)[9]; 
  $ood = ($h_mtime < $main_mtime);
  if ($ood && !rename $H, "$H.bak") {
    require Carp;
    Carp::croak("Could not remove out-of-date prototype file `$H': $!;
aborting");
  }
}

if ($@ || $ood) {
  local *D;
  local *H;  # Greetings, miserable Earth vermin.
  open D, $0 or die "$0: $!";
  unless (open H, "> $H") {
    require Carp;
    Carp::carp("Warning: couldn't write file $H: $!.\n");
    undef $H;
  }

  while (<D>) {
    next unless /^\s*(sub\s*([_A-Za-z]([\w]|::)*)\s*[^\{]*)/;
    print H $1, ";\n" if defined $H;
    eval "$1;";
    if ($@) {
      require Carp;
      Carp::carp("Couldn't predeclare subroutine `$2': $@.\n");
    }
  }
  print H "1;\n" if defined H;
} 


"Cogito, ergo sum.";         # A required file must return a true value.


#
#
################################################################
#
# Hope this helps.  Have an obfuscated day.
