summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl0/lib/PAR/Heavy.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl0/lib/PAR/Heavy.pm')
-rwxr-xr-xMaster/tlpkg/tlperl0/lib/PAR/Heavy.pm204
1 files changed, 204 insertions, 0 deletions
diff --git a/Master/tlpkg/tlperl0/lib/PAR/Heavy.pm b/Master/tlpkg/tlperl0/lib/PAR/Heavy.pm
new file mode 100755
index 00000000000..e05e5d1ebce
--- /dev/null
+++ b/Master/tlpkg/tlperl0/lib/PAR/Heavy.pm
@@ -0,0 +1,204 @@
+package PAR::Heavy;
+$PAR::Heavy::VERSION = '0.11';
+
+=head1 NAME
+
+PAR::Heavy - PAR guts
+
+=head1 SYNOPSIS
+
+(internal use only)
+
+=head1 DESCRIPTION
+
+No user-serviceable parts inside.
+
+=cut
+
+########################################################################
+# Dynamic inclusion of XS modules
+
+my ($bootstrap, $dl_findfile); # Caches for code references
+my ($dlext); # Cache for $Config{dlext}
+my ($cache_key); # The current file to find
+my $is_insensitive_fs = (
+ -s $0
+ and (-s lc($0) || -1) == (-s uc($0) || -1)
+ and (-s lc($0) || -1) == -s $0
+);
+
+# Adds pre-hooks to Dynaloader's key methods
+sub _init_dynaloader {
+ return if $bootstrap;
+ return unless eval { require DynaLoader; DynaLoader::dl_findfile(); 1 };
+
+ $bootstrap = \&DynaLoader::bootstrap;
+ $dl_findfile = \&DynaLoader::dl_findfile;
+
+ local $^W;
+ *{'DynaLoader::dl_expandspec'} = sub { return };
+ *{'DynaLoader::bootstrap'} = \&_bootstrap;
+ *{'DynaLoader::dl_findfile'} = \&_dl_findfile;
+}
+
+# Return the cached location of .dll inside PAR first, if possible.
+sub _dl_findfile {
+ return $FullCache{$cache_key} if exists $FullCache{$cache_key};
+ if ($is_insensitive_fs) {
+ # We have a case-insensitive filesystem...
+ my ($key) = grep { lc($_) eq lc($cache_key) } keys %FullCache;
+ return $FullCache{$key} if defined $key;
+ }
+ return $dl_findfile->(@_);
+}
+
+# Find and extract .dll from PAR files for a given dynamic module.
+sub _bootstrap {
+ my (@args) = @_;
+ my ($module) = $args[0] or return;
+
+ my @modparts = split(/::/, $module);
+ my $modfname = $modparts[-1];
+
+ $modfname = &DynaLoader::mod2fname(\@modparts)
+ if defined &DynaLoader::mod2fname;
+
+ if (($^O eq 'NetWare') && (length($modfname) > 8)) {
+ $modfname = substr($modfname, 0, 8);
+ }
+
+ # XXX: Multi-platform .dll support in PARs needs better than $Config.
+ # FIXME: Config is always loaded by PAR.pm!
+ $dlext ||= do {
+ require Config;
+ (defined %Config::Config) ? $Config::Config{dlext} : '';
+ };
+
+ my $modpname = join((($^O eq 'MacOS') ? ':' : '/'), @modparts);
+ my $file = $cache_key = "auto/$modpname/$modfname.$dlext";
+
+ if ($FullCache{$file}) {
+ # TODO: understand
+ local $DynaLoader::do_expand = 1;
+ return $bootstrap->(@args);
+ }
+
+ my $member;
+ # First, try to find things in the peferentially loaded PARs:
+ $member = PAR::_find_par_internals([@PAR::PAR_INC], undef, $file, 1)
+ if defined &PAR::_find_par_internals;
+
+ # If that failed to find the dll, let DynaLoader (try or) throw an error
+ unless ($member) {
+ my $filename = eval { $bootstrap->(@args) };
+ return $filename if not $@ and defined $filename;
+
+ # Now try the fallback pars
+ $member = PAR::_find_par_internals([@PAR::PAR_INC_LAST], undef, $file, 1)
+ if defined &PAR::_find_par_internals;
+
+ # If that fails, let dynaloader have another go JUST to throw an error
+ # While this may seem wasteful, nothing really matters once we fail to
+ # load shared libraries!
+ unless ($member) {
+ return $bootstrap->(@args);
+ }
+ }
+
+ $FullCache{$file} = _dl_extract($member, $file);
+
+ # Now extract all associated shared objs in the same auto/ dir
+ # XXX: shouldn't this also set $FullCache{...} for those files?
+ my $first = $member->fileName;
+ my $path_pattern = $first;
+ $path_pattern =~ s{[^/]*$}{};
+ if ($PAR::LastAccessedPAR) {
+ foreach my $member ( $PAR::LastAccessedPAR->members ) {
+ next if $member->isDirectory;
+
+ my $name = $member->fileName;
+ next if $name eq $first;
+ next unless $name =~ m{^/?\Q$path_pattern\E\/[^/]*\.\Q$dlext\E[^/]*$};
+ $name =~ s{.*/}{};
+ _dl_extract($member, $file, $name);
+ }
+ }
+
+ local $DynaLoader::do_expand = 1;
+ return $bootstrap->(@args);
+}
+
+sub _dl_extract {
+ my ($member, $file, $name) = @_;
+
+ require File::Spec;
+ require File::Temp;
+
+ my ($fh, $filename);
+
+ # fix borked tempdir from earlier versions
+ if ($ENV{PAR_TEMP} and -e $ENV{PAR_TEMP} and !-d $ENV{PAR_TEMP}) {
+ unlink($ENV{PAR_TEMP});
+ mkdir($ENV{PAR_TEMP}, 0755);
+ }
+
+ if ($ENV{PAR_CLEAN} and !$name) {
+ ($fh, $filename) = File::Temp::tempfile(
+ DIR => ($ENV{PAR_TEMP} || File::Spec->tmpdir),
+ SUFFIX => ".$dlext",
+ UNLINK => ($^O ne 'MSWin32' and $^O !~ /hpux/),
+ );
+ ($filename) = $filename =~ /^([\x20-\xff]+)$/;
+ }
+ else {
+ $filename = File::Spec->catfile(
+ ($ENV{PAR_TEMP} || File::Spec->tmpdir),
+ ($name || ($member->crc32String . ".$dlext"))
+ );
+ ($filename) = $filename =~ /^([\x20-\xff]+)$/;
+
+ open $fh, '>', $filename or die $!
+ unless -r $filename and -e _
+ and -s _ == $member->uncompressedSize;
+ }
+
+ if ($fh) {
+ binmode($fh);
+ $member->extractToFileHandle($fh);
+ close $fh;
+ chmod 0755, $filename;
+ }
+
+ return $filename;
+}
+
+1;
+
+=head1 SEE ALSO
+
+L<PAR>
+
+=head1 AUTHORS
+
+Audrey Tang E<lt>cpan@audreyt.orgE<gt>
+
+L<http://par.perl.org/> is the official PAR website. You can write
+to the mailing list at E<lt>par@perl.orgE<gt>, or send an empty mail to
+E<lt>par-subscribe@perl.orgE<gt> to participate in the discussion.
+
+Please submit bug reports to E<lt>bug-par@rt.cpan.orgE<gt>.
+
+=head1 COPYRIGHT
+
+Copyright 2002-2009 by Audrey Tang
+E<lt>cpan@audreyt.orgE<gt>.
+
+Copyright 2006-2009 by Steffen Mueller
+E<lt>smueller@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+See L<http://www.perl.com/perl/misc/Artistic.html>
+
+=cut