add Math/Trig/Radial.pm, update MANIFEST
[p5sagit/p5-mst-13.2.git] / lib / AutoLoader.pm
index c45483b..666c6ca 100644 (file)
@@ -1,33 +1,74 @@
 package AutoLoader;
 
-use Carp;
 use vars qw(@EXPORT @EXPORT_OK);
 
+my $is_dosish;
+my $is_vms;
+
 BEGIN {
     require Exporter;
     @EXPORT = ();
     @EXPORT_OK = qw(AUTOLOAD);
+    $is_dosish = $^O eq 'dos' || $^O eq 'os2' || $^O eq 'MSWin32';
+    $is_vms = $^O eq 'VMS';
 }
 
 AUTOLOAD {
     my $name;
     # Braces used to preserve $1 et al.
     {
-     my ($pkg,$func) = $AUTOLOAD =~ /(.*)::([^:]+)$/;
-     $pkg =~ s#::#/#g;
-     if (defined($name=$INC{"$pkg.pm"}))
-      {
-       $name =~ s#^(.*)$pkg\.pm$#$1auto/$pkg/$func.al#;
-       $name = undef unless (-r $name); 
-      }
-     unless (defined $name)
-      {
-       $name = "auto/$AUTOLOAD.al";
-       $name =~ s#::#/#g;
-      }
+       # Try to find the autoloaded file from the package-qualified
+       # name of the sub. e.g., if the sub needed is
+       # Getopt::Long::GetOptions(), then $INC{Getopt/Long.pm} is
+       # something like '/usr/lib/perl5/Getopt/Long.pm', and the
+       # autoload file is '/usr/lib/perl5/auto/Getopt/Long/GetOptions.al'.
+       #
+       # However, if @INC is a relative path, this might not work.  If,
+       # for example, @INC = ('lib'), then $INC{Getopt/Long.pm} is
+       # 'lib/Getopt/Long.pm', and we want to require
+       # 'auto/Getopt/Long/GetOptions.al' (without the leading 'lib').
+       # In this case, we simple prepend the 'auto/' and let the
+       # C<require> take care of the searching for us.
+
+       my ($pkg,$func) = $AUTOLOAD =~ /(.*)::([^:]+)$/;
+       $pkg =~ s#::#/#g;
+       if (defined($name=$INC{"$pkg.pm"})) {
+           $name =~ s#^(.*)$pkg\.pm$#$1auto/$pkg/$func.al#;
+
+           # if the file exists, then make sure that it is a
+           # a fully anchored path (i.e either '/usr/lib/auto/foo/bar.al',
+           # or './lib/auto/foo/bar.al'.  This avoids C<require> searching
+           # (and failing) to find the 'lib/auto/foo/bar.al' because it
+           # looked for 'lib/lib/auto/foo/bar.al', given @INC = ('lib').
+
+           if (-r $name) {
+               unless ($name =~ m|^/|) {
+                   if ($is_dosish) {
+                       unless ($name =~ m{^([a-z]:)?[\\/]}i) {
+                            $name = "./$name";
+                       }
+                   }
+                   elsif ($is_vms) {
+                       # XXX todo by VMSmiths
+                       $name = "./$name";
+                   }
+                   else {
+                       $name = "./$name";
+                   }
+               }
+           }
+           else {
+               $name = undef;
+           }
+       }
+       unless (defined $name) {
+           # let C<require> do the searching
+           $name = "auto/$AUTOLOAD.al";
+           $name =~ s#::#/#g;
+       }
     }
     my $save = $@;
-    eval {local $SIG{__DIE__};require $name};
+    eval { local $SIG{__DIE__}; require $name };
     if ($@) {
        if (substr($AUTOLOAD,-9) eq '::DESTROY') {
            *$AUTOLOAD = sub {};
@@ -42,7 +83,9 @@ AUTOLOAD {
            }
            if ($@){
                $@ =~ s/ at .*\n//;
-               croak $@;
+               my $error = $@;
+               require Carp;
+               Carp::croak($error);
            }
        }
     }
@@ -72,7 +115,7 @@ sub import {
     # 'auto/POSIX/autosplit.ix' (without the leading 'lib').
     #
 
-    (my $calldir = $callpkg) =~ s#::#/#;
+    (my $calldir = $callpkg) =~ s#::#/#g;
     my $path = $INC{$calldir . '.pm'};
     if (defined($path)) {
        # Try absolute path name.
@@ -83,7 +126,11 @@ sub import {
            $path ="auto/$calldir/autosplit.ix";
            eval { require $path; };
        }
-       carp $@ if ($@);  
+       if ($@) {
+           my $error = $@;
+           require Carp;
+           Carp::carp($error);
+       }
     } 
 }
 
@@ -169,6 +216,7 @@ Instead, they should define their own AUTOLOAD subroutines along these
 lines:
 
     use AutoLoader;
+    use Carp;
 
     sub AUTOLOAD {
         my $constname;
@@ -183,7 +231,7 @@ lines:
                 croak "Your vendor has not defined constant $constname";
             }
         }
-        eval "sub $AUTOLOAD { $val }";
+       *$AUTOLOAD = sub { $val }; # same as: eval "sub $AUTOLOAD { $val }";
         goto &$AUTOLOAD;
     }
 
@@ -236,6 +284,10 @@ to a subroutine may have a shorter name that the routine itself.  This
 can lead to conflicting file names.  The I<AutoSplit> package warns of
 these potential conflicts when used to split a module.
 
+AutoLoader may fail to find the autosplit files (or even find the wrong
+ones) in cases where C<@INC> contains relative paths, B<and> the program
+does C<chdir>.
+
 =head1 SEE ALSO
 
 L<SelfLoader> - an autoloader that doesn't use external files.