summaryrefslogtreecommitdiff
path: root/dist/lib
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2009-09-28 15:11:36 +0100
committerNicholas Clark <nick@ccl4.org>2009-09-29 11:12:38 +0100
commit88697c04890059636ae16bf315df6e3817777136 (patch)
tree934b1dd33646044c93489c83bdb7828ce9b56a56 /dist/lib
parent725607636edc598ad6823e49789420d734f8aa28 (diff)
downloadperl-88697c04890059636ae16bf315df6e3817777136.tar.gz
Move lib from ext/ to dist/
Diffstat (limited to 'dist/lib')
-rw-r--r--dist/lib/.gitignore1
-rw-r--r--dist/lib/Makefile.PL49
-rw-r--r--dist/lib/lib_pm.PL319
-rw-r--r--dist/lib/t/01lib.t81
4 files changed, 450 insertions, 0 deletions
diff --git a/dist/lib/.gitignore b/dist/lib/.gitignore
new file mode 100644
index 0000000000..8caf3063dc
--- /dev/null
+++ b/dist/lib/.gitignore
@@ -0,0 +1 @@
+/lib.pm
diff --git a/dist/lib/Makefile.PL b/dist/lib/Makefile.PL
new file mode 100644
index 0000000000..1f80b02cf2
--- /dev/null
+++ b/dist/lib/Makefile.PL
@@ -0,0 +1,49 @@
+## This -*- perl -*- script writes the Makefile for lib.pm
+# You should read "perldoc perlmodinstall" for instructions on
+# how to install modules like this.
+
+require 5.006_001;
+use strict;
+use ExtUtils::MakeMaker;
+
+my $lib_version = '0.62';
+
+my $extra_meta = <<"EMETA";
+provides:
+ lib:
+ file: lib_pm.PL
+ version: $lib_version
+EMETA
+
+my $extra_meta_hash = {
+ provides => {
+ lib => { file => 'lib_pm.PL',
+ version => $lib_version, },
+ },
+};
+
+my $mm_version = $ExtUtils::MakeMaker::VERSION;
+
+WriteMakefile(
+ 'NAME' => 'lib',
+ 'VERSION' => $lib_version,
+ 'LICENSE' => 'perl',
+ 'PREREQ_PM' => {},
+ 'ABSTRACT_FROM' => 'lib_pm.PL',
+ 'AUTHOR' => 'Steffen Mueller <smueller@cpan.org>',
+ 'INSTALLDIRS' => 'perl',
+ 'PL_FILES' => {'lib_pm.PL' => 'lib.pm'},
+ 'PM' => {'lib.pm' => '$(INST_LIBDIR)/lib.pm'},
+ 'clean' => {FILES => 'lib.pm'},
+ (
+ $mm_version >= 6.46
+ ? (META_ADD => $extra_meta_hash)
+ : (
+ $mm_version >= 6.3002
+ ? (EXTRA_META => $extra_meta)
+ : ()
+ )
+ ),
+);
+
+
diff --git a/dist/lib/lib_pm.PL b/dist/lib/lib_pm.PL
new file mode 100644
index 0000000000..fabdbd0a7d
--- /dev/null
+++ b/dist/lib/lib_pm.PL
@@ -0,0 +1,319 @@
+use Config;
+use File::Basename qw(&basename &dirname);
+use File::Spec;
+use Cwd;
+
+my $origdir = cwd;
+chdir dirname($0);
+my $file = basename($0, '.PL');
+$file =~ s/_(pm)$/.$1/i;
+
+my $useConfig;
+my $Config_archname;
+my $Config_version;
+my $Config_inc_version_list;
+
+# Expand the variables only if explicitly requested
+# or if a previously installed lib.pm does this, too
+# because otherwise relocating Perl becomes much harder.
+
+my $expand_config_vars = 0;
+if ($ENV{PERL_BUILD_EXPAND_CONFIG_VARS}) {
+ $expand_config_vars = 1;
+}
+elsif (exists $ENV{PERL_BUILD_EXPAND_CONFIG_VARS}) {
+ $expand_config_vars = 0;
+}
+else {
+ eval <<'HERE';
+ require lib;
+ my $lib_file = $INC{"lib.pm"};
+ open my $fh, '<', $lib_file
+ or die "Could not open file '$lib_file' for reading: $!";
+ my $ConfigRegex = qr/(?:use|require)\s+Config(?:\s+|;)/;
+ my $found_config = 0;
+ while (defined($_ = <$fh>)) {
+ # crude heuristics to check that we were using Config
+ if (/^\s*$ConfigRegex/ || /^\s*eval.*$ConfigRegex/) {
+ $found_config = 1;
+ last;
+ }
+ }
+ $expand_config_vars = $found_config ? 0 : 1;
+HERE
+ $expand_config_vars = 0 if $@;
+}
+
+if ($expand_config_vars) {
+ $useConfig = '';
+ $Config_archname = qq('$Config{archname}');
+ $Config_version = qq('$Config{version}');
+ my @Config_inc_version_list =
+ reverse split / /, $Config{inc_version_list};
+ $Config_inc_version_list =
+ @Config_inc_version_list ?
+ qq(qw(@Config_inc_version_list)) : q(());
+} else {
+ $useConfig = 'use Config;';
+ $Config_archname = q($Config{archname});
+ $Config_version = q($Config{version});
+ $Config_inc_version_list =
+ q(reverse split / /, $Config{inc_version_list});
+}
+
+open OUT,">$file" or die "Can't create $file: $!";
+
+print "Extracting $file (with variable substitutions)\n";
+
+# In this section, perl variables will be expanded during extraction.
+# You can use $Config{...} to use Configure variables.
+
+print OUT <<"!GROK!THIS!";
+package lib;
+
+# THIS FILE IS AUTOMATICALLY GENERATED FROM lib_pm.PL.
+# ANY CHANGES TO THIS FILE WILL BE OVERWRITTEN BY THE NEXT PERL BUILD.
+
+$useConfig
+
+use strict;
+
+my \$archname = $Config_archname;
+my \$version = $Config_version;
+my \@inc_version_list = $Config_inc_version_list;
+
+!GROK!THIS!
+print OUT <<'!NO!SUBS!';
+
+our @ORIG_INC = @INC; # take a handy copy of 'original' value
+our $VERSION = '0.62';
+my $Is_MacOS = $^O eq 'MacOS';
+my $Mac_FS;
+if ($Is_MacOS) {
+ require File::Spec;
+ $Mac_FS = eval { require Mac::FileSpec::Unixish };
+}
+
+sub import {
+ shift;
+
+ my %names;
+ foreach (reverse @_) {
+ my $path = $_; # we'll be modifying it, so break the alias
+ if ($path eq '') {
+ require Carp;
+ Carp::carp("Empty compile time value given to use lib");
+ }
+
+ $path = _nativize($path);
+
+ if ($path !~ /\.par$/i && -e $path && ! -d _) {
+ require Carp;
+ Carp::carp("Parameter to use lib must be directory, not file");
+ }
+ unshift(@INC, $path);
+ # Add any previous version directories we found at configure time
+ foreach my $incver (@inc_version_list)
+ {
+ my $dir = $Is_MacOS
+ ? File::Spec->catdir( $path, $incver )
+ : "$path/$incver";
+ unshift(@INC, $dir) if -d $dir;
+ }
+ # Put a corresponding archlib directory in front of $path if it
+ # looks like $path has an archlib directory below it.
+ my($arch_auto_dir, $arch_dir, $version_dir, $version_arch_dir)
+ = _get_dirs($path);
+ unshift(@INC, $arch_dir) if -d $arch_auto_dir;
+ unshift(@INC, $version_dir) if -d $version_dir;
+ unshift(@INC, $version_arch_dir) if -d $version_arch_dir;
+ }
+
+ # remove trailing duplicates
+ @INC = grep { ++$names{$_} == 1 } @INC;
+ return;
+}
+
+
+sub unimport {
+ shift;
+
+ my %names;
+ foreach (@_) {
+ my $path = _nativize($_);
+
+ my($arch_auto_dir, $arch_dir, $version_dir, $version_arch_dir)
+ = _get_dirs($path);
+ ++$names{$path};
+ ++$names{$arch_dir} if -d $arch_auto_dir;
+ ++$names{$version_dir} if -d $version_dir;
+ ++$names{$version_arch_dir} if -d $version_arch_dir;
+ }
+
+ # Remove ALL instances of each named directory.
+ @INC = grep { !exists $names{$_} } @INC;
+ return;
+}
+
+sub _get_dirs {
+ my($dir) = @_;
+ my($arch_auto_dir, $arch_dir, $version_dir, $version_arch_dir);
+
+ # we could use this for all platforms in the future, but leave it
+ # Mac-only for now, until there is more time for testing it.
+ if ($Is_MacOS) {
+ $arch_auto_dir = File::Spec->catdir( $dir, $archname, 'auto' );
+ $arch_dir = File::Spec->catdir( $dir, $archname, );
+ $version_dir = File::Spec->catdir( $dir, $version );
+ $version_arch_dir = File::Spec->catdir( $dir, $version, $archname );
+ } else {
+ $arch_auto_dir = "$dir/$archname/auto";
+ $arch_dir = "$dir/$archname";
+ $version_dir = "$dir/$version";
+ $version_arch_dir = "$dir/$version/$archname";
+ }
+ return($arch_auto_dir, $arch_dir, $version_dir, $version_arch_dir);
+}
+
+sub _nativize {
+ my($dir) = @_;
+
+ if ($Is_MacOS && $Mac_FS && ! -d $dir) {
+ $dir = Mac::FileSpec::Unixish::nativize($dir);
+ $dir .= ":" unless $dir =~ /:$/;
+ }
+
+ return $dir;
+}
+
+1;
+__END__
+
+=head1 NAME
+
+lib - manipulate @INC at compile time
+
+=head1 SYNOPSIS
+
+ use lib LIST;
+
+ no lib LIST;
+
+=head1 DESCRIPTION
+
+This is a small simple module which simplifies the manipulation of @INC
+at compile time.
+
+It is typically used to add extra directories to perl's search path so
+that later C<use> or C<require> statements will find modules which are
+not located on perl's default search path.
+
+=head2 Adding directories to @INC
+
+The parameters to C<use lib> are added to the start of the perl search
+path. Saying
+
+ use lib LIST;
+
+is I<almost> the same as saying
+
+ BEGIN { unshift(@INC, LIST) }
+
+For each directory in LIST (called $dir here) the lib module also
+checks to see if a directory called $dir/$archname/auto exists.
+If so the $dir/$archname directory is assumed to be a corresponding
+architecture specific directory and is added to @INC in front of $dir.
+lib.pm also checks if directories called $dir/$version and $dir/$version/$archname
+exist and adds these directories to @INC.
+
+The current value of C<$archname> can be found with this command:
+
+ perl -V:archname
+
+The corresponding command to get the current value of C<$version> is:
+
+ perl -V:version
+
+To avoid memory leaks, all trailing duplicate entries in @INC are
+removed.
+
+=head2 Deleting directories from @INC
+
+You should normally only add directories to @INC. If you need to
+delete directories from @INC take care to only delete those which you
+added yourself or which you are certain are not needed by other modules
+in your script. Other modules may have added directories which they
+need for correct operation.
+
+The C<no lib> statement deletes all instances of each named directory
+from @INC.
+
+For each directory in LIST (called $dir here) the lib module also
+checks to see if a directory called $dir/$archname/auto exists.
+If so the $dir/$archname directory is assumed to be a corresponding
+architecture specific directory and is also deleted from @INC.
+
+=head2 Restoring original @INC
+
+When the lib module is first loaded it records the current value of @INC
+in an array C<@lib::ORIG_INC>. To restore @INC to that value you
+can say
+
+ @INC = @lib::ORIG_INC;
+
+=head1 CAVEATS
+
+In order to keep lib.pm small and simple, it only works with Unix
+filepaths. This doesn't mean it only works on Unix, but non-Unix
+users must first translate their file paths to Unix conventions.
+
+ # VMS users wanting to put [.stuff.moo] into
+ # their @INC would write
+ use lib 'stuff/moo';
+
+=head1 NOTES
+
+In the future, this module will likely use File::Spec for determining
+paths, as it does now for Mac OS (where Unix-style or Mac-style paths
+work, and Unix-style paths are converted properly to Mac-style paths
+before being added to @INC).
+
+If you try to add a file to @INC as follows:
+
+ use lib 'this_is_a_file.txt';
+
+C<lib> will warn about this. The sole exceptions are files with the
+C<.par> extension which are intended to be used as libraries.
+
+=head1 SEE ALSO
+
+FindBin - optional module which deals with paths relative to the source file.
+
+PAR - optional module which can treat C<.par> files as Perl libraries.
+
+=head1 AUTHOR
+
+Tim Bunce, 2nd June 1995.
+
+C<lib> 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.
+
+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 perl 5.001.
+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.
+
+=cut
+!NO!SUBS!
+
+close OUT or die "Can't close $file: $!";
+chdir $origdir;
diff --git a/dist/lib/t/01lib.t b/dist/lib/t/01lib.t
new file mode 100644
index 0000000000..d39a656bf8
--- /dev/null
+++ b/dist/lib/t/01lib.t
@@ -0,0 +1,81 @@
+#!./perl -w
+
+BEGIN {
+ chdir 't';
+ unshift @INC, '..';
+ unshift @INC, '../lib';
+ @OrigINC = @INC;
+}
+
+use Test::More tests => 13;
+use Config;
+use File::Spec;
+use File::Path;
+
+#set up files and directories
+my @lib_dir;
+my $Lib_Dir;
+my $Arch_Dir;
+my $Auto_Dir;
+my $Module;
+BEGIN {
+ # lib.pm is documented to only work with Unix filepaths.
+ @lib_dir = qw(stuff moo);
+ $Lib_Dir = join "/", @lib_dir;
+ $Arch_Dir = join "/", @lib_dir, $Config{archname};
+
+ # create the auto/ directory and a module
+ $Auto_Dir = File::Spec->catdir(@lib_dir, $Config{archname},'auto');
+ $Module = File::Spec->catfile(@lib_dir, 'Yup.pm');
+
+ mkpath [$Auto_Dir];
+
+ open(MOD, ">$Module") || DIE $!;
+ print MOD <<'MODULE';
+package Yup;
+$Plan = 9;
+return '42';
+MODULE
+
+ close MOD;
+}
+
+END {
+ # cleanup the auto/ directory we created.
+ rmtree([$lib_dir[0]]);
+}
+
+
+use lib $Lib_Dir;
+use lib $Lib_Dir;
+
+BEGIN { use_ok('Yup') }
+
+BEGIN {
+ is( $INC[1], $Lib_Dir, 'lib adding at end of @INC' );
+ print "# \@INC == @INC\n";
+ is( $INC[0], $Arch_Dir, ' auto/ dir in front of that' );
+ is( grep(/^\Q$Lib_Dir\E$/, @INC), 1, ' no duplicates' );
+
+ # Yes, %INC uses Unixy filepaths.
+ # Not on Mac OS, it doesn't ... it never has, at least.
+ my $path = join("/",$Lib_Dir, 'Yup.pm');
+ is( $INC{'Yup.pm'}, $path, '%INC set properly' );
+
+ is( eval { do 'Yup.pm' }, 42, 'do() works' );
+ ok( eval { require Yup; }, ' require()' );
+ ok( eval "use Yup; 1;", ' use()' );
+ is( $@, '' );
+
+ is_deeply(\@OrigINC, \@lib::ORIG_INC, '@lib::ORIG_INC' );
+}
+
+no lib $Lib_Dir;
+
+unlike( do { eval 'use lib $Config{installsitelib};'; $@ || '' },
+ qr/::Config is read-only/, 'lib handles readonly stuff' );
+
+BEGIN {
+ is( grep(/stuff/, @INC), 0, 'no lib' );
+ ok( !do 'Yup.pm', ' do() effected' );
+}