File Coverage

lib/AutoLoader.pm
Criterion Covered Total %
statement 86 107 80.3
branch 26 54 48.1
condition 5 12 41.6
subroutine 11 12 91.6
pod 0 2 0.0
total 128 187 68.4


line stmt bran cond sub pod time code
1             package AutoLoader;
2              
3 2     2   100764 use strict;
  2         8  
  2         134  
4 2     2   67 use 5.006_001;
  2         8  
  2         311  
5              
6             our($VERSION, $AUTOLOAD);
7              
8             my $is_dosish;
9             my $is_epoc;
10             my $is_vms;
11             my $is_macos;
12              
13             BEGIN {
14 2   33 2   61 $is_dosish = $^O eq 'dos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare';
15 2         7 $is_epoc = $^O eq 'epoc';
16 2         5 $is_vms = $^O eq 'VMS';
17 2         6 $is_macos = $^O eq 'MacOS';
18 2         380 $VERSION = '5.74';
19             }
20              
21             AUTOLOAD {
22 23     23   8315944 my $sub = $AUTOLOAD;
23 23         88 autoload_sub($sub);
24 19         457 goto &$sub;
25             }
26              
27             sub autoload_sub {
28 25     25 0 1329 my $sub = shift;
29              
30 25         58 my $filename = AutoLoader::find_filename( $sub );
31              
32 25         39 my $save = $@;
33 25         90 local $!; # Do not munge the value.
34 25         28 eval { local $SIG{__DIE__}; require $filename };
  25         85  
  25         9121  
35 25 100       179 if ($@) {
36 5 50       67 if (substr($sub,-9) eq '::DESTROY') {
    100          
37 2     2   20 no strict 'refs';
  2         4  
  2         4327  
38 0     0   0 *$sub = sub {};
  0         0  
39 0         0 $@ = undef;
40             } elsif ($@ =~ /^Can't locate/) {
41             # The load might just have failed because the filename was too
42             # long for some old SVR3 systems which treat long names as errors.
43             # If we can successfully truncate a long name then it's worth a go.
44             # There is a slight risk that we could pick up the wrong file here
45             # but autosplit should have warned about that when splitting.
46 4 100       36 if ($filename =~ s/(\w{12,})\.al$/substr($1,0,11).".al"/e){
  1         8  
47 1         2 eval { local $SIG{__DIE__}; require $filename };
  1         4  
  1         622  
48             }
49             }
50 5 100       18 if ($@){
51 4         33 $@ =~ s/ at .*\n//;
52 4         11 my $error = $@;
53 4         20 require Carp;
54 4         882 Carp::croak($error);
55             }
56             }
57 21         31 $@ = $save;
58              
59 21         65 return 1;
60             }
61              
62             sub find_filename {
63 25     25 0 37 my $sub = shift;
64 25         31 my $filename;
65             # Braces used to preserve $1 et al.
66             {
67             # Try to find the autoloaded file from the package-qualified
68             # name of the sub. e.g., if the sub needed is
69             # Getopt::Long::GetOptions(), then $INC{Getopt/Long.pm} is
70             # something like '/usr/lib/perl5/Getopt/Long.pm', and the
71             # autoload file is '/usr/lib/perl5/auto/Getopt/Long/GetOptions.al'.
72             #
73             # However, if @INC is a relative path, this might not work. If,
74             # for example, @INC = ('lib'), then $INC{Getopt/Long.pm} is
75             # 'lib/Getopt/Long.pm', and we want to require
76             # 'auto/Getopt/Long/GetOptions.al' (without the leading 'lib').
77             # In this case, we simple prepend the 'auto/' and let the
78             # C take care of the searching for us.
79              
80 25         34 my ($pkg,$func) = ($sub =~ /(.*)::([^:]+)$/);
  25         253  
81 25         76 $pkg =~ s#::#/#g;
82 25 100       118 if (defined($filename = $INC{"$pkg.pm"})) {
83 1 50       3 if ($is_macos) {
84 0         0 $pkg =~ tr#/#:#;
85 0 0       0 $filename = undef
86             unless $filename =~ s#^(.*)$pkg\.pm\z#$1auto:$pkg:$func.al#s;
87             } else {
88 1 50       22 $filename = undef
89             unless $filename =~ s#^(.*)$pkg\.pm\z#$1auto/$pkg/$func.al#s;
90             }
91              
92             # if the file exists, then make sure that it is a
93             # a fully anchored path (i.e either '/usr/lib/auto/foo/bar.al',
94             # or './lib/auto/foo/bar.al'. This avoids C searching
95             # (and failing) to find the 'lib/auto/foo/bar.al' because it
96             # looked for 'lib/lib/auto/foo/bar.al', given @INC = ('lib').
97              
98 1 50 33     6 if (defined $filename and -r $filename) {
99 0 0       0 unless ($filename =~ m|^/|s) {
100 0 0       0 if ($is_dosish) {
    0          
    0          
    0          
101 0 0       0 unless ($filename =~ m{^([a-z]:)?[\\/]}is) {
102 0 0       0 if ($^O ne 'NetWare') {
103 0         0 $filename = "./$filename";
104             } else {
105 0         0 $filename = "$filename";
106             }
107             }
108             }
109             elsif ($is_epoc) {
110 0 0       0 unless ($filename =~ m{^([a-z?]:)?[\\/]}is) {
111 0         0 $filename = "./$filename";
112             }
113             }
114             elsif ($is_vms) {
115             # XXX todo by VMSmiths
116 0         0 $filename = "./$filename";
117             }
118             elsif (!$is_macos) {
119 0         0 $filename = "./$filename";
120             }
121             }
122             }
123             else {
124 1         2 $filename = undef;
125             }
126             }
127 25 50       59 unless (defined $filename) {
128             # let C do the searching
129 25         58 $filename = "auto/$sub.al";
130 25         93 $filename =~ s#::#/#g;
131             }
132             }
133 25         55 return $filename;
134             }
135              
136             sub import {
137 10     10   8397065 my $pkg = shift;
138 10         40 my $callpkg = caller;
139              
140             #
141             # Export symbols, but not by accident of inheritance.
142             #
143              
144 10 50       49 if ($pkg eq 'AutoLoader') {
145 10 100 66     111 if ( @_ and $_[0] =~ /^&?AUTOLOAD$/ ) {
146 2     2   16 no strict 'refs';
  2         4  
  2         590  
147 8         40 *{ $callpkg . '::AUTOLOAD' } = \&AUTOLOAD;
  8         49  
148             }
149             }
150              
151             #
152             # Try to find the autosplit index file. Eg., if the call package
153             # is POSIX, then $INC{POSIX.pm} is something like
154             # '/usr/local/lib/perl5/POSIX.pm', and the autosplit index file is in
155             # '/usr/local/lib/perl5/auto/POSIX/autosplit.ix', so we require that.
156             #
157             # However, if @INC is a relative path, this might not work. If,
158             # for example, @INC = ('lib'), then
159             # $INC{POSIX.pm} is 'lib/POSIX.pm', and we want to require
160             # 'auto/POSIX/autosplit.ix' (without the leading 'lib').
161             #
162              
163 10         35 (my $calldir = $callpkg) =~ s#::#/#g;
164 10         30 my $path = $INC{$calldir . '.pm'};
165 10 100       2246 if (defined($path)) {
166             # Try absolute path name, but only eval it if the
167             # transformation from module path to autosplit.ix path
168             # succeeded!
169 1         3 my $replaced_okay;
170 1 50       4 if ($is_macos) {
171 0         0 (my $malldir = $calldir) =~ tr#/#:#;
172 0         0 $replaced_okay = ($path =~ s#^(.*)$malldir\.pm\z#$1auto:$malldir:autosplit.ix#s);
173             } else {
174 1         40 $replaced_okay = ($path =~ s#^(.*)$calldir\.pm\z#$1auto/$calldir/autosplit.ix#);
175             }
176              
177 1 50       15 eval { require $path; } if $replaced_okay;
  0         0  
178             # If that failed, try relative path with normal @INC searching.
179 1 50 33     10 if (!$replaced_okay or $@) {
180 1         3 $path ="auto/$calldir/autosplit.ix";
181 1         2 eval { require $path; };
  1         442  
182             }
183 1 50       28 if ($@) {
184 0         0 my $error = $@;
185 0         0 require Carp;
186 0         0 Carp::carp($error);
187             }
188             }
189             }
190              
191             sub unimport {
192 2     2   880 my $callpkg = caller;
193              
194 2     2   10 no strict 'refs';
  2         5  
  2         264  
195              
196 2         5 for my $exported (qw( AUTOLOAD )) {
197 2         5 my $symname = $callpkg . '::' . $exported;
198 2 100       3 undef *{ $symname } if \&{ $symname } == \&{ $exported };
  1         5  
  2         7  
  2         10  
199 2         4 *{ $symname } = \&{ $symname };
  2         9  
  2         7  
200             }
201             }
202              
203             1;
204              
205             __END__