From: Gurusamy Sarathy Date: Thu, 18 Jun 1998 16:26:59 +0000 (+0000) Subject: fix AutoLoader to do the right thing when there are relative paths X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=adaafad26d5bef10acc55989794c3767dc3c9dec;p=p5sagit%2Fp5-mst-13.2.git fix AutoLoader to do the right thing when there are relative paths in @INC p4raw-id: //depot/perl@1141 --- diff --git a/lib/AutoLoader.pm b/lib/AutoLoader.pm index 46e0a4b..666c6ca 100644 --- a/lib/AutoLoader.pm +++ b/lib/AutoLoader.pm @@ -2,31 +2,73 @@ package AutoLoader; 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 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 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 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 {}; @@ -242,6 +284,10 @@ to a subroutine may have a shorter name that the routine itself. This can lead to conflicting file names. The I 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 the program +does C. + =head1 SEE ALSO L - an autoloader that doesn't use external files.