diff options
author | Nicholas Clark <nick@ccl4.org> | 2009-09-26 06:13:26 +0100 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2009-09-26 06:13:26 +0100 |
commit | afbf6680b6636f5aeeceb87d873ea5935f57334b (patch) | |
tree | 45098b00f3b3fad8e4e73e2bb3056a9106d19ed7 /ext | |
parent | e853d2264b77e2bdc0758f8ab38e819629763e81 (diff) | |
download | perl-afbf6680b6636f5aeeceb87d873ea5935f57334b.tar.gz |
Move AutoLoader from ext/ to cpan/
Diffstat (limited to 'ext')
-rw-r--r-- | ext/AutoLoader/lib/AutoLoader.pm | 429 | ||||
-rw-r--r-- | ext/AutoLoader/lib/AutoSplit.pm | 592 | ||||
-rw-r--r-- | ext/AutoLoader/t/01AutoLoader.t | 222 | ||||
-rw-r--r-- | ext/AutoLoader/t/02AutoSplit.t | 442 |
4 files changed, 0 insertions, 1685 deletions
diff --git a/ext/AutoLoader/lib/AutoLoader.pm b/ext/AutoLoader/lib/AutoLoader.pm deleted file mode 100644 index 06f986b50d..0000000000 --- a/ext/AutoLoader/lib/AutoLoader.pm +++ /dev/null @@ -1,429 +0,0 @@ -package AutoLoader; - -use strict; -use 5.006_001; - -our($VERSION, $AUTOLOAD); - -my $is_dosish; -my $is_epoc; -my $is_vms; -my $is_macos; - -BEGIN { - $is_dosish = $^O eq 'dos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare'; - $is_epoc = $^O eq 'epoc'; - $is_vms = $^O eq 'VMS'; - $is_macos = $^O eq 'MacOS'; - $VERSION = '5.70'; -} - -AUTOLOAD { - my $sub = $AUTOLOAD; - my $filename = AutoLoader::find_filename( $sub ); - - my $save = $@; - local $!; # Do not munge the value. - eval { local $SIG{__DIE__}; require $filename }; - if ($@) { - if (substr($sub,-9) eq '::DESTROY') { - no strict 'refs'; - *$sub = sub {}; - $@ = undef; - } elsif ($@ =~ /^Can't locate/) { - # The load might just have failed because the filename was too - # long for some old SVR3 systems which treat long names as errors. - # If we can successfully truncate a long name then it's worth a go. - # There is a slight risk that we could pick up the wrong file here - # but autosplit should have warned about that when splitting. - if ($filename =~ s/(\w{12,})\.al$/substr($1,0,11).".al"/e){ - eval { local $SIG{__DIE__}; require $filename }; - } - } - if ($@){ - $@ =~ s/ at .*\n//; - my $error = $@; - require Carp; - Carp::croak($error); - } - } - $@ = $save; - goto &$sub; -} - -sub find_filename { - my $sub = shift; - my $filename; - # Braces used to preserve $1 et al. - { - # 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) = ($sub =~ /(.*)::([^:]+)$/); - $pkg =~ s#::#/#g; - if (defined($filename = $INC{"$pkg.pm"})) { - if ($is_macos) { - $pkg =~ tr#/#:#; - $filename = undef - unless $filename =~ s#^(.*)$pkg\.pm\z#$1auto:$pkg:$func.al#s; - } else { - $filename = undef - unless $filename =~ s#^(.*)$pkg\.pm\z#$1auto/$pkg/$func.al#s; - } - - # 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 (defined $filename and -r $filename) { - unless ($filename =~ m|^/|s) { - if ($is_dosish) { - unless ($filename =~ m{^([a-z]:)?[\\/]}is) { - if ($^O ne 'NetWare') { - $filename = "./$filename"; - } else { - $filename = "$filename"; - } - } - } - elsif ($is_epoc) { - unless ($filename =~ m{^([a-z?]:)?[\\/]}is) { - $filename = "./$filename"; - } - } - elsif ($is_vms) { - # XXX todo by VMSmiths - $filename = "./$filename"; - } - elsif (!$is_macos) { - $filename = "./$filename"; - } - } - } - else { - $filename = undef; - } - } - unless (defined $filename) { - # let C<require> do the searching - $filename = "auto/$sub.al"; - $filename =~ s#::#/#g; - } - } - return $filename; -} - -sub import { - my $pkg = shift; - my $callpkg = caller; - - # - # Export symbols, but not by accident of inheritance. - # - - if ($pkg eq 'AutoLoader') { - if ( @_ and $_[0] =~ /^&?AUTOLOAD$/ ) { - no strict 'refs'; - *{ $callpkg . '::AUTOLOAD' } = \&AUTOLOAD; - } - } - - # - # Try to find the autosplit index file. Eg., if the call package - # is POSIX, then $INC{POSIX.pm} is something like - # '/usr/local/lib/perl5/POSIX.pm', and the autosplit index file is in - # '/usr/local/lib/perl5/auto/POSIX/autosplit.ix', so we require that. - # - # However, if @INC is a relative path, this might not work. If, - # for example, @INC = ('lib'), then - # $INC{POSIX.pm} is 'lib/POSIX.pm', and we want to require - # 'auto/POSIX/autosplit.ix' (without the leading 'lib'). - # - - (my $calldir = $callpkg) =~ s#::#/#g; - my $path = $INC{$calldir . '.pm'}; - if (defined($path)) { - # Try absolute path name, but only eval it if the - # transformation from module path to autosplit.ix path - # succeeded! - my $replaced_okay; - if ($is_macos) { - (my $malldir = $calldir) =~ tr#/#:#; - $replaced_okay = ($path =~ s#^(.*)$malldir\.pm\z#$1auto:$malldir:autosplit.ix#s); - } else { - $replaced_okay = ($path =~ s#^(.*)$calldir\.pm\z#$1auto/$calldir/autosplit.ix#); - } - - eval { require $path; } if $replaced_okay; - # If that failed, try relative path with normal @INC searching. - if (!$replaced_okay or $@) { - $path ="auto/$calldir/autosplit.ix"; - eval { require $path; }; - } - if ($@) { - my $error = $@; - require Carp; - Carp::carp($error); - } - } -} - -sub unimport { - my $callpkg = caller; - - no strict 'refs'; - - for my $exported (qw( AUTOLOAD )) { - my $symname = $callpkg . '::' . $exported; - undef *{ $symname } if \&{ $symname } == \&{ $exported }; - *{ $symname } = \&{ $symname }; - } -} - -1; - -__END__ - -=head1 NAME - -AutoLoader - load subroutines only on demand - -=head1 SYNOPSIS - - package Foo; - use AutoLoader 'AUTOLOAD'; # import the default AUTOLOAD subroutine - - package Bar; - use AutoLoader; # don't import AUTOLOAD, define our own - sub AUTOLOAD { - ... - $AutoLoader::AUTOLOAD = "..."; - goto &AutoLoader::AUTOLOAD; - } - -=head1 DESCRIPTION - -The B<AutoLoader> module works with the B<AutoSplit> module and the -C<__END__> token to defer the loading of some subroutines until they are -used rather than loading them all at once. - -To use B<AutoLoader>, the author of a module has to place the -definitions of subroutines to be autoloaded after an C<__END__> token. -(See L<perldata>.) The B<AutoSplit> module can then be run manually to -extract the definitions into individual files F<auto/funcname.al>. - -B<AutoLoader> implements an AUTOLOAD subroutine. When an undefined -subroutine in is called in a client module of B<AutoLoader>, -B<AutoLoader>'s AUTOLOAD subroutine attempts to locate the subroutine in a -file with a name related to the location of the file from which the -client module was read. As an example, if F<POSIX.pm> is located in -F</usr/local/lib/perl5/POSIX.pm>, B<AutoLoader> will look for perl -subroutines B<POSIX> in F</usr/local/lib/perl5/auto/POSIX/*.al>, where -the C<.al> file has the same name as the subroutine, sans package. If -such a file exists, AUTOLOAD will read and evaluate it, -thus (presumably) defining the needed subroutine. AUTOLOAD will then -C<goto> the newly defined subroutine. - -Once this process completes for a given function, it is defined, so -future calls to the subroutine will bypass the AUTOLOAD mechanism. - -=head2 Subroutine Stubs - -In order for object method lookup and/or prototype checking to operate -correctly even when methods have not yet been defined it is necessary to -"forward declare" each subroutine (as in C<sub NAME;>). See -L<perlsub/"SYNOPSIS">. Such forward declaration creates "subroutine -stubs", which are place holders with no code. - -The AutoSplit and B<AutoLoader> modules automate the creation of forward -declarations. The AutoSplit module creates an 'index' file containing -forward declarations of all the AutoSplit subroutines. When the -AutoLoader module is 'use'd it loads these declarations into its callers -package. - -Because of this mechanism it is important that B<AutoLoader> is always -C<use>d and not C<require>d. - -=head2 Using B<AutoLoader>'s AUTOLOAD Subroutine - -In order to use B<AutoLoader>'s AUTOLOAD subroutine you I<must> -explicitly import it: - - use AutoLoader 'AUTOLOAD'; - -=head2 Overriding B<AutoLoader>'s AUTOLOAD Subroutine - -Some modules, mainly extensions, provide their own AUTOLOAD subroutines. -They typically need to check for some special cases (such as constants) -and then fallback to B<AutoLoader>'s AUTOLOAD for the rest. - -Such modules should I<not> import B<AutoLoader>'s AUTOLOAD subroutine. -Instead, they should define their own AUTOLOAD subroutines along these -lines: - - use AutoLoader; - use Carp; - - sub AUTOLOAD { - my $sub = $AUTOLOAD; - (my $constname = $sub) =~ s/.*:://; - my $val = constant($constname, @_ ? $_[0] : 0); - if ($! != 0) { - if ($! =~ /Invalid/ || $!{EINVAL}) { - $AutoLoader::AUTOLOAD = $sub; - goto &AutoLoader::AUTOLOAD; - } - else { - croak "Your vendor has not defined constant $constname"; - } - } - *$sub = sub { $val }; # same as: eval "sub $sub { $val }"; - goto &$sub; - } - -If any module's own AUTOLOAD subroutine has no need to fallback to the -AutoLoader's AUTOLOAD subroutine (because it doesn't have any AutoSplit -subroutines), then that module should not use B<AutoLoader> at all. - -=head2 Package Lexicals - -Package lexicals declared with C<my> in the main block of a package -using B<AutoLoader> will not be visible to auto-loaded subroutines, due to -the fact that the given scope ends at the C<__END__> marker. A module -using such variables as package globals will not work properly under the -B<AutoLoader>. - -The C<vars> pragma (see L<perlmod/"vars">) may be used in such -situations as an alternative to explicitly qualifying all globals with -the package namespace. Variables pre-declared with this pragma will be -visible to any autoloaded routines (but will not be invisible outside -the package, unfortunately). - -=head2 Not Using AutoLoader - -You can stop using AutoLoader by simply - - no AutoLoader; - -=head2 B<AutoLoader> vs. B<SelfLoader> - -The B<AutoLoader> is similar in purpose to B<SelfLoader>: both delay the -loading of subroutines. - -B<SelfLoader> uses the C<__DATA__> marker rather than C<__END__>. -While this avoids the use of a hierarchy of disk files and the -associated open/close for each routine loaded, B<SelfLoader> suffers a -startup speed disadvantage in the one-time parsing of the lines after -C<__DATA__>, after which routines are cached. B<SelfLoader> can also -handle multiple packages in a file. - -B<AutoLoader> only reads code as it is requested, and in many cases -should be faster, but requires a mechanism like B<AutoSplit> be used to -create the individual files. L<ExtUtils::MakeMaker> will invoke -B<AutoSplit> automatically if B<AutoLoader> is used in a module source -file. - -=head1 CAVEATS - -AutoLoaders prior to Perl 5.002 had a slightly different interface. Any -old modules which use B<AutoLoader> should be changed to the new calling -style. Typically this just means changing a require to a use, adding -the explicit C<'AUTOLOAD'> import if needed, and removing B<AutoLoader> -from C<@ISA>. - -On systems with restrictions on file name length, the file corresponding -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. - -=head1 AUTHOR - -C<AutoLoader> is maintained by the perl5-porters. Please direct -any questions to the canonical mailing list. Anything that -is applicable to the CPAN release can be sent to its maintainer, -though. - -Author and Maintainer: The Perl5-Porters <perl5-porters@perl.org> - -Maintainer of the CPAN release: Steffen Mueller <smueller@cpan.org> - -=head1 COPYRIGHT AND LICENSE - -This package has been part of the perl core since the first release -of perl5. It has been released separately to CPAN so older installations -can benefit from bug fixes. - -This package has the same copyright and license as the perl core: - - Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 - by Larry Wall and others - - All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of either: - - a) the GNU General Public License as published by the Free - Software Foundation; either version 1, or (at your option) any - later version, or - - b) the "Artistic License" which comes with this Kit. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either - the GNU General Public License or the Artistic License for more details. - - You should have received a copy of the Artistic License with this - Kit, in the file named "Artistic". If not, I'll be glad to provide one. - - You should also have received a copy of the GNU General Public License - along with this program in the file named "Copying". If not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA or visit their web page on the internet at - http://www.gnu.org/copyleft/gpl.html. - - For those of you that choose to use the GNU General Public License, - my interpretation of the GNU General Public License is that no Perl - script falls under the terms of the GPL unless you explicitly put - said script under the terms of the GPL yourself. Furthermore, any - object code linked with perl does not automatically fall under the - terms of the GPL, provided such object code only adds definitions - of subroutines and variables, and does not otherwise impair the - resulting interpreter from executing any standard Perl script. I - consider linking in C subroutines in this manner to be the moral - equivalent of defining subroutines in the Perl language itself. You - may sell such an object file as proprietary provided that you provide - or offer to provide the Perl source, as specified by the GNU General - Public License. (This is merely an alternate way of specifying input - to the program.) You may also sell a binary produced by the dumping of - a running Perl script that belongs to you, provided that you provide or - offer to provide the Perl source as specified by the GPL. (The - fact that a Perl interpreter and your code are in the same binary file - is, in this case, a form of mere aggregation.) This is my interpretation - of the GPL. If you still have concerns or difficulties understanding - my intent, feel free to contact me. Of course, the Artistic License - spells all this out for your protection, so you may prefer to use that. - -=cut diff --git a/ext/AutoLoader/lib/AutoSplit.pm b/ext/AutoLoader/lib/AutoSplit.pm deleted file mode 100644 index c093f2dd24..0000000000 --- a/ext/AutoLoader/lib/AutoSplit.pm +++ /dev/null @@ -1,592 +0,0 @@ -package AutoSplit; - -use Exporter (); -use Config qw(%Config); -use File::Basename (); -use File::Path qw(mkpath); -use File::Spec::Functions qw(curdir catfile catdir); -use strict; -our($VERSION, @ISA, @EXPORT, @EXPORT_OK, $Verbose, $Keep, $Maxlen, - $CheckForAutoloader, $CheckModTime); - -$VERSION = "1.06"; -@ISA = qw(Exporter); -@EXPORT = qw(&autosplit &autosplit_lib_modules); -@EXPORT_OK = qw($Verbose $Keep $Maxlen $CheckForAutoloader $CheckModTime); - -=head1 NAME - -AutoSplit - split a package for autoloading - -=head1 SYNOPSIS - - autosplit($file, $dir, $keep, $check, $modtime); - - autosplit_lib_modules(@modules); - -=head1 DESCRIPTION - -This function will split up your program into files that the AutoLoader -module can handle. It is used by both the standard perl libraries and by -the MakeMaker utility, to automatically configure libraries for autoloading. - -The C<autosplit> interface splits the specified file into a hierarchy -rooted at the directory C<$dir>. It creates directories as needed to reflect -class hierarchy, and creates the file F<autosplit.ix>. This file acts as -both forward declaration of all package routines, and as timestamp for the -last update of the hierarchy. - -The remaining three arguments to C<autosplit> govern other options to -the autosplitter. - -=over 2 - -=item $keep - -If the third argument, I<$keep>, is false, then any -pre-existing C<*.al> files in the autoload directory are removed if -they are no longer part of the module (obsoleted functions). -$keep defaults to 0. - -=item $check - -The -fourth argument, I<$check>, instructs C<autosplit> to check the module -currently being split to ensure that it includes a C<use> -specification for the AutoLoader module, and skips the module if -AutoLoader is not detected. -$check defaults to 1. - -=item $modtime - -Lastly, the I<$modtime> argument specifies -that C<autosplit> is to check the modification time of the module -against that of the C<autosplit.ix> file, and only split the module if -it is newer. -$modtime defaults to 1. - -=back - -Typical use of AutoSplit in the perl MakeMaker utility is via the command-line -with: - - perl -e 'use AutoSplit; autosplit($ARGV[0], $ARGV[1], 0, 1, 1)' - -Defined as a Make macro, it is invoked with file and directory arguments; -C<autosplit> will split the specified file into the specified directory and -delete obsolete C<.al> files, after checking first that the module does use -the AutoLoader, and ensuring that the module is not already currently split -in its current form (the modtime test). - -The C<autosplit_lib_modules> form is used in the building of perl. It takes -as input a list of files (modules) that are assumed to reside in a directory -B<lib> relative to the current directory. Each file is sent to the -autosplitter one at a time, to be split into the directory B<lib/auto>. - -In both usages of the autosplitter, only subroutines defined following the -perl I<__END__> token are split out into separate files. Some -routines may be placed prior to this marker to force their immediate loading -and parsing. - -=head2 Multiple packages - -As of version 1.01 of the AutoSplit module it is possible to have -multiple packages within a single file. Both of the following cases -are supported: - - package NAME; - __END__ - sub AAA { ... } - package NAME::option1; - sub BBB { ... } - package NAME::option2; - sub BBB { ... } - - package NAME; - __END__ - sub AAA { ... } - sub NAME::option1::BBB { ... } - sub NAME::option2::BBB { ... } - -=head1 DIAGNOSTICS - -C<AutoSplit> will inform the user if it is necessary to create the -top-level directory specified in the invocation. It is preferred that -the script or installation process that invokes C<AutoSplit> have -created the full directory path ahead of time. This warning may -indicate that the module is being split into an incorrect path. - -C<AutoSplit> will warn the user of all subroutines whose name causes -potential file naming conflicts on machines with drastically limited -(8 characters or less) file name length. Since the subroutine name is -used as the file name, these warnings can aid in portability to such -systems. - -Warnings are issued and the file skipped if C<AutoSplit> cannot locate -either the I<__END__> marker or a "package Name;"-style specification. - -C<AutoSplit> will also emit general diagnostics for inability to -create directories or files. - -=head1 AUTHOR - -C<AutoSplit> is maintained by the perl5-porters. Please direct -any questions to the canonical mailing list. Anything that -is applicable to the CPAN release can be sent to its maintainer, -though. - -Author and Maintainer: The Perl5-Porters <perl5-porters@perl.org> - -Maintainer of the CPAN release: Steffen Mueller <smueller@cpan.org> - -=head1 COPYRIGHT AND LICENSE - -This package has been part of the perl core since the first release -of perl5. It has been released separately to CPAN so older installations -can benefit from bug fixes. - -This package has the same copyright and license as the perl core: - - Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 - by Larry Wall and others - - All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of either: - - a) the GNU General Public License as published by the Free - Software Foundation; either version 1, or (at your option) any - later version, or - - b) the "Artistic License" which comes with this Kit. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either - the GNU General Public License or the Artistic License for more details. - - You should have received a copy of the Artistic License with this - Kit, in the file named "Artistic". If not, I'll be glad to provide one. - - You should also have received a copy of the GNU General Public License - along with this program in the file named "Copying". If not, write to the - Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA or visit their web page on the internet at - http://www.gnu.org/copyleft/gpl.html. - - For those of you that choose to use the GNU General Public License, - my interpretation of the GNU General Public License is that no Perl - script falls under the terms of the GPL unless you explicitly put - said script under the terms of the GPL yourself. Furthermore, any - object code linked with perl does not automatically fall under the - terms of the GPL, provided such object code only adds definitions - of subroutines and variables, and does not otherwise impair the - resulting interpreter from executing any standard Perl script. I - consider linking in C subroutines in this manner to be the moral - equivalent of defining subroutines in the Perl language itself. You - may sell such an object file as proprietary provided that you provide - or offer to provide the Perl source, as specified by the GNU General - Public License. (This is merely an alternate way of specifying input - to the program.) You may also sell a binary produced by the dumping of - a running Perl script that belongs to you, provided that you provide or - offer to provide the Perl source as specified by the GPL. (The - fact that a Perl interpreter and your code are in the same binary file - is, in this case, a form of mere aggregation.) This is my interpretation - of the GPL. If you still have concerns or difficulties understanding - my intent, feel free to contact me. Of course, the Artistic License - spells all this out for your protection, so you may prefer to use that. - -=cut - -# for portability warn about names longer than $maxlen -$Maxlen = 8; # 8 for dos, 11 (14-".al") for SYSVR3 -$Verbose = 1; # 0=none, 1=minimal, 2=list .al files -$Keep = 0; -$CheckForAutoloader = 1; -$CheckModTime = 1; - -my $IndexFile = "autosplit.ix"; # file also serves as timestamp -my $maxflen = 255; -$maxflen = 14 if $Config{'d_flexfnam'} ne 'define'; -if (defined (&Dos::UseLFN)) { - $maxflen = Dos::UseLFN() ? 255 : 11; -} -my $Is_VMS = ($^O eq 'VMS'); - -# allow checking for valid ': attrlist' attachments. -# extra jugglery required to support both 5.8 and 5.9/5.10 features -# (support for 5.8 required for cross-compiling environments) - -my $attr_list = - $] >= 5.009005 ? - eval <<'__QR__' - qr{ - \s* : \s* - (?: - # one attribute - (?> # no backtrack - (?! \d) \w+ - (?<nested> \( (?: [^()]++ | (?&nested)++ )*+ \) ) ? - ) - (?: \s* : \s* | \s+ (?! :) ) - )* - }x -__QR__ - : - do { - # In pre-5.9.5 world we have to do dirty tricks. - # (we use 'our' rather than 'my' here, due to the rather complex and buggy - # behaviour of lexicals with qr// and (??{$lex}) ) - our $trick1; # yes, cannot our and assign at the same time. - $trick1 = qr{ \( (?: (?> [^()]+ ) | (??{ $trick1 }) )* \) }x; - our $trick2 = qr{ (?> (?! \d) \w+ (?:$trick1)? ) (?:\s*\:\s*|\s+(?!\:)) }x; - qr{ \s* : \s* (?: $trick2 )* }x; - }; - -sub autosplit{ - my($file, $autodir, $keep, $ckal, $ckmt) = @_; - # $file - the perl source file to be split (after __END__) - # $autodir - the ".../auto" dir below which to write split subs - # Handle optional flags: - $keep = $Keep unless defined $keep; - $ckal = $CheckForAutoloader unless defined $ckal; - $ckmt = $CheckModTime unless defined $ckmt; - autosplit_file($file, $autodir, $keep, $ckal, $ckmt); -} - -sub carp{ - require Carp; - goto &Carp::carp; -} - -# This function is used during perl building/installation -# ./miniperl -e 'use AutoSplit; autosplit_lib_modules(@ARGV)' ... - -sub autosplit_lib_modules { - my(@modules) = @_; # list of Module names - local $_; # Avoid clobber. - while (defined($_ = shift @modules)) { - while (m#([^:]+)::([^:].*)#) { # in case specified as ABC::XYZ - $_ = catfile($1, $2); - } - s|\\|/|g; # bug in ksh OS/2 - s#^lib/##s; # incase specified as lib/*.pm - my($lib) = catfile(curdir(), "lib"); - if ($Is_VMS) { # may need to convert VMS-style filespecs - $lib =~ s#^\[\]#.\/#; - } - s#^$lib\W+##s; # incase specified as ./lib/*.pm - if ($Is_VMS && /[:>\]]/) { # may need to convert VMS-style filespecs - my ($dir,$name) = (/(.*])(.*)/s); - $dir =~ s/.*lib[\.\]]//s; - $dir =~ s#[\.\]]#/#g; - $_ = $dir . $name; - } - autosplit_file(catfile($lib, $_), catfile($lib, "auto"), - $Keep, $CheckForAutoloader, $CheckModTime); - } - 0; -} - - -# private functions - -my $self_mod_time = (stat __FILE__)[9]; - -sub autosplit_file { - my($filename, $autodir, $keep, $check_for_autoloader, $check_mod_time) - = @_; - my(@outfiles); - local($_); - local($/) = "\n"; - - # where to write output files - $autodir ||= catfile(curdir(), "lib", "auto"); - if ($Is_VMS) { - ($autodir = VMS::Filespec::unixpath($autodir)) =~ s|/\z||; - $filename = VMS::Filespec::unixify($filename); # may have dirs - } - unless (-d $autodir){ - mkpath($autodir,0,0755); - # We should never need to create the auto dir - # here. installperl (or similar) should have done - # it. Expecting it to exist is a valuable sanity check against - # autosplitting into some random directory by mistake. - print "Warning: AutoSplit had to create top-level " . - "$autodir unexpectedly.\n"; - } - - # allow just a package name to be used - $filename .= ".pm" unless ($filename =~ m/\.pm\z/); - - open(my $in, "<$filename") or die "AutoSplit: Can't open $filename: $!\n"; - my($pm_mod_time) = (stat($filename))[9]; - my($autoloader_seen) = 0; - my($in_pod) = 0; - my($def_package,$last_package,$this_package,$fnr); - while (<$in>) { - # Skip pod text. - $fnr++; - $in_pod = 1 if /^=\w/; - $in_pod = 0 if /^=cut/; - next if ($in_pod || /^=cut/); - next if /^\s*#/; - - # record last package name seen - $def_package = $1 if (m/^\s*package\s+([\w:]+)\s*;/); - ++$autoloader_seen if m/^\s*(use|require)\s+AutoLoader\b/; - ++$autoloader_seen if m/\bISA\s*=.*\bAutoLoader\b/; - last if /^__END__/; - } - if ($check_for_autoloader && !$autoloader_seen){ - print "AutoSplit skipped $filename: no AutoLoader used\n" - if ($Verbose>=2); - return 0; - } - $_ or die "Can't find __END__ in $filename\n"; - - $def_package or die "Can't find 'package Name;' in $filename\n"; - - my($modpname) = _modpname($def_package); - - # this _has_ to match so we have a reasonable timestamp file - die "Package $def_package ($modpname.pm) does not ". - "match filename $filename" - unless ($filename =~ m/\Q$modpname.pm\E$/ or - ($^O eq 'dos') or ($^O eq 'MSWin32') or ($^O eq 'NetWare') or - $Is_VMS && $filename =~ m/$modpname.pm/i); - - my($al_idx_file) = catfile($autodir, $modpname, $IndexFile); - - if ($check_mod_time){ - my($al_ts_time) = (stat("$al_idx_file"))[9] || 1; - if ($al_ts_time >= $pm_mod_time and - $al_ts_time >= $self_mod_time){ - print "AutoSplit skipped ($al_idx_file newer than $filename)\n" - if ($Verbose >= 2); - return undef; # one undef, not a list - } - } - - my($modnamedir) = catdir($autodir, $modpname); - print "AutoSplitting $filename ($modnamedir)\n" - if $Verbose; - - unless (-d $modnamedir){ - mkpath($modnamedir,0,0777); - } - - # We must try to deal with some SVR3 systems with a limit of 14 - # characters for file names. Sadly we *cannot* simply truncate all - # file names to 14 characters on these systems because we *must* - # create filenames which exactly match the names used by AutoLoader.pm. - # This is a problem because some systems silently truncate the file - # names while others treat long file names as an error. - - my $Is83 = $maxflen==11; # plain, case INSENSITIVE dos filenames - - my(@subnames, $subname, %proto, %package); - my @cache = (); - my $caching = 1; - $last_package = ''; - my $out; - while (<$in>) { - $fnr++; - $in_pod = 1 if /^=\w/; - $in_pod = 0 if /^=cut/; - next if ($in_pod || /^=cut/); - # the following (tempting) old coding gives big troubles if a - # cut is forgotten at EOF: - # next if /^=\w/ .. /^=cut/; - if (/^package\s+([\w:]+)\s*;/) { - $this_package = $def_package = $1; - } - - if (/^sub\s+([\w:]+)(\s*(?:\(.*?\))?(?:$attr_list)?)/) { - print $out "# end of $last_package\::$subname\n1;\n" - if $last_package; - $subname = $1; - my $proto = $2 || ''; - if ($subname =~ s/(.*):://){ - $this_package = $1; - } else { - $this_package = $def_package; - } - my $fq_subname = "$this_package\::$subname"; - $package{$fq_subname} = $this_package; - $proto{$fq_subname} = $proto; - push(@subnames, $fq_subname); - my($lname, $sname) = ($subname, substr($subname,0,$maxflen-3)); - $modpname = _modpname($this_package); - my($modnamedir) = catdir($autodir, $modpname); - mkpath($modnamedir,0,0777); - my($lpath) = catfile($modnamedir, "$lname.al"); - my($spath) = catfile($modnamedir, "$sname.al"); - my $path; - - if (!$Is83 and open($out, ">$lpath")){ - $path=$lpath; - print " writing $lpath\n" if ($Verbose>=2); - } else { - open($out, ">$spath") or die "Can't create $spath: $!\n"; - $path=$spath; - print " writing $spath (with truncated name)\n" - if ($Verbose>=1); - } - push(@outfiles, $path); - my $lineno = $fnr - @cache; - print $out <<EOT; -# NOTE: Derived from $filename. -# Changes made here will be lost when autosplit is run again. -# See AutoSplit.pm. -package $this_package; - -#line $lineno "$filename (autosplit into $path)" -EOT - print $out @cache; - @cache = (); - $caching = 0; - } - if($caching) { - push(@cache, $_) if @cache || /\S/; - } else { - print $out $_; - } - if(/^\}/) { - if($caching) { - print $out @cache; - @cache = (); - } - print $out "\n"; - $caching = 1; - } - $last_package = $this_package if defined $this_package; - } - if ($subname) { - print $out @cache,"1;\n# end of $last_package\::$subname\n"; - close($out); - } - close($in); - - if (!$keep){ # don't keep any obsolete *.al files in the directory - my(%outfiles); - # @outfiles{@outfiles} = @outfiles; - # perl downcases all filenames on VMS (which upcases all filenames) so - # we'd better downcase the sub name list too, or subs with upper case - # letters in them will get their .al files deleted right after they're - # created. (The mixed case sub name won't match the all-lowercase - # filename, and so be cleaned up as a scrap file) - if ($Is_VMS or $Is83) { - %outfiles = map {lc($_) => lc($_) } @outfiles; - } else { - @outfiles{@outfiles} = @outfiles; - } - my(%outdirs,@outdirs); - for (@outfiles) { - $outdirs{File::Basename::dirname($_)}||=1; - } - for my $dir (keys %outdirs) { - opendir(my $outdir,$dir); - foreach (sort readdir($outdir)){ - next unless /\.al\z/; - my($file) = catfile($dir, $_); - $file = lc $file if $Is83 or $Is_VMS; - next if $outfiles{$file}; - print " deleting $file\n" if ($Verbose>=2); - my($deleted,$thistime); # catch all versions on VMS - do { $deleted += ($thistime = unlink $file) } while ($thistime); - carp ("Unable to delete $file: $!") unless $deleted; - } - closedir($outdir); - } - } - - open(my $ts,">$al_idx_file") or - carp ("AutoSplit: unable to create timestamp file ($al_idx_file): $!"); - print $ts "# Index created by AutoSplit for $filename\n"; - print $ts "# (file acts as timestamp)\n"; - $last_package = ''; - for my $fqs (@subnames) { - my($subname) = $fqs; - $subname =~ s/.*:://; - print $ts "package $package{$fqs};\n" - unless $last_package eq $package{$fqs}; - print $ts "sub $subname $proto{$fqs};\n"; - $last_package = $package{$fqs}; - } - print $ts "1;\n"; - close($ts); - - _check_unique($filename, $Maxlen, 1, @outfiles); - - @outfiles; -} - -sub _modpname ($) { - my($package) = @_; - my $modpname = $package; - if ($^O eq 'MSWin32') { - $modpname =~ s#::#\\#g; - } else { - my @modpnames = (); - while ($modpname =~ m#(.*?[^:])::([^:].*)#) { - push @modpnames, $1; - $modpname = $2; - } - $modpname = catfile(@modpnames, $modpname); - } - if ($Is_VMS) { - $modpname = VMS::Filespec::unixify($modpname); # may have dirs - } - $modpname; -} - -sub _check_unique { - my($filename, $maxlen, $warn, @outfiles) = @_; - my(%notuniq) = (); - my(%shorts) = (); - my(@toolong) = grep( - length(File::Basename::basename($_)) - > $maxlen, - @outfiles - ); - - foreach (@toolong){ - my($dir) = File::Basename::dirname($_); - my($file) = File::Basename::basename($_); - my($trunc) = substr($file,0,$maxlen); - $notuniq{$dir}{$trunc} = 1 if $shorts{$dir}{$trunc}; - $shorts{$dir}{$trunc} = $shorts{$dir}{$trunc} ? - "$shorts{$dir}{$trunc}, $file" : $file; - } - if (%notuniq && $warn){ - print "$filename: some names are not unique when " . - "truncated to $maxlen characters:\n"; - foreach my $dir (sort keys %notuniq){ - print " directory $dir:\n"; - foreach my $trunc (sort keys %{$notuniq{$dir}}) { - print " $shorts{$dir}{$trunc} truncate to $trunc\n"; - } - } - } -} - -1; -__END__ - -# test functions so AutoSplit.pm can be applied to itself: -sub test1 ($) { "test 1\n"; } -sub test2 ($$) { "test 2\n"; } -sub test3 ($$$) { "test 3\n"; } -sub testtesttesttest4_1 { "test 4\n"; } -sub testtesttesttest4_2 { "duplicate test 4\n"; } -sub Just::Another::test5 { "another test 5\n"; } -sub test6 { return join ":", __FILE__,__LINE__; } -package Yet::Another::AutoSplit; -sub testtesttesttest4_1 ($) { "another test 4\n"; } -sub testtesttesttest4_2 ($$) { "another duplicate test 4\n"; } -package Yet::More::Attributes; -sub test_a1 ($) : locked :locked { 1; } -sub test_a2 : locked { 1; } diff --git a/ext/AutoLoader/t/01AutoLoader.t b/ext/AutoLoader/t/01AutoLoader.t deleted file mode 100644 index dcee5c518a..0000000000 --- a/ext/AutoLoader/t/01AutoLoader.t +++ /dev/null @@ -1,222 +0,0 @@ -#!./perl -w - -BEGIN { - if ($ENV{PERL_CORE}) { - chdir 't' if -d 't'; - #@INC = '../lib'; - } -} - -use strict; -use File::Spec; -use File::Path; - -my $dir; -BEGIN -{ - $dir = File::Spec->catdir( "auto-$$" ); - unshift @INC, $dir; -} - -use Test::More tests => 18; - -sub write_file { - my ($file, $text) = @_; - open my $fh, '>', $file - or die "Could not open file '$file' for writing: $!"; - print $fh $text; - close $fh; -} - -# First we must set up some autoloader files -my $fulldir = File::Spec->catdir( $dir, 'auto', 'Foo' ); -mkpath( $fulldir ) or die "Can't mkdir '$fulldir': $!"; - -write_file( File::Spec->catfile( $fulldir, 'foo.al' ), <<'EOT' ); -package Foo; -sub foo { shift; shift || "foo" } -1; -EOT - -write_file( File::Spec->catfile( $fulldir, 'bazmarkhian.al' ), <<'EOT' ); -package Foo; -sub bazmarkhianish { shift; shift || "baz" } -1; -EOT - -my $blechanawilla_text = <<'EOT'; -package Foo; -sub blechanawilla { compilation error ( -EOT -write_file( File::Spec->catfile( $fulldir, 'blechanawilla.al' ), $blechanawilla_text ); -# This is just to keep the old SVR3 systems happy; they may fail -# to find the above file so we duplicate it where they should find it. -write_file( File::Spec->catfile( $fulldir, 'blechanawil.al' ), $blechanawilla_text ); - -# Let's define the package -package Foo; -require AutoLoader; -AutoLoader->import( 'AUTOLOAD' ); - -sub new { bless {}, shift }; -sub foo; -sub bazmarkhianish; - -package main; - -my $foo = Foo->new(); - -my $result = $foo->can( 'foo' ); -ok( $result, 'can() first time' ); -is( $foo->foo, 'foo', 'autoloaded first time' ); -is( $foo->foo, 'foo', 'regular call' ); -is( $result, \&Foo::foo, 'can() returns ref to regular installed sub' ); - -eval { - $foo->will_fail; -}; -like( $@, qr/^Can't locate/, 'undefined method' ); - -$result = $foo->can( 'will_fail' ); -ok( ! $result, 'can() should fail on undefined methods' ); - -# Used to be trouble with this -eval { - my $foo = Foo->new(); - die "oops"; -}; -like( $@, qr/oops/, 'indirect method call' ); - -# Pass regular expression variable to autoloaded function. This used -# to go wrong because AutoLoader used regular expressions to generate -# autoloaded filename. -'foo' =~ /(\w+)/; - -is( $foo->bazmarkhianish($1), 'foo', 'autoloaded method should not stomp match vars' ); -is( $foo->bazmarkhianish($1), 'foo', '(again)' ); - -# Used to retry long subnames with shorter filenames on any old -# exception, including compilation error. Now AutoLoader only -# tries shorter filenames if it can't find the long one. -eval { - $foo->blechanawilla; -}; -like( $@, qr/syntax error/i, 'require error propagates' ); - -# test recursive autoloads -write_file( File::Spec->catfile( $fulldir, 'a.al' ), <<'EOT' ); -package Foo; -BEGIN { b() } -sub a { ::ok( 1, 'adding a new autoloaded method' ); } -1; -EOT -write_file( File::Spec->catfile( $fulldir, 'b.al' ), <<'EOT' ); -package Foo; -sub b { ::ok( 1, 'adding a new autoloaded method' ) } -1; -EOT - -Foo::a(); - -package Bar; -AutoLoader->import(); -::ok( ! defined &AUTOLOAD, 'AutoLoader should not export AUTOLOAD by default' ); -::ok( ! defined &can, '... nor can()' ); - -package Foo; -AutoLoader->unimport(); -eval { Foo->baz() }; -::like( $@, qr/locate object method "baz"/, - 'unimport() should remove imported AUTOLOAD()' ); - -package Baz; - -sub AUTOLOAD { 'i am here' } - -AutoLoader->import(); -AutoLoader->unimport(); - -::is( Baz->AUTOLOAD(), 'i am here', '... but not non-imported AUTOLOAD()' ); - - -package SomeClass; -use AutoLoader 'AUTOLOAD'; -sub new { - bless {} => shift; -} - -package main; - -$INC{"SomeClass.pm"} = $0; # Prepare possible recursion -{ - my $p = SomeClass->new(); -} # <-- deep recursion in AUTOLOAD looking for SomeClass::DESTROY? -::ok(1, "AutoLoader shouldn't loop forever if \%INC is modified"); - -# Now test the bug that lead to AutoLoader 0.67: -# If the module is loaded from a file name different than normal, -# we could formerly have trouble finding autosplit.ix -# Contributed by Christoph Lamprecht. -# Recreate the following file structure: -# auto/MyAddon/autosplit.ix -# auto/MyAddon/testsub.al -# MyModule.pm -SCOPE: { - my $autopath = File::Spec->catdir( $dir, 'auto', 'MyAddon' ); - mkpath( $autopath ) or die "Can't mkdir '$autopath': $!"; - my $autosplit_text = <<'EOT'; -# Index created by AutoSplit for MyModule.pm -# (file acts as timestamp) -package MyAddon; -sub testsub ; -1; -EOT - write_file( File::Spec->catfile( $autopath, 'autosplit.ix' ), $autosplit_text ); - - my $testsub_text = <<'EOT'; -# NOTE: Derived from MyModule.pm. -# Changes made here will be lost when autosplit is run again. -# See AutoSplit.pm. -package MyAddon; - -#line 13 "MyModule.pm (autosplit into auto/MyAddon/testsub.al)" -sub testsub{ - return "MyAddon"; -} - -1; -# end of MyAddon::testsub -EOT - write_file( File::Spec->catfile( $autopath, 'testsub.al' ), $testsub_text); - - my $mymodule_text = <<'EOT'; -use strict; -use warnings; -package MyModule; -sub testsub{return 'MyModule';} - -package MyAddon; -our @ISA = ('MyModule'); -BEGIN{$INC{'MyAddon.pm'} = __FILE__} -use AutoLoader 'AUTOLOAD'; -1; -__END__ - -sub testsub{ - return "MyAddon"; -} -EOT - write_file( File::Spec->catfile( $dir, 'MyModule.pm' ), $mymodule_text); - - require MyModule; - - my $res = MyAddon->testsub(); - ::is ($res , 'MyAddon', 'invoke MyAddon::testsub'); -} - -# cleanup -END { - return unless $dir && -d $dir; - rmtree $dir; -} - diff --git a/ext/AutoLoader/t/02AutoSplit.t b/ext/AutoLoader/t/02AutoSplit.t deleted file mode 100644 index c652562b30..0000000000 --- a/ext/AutoLoader/t/02AutoSplit.t +++ /dev/null @@ -1,442 +0,0 @@ -# AutoLoader.t runs before this test, so it seems safe to assume that it will -# work. - -my($incdir, $lib); -BEGIN { - chdir 't' if -d 't'; - if ($^O eq 'dos') { - print "1..0 # This test is not 8.3-aware.\n"; - exit 0; - } - if ($^O eq 'MacOS') { - $incdir = ":auto-$$"; - $lib = '-I::lib:'; - } else { - $incdir = "auto-$$"; - $lib = '"-I../lib"'; # ok on unix, nt, The extra \" are for VMS - } - unshift @INC, $incdir; - unshift @INC, '../lib'; -} -my $runperl = "$^X $lib"; - -use warnings; -use strict; -use Test::More tests => 58; -use File::Spec; -use File::Find; - -my $Is_VMS = $^O eq 'VMS'; -my $Is_VMS_mode = 0; -my $Is_VMS_lc = 0; - -if ($Is_VMS) { - require VMS::Filespec if $Is_VMS; - my $vms_unix_rpt; - my $vms_case; - - $Is_VMS_mode = 1; - $Is_VMS_lc = 1; - if (eval 'require VMS::Feature') { - $vms_unix_rpt = VMS::Feature::current("filename_unix_report"); - $vms_case = VMS::Feature::current("efs_case_preserve"); - } else { - my $unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || ''; - my $efs_case = $ENV{'DECC$EFS_CASE_PRESERVE'} || ''; - $vms_unix_rpt = $unix_rpt =~ /^[ET1]/i; - $vms_case = $efs_case =~ /^[ET1]/i; - } - $Is_VMS_lc = 0 if ($vms_case); - $Is_VMS_mode = 0 if ($vms_unix_rpt); -} - - -require AutoSplit; # Run time. Check it compiles. -ok (1, "AutoSplit loaded"); - -END { - use File::Path; - print "# $incdir being removed...\n"; - rmtree($incdir); -} - -mkdir $incdir,0755; - -my @tests; -{ - # local this else it buggers up the chomp() below. - # Hmm. Would be nice to have this as a regexp. - local $/ - = "################################################################\n"; - @tests = <DATA>; - close DATA; -} - -my $pathsep = $^O eq 'MSWin32' ? '\\' : $^O eq 'MacOS' ? ':' : '/'; -my $endpathsep = $^O eq 'MacOS' ? ':' : ''; - -sub split_a_file { - my $contents = shift; - my $file = $_[0]; - if (defined $contents) { - open FILE, ">$file" or die "Can't open $file: $!"; - print FILE $contents; - close FILE or die "Can't close $file: $!"; - } - - # Assumption: no characters in arguments need escaping from the shell or perl - my $com = qq($runperl -e "use AutoSplit; autosplit (qw(@_))"); - print "# command: $com\n"; - # There may be a way to capture STDOUT without spawning a child process, but - # it's probably worthwhile spawning, as it ensures that nothing in AutoSplit - # can load functions from split modules into this perl. - my $output = `$com`; - warn "Exit status $? from running: >>$com<<" if $?; - return $output; -} - -my $i = 0; -my $dir = File::Spec->catdir($incdir, 'auto'); -if ($Is_VMS_mode) { - $dir = VMS::Filespec::unixify($dir); - $dir =~ s/\/$//; -} elsif ($^O eq 'MacOS') { - $dir =~ s/:$//; -} - -foreach (@tests) { - my $module = 'A' . $i . '_' . $$ . 'splittest'; - my $file = File::Spec->catfile($incdir,"$module.pm"); - s/\*INC\*/$incdir/gm; - s/\*DIR\*/$dir/gm; - s/\*MOD\*/$module/gm; - s/\*PATHSEP\*/$pathsep/gm; - s/\*ENDPATHSEP\*/$endpathsep/gm; - s#//#/#gm; - # Build a hash for this test. - my %args = /^\#\#\ ([^\n]*)\n # Key is on a line starting ## - ((?:[^\#]+ # Any number of characters not # - | \#(?!\#) # or a # character not followed by # - | (?<!\n)\# # or a # character not preceded by \n - )*)/sgmx; - foreach ($args{Name}, $args{Require}, $args{Extra}) { - chomp $_ if defined $_; - } - $args{Get} ||= ''; - - my @extra_args = !defined $args{Extra} ? () : split /,/, $args{Extra}; - my ($output, $body); - if ($args{File}) { - $body ="package $module;\n" . $args{File}; - $output = split_a_file ($body, $file, $dir, @extra_args); - } else { - # Repeat tests - $output = split_a_file (undef, $file, $dir, @extra_args); - } - - if ($Is_VMS_mode) { - my ($filespec, $replacement); - while ($output =~ m/(\[.+\])/) { - $filespec = $1; - $replacement = VMS::Filespec::unixify($filespec); - $replacement =~ s/\/$//; - $output =~ s/\Q$filespec\E/$replacement/; - } - } - - # test n+1 - is($output, $args{Get}, "Output from autosplit()ing $args{Name}"); - - if ($args{Files}) { - $args{Files} =~ s!/!:!gs if $^O eq 'MacOS'; - my (%missing, %got); - find (sub {$got{$File::Find::name}++ unless -d $_}, $dir); - foreach (split /\n/, $args{Files}) { - next if /^#/; - $_ = lc($_) if $Is_VMS_lc; - unless (delete $got{$_}) { - $missing{$_}++; - } - } - my @missing = keys %missing; - # test n+2 - unless (ok (!@missing, "Are any expected files missing?")) { - print "# These files are missing\n"; - print "# $_\n" foreach sort @missing; - } - my @extra = keys %got; - # test n+3 - unless (ok (!@extra, "Are any extra files present?")) { - print "# These files are unexpectedly present:\n"; - print "# $_\n" foreach sort @extra; - } - } - if ($args{Require}) { - $args{Require} =~ s|/|:|gm if $^O eq 'MacOS'; - my $com = 'require "' . File::Spec->catfile ('auto', $args{Require}) . '"'; - $com =~ s{\\}{/}gm if ($^O eq 'MSWin32'); - eval $com; - # test n+3 - ok ($@ eq '', $com) or print "# \$\@ = '$@'\n"; - if (defined $body) { - eval $body or die $@; - } - } - # match tests to check for prototypes - if ($args{Match}) { - local $/; - my $file = File::Spec->catfile($dir, $args{Require}); - open IX, $file or die "Can't open '$file': $!"; - my $ix = <IX>; - close IX or die "Can't close '$file': $!"; - foreach my $pat (split /\n/, $args{Match}) { - next if $pat =~ /^\#/; - like ($ix, qr/^\s*$pat\s*$/m, "match $pat"); - } - } - # code tests contain eval{}ed ok()s etc - if ($args{Tests}) { - foreach my $code (split /\n/, $args{Tests}) { - next if $code =~ /^\#/; - defined eval $code or fail(), print "# Code: $code\n# Error: $@"; - } - } - if (my $sleepfor = $args{Sleep}) { - # We need to sleep for a while - # Need the sleep hack else the next test is so fast that the timestamp - # compare routine in AutoSplit thinks that it shouldn't split the files. - my $time = time; - my $until = $time + $sleepfor; - my $attempts = 3; - do { - sleep ($sleepfor) - } while (time < $until && --$attempts > 0); - if ($attempts == 0) { - printf << "EOM", time; -# Attempted to sleep for $sleepfor second(s), started at $time, now %d. -# sleep attempt ppears to have failed; some tests may fail as a result. -EOM - } - } - unless ($args{SameAgain}) { - $i++; - rmtree($dir); - mkdir $dir, 0775; - } -} - -__DATA__ -## Name -tests from the end of the AutoSplit module. -## File -use AutoLoader 'AUTOLOAD'; -{package Just::Another; - use AutoLoader 'AUTOLOAD'; -} -@Yet::Another::AutoSplit::ISA = 'AutoLoader'; -1; -__END__ -sub test1 ($) { "test 1"; } -sub test2 ($$) { "test 2"; } -sub test3 ($$$) { "test 3"; } -sub testtesttesttest4_1 { "test 4"; } -sub testtesttesttest4_2 { "duplicate test 4"; } -sub Just::Another::test5 { "another test 5"; } -sub test6 { return join ":", __FILE__,__LINE__; } -package Yet::Another::AutoSplit; -sub testtesttesttest4_1 ($) { "another test 4"; } -sub testtesttesttest4_2 ($$) { "another duplicate test 4"; } -package Yet::More::Attributes; -sub test_a1 ($) : locked :locked { 1; } -sub test_a2 : locked { 1; } -# And that was all it has. You were expected to manually inspect the output -## Get -Warning: AutoSplit had to create top-level *DIR* unexpectedly. -AutoSplitting *INC**PATHSEP**MOD*.pm (*DIR**PATHSEP**MOD**ENDPATHSEP*) -*INC**PATHSEP**MOD*.pm: some names are not unique when truncated to 8 characters: - directory *DIR**PATHSEP**MOD**ENDPATHSEP*: - testtesttesttest4_1.al, testtesttesttest4_2.al truncate to testtest - directory *DIR**PATHSEP*Yet*PATHSEP*Another*PATHSEP*AutoSplit*ENDPATHSEP*: - testtesttesttest4_1.al, testtesttesttest4_2.al truncate to testtest -## Files -*DIR*/*MOD*/autosplit.ix -*DIR*/*MOD*/test1.al -*DIR*/*MOD*/test2.al -*DIR*/*MOD*/test3.al -*DIR*/*MOD*/testtesttesttest4_1.al -*DIR*/*MOD*/testtesttesttest4_2.al -*DIR*/Just/Another/test5.al -*DIR*/*MOD*/test6.al -*DIR*/Yet/Another/AutoSplit/testtesttesttest4_1.al -*DIR*/Yet/Another/AutoSplit/testtesttesttest4_2.al -*DIR*/Yet/More/Attributes/test_a1.al -*DIR*/Yet/More/Attributes/test_a2.al -## Require -*MOD*/autosplit.ix -## Match -# Need to find these lines somewhere in the required file -sub test1\s*\(\$\); -sub test2\s*\(\$\$\); -sub test3\s*\(\$\$\$\); -sub testtesttesttest4_1\s*\(\$\); -sub testtesttesttest4_2\s*\(\$\$\); -sub test_a1\s*\(\$\)\s*:\s*locked\s*:\s*locked\s*; -sub test_a2\s*:\s*locked\s*; -## Tests -is (*MOD*::test1 (1), 'test 1'); -is (*MOD*::test2 (1,2), 'test 2'); -is (*MOD*::test3 (1,2,3), 'test 3'); -ok (!defined eval "*MOD*::test1 () eq 'test 1'" and $@ =~ /^Not enough arguments for *MOD*::test1/, "Check prototypes mismatch fails") or print "# \$\@='$@'"; -is (&*MOD*::testtesttesttest4_1, "test 4"); -is (&*MOD*::testtesttesttest4_2, "duplicate test 4"); -is (&Just::Another::test5, "another test 5"); -# very messy way to interpolate function into regexp, but it's going to be -# needed to get : for Mac filespecs -like (&*MOD*::test6, qr!^\Q*INC**PATHSEP**MOD*\E\.pm \(autosplit into \Q@{[File::Spec->catfile('*DIR*','*MOD*', 'test6.al')]}\E\):\d+$!); -ok (Yet::Another::AutoSplit->testtesttesttest4_1 eq "another test 4"); -################################################################ -## Name -missing use AutoLoader; -## File -1; -__END__ -## Get -## Files -# There should be no files. -################################################################ -## Name -missing use AutoLoader; (but don't skip) -## Extra -0, 0 -## File -1; -__END__ -## Get -AutoSplitting *INC**PATHSEP**MOD*.pm (*DIR**PATHSEP**MOD**ENDPATHSEP*) -## Require -*MOD*/autosplit.ix -## Files -*DIR*/*MOD*/autosplit.ix -################################################################ -## Name -Split prior to checking whether obsolete files get deleted -## File -use AutoLoader 'AUTOLOAD'; -1; -__END__ -sub obsolete {our $hidden_a; return $hidden_a++;} -sub gonner {warn "This gonner function should never get called"} -## Get -AutoSplitting *INC**PATHSEP**MOD*.pm (*DIR**PATHSEP**MOD**ENDPATHSEP*) -## Require -*MOD*/autosplit.ix -## Files -*DIR*/*MOD*/autosplit.ix -*DIR*/*MOD*/gonner.al -*DIR*/*MOD*/obsolete.al -## Tests -is (&*MOD*::obsolete, 0); -is (&*MOD*::obsolete, 1); -## Sleep -4 -## SameAgain -True, so don't scrub this directory. -IIRC DOS FAT filesystems have only 2 second granularity. -################################################################ -## Name -Check whether obsolete files get deleted -## File -use AutoLoader 'AUTOLOAD'; -1; -__END__ -sub skeleton {"bones"}; -sub ghost {"scream"}; # This definition gets overwritten with the one below -sub ghoul {"wail"}; -sub zombie {"You didn't use fire."}; -sub flying_pig {"Oink oink flap flap"}; -## Get -AutoSplitting *INC**PATHSEP**MOD*.pm (*DIR**PATHSEP**MOD**ENDPATHSEP*) -## Require -*MOD*/autosplit.ix -## Files -*DIR*/*MOD*/autosplit.ix -*DIR*/*MOD*/skeleton.al -*DIR*/*MOD*/zombie.al -*DIR*/*MOD*/ghost.al -*DIR*/*MOD*/ghoul.al -*DIR*/*MOD*/flying_pig.al -## Tests -is (&*MOD*::skeleton, "bones", "skeleton"); -eval {&*MOD*::gonner}; ok ($@ =~ m!^Can't locate auto/*MOD*/gonner.al in \@INC!, "Check &*MOD*::gonner is now a gonner") or print "# \$\@='$@'\n"; -## Sleep -4 -## SameAgain -True, so don't scrub this directory. -################################################################ -## Name -Check whether obsolete files remain when keep is 1 -## Extra -1, 1 -## File -use AutoLoader 'AUTOLOAD'; -1; -__END__ -sub ghost {"bump"}; -sub wraith {9}; -## Get -AutoSplitting *INC**PATHSEP**MOD*.pm (*DIR**PATHSEP**MOD**ENDPATHSEP*) -## Require -*MOD*/autosplit.ix -## Files -*DIR*/*MOD*/autosplit.ix -*DIR*/*MOD*/skeleton.al -*DIR*/*MOD*/zombie.al -*DIR*/*MOD*/ghost.al -*DIR*/*MOD*/ghoul.al -*DIR*/*MOD*/wraith.al -*DIR*/*MOD*/flying_pig.al -## Tests -is (&*MOD*::ghost, "bump"); -is (&*MOD*::zombie, "You didn't use fire.", "Are our zombies undead?"); -## Sleep -4 -## SameAgain -True, so don't scrub this directory. -################################################################ -## Name -Without the timestamp check make sure that nothing happens -## Extra -0, 1, 1 -## Require -*MOD*/autosplit.ix -## Files -*DIR*/*MOD*/autosplit.ix -*DIR*/*MOD*/skeleton.al -*DIR*/*MOD*/zombie.al -*DIR*/*MOD*/ghost.al -*DIR*/*MOD*/ghoul.al -*DIR*/*MOD*/wraith.al -*DIR*/*MOD*/flying_pig.al -## Tests -is (&*MOD*::ghoul, "wail", "still haunted"); -is (&*MOD*::zombie, "You didn't use fire.", "Are our zombies still undead?"); -## Sleep -4 -## SameAgain -True, so don't scrub this directory. -################################################################ -## Name -With the timestamp check make sure that things happen (stuff gets deleted) -## Extra -0, 1, 0 -## Get -AutoSplitting *INC**PATHSEP**MOD*.pm (*DIR**PATHSEP**MOD**ENDPATHSEP*) -## Require -*MOD*/autosplit.ix -## Files -*DIR*/*MOD*/autosplit.ix -*DIR*/*MOD*/ghost.al -*DIR*/*MOD*/wraith.al -## Tests -is (&*MOD*::wraith, 9); -eval {&*MOD*::flying_pig}; ok ($@ =~ m!^Can't locate auto/*MOD*/flying_pig.al in \@INC!, "There are no flying pigs") or print "# \$\@='$@'\n"; |