summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/perl/lib/ExtUtils
diff options
context:
space:
mode:
authormillert <millert@openbsd.org>2008-09-29 17:17:50 +0000
committermillert <millert@openbsd.org>2008-09-29 17:17:50 +0000
commit850e275390052b330d93020bf619a739a3c277ac (patch)
treedb372d287586cf504a5ead4801f6c6cf7eb31449 /gnu/usr.bin/perl/lib/ExtUtils
parentmore updates on which args do and do not mix (doc only, this time): (diff)
downloadwireguard-openbsd-850e275390052b330d93020bf619a739a3c277ac.tar.xz
wireguard-openbsd-850e275390052b330d93020bf619a739a3c277ac.zip
import perl 5.10.0 from CPAN
Diffstat (limited to 'gnu/usr.bin/perl/lib/ExtUtils')
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder.pm318
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Base.pm279
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Changes207
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/Unix.pm37
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/VMS.pm294
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/Windows.pm732
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/aix.pm31
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/cygwin.pm30
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/darwin.pm22
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/dec_osf.pm18
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/os2.pm80
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/t/01-basic.t58
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/CBuilder/t/02-link.t77
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Changes223
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Command/MM.pm5
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Constant.pm102
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Constant/Base.pm237
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Constant/ProxySubs.pm524
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Constant/Utils.pm12
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Constant/XS.pm13
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Installed.pm136
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Liblist/Kid.pm8
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM.pm11
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_AIX.pm2
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_BeOS.pm6
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_Cygwin.pm2
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_DOS.pm2
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_MacOS.pm5
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_NW5.pm3
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_QNX.pm2
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_UWIN.pm2
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_VOS.pm2
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MM_Win95.pm6
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MY.pm2
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/Config.pm2
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/bytes.pm4
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/vmsish.pm4
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/PATCHING17
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/Packlist.pm89
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/ParseXS.pm2052
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/XSTest.pm8
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/XSTest.xs67
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/basic.t79
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/README13
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/TODO3
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/Constant.t268
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/Embed.t37
-rwxr-xr-xgnu/usr.bin/perl/lib/ExtUtils/t/FIRST_MAKEFILE.t2
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/INSTALL_BASE.t81
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/Install.t28
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/Installed.t119
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/MM_NW5.t17
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/MM_Unix.t7
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/MM_VMS.t1
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/MM_Win32.t1
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/Manifest.t64
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/Packlist.t10
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/WriteEmptyMakefile.t40
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/basic.t31
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/build_man.t86
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/cd.t67
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/eu_command.t295
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/fixin.t45
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/make.t24
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/maketext_filter.t65
-rwxr-xr-xgnu/usr.bin/perl/lib/ExtUtils/t/parse_version.t55
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/pm.t47
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/prereq.t133
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/recurs.t11
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/revision.t23
-rw-r--r--gnu/usr.bin/perl/lib/ExtUtils/t/writemakefile_args.t81
-rwxr-xr-xgnu/usr.bin/perl/lib/ExtUtils/t/xs.t41
72 files changed, 7097 insertions, 408 deletions
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder.pm
new file mode 100644
index 00000000000..fae01b116dd
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder.pm
@@ -0,0 +1,318 @@
+package ExtUtils::CBuilder;
+
+use File::Spec ();
+use File::Path ();
+use File::Basename ();
+
+use vars qw($VERSION @ISA);
+$VERSION = '0.21';
+$VERSION = eval $VERSION;
+
+# Okay, this is the brute-force method of finding out what kind of
+# platform we're on. I don't know of a systematic way. These values
+# came from the latest (bleadperl) perlport.pod.
+
+my %OSTYPES = qw(
+ aix Unix
+ bsdos Unix
+ dgux Unix
+ dynixptx Unix
+ freebsd Unix
+ linux Unix
+ hpux Unix
+ irix Unix
+ darwin Unix
+ machten Unix
+ next Unix
+ openbsd Unix
+ netbsd Unix
+ dec_osf Unix
+ svr4 Unix
+ svr5 Unix
+ sco_sv Unix
+ unicos Unix
+ unicosmk Unix
+ solaris Unix
+ sunos Unix
+ cygwin Unix
+ os2 Unix
+
+ dos Windows
+ MSWin32 Windows
+
+ os390 EBCDIC
+ os400 EBCDIC
+ posix-bc EBCDIC
+ vmesa EBCDIC
+
+ MacOS MacOS
+ VMS VMS
+ VOS VOS
+ riscos RiscOS
+ amigaos Amiga
+ mpeix MPEiX
+ );
+
+# We only use this once - don't waste a symbol table entry on it.
+# More importantly, don't make it an inheritable method.
+my $load = sub {
+ my $mod = shift;
+ eval "use $mod";
+ die $@ if $@;
+ @ISA = ($mod);
+};
+
+{
+ my @package = split /::/, __PACKAGE__;
+
+ if (grep {-e File::Spec->catfile($_, @package, 'Platform', $^O) . '.pm'} @INC) {
+ $load->(__PACKAGE__ . "::Platform::$^O");
+
+ } elsif (exists $OSTYPES{$^O} and
+ grep {-e File::Spec->catfile($_, @package, 'Platform', $OSTYPES{$^O}) . '.pm'} @INC) {
+ $load->(__PACKAGE__ . "::Platform::$OSTYPES{$^O}");
+
+ } else {
+ $load->(__PACKAGE__ . "::Base");
+ }
+}
+
+sub os_type { $OSTYPES{$^O} }
+
+1;
+__END__
+
+=head1 NAME
+
+ExtUtils::CBuilder - Compile and link C code for Perl modules
+
+=head1 SYNOPSIS
+
+ use ExtUtils::CBuilder;
+
+ my $b = ExtUtils::CBuilder->new(%options);
+ $obj_file = $b->compile(source => 'MyModule.c');
+ $lib_file = $b->link(objects => $obj_file);
+
+=head1 DESCRIPTION
+
+This module can build the C portions of Perl modules by invoking the
+appropriate compilers and linkers in a cross-platform manner. It was
+motivated by the C<Module::Build> project, but may be useful for other
+purposes as well. However, it is I<not> intended as a general
+cross-platform interface to all your C building needs. That would
+have been a much more ambitious goal!
+
+=head1 METHODS
+
+=over 4
+
+=item new
+
+Returns a new C<ExtUtils::CBuilder> object. A C<config> parameter
+lets you override C<Config.pm> settings for all operations performed
+by the object, as in the following example:
+
+ # Use a different compiler than Config.pm says
+ my $b = ExtUtils::CBuilder->new( config =>
+ { ld => 'gcc' } );
+
+A C<quiet> parameter tells C<CBuilder> to not print its C<system()>
+commands before executing them:
+
+ # Be quieter than normal
+ my $b = ExtUtils::CBuilder->new( quiet => 1 );
+
+=item have_compiler
+
+Returns true if the current system has a working C compiler and
+linker, false otherwise. To determine this, we actually compile and
+link a sample C library.
+
+=item compile
+
+Compiles a C source file and produces an object file. The name of the
+object file is returned. The source file is specified in a C<source>
+parameter, which is required; the other parameters listed below are
+optional.
+
+=over 4
+
+=item C<object_file>
+
+Specifies the name of the output file to create. Otherwise the
+C<object_file()> method will be consulted, passing it the name of the
+C<source> file.
+
+=item C<include_dirs>
+
+Specifies any additional directories in which to search for header
+files. May be given as a string indicating a single directory, or as
+a list reference indicating multiple directories.
+
+=item C<extra_compiler_flags>
+
+Specifies any additional arguments to pass to the compiler. Should be
+given as a list reference containing the arguments individually, or if
+this is not possible, as a string containing all the arguments
+together.
+
+=back
+
+The operation of this method is also affected by the
+C<archlibexp>, C<cccdlflags>, C<ccflags>, C<optimize>, and C<cc>
+entries in C<Config.pm>.
+
+=item link
+
+Invokes the linker to produce a library file from object files. In
+scalar context, the name of the library file is returned. In list
+context, the library file and any temporary files created are
+returned. A required C<objects> parameter contains the name of the
+object files to process, either in a string (for one object file) or
+list reference (for one or more files). The following parameters are
+optional:
+
+
+=over 4
+
+=item lib_file
+
+Specifies the name of the output library file to create. Otherwise
+the C<lib_file()> method will be consulted, passing it the name of
+the first entry in C<objects>.
+
+=item module_name
+
+Specifies the name of the Perl module that will be created by linking.
+On platforms that need to do prelinking (Win32, OS/2, etc.) this is a
+required parameter.
+
+=item extra_linker_flags
+
+Any additional flags you wish to pass to the linker.
+
+=back
+
+On platforms where C<need_prelink()> returns true, C<prelink()>
+will be called automatically.
+
+The operation of this method is also affected by the C<lddlflags>,
+C<shrpenv>, and C<ld> entries in C<Config.pm>.
+
+=item link_executable
+
+Invokes the linker to produce an executable file from object files. In
+scalar context, the name of the executable file is returned. In list
+context, the executable file and any temporary files created are
+returned. A required C<objects> parameter contains the name of the
+object files to process, either in a string (for one object file) or
+list reference (for one or more files). The optional parameters are
+the same as C<link> with exception for
+
+
+=over 4
+
+=item exe_file
+
+Specifies the name of the output executable file to create. Otherwise
+the C<exe_file()> method will be consulted, passing it the name of the
+first entry in C<objects>.
+
+=back
+
+=item object_file
+
+ my $object_file = $b->object_file($source_file);
+
+Converts the name of a C source file to the most natural name of an
+output object file to create from it. For instance, on Unix the
+source file F<foo.c> would result in the object file F<foo.o>.
+
+=item lib_file
+
+ my $lib_file = $b->lib_file($object_file);
+
+Converts the name of an object file to the most natural name of a
+output library file to create from it. For instance, on Mac OS X the
+object file F<foo.o> would result in the library file F<foo.bundle>.
+
+=item exe_file
+
+ my $exe_file = $b->exe_file($object_file);
+
+Converts the name of an object file to the most natural name of an
+executable file to create from it. For instance, on Mac OS X the
+object file F<foo.o> would result in the executable file F<foo>, and
+on Windows it would result in F<foo.exe>.
+
+
+=item prelink
+
+On certain platforms like Win32, OS/2, VMS, and AIX, it is necessary
+to perform some actions before invoking the linker. The
+C<ExtUtils::Mksymlists> module does this, writing files used by the
+linker during the creation of shared libraries for dynamic extensions.
+The names of any files written will be returned as a list.
+
+Several parameters correspond to C<ExtUtils::Mksymlists::Mksymlists()>
+options, as follows:
+
+ Mksymlists() prelink() type
+ -------------|-------------------|-------------------
+ NAME | dl_name | string (required)
+ DLBASE | dl_base | string
+ FILE | dl_file | string
+ DL_VARS | dl_vars | array reference
+ DL_FUNCS | dl_funcs | hash reference
+ FUNCLIST | dl_func_list | array reference
+ IMPORTS | dl_imports | hash reference
+ VERSION | dl_version | string
+
+Please see the documentation for C<ExtUtils::Mksymlists> for the
+details of what these parameters do.
+
+=item need_prelink
+
+Returns true on platforms where C<prelink()> should be called
+during linking, and false otherwise.
+
+=item extra_link_args_after_prelink
+
+Returns list of extra arguments to give to the link command; the arguments
+are the same as for prelink(), with addition of array reference to the
+results of prelink(); this reference is indexed by key C<prelink_res>.
+
+=back
+
+=head1 TO DO
+
+Currently this has only been tested on Unix and doesn't contain any of
+the Windows-specific code from the C<Module::Build> project. I'll do
+that next.
+
+=head1 HISTORY
+
+This module is an outgrowth of the C<Module::Build> project, to which
+there have been many contributors. Notably, Randy W. Sims submitted
+lots of code to support 3 compilers on Windows and helped with various
+other platform-specific issues. Ilya Zakharevich has contributed
+fixes for OS/2; John E. Malmberg and Peter Prymmer have done likewise
+for VMS.
+
+=head1 AUTHOR
+
+Ken Williams, kwilliams@cpan.org
+
+=head1 COPYRIGHT
+
+Copyright (c) 2003-2005 Ken Williams. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+perl(1), Module::Build(3)
+
+=cut
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Base.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Base.pm
new file mode 100644
index 00000000000..0c08ab71b73
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Base.pm
@@ -0,0 +1,279 @@
+package ExtUtils::CBuilder::Base;
+
+use strict;
+use File::Spec;
+use File::Basename;
+use Cwd ();
+use Config;
+use Text::ParseWords;
+
+use vars qw($VERSION);
+$VERSION = '0.21';
+
+sub new {
+ my $class = shift;
+ my $self = bless {@_}, $class;
+
+ $self->{properties}{perl} = $class->find_perl_interpreter
+ or warn "Warning: Can't locate your perl binary";
+
+ while (my ($k,$v) = each %Config) {
+ $self->{config}{$k} = $v unless exists $self->{config}{$k};
+ }
+ return $self;
+}
+
+sub find_perl_interpreter {
+ my $perl;
+ File::Spec->file_name_is_absolute($perl = $^X)
+ or -f ($perl = $Config::Config{perlpath})
+ or ($perl = $^X);
+ return $perl;
+}
+
+sub add_to_cleanup {
+ my $self = shift;
+ foreach (@_) {
+ $self->{files_to_clean}{$_} = 1;
+ }
+}
+
+sub cleanup {
+ my $self = shift;
+ foreach my $file (keys %{$self->{files_to_clean}}) {
+ unlink $file;
+ }
+}
+
+sub object_file {
+ my ($self, $filename) = @_;
+
+ # File name, minus the suffix
+ (my $file_base = $filename) =~ s/\.[^.]+$//;
+ return "$file_base$self->{config}{obj_ext}";
+}
+
+sub arg_include_dirs {
+ my $self = shift;
+ return map {"-I$_"} @_;
+}
+
+sub arg_nolink { '-c' }
+
+sub arg_object_file {
+ my ($self, $file) = @_;
+ return ('-o', $file);
+}
+
+sub arg_share_object_file {
+ my ($self, $file) = @_;
+ return ($self->split_like_shell($self->{config}{lddlflags}), '-o', $file);
+}
+
+sub arg_exec_file {
+ my ($self, $file) = @_;
+ return ('-o', $file);
+}
+
+sub arg_defines {
+ my ($self, %args) = @_;
+ return map "-D$_=$args{$_}", keys %args;
+}
+
+sub compile {
+ my ($self, %args) = @_;
+ die "Missing 'source' argument to compile()" unless defined $args{source};
+
+ my $cf = $self->{config}; # For convenience
+
+ $args{object_file} ||= $self->object_file($args{source});
+
+ my @include_dirs = $self->arg_include_dirs
+ (@{$args{include_dirs} || []},
+ $self->perl_inc());
+
+ my @defines = $self->arg_defines( %{$args{defines} || {}} );
+
+ my @extra_compiler_flags = $self->split_like_shell($args{extra_compiler_flags});
+ my @cccdlflags = $self->split_like_shell($cf->{cccdlflags});
+ my @ccflags = $self->split_like_shell($cf->{ccflags});
+ my @optimize = $self->split_like_shell($cf->{optimize});
+ my @flags = (@include_dirs, @defines, @cccdlflags, @extra_compiler_flags,
+ $self->arg_nolink,
+ @ccflags, @optimize,
+ $self->arg_object_file($args{object_file}),
+ );
+
+ my @cc = $self->split_like_shell($cf->{cc});
+
+ $self->do_system(@cc, @flags, $args{source})
+ or die "error building $args{object_file} from '$args{source}'";
+
+ return $args{object_file};
+}
+
+sub have_compiler {
+ my ($self) = @_;
+ return $self->{have_compiler} if defined $self->{have_compiler};
+
+ my $tmpfile = File::Spec->catfile(File::Spec->tmpdir, 'compilet.c');
+ {
+ local *FH;
+ open FH, "> $tmpfile" or die "Can't create $tmpfile: $!";
+ print FH "int boot_compilet() { return 1; }\n";
+ close FH;
+ }
+
+ my ($obj_file, @lib_files);
+ eval {
+ $obj_file = $self->compile(source => $tmpfile);
+ @lib_files = $self->link(objects => $obj_file, module_name => 'compilet');
+ };
+ warn $@ if $@;
+ my $result = $self->{have_compiler} = $@ ? 0 : 1;
+
+ foreach (grep defined, $tmpfile, $obj_file, @lib_files) {
+ 1 while unlink;
+ }
+ return $result;
+}
+
+sub lib_file {
+ my ($self, $dl_file) = @_;
+ $dl_file =~ s/\.[^.]+$//;
+ $dl_file =~ tr/"//d;
+ return "$dl_file.$self->{config}{dlext}";
+}
+
+
+sub exe_file {
+ my ($self, $dl_file) = @_;
+ $dl_file =~ s/\.[^.]+$//;
+ $dl_file =~ tr/"//d;
+ return "$dl_file$self->{config}{_exe}";
+}
+
+sub need_prelink { 0 }
+
+sub extra_link_args_after_prelink { return }
+
+sub prelink {
+ my ($self, %args) = @_;
+
+ ($args{dl_file} = $args{dl_name}) =~ s/.*::// unless $args{dl_file};
+
+ require ExtUtils::Mksymlists;
+ ExtUtils::Mksymlists::Mksymlists( # dl. abbrev for dynamic library
+ DL_VARS => $args{dl_vars} || [],
+ DL_FUNCS => $args{dl_funcs} || {},
+ FUNCLIST => $args{dl_func_list} || [],
+ IMPORTS => $args{dl_imports} || {},
+ NAME => $args{dl_name}, # Name of the Perl module
+ DLBASE => $args{dl_base}, # Basename of DLL file
+ FILE => $args{dl_file}, # Dir + Basename of symlist file
+ VERSION => (defined $args{dl_version} ? $args{dl_version} : '0.0'),
+ );
+
+ # Mksymlists will create one of these files
+ return grep -e, map "$args{dl_file}.$_", qw(ext def opt);
+}
+
+sub link {
+ my ($self, %args) = @_;
+ return $self->_do_link('lib_file', lddl => 1, %args);
+}
+
+sub link_executable {
+ my ($self, %args) = @_;
+ return $self->_do_link('exe_file', lddl => 0, %args);
+}
+
+sub _do_link {
+ my ($self, $type, %args) = @_;
+
+ my $cf = $self->{config}; # For convenience
+
+ my $objects = delete $args{objects};
+ $objects = [$objects] unless ref $objects;
+ my $out = $args{$type} || $self->$type($objects->[0]);
+
+ my @temp_files;
+ @temp_files =
+ $self->prelink(%args,
+ dl_name => $args{module_name}) if $args{lddl} && $self->need_prelink;
+
+ my @linker_flags = ($self->split_like_shell($args{extra_linker_flags}),
+ $self->extra_link_args_after_prelink(%args, dl_name => $args{module_name},
+ prelink_res => \@temp_files));
+
+ my @output = $args{lddl} ? $self->arg_share_object_file($out) : $self->arg_exec_file($out);
+ my @shrp = $self->split_like_shell($cf->{shrpenv});
+ my @ld = $self->split_like_shell($cf->{ld});
+
+ $self->do_system(@shrp, @ld, @output, @$objects, @linker_flags)
+ or die "error building $out from @$objects";
+
+ return wantarray ? ($out, @temp_files) : $out;
+}
+
+
+sub do_system {
+ my ($self, @cmd) = @_;
+ print "@cmd\n" if !$self->{quiet};
+ return !system(@cmd);
+}
+
+sub split_like_shell {
+ my ($self, $string) = @_;
+
+ return () unless defined($string);
+ return @$string if UNIVERSAL::isa($string, 'ARRAY');
+ $string =~ s/^\s+|\s+$//g;
+ return () unless length($string);
+
+ return Text::ParseWords::shellwords($string);
+}
+
+# if building perl, perl's main source directory
+sub perl_src {
+ # N.B. makemaker actually searches regardless of PERL_CORE, but
+ # only squawks at not finding it if PERL_CORE is set
+
+ return unless $ENV{PERL_CORE};
+
+ my $Updir = File::Spec->updir;
+ my $dir = File::Spec->curdir;
+
+ # Try up to 5 levels upwards
+ for (0..10) {
+ if (
+ -f File::Spec->catfile($dir,"config_h.SH")
+ &&
+ -f File::Spec->catfile($dir,"perl.h")
+ &&
+ -f File::Spec->catfile($dir,"lib","Exporter.pm")
+ ) {
+ return Cwd::realpath( $dir );
+ }
+
+ $dir = File::Spec->catdir($dir, $Updir);
+ }
+
+ warn "PERL_CORE is set but I can't find your perl source!\n";
+ return ''; # return empty string if $ENV{PERL_CORE} but can't find dir ???
+}
+
+# directory of perl's include files
+sub perl_inc {
+ my $self = shift;
+
+ $self->perl_src() || File::Spec->catdir($self->{config}{archlibexp},"CORE");
+}
+
+sub DESTROY {
+ my $self = shift;
+ local($., $@, $!, $^E, $?);
+ $self->cleanup();
+}
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Changes b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Changes
new file mode 100644
index 00000000000..fbf6f4a1200
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Changes
@@ -0,0 +1,207 @@
+Revision history for Perl extension ExtUtils::CBuilder.
+
+ - Clean up perl_src path using Cwd::realpath(). Only affects usage
+ as part of the perl core.
+
+ - Protect $., $@, $!, $^E, and $? from any clobbering that might
+ occur in our DESTROY method. [Zefram]
+
+ - From bleadperl, a patch to clean up debug symbol files (.pdb for
+ VC++, .tds for BCC) when running have_compiler(). [Steve Hay &
+ Steve Peters]
+
+0.19 - Sun May 13 14:29:18 2007
+
+ - When building as part of the perl core (so this is irrelevant for
+ people downloading from CPAN) we now try a little harder to find
+ the perl sources. [Jos Boumans]
+
+ - Fixed a part of the manifest thingy that got broken on 64-bit
+ Windows platforms in version 0.18. [Steve Hay, Jan Dubois]
+
+0.18 - Mon Mar 26 21:29:09 2007
+
+ - Various OS/2 fixes:
+ + Put .LIB file near .DEF file
+ + Got library-file building working better
+ + Handled libperl_overrides better
+ [Ilya Zakharevich]
+
+ - On Windows: embed manifest files in DLLs built with Module-Build
+ when using VC8. [Steve Hay]
+
+ - Added a workaround for a config error on dec_osf: the linker is
+ $Config{cc}, not $Config{ld}. [Jarkko Hietaniemi]
+
+ - Borland's compiler "response files" will not pass through macro
+ definitions that contain quotes. The quotes get stripped and there
+ seems to be no way to escape them. So we leave macros on the
+ command line. [Randy W. Sims]
+
+0.18 Sat Mar 25 13:35:47 CST 2006
+
+ - Yet more fixes for arg_defines() on VMS. [Craig A. Berry and John
+ E. Malmberg]
+
+0.17 Wed Mar 15 22:46:15 CST 2006
+
+ - When we're being run from an uninstalled perl distribution
+ (e.g. one that's in the process of being built and tested), we
+ search for perl first in the current working directory. [Randy
+ Sims]
+
+ - More fixing of the arg_defines() method on VMS. [Craig A. Berry and
+ John E. Malmberg]
+
+0.16 Mon Mar 13 17:08:21 CST 2006
+
+ - Fix quoting of command line arguments on Windows. [Yitzchak
+ Scott-Thoennes]
+
+ - Provided a custom arg_defines() on VMS that does essentially the
+ same thing for /define that version 0.14 did for /include. [Craig
+ A. Berry]
+
+ - Documented the existing 'quiet' parameter, which silences the
+ printing of system() commands. [Suggested by Yitzchak
+ Scott-Thoennes]
+
+0.15 Mon Oct 3 17:10:32 CDT 2005
+
+ - Several OS/2 fixes have been made, including: 1) adding the
+ necessary version string to DLLs, 2) passing the executable's name
+ to 'ldopts' without the .exe extension, 3) avoiding calling 'env'
+ via the 'shrpenv' thingy, since it triggers a fork() bug. [Ilya
+ Zakharevich]
+
+ - Integrate a couple cleanup-related changes from bleadperl that
+ somehow never got into this copy. [Steve Hay]
+
+ - Added a new 'defines' parameter to compile(), which gives a
+ platform-independant way to specify various -Dfoo=bar (or the
+ equivalent) compiler defines. [Randy W. Sims]
+
+0.14 Mon Sep 19 13:40:37 CDT 2005
+
+ - Several fixes have been made for VMS, including: 1) there can only
+ be one /include qualifier, so merge multiple /includes into one; 2)
+ make sure the executable is named the same way that dynaloader will
+ look for it; 3) make sure the option files for the exported symbols
+ and the PERLSHR image are passed properly to the linker. [John
+ E. Malmberg]
+
+0.13 Wed Aug 24 20:05:59 CDT 2005
+
+ - Several temporary files weren't being cleaned up during testing,
+ because the 'cleanup' mechanism was never properly implemented.
+ This is now fixed. [Steve Hay]
+
+0.12 Mon May 30 16:40:10 CDT 2005
+
+ - In order to integrate into the perl core, patches were contributed
+ that a) put a $VERSION variable in each .pm file, b) add a 'quiet'
+ parameter to new() to shut up some of the command-echoing, c)
+ checks for the perl source headers in the CORE/ directory in the
+ perl source tree, not in the post-installation location, and d)
+ adjusts the CWD when running the regression tests under the perl
+ core. [Yitzchak Scott-Thoennes]
+
+ - Various parts of the code were looking for the CORE/ directory in
+ $Config{archlib}, $Config{installarchlib}, and $Config{archlibexp}.
+ Only the latter is correct, so we use that everywhere now.
+ [Curt Tilmes]
+
+ - For Unix-ish platforms, link_executable() will now prefer
+ $Config{cc} to $Config{ld}, because that typically works
+ better. [Jarkko Hietaniemi and H.Merijn Brand]
+
+ - Prelinking (invoking ExtUtils::Mksymlists to create options-files)
+ is now only done when we're building dynamic libraries. [Yitzchak
+ Scott-Thoennes]
+
+0.11 Tue Apr 5 20:58:41 CDT 2005
+
+ - Added a licensing statement to CBuilder.pm. [Spotted by Chip
+ Salzenberg]
+
+0.10 Mon Mar 14 20:18:19 CST 2005
+
+ - Split out a few simple routines that format how compile switches
+ are formatted, so that we can override them for platforms like VMS
+ where they're very different.
+
+ - Fix compile() and link() on VMS. [Help from Michael Schwern and
+ Peter Prymmer]
+
+0.09 Tue Feb 8 17:57:41 CST 2005
+
+ - Fixed a broken link_executable() method on cygwin - it now uses
+ 'gcc' instead of $Config{ld} for the linking, because the latter is
+ actually a shell script which calls a perl script which calls gcc
+ in a way that only works for creating shared libraries, not
+ executables.
+
+0.08 Tue Jan 18 21:54:11 CST 2005
+
+ - Fixed a testing error in which I had the prototype wrong for the
+ main() function. [Jose Pedro Oliveira]
+
+0.07 Wed Jan 12 21:50:34 CST 2005
+
+ - Added the link_executable() method, which provides the ability to
+ create standalone executables. This is NOT yet implemented on
+ Windows, and therefore the tests for it are skipped on Win32.
+ [Alberto Manuel Brandao Simoes]
+
+ - Integrated the latest split_like_shell() for Windows from
+ Module::Build (really need to find a better home for this code...),
+ which now does a much better job of handling quotes and backslashes
+ and so on. [Randy Sims]
+
+ - Fixed a couple of Windows problems related to the output-file name
+ in link(), and some clobbering of the 'include_dirs' parameter to
+ compile(). [Randy Sims]
+
+0.06 Mon Dec 27 22:51:36 CST 2004
+
+ - Fixed a bug on Unix environments in which our work-around for
+ shell-commands like "FOO=BAR cc" (which is supposed to be turned
+ into "env FOO=BAR cc" to actually work) wasn't being called.
+
+0.05 Wed Oct 13 23:09:09 CDT 2004
+
+ - Fixed a bug in split_like_shell() in which leading whitespace was
+ creating an empty word, manifesting as something like "gcc - no
+ such file or directory" during tests. [Spotted by Warren L. Dodge]
+
+ - Incorporate another split_like_shell() fix from Module::Build.
+
+0.04 Sun Oct 10 00:31:08 CDT 2004
+
+ - Changed the split_like_shell() method to use the shellwords()
+ function from Text::ParseWords (a core module since 5.0), which
+ does a much better job than the split() we were using.
+
+
+0.03 Fri May 14 23:12:23 CDT 2004
+
+ - Fixed minor problems with the Build.PL file, the module names
+ should be quoted.
+
+ - The VMS module declared itself with the wrong package name.
+
+
+0.02 Fri Feb 20 10:17:40 CST 2004
+
+ - Fixed a bug in .../Platform/Windows.pm, in which compile() was
+ ignoring an 'include_dirs' argument. [Randy Sims]
+
+ - Fixed a bug in .../Platform/Windows.pm, in which output files were
+ being created in the root directory \ when they should be created
+ in the current directory. [Randy Sims]
+
+
+0.01 Mon Jan 12 08:12:35 CST 2004
+
+ - Original release, taken from Module::Build's C-building code, with
+ patching help from Randy Sims.
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/Unix.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/Unix.pm
new file mode 100644
index 00000000000..3fa73788c0c
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/Unix.pm
@@ -0,0 +1,37 @@
+package ExtUtils::CBuilder::Platform::Unix;
+
+use strict;
+use ExtUtils::CBuilder::Base;
+
+use vars qw($VERSION @ISA);
+$VERSION = '0.21';
+@ISA = qw(ExtUtils::CBuilder::Base);
+
+sub link_executable {
+ my $self = shift;
+ # $Config{cc} is usually a better bet for linking executables than $Config{ld}
+ local $self->{config}{ld} =
+ $self->{config}{cc} . " " . $self->{config}{ldflags};
+ return $self->SUPER::link_executable(@_);
+}
+
+sub link {
+ my $self = shift;
+ my $cf = $self->{config};
+
+ # Some platforms (notably Mac OS X 10.3, but some others too) expect
+ # the syntax "FOO=BAR /bin/command arg arg" to work in %Config
+ # (notably $Config{ld}). It usually works in system(SCALAR), but we
+ # use system(LIST). We fix it up here with 'env'.
+
+ local $cf->{ld} = $cf->{ld};
+ if (ref $cf->{ld}) {
+ unshift @{$cf->{ld}}, 'env' if $cf->{ld}[0] =~ /^\s*\w+=/;
+ } else {
+ $cf->{ld} =~ s/^(\s*\w+=)/env $1/;
+ }
+
+ return $self->SUPER::link(@_);
+}
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/VMS.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/VMS.pm
new file mode 100644
index 00000000000..ab22cb23acc
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/VMS.pm
@@ -0,0 +1,294 @@
+package ExtUtils::CBuilder::Platform::VMS;
+
+use strict;
+use ExtUtils::CBuilder::Base;
+
+use vars qw($VERSION @ISA);
+$VERSION = '0.22';
+@ISA = qw(ExtUtils::CBuilder::Base);
+
+use File::Spec::Functions qw(catfile catdir);
+
+# We do prelink, but don't want the parent to redo it.
+
+sub need_prelink { 0 }
+
+sub arg_defines {
+ my ($self, %args) = @_;
+
+ s/"/""/g foreach values %args;
+
+ my @config_defines;
+
+ # VMS can only have one define qualifier; add the one from config, if any.
+ if ($self->{config}{ccflags} =~ s{/ def[^=]+ =+ \(? ([^\/\)]*) } {}ix) {
+ push @config_defines, $1;
+ }
+
+ return '' unless keys(%args) || @config_defines;
+
+ return ('/define=('
+ . join(',',
+ @config_defines,
+ map "\"$_" . ( length($args{$_}) ? "=$args{$_}" : '') . "\"",
+ keys %args)
+ . ')');
+}
+
+sub arg_include_dirs {
+ my ($self, @dirs) = @_;
+
+ # VMS can only have one include list, add the one from config.
+ if ($self->{config}{ccflags} =~ s{/inc[^=]+(?:=)+(?:\()?([^\/\)]*)} {}i) {
+ unshift @dirs, $1;
+ }
+ return unless @dirs;
+
+ return ('/include=(' . join(',', @dirs) . ')');
+}
+
+sub _do_link {
+ my ($self, $type, %args) = @_;
+
+ my $objects = delete $args{objects};
+ $objects = [$objects] unless ref $objects;
+
+ if ($args{lddl}) {
+
+ # prelink will call Mksymlists, which creates the extension-specific
+ # linker options file and populates it with the boot symbol.
+
+ my @temp_files = $self->prelink(%args, dl_name => $args{module_name});
+
+ # We now add the rest of what we need to the linker options file. We
+ # should replicate the functionality of C<ExtUtils::MM_VMS::dlsyms>,
+ # but there is as yet no infrastructure for handling object libraries,
+ # so for now we depend on object files being listed individually on the
+ # command line, which should work for simple cases. We do bring in our
+ # own version of C<ExtUtils::Liblist::Kid::ext> so that any additional
+ # libraries (including PERLSHR) can be added to the options file.
+
+ my @optlibs = $self->_liblist_ext( $args{'libs'} );
+
+ my $optfile = 'sys$disk:[]' . $temp_files[0];
+ open my $opt_fh, '>>', $optfile
+ or die "_do_link: Unable to open $optfile: $!";
+ for my $lib (@optlibs) {print $opt_fh "$lib\n" if length $lib }
+ close $opt_fh;
+
+ $objects->[-1] .= ',';
+ push @$objects, $optfile . '/OPTIONS,';
+
+ # This one not needed for DEC C, but leave for completeness.
+ push @$objects, $self->perl_inc() . 'perlshr_attr.opt/OPTIONS';
+ }
+
+ return $self->SUPER::_do_link($type, %args, objects => $objects);
+}
+
+sub arg_nolink { return; }
+
+sub arg_object_file {
+ my ($self, $file) = @_;
+ return "/obj=$file";
+}
+
+sub arg_exec_file {
+ my ($self, $file) = @_;
+ return ("/exe=$file");
+}
+
+sub arg_share_object_file {
+ my ($self, $file) = @_;
+ return ("$self->{config}{lddlflags}=$file");
+}
+
+
+sub lib_file {
+ my ($self, $dl_file) = @_;
+ $dl_file =~ s/\.[^.]+$//;
+ $dl_file =~ tr/"//d;
+ $dl_file = $dl_file .= '.' . $self->{config}{dlext};
+
+ # Need to create with the same name as DynaLoader will load with.
+ if (defined &DynaLoader::mod2fname) {
+ my ($dev,$dir,$file) = File::Spec->splitpath($dl_file);
+ $file = DynaLoader::mod2fname([$file]);
+ $dl_file = File::Spec->catpath($dev,$dir,$file);
+ }
+ return $dl_file;
+}
+
+# The following is reproduced almost verbatim from ExtUtils::Liblist::Kid::_vms_ext.
+# We can't just call that because it's tied up with the MakeMaker object hierarchy.
+
+sub _liblist_ext {
+ my($self, $potential_libs,$verbose,$give_libs) = @_;
+ $verbose ||= 0;
+
+ my(@crtls,$crtlstr);
+ @crtls = ( ($self->{'config'}{'ldflags'} =~ m-/Debug-i ? $self->{'config'}{'dbgprefix'} : '')
+ . 'PerlShr/Share' );
+ push(@crtls, grep { not /\(/ } split /\s+/, $self->{'config'}{'perllibs'});
+ push(@crtls, grep { not /\(/ } split /\s+/, $self->{'config'}{'libc'});
+ # In general, we pass through the basic libraries from %Config unchanged.
+ # The one exception is that if we're building in the Perl source tree, and
+ # a library spec could be resolved via a logical name, we go to some trouble
+ # to insure that the copy in the local tree is used, rather than one to
+ # which a system-wide logical may point.
+ if ($self->perl_src) {
+ my($lib,$locspec,$type);
+ foreach $lib (@crtls) {
+ if (($locspec,$type) = $lib =~ m{^([\w\$-]+)(/\w+)?} and $locspec =~ /perl/i) {
+ if (lc $type eq '/share') { $locspec .= $self->{'config'}{'exe_ext'}; }
+ elsif (lc $type eq '/library') { $locspec .= $self->{'config'}{'lib_ext'}; }
+ else { $locspec .= $self->{'config'}{'obj_ext'}; }
+ $locspec = catfile($self->perl_src, $locspec);
+ $lib = "$locspec$type" if -e $locspec;
+ }
+ }
+ }
+ $crtlstr = @crtls ? join(' ',@crtls) : '';
+
+ unless ($potential_libs) {
+ warn "Result:\n\tEXTRALIBS: \n\tLDLOADLIBS: $crtlstr\n" if $verbose;
+ return ('', '', $crtlstr, '', ($give_libs ? [] : ()));
+ }
+
+ my(@dirs,@libs,$dir,$lib,%found,@fndlibs,$ldlib);
+ my $cwd = cwd();
+ my($so,$lib_ext,$obj_ext) = @{$self->{'config'}}{'so','lib_ext','obj_ext'};
+ # List of common Unix library names and their VMS equivalents
+ # (VMS equivalent of '' indicates that the library is automatically
+ # searched by the linker, and should be skipped here.)
+ my(@flibs, %libs_seen);
+ my %libmap = ( 'm' => '', 'f77' => '', 'F77' => '', 'V77' => '', 'c' => '',
+ 'malloc' => '', 'crypt' => '', 'resolv' => '', 'c_s' => '',
+ 'socket' => '', 'X11' => 'DECW$XLIBSHR',
+ 'Xt' => 'DECW$XTSHR', 'Xm' => 'DECW$XMLIBSHR',
+ 'Xmu' => 'DECW$XMULIBSHR');
+ if ($self->{'config'}{'vms_cc_type'} ne 'decc') { $libmap{'curses'} = 'VAXCCURSE'; }
+
+ warn "Potential libraries are '$potential_libs'\n" if $verbose;
+
+ # First, sort out directories and library names in the input
+ foreach $lib (split ' ',$potential_libs) {
+ push(@dirs,$1), next if $lib =~ /^-L(.*)/;
+ push(@dirs,$lib), next if $lib =~ /[:>\]]$/;
+ push(@dirs,$lib), next if -d $lib;
+ push(@libs,$1), next if $lib =~ /^-l(.*)/;
+ push(@libs,$lib);
+ }
+ push(@dirs,split(' ',$self->{'config'}{'libpth'}));
+
+ # Now make sure we've got VMS-syntax absolute directory specs
+ # (We don't, however, check whether someone's hidden a relative
+ # path in a logical name.)
+ foreach $dir (@dirs) {
+ unless (-d $dir) {
+ warn "Skipping nonexistent Directory $dir\n" if $verbose > 1;
+ $dir = '';
+ next;
+ }
+ warn "Resolving directory $dir\n" if $verbose;
+ if (!File::Spec->file_name_is_absolute($dir)) {
+ $dir = catdir($cwd,$dir);
+ }
+ }
+ @dirs = grep { length($_) } @dirs;
+ unshift(@dirs,''); # Check each $lib without additions first
+
+ LIB: foreach $lib (@libs) {
+ if (exists $libmap{$lib}) {
+ next unless length $libmap{$lib};
+ $lib = $libmap{$lib};
+ }
+
+ my(@variants,$variant,$cand);
+ my($ctype) = '';
+
+ # If we don't have a file type, consider it a possibly abbreviated name and
+ # check for common variants. We try these first to grab libraries before
+ # a like-named executable image (e.g. -lperl resolves to perlshr.exe
+ # before perl.exe).
+ if ($lib !~ /\.[^:>\]]*$/) {
+ push(@variants,"${lib}shr","${lib}rtl","${lib}lib");
+ push(@variants,"lib$lib") if $lib !~ /[:>\]]/;
+ }
+ push(@variants,$lib);
+ warn "Looking for $lib\n" if $verbose;
+ foreach $variant (@variants) {
+ my($fullname, $name);
+
+ foreach $dir (@dirs) {
+ my($type);
+
+ $name = "$dir$variant";
+ warn "\tChecking $name\n" if $verbose > 2;
+ $fullname = VMS::Filespec::rmsexpand($name);
+ if (defined $fullname and -f $fullname) {
+ # It's got its own suffix, so we'll have to figure out the type
+ if ($fullname =~ /(?:$so|exe)$/i) { $type = 'SHR'; }
+ elsif ($fullname =~ /(?:$lib_ext|olb)$/i) { $type = 'OLB'; }
+ elsif ($fullname =~ /(?:$obj_ext|obj)$/i) {
+ warn "Note (probably harmless): "
+ ."Plain object file $fullname found in library list\n";
+ $type = 'OBJ';
+ }
+ else {
+ warn "Note (probably harmless): "
+ ."Unknown library type for $fullname; assuming shared\n";
+ $type = 'SHR';
+ }
+ }
+ elsif (-f ($fullname = VMS::Filespec::rmsexpand($name,$so)) or
+ -f ($fullname = VMS::Filespec::rmsexpand($name,'.exe'))) {
+ $type = 'SHR';
+ $name = $fullname unless $fullname =~ /exe;?\d*$/i;
+ }
+ elsif (not length($ctype) and # If we've got a lib already,
+ # don't bother
+ ( -f ($fullname = VMS::Filespec::rmsexpand($name,$lib_ext)) or
+ -f ($fullname = VMS::Filespec::rmsexpand($name,'.olb')))) {
+ $type = 'OLB';
+ $name = $fullname unless $fullname =~ /olb;?\d*$/i;
+ }
+ elsif (not length($ctype) and # If we've got a lib already,
+ # don't bother
+ ( -f ($fullname = VMS::Filespec::rmsexpand($name,$obj_ext)) or
+ -f ($fullname = VMS::Filespec::rmsexpand($name,'.obj')))) {
+ warn "Note (probably harmless): "
+ ."Plain object file $fullname found in library list\n";
+ $type = 'OBJ';
+ $name = $fullname unless $fullname =~ /obj;?\d*$/i;
+ }
+ if (defined $type) {
+ $ctype = $type; $cand = $name;
+ last if $ctype eq 'SHR';
+ }
+ }
+ if ($ctype) {
+ # This has to precede any other CRTLs, so just make it first
+ if ($cand eq 'VAXCCURSE') { unshift @{$found{$ctype}}, $cand; }
+ else { push @{$found{$ctype}}, $cand; }
+ warn "\tFound as $cand (really $fullname), type $ctype\n"
+ if $verbose > 1;
+ push @flibs, $name unless $libs_seen{$fullname}++;
+ next LIB;
+ }
+ }
+ warn "Note (probably harmless): "
+ ."No library found for $lib\n";
+ }
+
+ push @fndlibs, @{$found{OBJ}} if exists $found{OBJ};
+ push @fndlibs, map { "$_/Library" } @{$found{OLB}} if exists $found{OLB};
+ push @fndlibs, map { "$_/Share" } @{$found{SHR}} if exists $found{SHR};
+ $lib = join(' ',@fndlibs);
+
+ $ldlib = $crtlstr ? "$lib $crtlstr" : $lib;
+ warn "Result:\n\tEXTRALIBS: $lib\n\tLDLOADLIBS: $ldlib\n" if $verbose;
+ wantarray ? ($lib, '', $ldlib, '', ($give_libs ? \@flibs : ())) : $lib;
+}
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/Windows.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/Windows.pm
new file mode 100644
index 00000000000..7b74ae0d99a
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/Windows.pm
@@ -0,0 +1,732 @@
+package ExtUtils::CBuilder::Platform::Windows;
+
+use strict;
+use warnings;
+
+use File::Basename;
+use File::Spec;
+
+use ExtUtils::CBuilder::Base;
+
+use vars qw($VERSION @ISA);
+$VERSION = '0.21';
+@ISA = qw(ExtUtils::CBuilder::Base);
+
+sub new {
+ my $class = shift;
+ my $self = $class->SUPER::new(@_);
+ my $cf = $self->{config};
+
+ # Inherit from an appropriate compiler driver class
+ unshift @ISA, "ExtUtils::CBuilder::Platform::Windows::" . $self->_compiler_type;
+
+ return $self;
+}
+
+sub _compiler_type {
+ my $self = shift;
+ my $cc = $self->{config}{cc};
+
+ return ( $cc =~ /cl(\.exe)?$/ ? 'MSVC'
+ : $cc =~ /bcc32(\.exe)?$/ ? 'BCC'
+ : 'GCC');
+}
+
+sub split_like_shell {
+ # As it turns out, Windows command-parsing is very different from
+ # Unix command-parsing. Double-quotes mean different things,
+ # backslashes don't necessarily mean escapes, and so on. So we
+ # can't use Text::ParseWords::shellwords() to break a command string
+ # into words. The algorithm below was bashed out by Randy and Ken
+ # (mostly Randy), and there are a lot of regression tests, so we
+ # should feel free to adjust if desired.
+
+ (my $self, local $_) = @_;
+
+ return @$_ if defined() && UNIVERSAL::isa($_, 'ARRAY');
+
+ my @argv;
+ return @argv unless defined() && length();
+
+ my $arg = '';
+ my( $i, $quote_mode ) = ( 0, 0 );
+
+ while ( $i < length() ) {
+
+ my $ch = substr( $_, $i , 1 );
+ my $next_ch = substr( $_, $i+1, 1 );
+
+ if ( $ch eq '\\' && $next_ch eq '"' ) {
+ $arg .= '"';
+ $i++;
+ } elsif ( $ch eq '\\' && $next_ch eq '\\' ) {
+ $arg .= '\\';
+ $i++;
+ } elsif ( $ch eq '"' && $next_ch eq '"' && $quote_mode ) {
+ $quote_mode = !$quote_mode;
+ $arg .= '"';
+ $i++;
+ } elsif ( $ch eq '"' && $next_ch eq '"' && !$quote_mode &&
+ ( $i + 2 == length() ||
+ substr( $_, $i + 2, 1 ) eq ' ' )
+ ) { # for cases like: a"" => [ 'a' ]
+ push( @argv, $arg );
+ $arg = '';
+ $i += 2;
+ } elsif ( $ch eq '"' ) {
+ $quote_mode = !$quote_mode;
+ } elsif ( $ch eq ' ' && !$quote_mode ) {
+ push( @argv, $arg ) if $arg;
+ $arg = '';
+ ++$i while substr( $_, $i + 1, 1 ) eq ' ';
+ } else {
+ $arg .= $ch;
+ }
+
+ $i++;
+ }
+
+ push( @argv, $arg ) if defined( $arg ) && length( $arg );
+ return @argv;
+}
+
+sub arg_defines {
+ my ($self, %args) = @_;
+ s/"/\\"/g foreach values %args;
+ return map qq{"-D$_=$args{$_}"}, keys %args;
+}
+
+sub compile {
+ my ($self, %args) = @_;
+ my $cf = $self->{config};
+
+ die "Missing 'source' argument to compile()" unless defined $args{source};
+
+ my ($basename, $srcdir) =
+ ( File::Basename::fileparse($args{source}, '\.[^.]+$') )[0,1];
+
+ $srcdir ||= File::Spec->curdir();
+
+ my @defines = $self->arg_defines( %{ $args{defines} || {} } );
+
+ my %spec = (
+ srcdir => $srcdir,
+ builddir => $srcdir,
+ basename => $basename,
+ source => $args{source},
+ output => File::Spec->catfile($srcdir, $basename) . $cf->{obj_ext},
+ cc => $cf->{cc},
+ cflags => [
+ $self->split_like_shell($cf->{ccflags}),
+ $self->split_like_shell($cf->{cccdlflags}),
+ $self->split_like_shell($cf->{extra_compiler_flags}),
+ ],
+ optimize => [ $self->split_like_shell($cf->{optimize}) ],
+ defines => \@defines,
+ includes => [ @{$args{include_dirs} || []} ],
+ perlinc => [
+ $self->perl_inc(),
+ $self->split_like_shell($cf->{incpath}),
+ ],
+ use_scripts => 1, # XXX provide user option to change this???
+ );
+
+ $self->normalize_filespecs(
+ \$spec{source},
+ \$spec{output},
+ $spec{includes},
+ $spec{perlinc},
+ );
+
+ my @cmds = $self->format_compiler_cmd(%spec);
+ while ( my $cmd = shift @cmds ) {
+ $self->do_system( @$cmd )
+ or die "error building $cf->{dlext} file from '$args{source}'";
+ }
+
+ (my $out = $spec{output}) =~ tr/'"//d;
+ return $out;
+}
+
+sub need_prelink { 1 }
+
+sub link {
+ my ($self, %args) = @_;
+ my $cf = $self->{config};
+
+ my @objects = ( ref $args{objects} eq 'ARRAY' ? @{$args{objects}} : $args{objects} );
+ my $to = join '', (File::Spec->splitpath($objects[0]))[0,1];
+ $to ||= File::Spec->curdir();
+
+ (my $file_base = $args{module_name}) =~ s/.*:://;
+ my $output = $args{lib_file} ||
+ File::Spec->catfile($to, "$file_base.$cf->{dlext}");
+
+ # if running in perl source tree, look for libs there, not installed
+ my $lddlflags = $cf->{lddlflags};
+ my $perl_src = $self->perl_src();
+ $lddlflags =~ s/\Q$cf->{archlibexp}\E[\\\/]CORE/$perl_src/ if $perl_src;
+
+ my %spec = (
+ srcdir => $to,
+ builddir => $to,
+ startup => [ ],
+ objects => \@objects,
+ libs => [ ],
+ output => $output,
+ ld => $cf->{ld},
+ libperl => $cf->{libperl},
+ perllibs => [ $self->split_like_shell($cf->{perllibs}) ],
+ libpath => [ $self->split_like_shell($cf->{libpth}) ],
+ lddlflags => [ $self->split_like_shell($lddlflags) ],
+ other_ldflags => [ $self->split_like_shell($args{extra_linker_flags} || '') ],
+ use_scripts => 1, # XXX provide user option to change this???
+ );
+
+ unless ( $spec{basename} ) {
+ ($spec{basename} = $args{module_name}) =~ s/.*:://;
+ }
+
+ $spec{srcdir} = File::Spec->canonpath( $spec{srcdir} );
+ $spec{builddir} = File::Spec->canonpath( $spec{builddir} );
+
+ $spec{output} ||= File::Spec->catfile( $spec{builddir},
+ $spec{basename} . '.'.$cf->{dlext} );
+ $spec{manifest} ||= File::Spec->catfile( $spec{builddir},
+ $spec{basename} . '.'.$cf->{dlext}.'.manifest');
+ $spec{implib} ||= File::Spec->catfile( $spec{builddir},
+ $spec{basename} . $cf->{lib_ext} );
+ $spec{explib} ||= File::Spec->catfile( $spec{builddir},
+ $spec{basename} . '.exp' );
+ if ($cf->{cc} eq 'cl') {
+ $spec{dbg_file} ||= File::Spec->catfile( $spec{builddir},
+ $spec{basename} . '.pdb' );
+ }
+ elsif ($cf->{cc} eq 'bcc32') {
+ $spec{dbg_file} ||= File::Spec->catfile( $spec{builddir},
+ $spec{basename} . '.tds' );
+ }
+ $spec{def_file} ||= File::Spec->catfile( $spec{srcdir} ,
+ $spec{basename} . '.def' );
+ $spec{base_file} ||= File::Spec->catfile( $spec{srcdir} ,
+ $spec{basename} . '.base' );
+
+ $self->add_to_cleanup(
+ grep defined,
+ @{[ @spec{qw(manifest implib explib dbg_file def_file base_file map_file)} ]}
+ );
+
+ foreach my $opt ( qw(output manifest implib explib dbg_file def_file map_file base_file) ) {
+ $self->normalize_filespecs( \$spec{$opt} );
+ }
+
+ foreach my $opt ( qw(libpath startup objects) ) {
+ $self->normalize_filespecs( $spec{$opt} );
+ }
+
+ (my $def_base = $spec{def_file}) =~ tr/'"//d;
+ $def_base =~ s/\.def$//;
+ $self->prelink( dl_name => $args{module_name},
+ dl_file => $def_base,
+ dl_base => $spec{basename} );
+
+ my @cmds = $self->format_linker_cmd(%spec);
+ while ( my $cmd = shift @cmds ) {
+ $self->do_system( @$cmd );
+ }
+
+ $spec{output} =~ tr/'"//d;
+ return wantarray
+ ? grep defined, @spec{qw[output manifest implib explib dbg_file def_file map_file base_file]}
+ : $spec{output};
+}
+
+# canonize & quote paths
+sub normalize_filespecs {
+ my ($self, @specs) = @_;
+ foreach my $spec ( grep defined, @specs ) {
+ if ( ref $spec eq 'ARRAY') {
+ $self->normalize_filespecs( map {\$_} grep defined, @$spec )
+ } elsif ( ref $spec eq 'SCALAR' ) {
+ $$spec =~ tr/"//d if $$spec;
+ next unless $$spec;
+ $$spec = '"' . File::Spec->canonpath($$spec) . '"';
+ } elsif ( ref $spec eq '' ) {
+ $spec = '"' . File::Spec->canonpath($spec) . '"';
+ } else {
+ die "Don't know how to normalize " . (ref $spec || $spec) . "\n";
+ }
+ }
+}
+
+# directory of perl's include files
+sub perl_inc {
+ my $self = shift;
+
+ my $perl_src = $self->perl_src();
+
+ if ($perl_src) {
+ File::Spec->catdir($perl_src, "lib", "CORE");
+ } else {
+ File::Spec->catdir($self->{config}{archlibexp},"CORE");
+ }
+}
+
+1;
+
+########################################################################
+
+=begin comment
+
+The packages below implement functions for generating properly
+formatted commandlines for the compiler being used. Each package
+defines two primary functions 'format_linker_cmd()' &
+'format_compiler_cmd()' that accepts a list of named arguments (a
+hash) and returns a list of formatted options suitable for invoking the
+compiler. By default, if the compiler supports scripting of its
+operation then a script file is built containing the options while
+those options are removed from the commandline, and a reference to the
+script is pushed onto the commandline in their place. Scripting the
+compiler in this way helps to avoid the problems associated with long
+commandlines under some shells.
+
+=end comment
+
+=cut
+
+########################################################################
+package ExtUtils::CBuilder::Platform::Windows::MSVC;
+
+sub format_compiler_cmd {
+ my ($self, %spec) = @_;
+
+ foreach my $path ( @{ $spec{includes} || [] },
+ @{ $spec{perlinc} || [] } ) {
+ $path = '-I' . $path;
+ }
+
+ %spec = $self->write_compiler_script(%spec)
+ if $spec{use_scripts};
+
+ return [ grep {defined && length} (
+ $spec{cc},'-nologo','-c',
+ @{$spec{includes}} ,
+ @{$spec{cflags}} ,
+ @{$spec{optimize}} ,
+ @{$spec{defines}} ,
+ @{$spec{perlinc}} ,
+ "-Fo$spec{output}" ,
+ $spec{source} ,
+ ) ];
+}
+
+sub write_compiler_script {
+ my ($self, %spec) = @_;
+
+ my $script = File::Spec->catfile( $spec{srcdir},
+ $spec{basename} . '.ccs' );
+
+ $self->add_to_cleanup($script);
+ print "Generating script '$script'\n" if !$self->{quiet};
+
+ open( SCRIPT, ">$script" )
+ or die( "Could not create script '$script': $!" );
+
+ print SCRIPT join( "\n",
+ map { ref $_ ? @{$_} : $_ }
+ grep defined,
+ delete(
+ @spec{ qw(includes cflags optimize defines perlinc) } )
+ );
+
+ close SCRIPT;
+
+ push @{$spec{includes}}, '@"' . $script . '"';
+
+ return %spec;
+}
+
+sub format_linker_cmd {
+ my ($self, %spec) = @_;
+ my $cf = $self->{config};
+
+ foreach my $path ( @{$spec{libpath}} ) {
+ $path = "-libpath:$path";
+ }
+
+ my $output = $spec{output};
+
+ $spec{def_file} &&= '-def:' . $spec{def_file};
+ $spec{output} &&= '-out:' . $spec{output};
+ $spec{manifest} &&= '-manifest ' . $spec{manifest};
+ $spec{implib} &&= '-implib:' . $spec{implib};
+ $spec{map_file} &&= '-map:' . $spec{map_file};
+
+ %spec = $self->write_linker_script(%spec)
+ if $spec{use_scripts};
+
+ my @cmds; # Stores the series of commands needed to build the module.
+
+ push @cmds, [ grep {defined && length} (
+ $spec{ld} ,
+ @{$spec{lddlflags}} ,
+ @{$spec{libpath}} ,
+ @{$spec{other_ldflags}} ,
+ @{$spec{startup}} ,
+ @{$spec{objects}} ,
+ $spec{map_file} ,
+ $spec{libperl} ,
+ @{$spec{perllibs}} ,
+ $spec{def_file} ,
+ $spec{implib} ,
+ $spec{output} ,
+ ) ];
+
+ # Embed the manifest file for VC 2005 (aka VC 8) or higher, but not for the 64-bit Platform SDK compiler
+ if ($cf->{ivsize} == 4 && $cf->{cc} eq 'cl' and $cf->{ccversion} =~ /^(\d+)/ and $1 >= 14) {
+ push @cmds, [
+ 'mt', '-nologo', $spec{manifest}, '-outputresource:' . "$output;2"
+ ];
+ }
+
+ return @cmds;
+}
+
+sub write_linker_script {
+ my ($self, %spec) = @_;
+
+ my $script = File::Spec->catfile( $spec{srcdir},
+ $spec{basename} . '.lds' );
+
+ $self->add_to_cleanup($script);
+
+ print "Generating script '$script'\n" if !$self->{quiet};
+
+ open( SCRIPT, ">$script" )
+ or die( "Could not create script '$script': $!" );
+
+ print SCRIPT join( "\n",
+ map { ref $_ ? @{$_} : $_ }
+ grep defined,
+ delete(
+ @spec{ qw(lddlflags libpath other_ldflags
+ startup objects libperl perllibs
+ def_file implib map_file) } )
+ );
+
+ close SCRIPT;
+
+ push @{$spec{lddlflags}}, '@"' . $script . '"';
+
+ return %spec;
+}
+
+1;
+
+########################################################################
+package ExtUtils::CBuilder::Platform::Windows::BCC;
+
+sub format_compiler_cmd {
+ my ($self, %spec) = @_;
+
+ foreach my $path ( @{ $spec{includes} || [] },
+ @{ $spec{perlinc} || [] } ) {
+ $path = '-I' . $path;
+ }
+
+ %spec = $self->write_compiler_script(%spec)
+ if $spec{use_scripts};
+
+ return [ grep {defined && length} (
+ $spec{cc}, '-c' ,
+ @{$spec{includes}} ,
+ @{$spec{cflags}} ,
+ @{$spec{optimize}} ,
+ @{$spec{defines}} ,
+ @{$spec{perlinc}} ,
+ "-o$spec{output}" ,
+ $spec{source} ,
+ ) ];
+}
+
+sub write_compiler_script {
+ my ($self, %spec) = @_;
+
+ my $script = File::Spec->catfile( $spec{srcdir},
+ $spec{basename} . '.ccs' );
+
+ $self->add_to_cleanup($script);
+
+ print "Generating script '$script'\n" if !$self->{quiet};
+
+ open( SCRIPT, ">$script" )
+ or die( "Could not create script '$script': $!" );
+
+ # XXX Borland "response files" seem to be unable to accept macro
+ # definitions containing quoted strings. Escaping strings with
+ # backslash doesn't work, and any level of quotes are stripped. The
+ # result is is a floating point number in the source file where a
+ # string is expected. So we leave the macros on the command line.
+ print SCRIPT join( "\n",
+ map { ref $_ ? @{$_} : $_ }
+ grep defined,
+ delete(
+ @spec{ qw(includes cflags optimize perlinc) } )
+ );
+
+ close SCRIPT;
+
+ push @{$spec{includes}}, '@"' . $script . '"';
+
+ return %spec;
+}
+
+sub format_linker_cmd {
+ my ($self, %spec) = @_;
+
+ foreach my $path ( @{$spec{libpath}} ) {
+ $path = "-L$path";
+ }
+
+ push( @{$spec{startup}}, 'c0d32.obj' )
+ unless ( $spec{starup} && @{$spec{startup}} );
+
+ %spec = $self->write_linker_script(%spec)
+ if $spec{use_scripts};
+
+ return [ grep {defined && length} (
+ $spec{ld} ,
+ @{$spec{lddlflags}} ,
+ @{$spec{libpath}} ,
+ @{$spec{other_ldflags}} ,
+ @{$spec{startup}} ,
+ @{$spec{objects}} , ',',
+ $spec{output} , ',',
+ $spec{map_file} , ',',
+ $spec{libperl} ,
+ @{$spec{perllibs}} , ',',
+ $spec{def_file}
+ ) ];
+}
+
+sub write_linker_script {
+ my ($self, %spec) = @_;
+
+ # To work around Borlands "unique" commandline syntax,
+ # two scripts are used:
+
+ my $ld_script = File::Spec->catfile( $spec{srcdir},
+ $spec{basename} . '.lds' );
+ my $ld_libs = File::Spec->catfile( $spec{srcdir},
+ $spec{basename} . '.lbs' );
+
+ $self->add_to_cleanup($ld_script, $ld_libs);
+
+ print "Generating scripts '$ld_script' and '$ld_libs'.\n" if !$self->{quiet};
+
+ # Script 1: contains options & names of object files.
+ open( LD_SCRIPT, ">$ld_script" )
+ or die( "Could not create linker script '$ld_script': $!" );
+
+ print LD_SCRIPT join( " +\n",
+ map { @{$_} }
+ grep defined,
+ delete(
+ @spec{ qw(lddlflags libpath other_ldflags startup objects) } )
+ );
+
+ close LD_SCRIPT;
+
+ # Script 2: contains name of libs to link against.
+ open( LD_LIBS, ">$ld_libs" )
+ or die( "Could not create linker script '$ld_libs': $!" );
+
+ print LD_LIBS join( " +\n",
+ (delete $spec{libperl} || ''),
+ @{delete $spec{perllibs} || []},
+ );
+
+ close LD_LIBS;
+
+ push @{$spec{lddlflags}}, '@"' . $ld_script . '"';
+ push @{$spec{perllibs}}, '@"' . $ld_libs . '"';
+
+ return %spec;
+}
+
+1;
+
+########################################################################
+package ExtUtils::CBuilder::Platform::Windows::GCC;
+
+sub format_compiler_cmd {
+ my ($self, %spec) = @_;
+
+ foreach my $path ( @{ $spec{includes} || [] },
+ @{ $spec{perlinc} || [] } ) {
+ $path = '-I' . $path;
+ }
+
+ # split off any -arguments included in cc
+ my @cc = split / (?=-)/, $spec{cc};
+
+ return [ grep {defined && length} (
+ @cc, '-c' ,
+ @{$spec{includes}} ,
+ @{$spec{cflags}} ,
+ @{$spec{optimize}} ,
+ @{$spec{defines}} ,
+ @{$spec{perlinc}} ,
+ '-o', $spec{output} ,
+ $spec{source} ,
+ ) ];
+}
+
+sub format_linker_cmd {
+ my ($self, %spec) = @_;
+
+ # The Config.pm variable 'libperl' is hardcoded to the full name
+ # of the perl import library (i.e. 'libperl56.a'). GCC will not
+ # find it unless the 'lib' prefix & the extension are stripped.
+ $spec{libperl} =~ s/^(?:lib)?([^.]+).*$/-l$1/;
+
+ unshift( @{$spec{other_ldflags}}, '-nostartfiles' )
+ if ( $spec{startup} && @{$spec{startup}} );
+
+ # From ExtUtils::MM_Win32:
+ #
+ ## one thing for GCC/Mingw32:
+ ## we try to overcome non-relocateable-DLL problems by generating
+ ## a (hopefully unique) image-base from the dll's name
+ ## -- BKS, 10-19-1999
+ File::Basename::basename( $spec{output} ) =~ /(....)(.{0,4})/;
+ $spec{image_base} = sprintf( "0x%x0000", unpack('n', $1 ^ $2) );
+
+ %spec = $self->write_linker_script(%spec)
+ if $spec{use_scripts};
+
+ foreach my $path ( @{$spec{libpath}} ) {
+ $path = "-L$path";
+ }
+
+ my @cmds; # Stores the series of commands needed to build the module.
+
+ push @cmds, [
+ 'dlltool', '--def' , $spec{def_file},
+ '--output-exp' , $spec{explib}
+ ];
+
+ # split off any -arguments included in ld
+ my @ld = split / (?=-)/, $spec{ld};
+
+ push @cmds, [ grep {defined && length} (
+ @ld ,
+ '-o', $spec{output} ,
+ "-Wl,--base-file,$spec{base_file}" ,
+ "-Wl,--image-base,$spec{image_base}" ,
+ @{$spec{lddlflags}} ,
+ @{$spec{libpath}} ,
+ @{$spec{startup}} ,
+ @{$spec{objects}} ,
+ @{$spec{other_ldflags}} ,
+ $spec{libperl} ,
+ @{$spec{perllibs}} ,
+ $spec{explib} ,
+ $spec{map_file} ? ('-Map', $spec{map_file}) : ''
+ ) ];
+
+ push @cmds, [
+ 'dlltool', '--def' , $spec{def_file},
+ '--output-exp' , $spec{explib},
+ '--base-file' , $spec{base_file}
+ ];
+
+ push @cmds, [ grep {defined && length} (
+ @ld ,
+ '-o', $spec{output} ,
+ "-Wl,--image-base,$spec{image_base}" ,
+ @{$spec{lddlflags}} ,
+ @{$spec{libpath}} ,
+ @{$spec{startup}} ,
+ @{$spec{objects}} ,
+ @{$spec{other_ldflags}} ,
+ $spec{libperl} ,
+ @{$spec{perllibs}} ,
+ $spec{explib} ,
+ $spec{map_file} ? ('-Map', $spec{map_file}) : ''
+ ) ];
+
+ return @cmds;
+}
+
+sub write_linker_script {
+ my ($self, %spec) = @_;
+
+ my $script = File::Spec->catfile( $spec{srcdir},
+ $spec{basename} . '.lds' );
+
+ $self->add_to_cleanup($script);
+
+ print "Generating script '$script'\n" if !$self->{quiet};
+
+ open( SCRIPT, ">$script" )
+ or die( "Could not create script '$script': $!" );
+
+ print( SCRIPT 'SEARCH_DIR(' . $_ . ")\n" )
+ for @{delete $spec{libpath} || []};
+
+ # gcc takes only one startup file, so the first object in startup is
+ # specified as the startup file and any others are shifted into the
+ # beginning of the list of objects.
+ if ( $spec{startup} && @{$spec{startup}} ) {
+ print SCRIPT 'STARTUP(' . shift( @{$spec{startup}} ) . ")\n";
+ unshift @{$spec{objects}},
+ @{delete $spec{startup} || []};
+ }
+
+ print SCRIPT 'INPUT(' . join( ',',
+ @{delete $spec{objects} || []}
+ ) . ")\n";
+
+ print SCRIPT 'INPUT(' . join( ' ',
+ (delete $spec{libperl} || ''),
+ @{delete $spec{perllibs} || []},
+ ) . ")\n";
+
+ close SCRIPT;
+
+ push @{$spec{other_ldflags}}, '"' . $script . '"';
+
+ return %spec;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+ExtUtils::CBuilder::Platform::Windows - Builder class for Windows platforms
+
+=head1 DESCRIPTION
+
+This module implements the Windows-specific parts of ExtUtils::CBuilder.
+Most of the Windows-specific stuff has to do with compiling and
+linking C code. Currently we support the 3 compilers perl itself
+supports: MSVC, BCC, and GCC.
+
+This module inherits from C<ExtUtils::CBuilder::Base>, so any functionality
+not implemented here will be implemented there. The interfaces are
+defined by the L<ExtUtils::CBuilder> documentation.
+
+=head1 AUTHOR
+
+Ken Williams <ken@mathforum.org>
+
+Most of the code here was written by Randy W. Sims <RandyS@ThePierianSpring.org>.
+
+=head1 SEE ALSO
+
+perl(1), ExtUtils::CBuilder(3), ExtUtils::MakeMaker(3)
+
+=cut
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/aix.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/aix.pm
new file mode 100644
index 00000000000..6ad2a6842f0
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/aix.pm
@@ -0,0 +1,31 @@
+package ExtUtils::CBuilder::Platform::aix;
+
+use strict;
+use ExtUtils::CBuilder::Platform::Unix;
+use File::Spec;
+
+use vars qw($VERSION @ISA);
+$VERSION = '0.21';
+@ISA = qw(ExtUtils::CBuilder::Platform::Unix);
+
+sub need_prelink { 1 }
+
+sub link {
+ my ($self, %args) = @_;
+ my $cf = $self->{config};
+
+ (my $baseext = $args{module_name}) =~ s/.*:://;
+ my $perl_inc = $self->perl_inc();
+
+ # Massage some very naughty bits in %Config
+ local $cf->{lddlflags} = $cf->{lddlflags};
+ for ($cf->{lddlflags}) {
+ s/\Q$(BASEEXT)\E/$baseext/;
+ s/\Q$(PERL_INC)\E/$perl_inc/;
+ }
+
+ return $self->SUPER::link(%args);
+}
+
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/cygwin.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/cygwin.pm
new file mode 100644
index 00000000000..623fe0a30c2
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/cygwin.pm
@@ -0,0 +1,30 @@
+package ExtUtils::CBuilder::Platform::cygwin;
+
+use strict;
+use File::Spec;
+use ExtUtils::CBuilder::Platform::Unix;
+
+use vars qw($VERSION @ISA);
+$VERSION = '0.21';
+@ISA = qw(ExtUtils::CBuilder::Platform::Unix);
+
+sub link_executable {
+ my $self = shift;
+ # $Config{ld} is set up as a special script for building
+ # perl-linkable libraries. We don't want that here.
+ local $self->{config}{ld} = 'gcc';
+ return $self->SUPER::link_executable(@_);
+}
+
+sub link {
+ my ($self, %args) = @_;
+
+ $args{extra_linker_flags} = [
+ File::Spec->catdir($self->perl_inc(), 'libperl.dll.a'),
+ $self->split_like_shell($args{extra_linker_flags})
+ ];
+
+ return $self->SUPER::link(%args);
+}
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/darwin.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/darwin.pm
new file mode 100644
index 00000000000..3b0cfb4c596
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/darwin.pm
@@ -0,0 +1,22 @@
+package ExtUtils::CBuilder::Platform::darwin;
+
+use strict;
+use ExtUtils::CBuilder::Platform::Unix;
+
+use vars qw($VERSION @ISA);
+$VERSION = '0.21';
+@ISA = qw(ExtUtils::CBuilder::Platform::Unix);
+
+sub compile {
+ my $self = shift;
+ my $cf = $self->{config};
+
+ # -flat_namespace isn't a compile flag, it's a linker flag. But
+ # it's mistakenly in Config.pm as both. Make the correction here.
+ local $cf->{ccflags} = $cf->{ccflags};
+ $cf->{ccflags} =~ s/-flat_namespace//;
+ $self->SUPER::compile(@_);
+}
+
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/dec_osf.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/dec_osf.pm
new file mode 100644
index 00000000000..cb7a9e3da5d
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/dec_osf.pm
@@ -0,0 +1,18 @@
+package ExtUtils::CBuilder::Platform::dec_osf;
+
+use strict;
+use ExtUtils::CBuilder::Platform::Unix;
+use File::Spec;
+
+use vars qw($VERSION @ISA);
+@ISA = qw(ExtUtils::CBuilder::Platform::Unix);
+$VERSION = '0.21';
+
+sub link_executable {
+ my $self = shift;
+ # $Config{ld} is 'ld' but that won't work: use the cc instead.
+ local $self->{config}{ld} = $self->{config}{cc};
+ return $self->SUPER::link_executable(@_);
+}
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/os2.pm b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/os2.pm
new file mode 100644
index 00000000000..4657c593ab2
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/Platform/os2.pm
@@ -0,0 +1,80 @@
+package ExtUtils::CBuilder::Platform::os2;
+
+use strict;
+use ExtUtils::CBuilder::Platform::Unix;
+
+use vars qw($VERSION @ISA);
+$VERSION = '0.21';
+@ISA = qw(ExtUtils::CBuilder::Platform::Unix);
+
+sub need_prelink { 1 }
+
+sub prelink {
+ # Generate import libraries (XXXX currently near .DEF; should be near DLL!)
+ my $self = shift;
+ my %args = @_;
+
+ my @res = $self->SUPER::prelink(%args);
+ die "Unexpected number of DEF files" unless @res == 1;
+ die "Can't find DEF file in the output"
+ unless $res[0] =~ m,^(.*)\.def$,si;
+ my $libname = "$1$self->{config}{lib_ext}"; # Put .LIB file near .DEF file
+ $self->do_system('emximp', '-o', $libname, $res[0]) or die "emxexp: res=$?";
+ return (@res, $libname);
+}
+
+sub _do_link {
+ my $self = shift;
+ my ($how, %args) = @_;
+ if ($how eq 'lib_file'
+ and (defined $args{module_name} and length $args{module_name})) {
+
+ # DynaLoader::mod2fname() is a builtin func
+ my $lib = DynaLoader::mod2fname([split /::/, $args{module_name}]);
+
+ # Now know the basename, find directory parts via lib_file, or objects
+ my $objs = ( (ref $args{objects}) ? $args{objects} : [$args{objects}] );
+ my $near_obj = $self->lib_file(@$objs);
+ my $ref_file = ( defined $args{lib_file} ? $args{lib_file} : $near_obj );
+ my $lib_dir = ($ref_file =~ m,(.*)[/\\],s ? "$1/" : '' );
+ my $exp_dir = ($near_obj =~ m,(.*)[/\\],s ? "$1/" : '' );
+
+ $args{dl_file} = $1 if $near_obj =~ m,(.*)\.,s; # put ExportList near OBJ
+ $args{lib_file} = "$lib_dir$lib.$self->{config}{dlext}"; # DLL file
+
+ # XXX _do_link does not have place to put libraries?
+ push @$objs, $self->perl_inc() . "/libperl$self->{config}{lib_ext}";
+ $args{objects} = $objs;
+ }
+ # Some 'env' do exec(), thus return too early when run from ksh;
+ # To avoid 'env', remove (useless) shrpenv
+ local $self->{config}{shrpenv} = '';
+ return $self->SUPER::_do_link($how, %args);
+}
+
+sub extra_link_args_after_prelink {
+ # Add .DEF file to the link line
+ my ($self, %args) = @_;
+
+ my @DEF = grep /\.def$/i, @{$args{prelink_res}};
+ die "More than one .def files created by `prelink' stage" if @DEF > 1;
+ # XXXX No "$how" argument here, so how to test for dynamic link?
+ die "No .def file created by `prelink' stage"
+ unless @DEF or not @{$args{prelink_res}};
+
+ my @after_libs = ($OS2::is_aout ? ()
+ : $self->perl_inc() . "/libperl_override$self->{config}{lib_ext}");
+ # , "-L", "-lperl"
+ (@after_libs, @DEF);
+}
+
+sub link_executable {
+ # ldflags is not expecting .exe extension given on command line; remove -Zexe
+ my $self = shift;
+ local $self->{config}{ldflags} = $self->{config}{ldflags};
+ $self->{config}{ldflags} =~ s/(?<!\S)-Zexe(?!\S)//;
+ return $self->SUPER::link_executable(@_);
+}
+
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/t/01-basic.t b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/t/01-basic.t
new file mode 100644
index 00000000000..9f14e8f0a7d
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/t/01-basic.t
@@ -0,0 +1,58 @@
+#! perl -w
+
+BEGIN {
+ if ($ENV{PERL_CORE}) {
+ chdir 't' if -d 't';
+ chdir '../lib/ExtUtils/CBuilder'
+ or die "Can't chdir to lib/ExtUtils/CBuilder: $!";
+ @INC = qw(../..);
+ }
+}
+
+use strict;
+use Test;
+BEGIN { plan tests => 11 }
+
+use ExtUtils::CBuilder;
+use File::Spec;
+ok 1;
+
+# TEST doesn't like extraneous output
+my $quiet = $ENV{PERL_CORE} && !$ENV{HARNESS_ACTIVE};
+
+my $b = ExtUtils::CBuilder->new(quiet => $quiet);
+ok $b;
+
+ok $b->have_compiler;
+
+my $source_file = File::Spec->catfile('t', 'compilet.c');
+{
+ local *FH;
+ open FH, "> $source_file" or die "Can't create $source_file: $!";
+ print FH "int boot_compilet(void) { return 1; }\n";
+ close FH;
+}
+ok -e $source_file;
+
+my $object_file = $b->object_file($source_file);
+ok 1;
+
+ok $object_file, $b->compile(source => $source_file);
+
+my $lib_file = $b->lib_file($object_file);
+ok 1;
+
+my ($lib, @temps) = $b->link(objects => $object_file,
+ module_name => 'compilet');
+$lib =~ tr/"'//d;
+ok $lib_file, $lib;
+
+for ($source_file, $object_file, $lib_file) {
+ tr/"'//d;
+ 1 while unlink;
+}
+
+my @words = $b->split_like_shell(' foo bar');
+ok @words, 2;
+ok $words[0], 'foo';
+ok $words[1], 'bar';
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/t/02-link.t b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/t/02-link.t
new file mode 100644
index 00000000000..30ecbe5d3b2
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/CBuilder/t/02-link.t
@@ -0,0 +1,77 @@
+#! perl -w
+
+BEGIN {
+ if ($ENV{PERL_CORE}) {
+ chdir 't' if -d 't';
+ chdir '../lib/ExtUtils/CBuilder'
+ or die "Can't chdir to lib/ExtUtils/CBuilder: $!";
+ @INC = qw(../..);
+ }
+}
+
+use strict;
+use Test;
+BEGIN {
+ if ($^O eq 'MSWin32') {
+ print "1..0 # Skipped: link_executable() is not implemented yet on Win32\n";
+ exit;
+ }
+ if ($^O eq 'VMS') {
+ # So we can get the return value of system()
+ require vmsish;
+ import vmsish;
+ }
+ plan tests => 5;
+}
+
+use ExtUtils::CBuilder;
+use File::Spec;
+
+# TEST doesn't like extraneous output
+my $quiet = $ENV{PERL_CORE} && !$ENV{HARNESS_ACTIVE};
+
+my $b = ExtUtils::CBuilder->new(quiet => $quiet);
+ok $b;
+
+my $source_file = File::Spec->catfile('t', 'compilet.c');
+{
+ local *FH;
+ open FH, "> $source_file" or die "Can't create $source_file: $!";
+ print FH "int main(void) { return 11; }\n";
+ close FH;
+}
+ok -e $source_file;
+
+# Compile
+my $object_file;
+ok $object_file = $b->compile(source => $source_file);
+
+# Link
+my ($exe_file, @temps);
+($exe_file, @temps) = $b->link_executable(objects => $object_file);
+ok $exe_file;
+
+if ($^O eq 'os2') { # Analogue of LDLOADPATH...
+ # Actually, not needed now, since we do not link with the generated DLL
+ my $old = OS2::extLibpath(); # [builtin function]
+ $old = ";$old" if defined $old and length $old;
+ # To pass the sanity check, components must have backslashes...
+ OS2::extLibpath_set(".\\$old");
+}
+
+# Try the executable
+ok my_system($exe_file), 11;
+
+# Clean up
+for ($source_file, $object_file, $exe_file) {
+ tr/"'//d;
+ 1 while unlink;
+}
+
+sub my_system {
+ my $cmd = shift;
+ if ($^O eq 'VMS') {
+ return system("mcr $cmd");
+ }
+ return system($cmd) >> 8;
+}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Changes b/gnu/usr.bin/perl/lib/ExtUtils/Changes
index af4b84c5212..c4c37c80a39 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/Changes
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Changes
@@ -1,3 +1,226 @@
+6.42 Fri Dec 7 17:00:14 PST 2007
+ Bug Fixes
+ - 6.33 moved PREREQ_FATAL to happen after CONFIGURE. This meant if
+ your CONFIGURE use a prereq it would fail and no PREREQ_FATAL
+ message would be displayed.
+ - Put the "nicetext" functionality back, VMS needs it to deal with
+ other people's custom make. But rename it to the more
+ accurate maketext_filter(), test it and fix a bug where it would
+ stop processing if it saw a macro declaration.
+
+6.40 Thu Dec 6 03:00:47 PST 2007
+ Bug Fixes
+ - Remove the dubious nicetext() Makefile formatting hack to account for
+ a lack of space between the target and colon needed on VMS. This
+ interfered with META.yml creation on VMS and possibly other output.
+ - Fix the remaining targets which don't have a space between the target
+ and the colon.
+
+6.38 Wed Nov 28 16:01:12 PST 2007
+ Releasing 6.37_03 as 6.38.
+
+6.37_03 Mon Nov 26 14:15:34 PST 2007
+ Tests
+ - parse_version.t had wrong test count when version.pm isn't installed.
+ - Fixed some warnings in the XS module we're using for testing.
+ - "our $VERSION" test in parse_version.t was never running
+ - Quoting uses of 1.2.3 style versions in parse_version.t to protect
+ older perls.
+
+ Portability
+ - Moved the minimum required version up to 5.6.0.
+
+6.37_02 Sun Nov 25 23:33:14 PST 2007
+ Test Improvements
+ - Added a test for a basic XS build.
+
+ Bug Fixes
+ - A refactoring in 6.37_01 broke XS compilation.
+
+6.37_01 Sun Nov 25 17:05:53 PST 2007
+ Improvements
+ - Upgraded the META.yml to version 1.3 of the spec (which really
+ doesn't change anything). Thanks bdfoy.
+ - MakeMaker now always includes the required 'author' field in
+ the META.yml even if it's undef to comply with the META.yml spec.
+ - Updated ExtUtils-Install to latest version (1.44)
+ - Unified the version numbers of all modules.
+
+ Test Fixes
+ - cd() test on VMS used non-native paths. [bleadperl 31534]
+ - Removed uses of "no_plan" in tests to remain compatible with
+ old versions of Test::Harness.
+ - writemakefile_args.t had the wrong test count if version.pm isn't
+ installed.
+
+ Bug Fixes
+ - $VERSION detection code would be confused by "sub version"
+ [rt.cpan.org 30747]
+ - LINKTYPE=static will now be propagated to child builds.
+ [bleadperl 31761]
+
+ Portability Fixes
+ - Add "dragonfly" to the list of BSDish operating systems
+ - BSD detection code would not pick up bsdos or internix
+ - Fix detection of shared libperl on NetBSD [bleadperl 31526]
+
+
+6.36 Tue Jul 3 01:06:40 PDT 2007
+ Test Fixes
+ - version.pm prior to 0.7203 caused Foo->VERSION to reformat
+ $Foo::VERSION. This caused prereq.t to fail.
+
+6.35 Sun Jul 1 20:53:38 PDT 2007
+ New Features
+ * MakeMaker will now try to "use version" before parsing $VERSION.
+ This allows "$VERSION = qv(1.2.3)" to work.
+
+ Test Fixes
+ - writemakefile_args.t now works with older versions of version.pm
+
+6.34 Sat Jun 30 11:06:54 CDT 2007
+ Test Fixes
+ - Accidentally hard coded the version of strict.pm [rt.cpan.org 27838]
+
+6.33 Fri Jun 29 17:15:34 CDT 2007
+ New Features
+ * VERSION now accepts version objects without warning.
+ [rt.cpan.org 26075]
+
+ Bug Fixes
+ - Properly not installing MANIFEST.SKIP when ExtUtils::Manifest is not
+ being installed. [rt.cpan.org 21318]
+ - fixin() no longer clobbers $/ [rt.cpan.org 26234]
+ - Fixed bug finding cross-compiled perls [bleadperl 31404]
+ - Looking up to 8 levels up to find uninstalled perls
+ [bleadperl 30932]
+ * A test failure in a sub-project would not cause "make test" to
+ fail. [rt.cpan.org 27804]
+
+ Windows
+ - Embed manifest files in EXEs and DLLs when building with VC++ 8.x
+ [bleadperl #29266] [rt.cpan.org 26208]
+ - Improved the subdir command code so DIR can do more than one level
+ down. [rt.cpan.org 25180]
+ - Fix static builds on Win32 by using -DPERLDLL [bleadperl 31229]
+
+ VMS
+ - Use linker flags rather than compiler flags to determine if the
+ perl sharable image was linked debug. This keeps OPTIMIZE from
+ confusing things. [rt.cpan.org 25268]
+ - Accidental use of $\ in a regex. [bleadperl 30521]
+
+ BSD
+ - If calling perl causes MakeMaker to emit warnings, then it
+ cannot find the location of its binary. [rt.cpan.org 23178]
+
+ Doc Improvements
+ - Typo fixes. $(TOUNIX) -> $(TO_UNIX). [rt.cpan.org 23495]
+ - The example for setting $VERSION from $Revision$ in SVN was
+ incorrect. (Thanks to ROBERTMAY@cpan.org) [rt.cpan.org 26995]
+ - Document what's wrong with PREFIX and what to use instead.
+ [rt.cpan.org 12919]
+ - Improve the PREREQ_FATAL docs to make it really clear that you
+ do NOT want to use this!
+
+ Misc
+ - Provide information during the install about whether we're using the
+ installed or provided dependency (ie. ExtUtils::Command).
+ - Updated included versions of ExtUtils::Manifest and Command.
+ - Add .bak and .old to veryclean [rt.cpan.org 21284]
+ - Improved the PREREQ_FATAL message.
+
+6.32 Wed Feb 21 07:59:57 PST 2007
+ New Features
+ - WriteEmptyMakefile() is now exportable upon request.
+
+ Bug Fixes
+ - Set binmode() when writing to files in Command.t for operating
+ systems which need that sort of thing. [bleadperl #29578]
+ - Fixed a minor duplication in manifypod_target(). [rt.cpan.org 22149]
+
+ Test Fixes
+ - The build_man.t test would fail if your Perl is configured to not
+ generate man pages ($Config{installman3dir} is set to none).
+
+ Doc Improvements
+ - Made the home dir install examples a little more friendly to non-Unix
+ folks.
+
+ Misc
+ - miniperl no longer has the Win32 functions.
+ - Turn on "use strict" where it was missing.
+
+6.31 Mon Oct 9 16:54:47 PDT 2006
+ - Update our META.yml to version 1.2 of the spec.
+ * Update the SEE ALSO to mention Module::Build, Module::Install,
+ ExtUtils::ModuleMaker and Module::Starter.
+ - Fix ARCHITECTURE tag in PPD generation for 5.8 (patch taken from
+ ActiveState 819). [rt.cpan.org 20566]
+ * Bring ExtUtils::Manifest up to 1.48
+
+6.30_04 Mon Sep 11 16:14:06 EDT 2006
+ - EXTRA_META has been undocumented as I don't like the way the
+ interface works but I don't want to hold up 6.31. It will be
+ replaced with something better next version.
+ - Added explaination of distclean behavior and instructions on how to
+ blow away anything not in the MANIFEST to the FAQ.
+ * 6.30_01 broke overrides of PM. MakeMaker would add to a user
+ suplied PM rather than simply accepting it.
+ * Document INSTALL_BASE.
+ * Added "How do I install a module into my home directory?" to the FAQ
+ * Added "How do I get MakeMaker and Module::Build to install to the
+ same place?"
+ - Moving ExtUtils::Mksymlists and ExtUtils::Mkbootstrap back into
+ lib/ because no independent distribution has taken them over.
+
+6.30_03 Fri Sep 1 17:03:11 EDT 2006
+ - Minor fix to Command.t for Win32.
+
+6.30_02 Fri Sep 1 15:03:55 EDT 2006
+ - Updated to ExtUtils::Install 1.41
+ * Won't scan for and build man pages when MAN3PODS is deliberately set
+ empty.
+ - Minor VMS fixes. [bleadperl@26813]
+ - VMS->one_liner must quote "--" argument. [bleadperl@27613]
+ * Split INSTALLSCRIPT into INSTALLSCRIPT, INSTALLSITESCRIPT and
+ INSTALLVENDORSCRIPT so it now honors INSTALLDIRS. [bleadperl@26536]
+ - Minor fix to work with Pod::man 2.04. [bleadperl@26457]
+ - $Revision was broken.
+ - Updated our internal version of Test::More to catch a few warnings.
+ - ExtUtils::Command::test_f() test was broken.
+ - Clarified that test_f() exits.
+
+6.30_01 Tue Aug 16 23:53:27 PDT 2005
+ * Fixed compiling modules using an uninstalled Perl on Win32 by using
+ the proper perl header location for Windows (which is different from
+ Unix). Looks like a very old bug. [bugs.perl.org 36128]
+ - $ExtUtils::MakeMaker::Revision accidentally left in a stray "Revision".
+ [thanks pdx.pm for noticing this]
+ - Fixed the $VERSION = $Revision$ example in the MakeMaker docs and the
+ FAQ. [thanks again, pdx.pm]
+ - Elaborated on the differences between CVS, SVN and others when using
+ $Revision$ based $VERSIONs.
+ * ExtUtils::Command, ExtUtils::Install, ExtUtils::Manifest,
+ ExtUtils::Mkbootstrap, ExtUtils::Mksymlists and ExtUtils::Packlist
+ are all now considered to be separate distributions. To avoid a
+ circular dependency, MakeMaker distributes its own versions but CPAN
+ should not index them and they will not overwrite a newer, installed
+ version.
+ * Added EXTRA_META option to allow module authors to append extra
+ text to the generated META.yml.
+ * Added a LICENSE field mirroring Module::Build's license.
+ * META.yml support updated to version 1.1. All required fields
+ now generated. (NOTE: 1.1 isn't yet complete but we're going with
+ it anyway. MakeMaker uses "author" instead of "authored_by" as its
+ expected the former will be used in 1.1 final).
+ * Non-conforming version_from and installdirs META.yml fields removed.
+ * META.yml distribution_type field now intelligent enough to guess at
+ the type rather than hard code 'module'.
+ * INSTALLBASE changed to INSTALL_BASE to match Module::Build.
+ * Added a MAKE parameter for Windows users to say if they're using
+ dmake or nmake.
+
6.30 Fri May 20 16:05:38 PDT 2005
* PL_FILES behavior tweak again to restore old behavior. Sometimes its
supposed to run before pm_to_blib, sometimes after.
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Command/MM.pm b/gnu/usr.bin/perl/lib/ExtUtils/Command/MM.pm
index 046fb8b5aef..48a66cedb95 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/Command/MM.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Command/MM.pm
@@ -9,7 +9,7 @@ use vars qw($VERSION @ISA @EXPORT);
@EXPORT = qw(test_harness pod2man perllocal_install uninstall
warn_if_old_packlist);
-$VERSION = '0.05';
+$VERSION = '6.42';
my $Is_VMS = $^O eq 'VMS';
@@ -117,8 +117,6 @@ sub pod2man {
# compatibility.
delete $options{lax};
- my $parser = Pod::Man->new(%options);
-
do {{ # so 'next' works
my ($pod, $man) = splice(@ARGV, 0, 2);
@@ -128,6 +126,7 @@ sub pod2man {
print "Manifying $man\n";
+ my $parser = Pod::Man->new(%options);
$parser->parse_from_file($pod, $man)
or do { warn("Could not install $man\n"); next };
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Constant.pm b/gnu/usr.bin/perl/lib/ExtUtils/Constant.pm
index 9e2b6b832e1..c449a9b3f83 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/Constant.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Constant.pm
@@ -1,6 +1,6 @@
package ExtUtils::Constant;
use vars qw (@ISA $VERSION @EXPORT_OK %EXPORT_TAGS);
-$VERSION = 0.17;
+$VERSION = 0.20;
=head1 NAME
@@ -243,17 +243,23 @@ EOT
$xs .= ', &sv' if $params->{SV};
$xs .= ");\n";
+ # If anyone is insane enough to suggest a package name containing %
+ my $package_sprintf_safe = $package;
+ $package_sprintf_safe =~ s/%/%%/g;
+
$xs .= << "EOT";
/* Return 1 or 2 items. First is error message, or undef if no error.
Second, if present, is found value */
switch (type) {
case PERL_constant_NOTFOUND:
- sv = sv_2mortal(newSVpvf("%s is not a valid $package macro", s));
+ sv =
+ sv_2mortal(newSVpvf("%s is not a valid $package_sprintf_safe macro", s));
PUSHs(sv);
break;
case PERL_constant_NOTDEF:
sv = sv_2mortal(newSVpvf(
- "Your vendor has not defined $package macro %s, used", s));
+ "Your vendor has not defined $package_sprintf_safe macro %s, used",
+ s));
PUSHs(sv);
break;
EOT
@@ -283,7 +289,7 @@ EOT
$xs .= << "EOT";
default:
sv = sv_2mortal(newSVpvf(
- "Unexpected return type %d while processing $package macro %s, used",
+ "Unexpected return type %d while processing $package_sprintf_safe macro %s, used",
type, s));
PUSHs(sv);
}
@@ -432,6 +438,11 @@ for each group with this number or more names in.
An array of constants' names, either scalars containing names, or hashrefs
as detailed in L<"C_constant">.
+=item C_FH
+
+A filehandle to write the C code to. If not given, then I<C_FILE> is opened
+for writing.
+
=item C_FILE
The name of the file to write containing the C code. The default is
@@ -440,6 +451,11 @@ mistaken for anything related to a legitimate perl package name, and
not naming the file C<.c> avoids having to override Makefile.PL's
C<.xs> to C<.c> rules.
+=item XS_FH
+
+A filehandle to write the XS code to. If not given, then I<XS_FILE> is opened
+for writing.
+
=item XS_FILE
The name of the file to write containing the XS code. The default is
@@ -474,42 +490,62 @@ sub WriteConstants {
croak "Module name not specified" unless length $ARGS{NAME};
- my ($c_fh, $xs_fh);
- if ($] <= 5.008) {
- # We need these little games, rather than doing things unconditionally,
- # because we're used in core Makefile.PLs before IO is available (needed
- # by filehandle), but also we want to work on older perls where undefined
- # scalars do not automatically turn into anonymous file handles.
- require FileHandle;
- $c_fh = FileHandle->new();
- $xs_fh = FileHandle->new();
+ my $c_fh = $ARGS{C_FH};
+ if (!$c_fh) {
+ if ($] <= 5.008) {
+ # We need these little games, rather than doing things
+ # unconditionally, because we're used in core Makefile.PLs before
+ # IO is available (needed by filehandle), but also we want to work on
+ # older perls where undefined scalars do not automatically turn into
+ # anonymous file handles.
+ require FileHandle;
+ $c_fh = FileHandle->new();
+ }
+ open $c_fh, ">$ARGS{C_FILE}" or die "Can't open $ARGS{C_FILE}: $!";
+ }
+
+ my $xs_fh = $ARGS{XS_FH};
+ if (!$xs_fh) {
+ if ($] <= 5.008) {
+ require FileHandle;
+ $xs_fh = FileHandle->new();
+ }
+ open $xs_fh, ">$ARGS{XS_FILE}" or die "Can't open $ARGS{XS_FILE}: $!";
}
- open $c_fh, ">$ARGS{C_FILE}" or die "Can't open $ARGS{C_FILE}: $!";
- open $xs_fh, ">$ARGS{XS_FILE}" or die "Can't open $ARGS{XS_FILE}: $!";
# As this subroutine is intended to make code that isn't edited, there's no
# need for the user to specify any types that aren't found in the list of
# names.
- my $types = {};
-
- print $c_fh constant_types(); # macro defs
- print $c_fh "\n";
-
- # indent is still undef. Until anyone implements indent style rules with it.
- foreach (ExtUtils::Constant::XS->C_constant({package => $ARGS{NAME},
- subname => $ARGS{C_SUBNAME},
- default_type =>
- $ARGS{DEFAULT_TYPE},
- types => $types,
- breakout => $ARGS{BREAKOUT_AT}},
- @{$ARGS{NAMES}})) {
- print $c_fh $_, "\n"; # C constant subs
+
+ if ($ARGS{PROXYSUBS}) {
+ require ExtUtils::Constant::ProxySubs;
+ $ARGS{C_FH} = $c_fh;
+ $ARGS{XS_FH} = $xs_fh;
+ ExtUtils::Constant::ProxySubs->WriteConstants(%ARGS);
+ } else {
+ my $types = {};
+
+ print $c_fh constant_types(); # macro defs
+ print $c_fh "\n";
+
+ # indent is still undef. Until anyone implements indent style rules with
+ # it.
+ foreach (ExtUtils::Constant::XS->C_constant({package => $ARGS{NAME},
+ subname => $ARGS{C_SUBNAME},
+ default_type =>
+ $ARGS{DEFAULT_TYPE},
+ types => $types,
+ breakout =>
+ $ARGS{BREAKOUT_AT}},
+ @{$ARGS{NAMES}})) {
+ print $c_fh $_, "\n"; # C constant subs
+ }
+ print $xs_fh XS_constant ($ARGS{NAME}, $types, $ARGS{XS_SUBNAME},
+ $ARGS{C_SUBNAME});
}
- print $xs_fh XS_constant ($ARGS{NAME}, $types, $ARGS{XS_SUBNAME},
- $ARGS{C_SUBNAME});
- close $c_fh or warn "Error closing $ARGS{C_FILE}: $!";
- close $xs_fh or warn "Error closing $ARGS{XS_FILE}: $!";
+ close $c_fh or warn "Error closing $ARGS{C_FILE}: $!" unless $ARGS{C_FH};
+ close $xs_fh or warn "Error closing $ARGS{XS_FILE}: $!" unless $ARGS{XS_FH};
}
1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Constant/Base.pm b/gnu/usr.bin/perl/lib/ExtUtils/Constant/Base.pm
index 8a6fc6fab02..b5b79af1ea7 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/Constant/Base.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Constant/Base.pm
@@ -1,14 +1,13 @@
package ExtUtils::Constant::Base;
use strict;
-use vars qw($VERSION $is_perl56);
+use vars qw($VERSION);
use Carp;
use Text::Wrap;
use ExtUtils::Constant::Utils qw(C_stringify perl_stringify);
+$VERSION = '0.04';
-$VERSION = '0.01';
-
-$is_perl56 = ($] < 5.007 && $] > 5.005_50);
+use constant is_perl56 => ($] < 5.007 && $] > 5.005_50);
=head1 NAME
@@ -69,6 +68,33 @@ sub macro_from_name {
1;
}
+sub macro_from_item {
+ 1;
+}
+
+sub macro_to_ifdef {
+ my ($self, $macro) = @_;
+ if (ref $macro) {
+ return $macro->[0];
+ }
+ if (defined $macro && $macro ne "" && $macro ne "1") {
+ return $macro ? "#ifdef $macro\n" : "#if 0\n";
+ }
+ return "";
+}
+
+sub macro_to_endif {
+ my ($self, $macro) = @_;
+
+ if (ref $macro) {
+ return $macro->[1];
+ }
+ if (defined $macro && $macro ne "" && $macro ne "1") {
+ return "#endif\n";
+ }
+ return "";
+}
+
sub name_param {
'name';
}
@@ -211,7 +237,7 @@ sub dump_names {
next if $_->{utf8} eq 'no';
# Copy the hashref, as we don't want to mess with the caller's hashref.
$_ = {%$_};
- unless ($is_perl56) {
+ unless (is_perl56) {
utf8::decode ($_->{name});
} else {
$_->{name} = pack 'U*', unpack 'U0U*', $_->{name};
@@ -349,26 +375,18 @@ sub return_clause {
my ($self, $args, $item) = @_;
my $indent = $args->{indent};
- my ($name, $value, $macro, $default, $pre, $post, $def_pre, $def_post, $type)
- = @$item{qw (name value macro default pre post def_pre def_post type)};
+ my ($name, $value, $default, $pre, $post, $def_pre, $def_post, $type)
+ = @$item{qw (name value default pre post def_pre def_post type)};
$value = $name unless defined $value;
- $macro = $self->macro_from_name($item) unless defined $macro;
- # "#if 1" is true to a C pre-processor
- $macro = 1 if !defined $macro or $macro eq '';
+ my $macro = $self->macro_from_item($item);
$indent = ' ' x ($indent || 6);
unless (defined $type) {
# use Data::Dumper; print STDERR Dumper ($item);
confess "undef \$type";
}
- my $clause;
-
##ifdef thingy
- if (ref $macro) {
- $clause = $macro->[0];
- } elsif ($macro ne "1") {
- $clause = "#ifdef $macro\n";
- }
+ my $clause = $self->macro_to_ifdef($macro);
# *iv_return = thingy;
# return PERL_constant_ISIV;
@@ -376,7 +394,7 @@ sub return_clause {
.= $self->assign ({indent=>$indent, type=>$type, pre=>$pre, post=>$post,
item=>$item}, ref $value ? @$value : $value);
- if (ref $macro or $macro ne "1") {
+ if (defined $macro && $macro ne "" && $macro ne "1") {
##else
$clause .= "#else\n";
@@ -390,14 +408,10 @@ sub return_clause {
$clause .= $self->assign ({indent=>$indent, type=>$type, pre=>$pre,
post=>$post, item=>$item}, @default);
}
-
- ##endif
- if (ref $macro) {
- $clause .= $macro->[1];
- } else {
- $clause .= "#endif\n";
- }
}
+ ##endif
+ $clause .= $self->macro_to_endif($macro);
+
return $clause;
}
@@ -501,7 +515,7 @@ sub switch_clause {
foreach my $i ($namelen - 1, 0 .. ($namelen - 2)) {
my ($min, $max) = (~0, 0);
my %spread;
- if ($is_perl56) {
+ if (is_perl56) {
# Need proper Unicode preserving hash keys for bytes in range 128-255
# here too, for some reason. grr 5.6.1 yet again.
tie %spread, 'ExtUtils::Constant::Aaargh56Hash';
@@ -643,6 +657,98 @@ sub dogfood {
''
}
+=item normalise_items args, default_type, seen_types, seen_items, ITEM...
+
+Convert the items to a normalised form. For 8 bit and Unicode values converts
+the item to an array of 1 or 2 items, both 8 bit and UTF-8 encoded.
+
+=cut
+
+sub normalise_items
+{
+ my $self = shift;
+ my $args = shift;
+ my $default_type = shift;
+ my $what = shift;
+ my $items = shift;
+ my @new_items;
+ foreach my $orig (@_) {
+ my ($name, $item);
+ if (ref $orig) {
+ # Make a copy which is a normalised version of the ref passed in.
+ $name = $orig->{name};
+ my ($type, $macro, $value) = @$orig{qw (type macro value)};
+ $type ||= $default_type;
+ $what->{$type} = 1;
+ $item = {name=>$name, type=>$type};
+
+ undef $macro if defined $macro and $macro eq $name;
+ $item->{macro} = $macro if defined $macro;
+ undef $value if defined $value and $value eq $name;
+ $item->{value} = $value if defined $value;
+ foreach my $key (qw(default pre post def_pre def_post weight
+ not_constant)) {
+ my $value = $orig->{$key};
+ $item->{$key} = $value if defined $value;
+ # warn "$key $value";
+ }
+ } else {
+ $name = $orig;
+ $item = {name=>$name, type=>$default_type};
+ $what->{$default_type} = 1;
+ }
+ warn +(ref ($self) || $self)
+ . "doesn't know how to handle values of type $_ used in macro $name"
+ unless $self->valid_type ($item->{type});
+ # tr///c is broken on 5.6.1 for utf8, so my original tr/\0-\177//c
+ # doesn't work. Upgrade to 5.8
+ # if ($name !~ tr/\0-\177//c || $] < 5.005_50) {
+ if ($name =~ tr/\0-\177// == length $name || $] < 5.005_50
+ || $args->{disable_utf8_duplication}) {
+ # No characters outside 7 bit ASCII.
+ if (exists $items->{$name}) {
+ die "Multiple definitions for macro $name";
+ }
+ $items->{$name} = $item;
+ } else {
+ # No characters outside 8 bit. This is hardest.
+ if (exists $items->{$name} and ref $items->{$name} ne 'ARRAY') {
+ confess "Unexpected ASCII definition for macro $name";
+ }
+ # Again, 5.6.1 tr broken, so s/5\.6.*/5\.8\.0/;
+ # if ($name !~ tr/\0-\377//c) {
+ if ($name =~ tr/\0-\377// == length $name) {
+# if ($] < 5.007) {
+# $name = pack "C*", unpack "U*", $name;
+# }
+ $item->{utf8} = 'no';
+ $items->{$name}[1] = $item;
+ push @new_items, $item;
+ # Copy item, to create the utf8 variant.
+ $item = {%$item};
+ }
+ # Encode the name as utf8 bytes.
+ unless (is_perl56) {
+ utf8::encode($name);
+ } else {
+# warn "Was >$name< " . length ${name};
+ $name = pack 'C*', unpack 'C*', $name . pack 'U*';
+# warn "Now '${name}' " . length ${name};
+ }
+ if ($items->{$name}[0]) {
+ die "Multiple definitions for macro $name";
+ }
+ $item->{utf8} = 'yes';
+ $item->{name} = $name;
+ $items->{$name}[0] = $item;
+ # We have need for the utf8 flag.
+ $what->{''} = 1;
+ }
+ push @new_items, $item;
+ }
+ @new_items;
+}
+
=item C_constant arg_hashref, ITEM...
A function that returns a B<list> of C subroutine definitions that return
@@ -779,10 +885,10 @@ sub C_constant {
# be a hashref, and pinch %$items from our parent to save recalculation.
($namelen, $items) = @$breakout;
} else {
- if ($is_perl56) {
+ $items = {};
+ if (is_perl56) {
# Need proper Unicode preserving hash keys.
require ExtUtils::Constant::Aaargh56Hash;
- $items = {};
tie %$items, 'ExtUtils::Constant::Aaargh56Hash';
}
$breakout ||= 3;
@@ -793,80 +899,7 @@ sub C_constant {
# Figure out what types we're dealing with, and assign all unknowns to the
# default type
}
- my @new_items;
- foreach my $orig (@items) {
- my ($name, $item);
- if (ref $orig) {
- # Make a copy which is a normalised version of the ref passed in.
- $name = $orig->{name};
- my ($type, $macro, $value) = @$orig{qw (type macro value)};
- $type ||= $default_type;
- $what->{$type} = 1;
- $item = {name=>$name, type=>$type};
-
- undef $macro if defined $macro and $macro eq $name;
- $item->{macro} = $macro if defined $macro;
- undef $value if defined $value and $value eq $name;
- $item->{value} = $value if defined $value;
- foreach my $key (qw(default pre post def_pre def_post weight)) {
- my $value = $orig->{$key};
- $item->{$key} = $value if defined $value;
- # warn "$key $value";
- }
- } else {
- $name = $orig;
- $item = {name=>$name, type=>$default_type};
- $what->{$default_type} = 1;
- }
- warn +(ref ($self) || $self)
- . "doesn't know how to handle values of type $_ used in macro $name"
- unless $self->valid_type ($item->{type});
- # tr///c is broken on 5.6.1 for utf8, so my original tr/\0-\177//c
- # doesn't work. Upgrade to 5.8
- # if ($name !~ tr/\0-\177//c || $] < 5.005_50) {
- if ($name =~ tr/\0-\177// == length $name || $] < 5.005_50) {
- # No characters outside 7 bit ASCII.
- if (exists $items->{$name}) {
- die "Multiple definitions for macro $name";
- }
- $items->{$name} = $item;
- } else {
- # No characters outside 8 bit. This is hardest.
- if (exists $items->{$name} and ref $items->{$name} ne 'ARRAY') {
- confess "Unexpected ASCII definition for macro $name";
- }
- # Again, 5.6.1 tr broken, so s/5\.6.*/5\.8\.0/;
- # if ($name !~ tr/\0-\377//c) {
- if ($name =~ tr/\0-\377// == length $name) {
-# if ($] < 5.007) {
-# $name = pack "C*", unpack "U*", $name;
-# }
- $item->{utf8} = 'no';
- $items->{$name}[1] = $item;
- push @new_items, $item;
- # Copy item, to create the utf8 variant.
- $item = {%$item};
- }
- # Encode the name as utf8 bytes.
- unless ($is_perl56) {
- utf8::encode($name);
- } else {
-# warn "Was >$name< " . length ${name};
- $name = pack 'C*', unpack 'C*', $name . pack 'U*';
-# warn "Now '${name}' " . length ${name};
- }
- if ($items->{$name}[0]) {
- die "Multiple definitions for macro $name";
- }
- $item->{utf8} = 'yes';
- $item->{name} = $name;
- $items->{$name}[0] = $item;
- # We have need for the utf8 flag.
- $what->{''} = 1;
- }
- push @new_items, $item;
- }
- @items = @new_items;
+ @items = $self->normalise_items ({}, $default_type, $what, $items, @items);
# use Data::Dumper; print Dumper @items;
}
my $params = $self->params ($what);
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Constant/ProxySubs.pm b/gnu/usr.bin/perl/lib/ExtUtils/Constant/ProxySubs.pm
new file mode 100644
index 00000000000..af8c458b634
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Constant/ProxySubs.pm
@@ -0,0 +1,524 @@
+package ExtUtils::Constant::ProxySubs;
+
+use strict;
+use vars qw($VERSION @ISA %type_to_struct %type_from_struct %type_to_sv
+ %type_to_C_value %type_is_a_problem %type_num_args
+ %type_temporary);
+use Carp;
+require ExtUtils::Constant::XS;
+use ExtUtils::Constant::Utils qw(C_stringify);
+use ExtUtils::Constant::XS qw(%XS_TypeSet);
+
+$VERSION = '0.05';
+@ISA = 'ExtUtils::Constant::XS';
+
+%type_to_struct =
+ (
+ IV => '{const char *name; I32 namelen; IV value;}',
+ NV => '{const char *name; I32 namelen; NV value;}',
+ UV => '{const char *name; I32 namelen; UV value;}',
+ PV => '{const char *name; I32 namelen; const char *value;}',
+ PVN => '{const char *name; I32 namelen; const char *value; STRLEN len;}',
+ YES => '{const char *name; I32 namelen;}',
+ NO => '{const char *name; I32 namelen;}',
+ UNDEF => '{const char *name; I32 namelen;}',
+ '' => '{const char *name; I32 namelen;} ',
+ );
+
+%type_from_struct =
+ (
+ IV => sub { $_[0] . '->value' },
+ NV => sub { $_[0] . '->value' },
+ UV => sub { $_[0] . '->value' },
+ PV => sub { $_[0] . '->value' },
+ PVN => sub { $_[0] . '->value', $_[0] . '->len' },
+ YES => sub {},
+ NO => sub {},
+ UNDEF => sub {},
+ '' => sub {},
+ );
+
+%type_to_sv =
+ (
+ IV => sub { "newSViv($_[0])" },
+ NV => sub { "newSVnv($_[0])" },
+ UV => sub { "newSVuv($_[0])" },
+ PV => sub { "newSVpv($_[0], 0)" },
+ PVN => sub { "newSVpvn($_[0], $_[1])" },
+ YES => sub { '&PL_sv_yes' },
+ NO => sub { '&PL_sv_no' },
+ UNDEF => sub { '&PL_sv_undef' },
+ '' => sub { '&PL_sv_yes' },
+ SV => sub {"SvREFCNT_inc($_[0])"},
+ );
+
+%type_to_C_value =
+ (
+ YES => sub {},
+ NO => sub {},
+ UNDEF => sub {},
+ '' => sub {},
+ );
+
+sub type_to_C_value {
+ my ($self, $type) = @_;
+ return $type_to_C_value{$type} || sub {return map {ref $_ ? @$_ : $_} @_};
+}
+
+# TODO - figure out if there is a clean way for the type_to_sv code to
+# attempt s/sv_2mortal// and if it succeeds tell type_to_sv not to add
+# SvREFCNT_inc
+%type_is_a_problem =
+ (
+ # The documentation says *mortal SV*, but we now need a non-mortal copy.
+ SV => 1,
+ );
+
+%type_temporary =
+ (
+ SV => ['SV *'],
+ PV => ['const char *'],
+ PVN => ['const char *', 'STRLEN'],
+ );
+$type_temporary{$_} = [$_] foreach qw(IV UV NV);
+
+while (my ($type, $value) = each %XS_TypeSet) {
+ $type_num_args{$type}
+ = defined $value ? ref $value ? scalar @$value : 1 : 0;
+}
+$type_num_args{''} = 0;
+
+sub partition_names {
+ my ($self, $default_type, @items) = @_;
+ my (%found, @notfound, @trouble);
+
+ while (my $item = shift @items) {
+ my $default = delete $item->{default};
+ if ($default) {
+ # If we find a default value, convert it into a regular item and
+ # append it to the queue of items to process
+ my $default_item = {%$item};
+ $default_item->{invert_macro} = 1;
+ $default_item->{pre} = delete $item->{def_pre};
+ $default_item->{post} = delete $item->{def_post};
+ $default_item->{type} = shift @$default;
+ $default_item->{value} = $default;
+ push @items, $default_item;
+ } else {
+ # It can be "not found" unless it's the default (invert the macro)
+ # or the "macro" is an empty string (ie no macro)
+ push @notfound, $item unless $item->{invert_macro}
+ or !$self->macro_to_ifdef($self->macro_from_item($item));
+ }
+
+ if ($item->{pre} or $item->{post} or $item->{not_constant}
+ or $type_is_a_problem{$item->{type}}) {
+ push @trouble, $item;
+ } else {
+ push @{$found{$item->{type}}}, $item;
+ }
+ }
+ # use Data::Dumper; print Dumper \%found;
+ (\%found, \@notfound, \@trouble);
+}
+
+sub boottime_iterator {
+ my ($self, $type, $iterator, $hash, $subname) = @_;
+ my $extractor = $type_from_struct{$type};
+ die "Can't find extractor code for type $type"
+ unless defined $extractor;
+ my $generator = $type_to_sv{$type};
+ die "Can't find generator code for type $type"
+ unless defined $generator;
+
+ my $athx = $self->C_constant_prefix_param();
+
+ return sprintf <<"EOBOOT", &$generator(&$extractor($iterator));
+ while ($iterator->name) {
+ $subname($athx $hash, $iterator->name,
+ $iterator->namelen, %s);
+ ++$iterator;
+ }
+EOBOOT
+}
+
+sub name_len_value_macro {
+ my ($self, $item) = @_;
+ my $name = $item->{name};
+ my $value = $item->{value};
+ $value = $item->{name} unless defined $value;
+
+ my $namelen = length $name;
+ if ($name =~ tr/\0-\377// != $namelen) {
+ # the hash API signals UTF-8 by passing the length negated.
+ utf8::encode($name);
+ $namelen = -length $name;
+ }
+ $name = C_stringify($name);
+
+ my $macro = $self->macro_from_item($item);
+ ($name, $namelen, $value, $macro);
+}
+
+sub WriteConstants {
+ my $self = shift;
+ my $ARGS = {@_};
+
+ my ($c_fh, $xs_fh, $c_subname, $xs_subname, $default_type, $package)
+ = @{$ARGS}{qw(C_FH XS_FH C_SUBNAME XS_SUBNAME DEFAULT_TYPE NAME)};
+
+ my $options = $ARGS->{PROXYSUBS};
+ $options = {} unless ref $options;
+ my $explosives = $options->{croak_on_read};
+
+ $xs_subname ||= 'constant';
+
+ # If anyone is insane enough to suggest a package name containing %
+ my $package_sprintf_safe = $package;
+ $package_sprintf_safe =~ s/%/%%/g;
+
+ # All the types we see
+ my $what = {};
+ # A hash to lookup items with.
+ my $items = {};
+
+ my @items = $self->normalise_items ({disable_utf8_duplication => 1},
+ $default_type, $what, $items,
+ @{$ARGS->{NAMES}});
+
+ # Partition the values by type. Also include any defaults in here
+ # Everything that doesn't have a default needs alternative code for
+ # "I'm missing"
+ # And everything that has pre or post code ends up in a private block
+ my ($found, $notfound, $trouble)
+ = $self->partition_names($default_type, @items);
+
+ my $pthx = $self->C_constant_prefix_param_defintion();
+ my $athx = $self->C_constant_prefix_param();
+ my $symbol_table = C_stringify($package) . '::';
+
+ print $c_fh $self->header(), <<"EOADD";
+static void
+${c_subname}_add_symbol($pthx HV *hash, const char *name, I32 namelen, SV *value) {
+ SV **sv = hv_fetch(hash, name, namelen, TRUE);
+ if (!sv) {
+ Perl_croak($athx "Couldn't add key '%s' to %%$package_sprintf_safe\::",
+ name);
+ }
+ if (SvOK(*sv) || SvTYPE(*sv) == SVt_PVGV) {
+ /* Someone has been here before us - have to make a real sub. */
+ newCONSTSUB(hash, name, value);
+ } else {
+ SvUPGRADE(*sv, SVt_RV);
+ SvRV_set(*sv, value);
+ SvROK_on(*sv);
+ SvREADONLY_on(value);
+ }
+}
+
+EOADD
+
+ print $c_fh $explosives ? <<"EXPLODE" : "\n";
+
+static int
+Im_sorry_Dave(pTHX_ SV *sv, MAGIC *mg)
+{
+ PERL_UNUSED_ARG(mg);
+ Perl_croak(aTHX_
+ "Your vendor has not defined $package_sprintf_safe macro %"SVf
+ " used", sv);
+ NORETURN_FUNCTION_END;
+}
+
+static MGVTBL not_defined_vtbl = {
+ Im_sorry_Dave, /* get - I'm afraid I can't do that */
+ Im_sorry_Dave, /* set */
+ 0, /* len */
+ 0, /* clear */
+ 0, /* free */
+ 0, /* copy */
+ 0, /* dup */
+};
+
+EXPLODE
+
+{
+ my $key = $symbol_table;
+ # Just seems tidier (and slightly more space efficient) not to have keys
+ # such as Fcntl::
+ $key =~ s/::$//;
+ my $key_len = length $key;
+
+ print $c_fh <<"MISSING";
+
+#ifndef SYMBIAN
+
+/* Store a hash of all symbols missing from the package. To avoid trampling on
+ the package namespace (uninvited) put each package's hash in our namespace.
+ To avoid creating lots of typeblogs and symbol tables for sub-packages, put
+ each package's hash into one hash in our namespace. */
+
+static HV *
+get_missing_hash(pTHX) {
+ HV *const parent
+ = get_hv("ExtUtils::Constant::ProxySubs::Missing", GVf_MULTI);
+ /* We could make a hash of hashes directly, but this would confuse anything
+ at Perl space that looks at us, and as we're visible in Perl space,
+ best to play nice. */
+ SV *const *const ref
+ = hv_fetch(parent, "$key", $key_len, TRUE);
+ HV *new_hv;
+
+ if (!ref)
+ return NULL;
+
+ if (SvROK(*ref))
+ return (HV*) SvRV(*ref);
+
+ new_hv = newHV();
+ SvUPGRADE(*ref, SVt_RV);
+ SvRV_set(*ref, (SV *)new_hv);
+ SvROK_on(*ref);
+ return new_hv;
+}
+
+#endif
+
+MISSING
+
+}
+
+ print $xs_fh <<"EOBOOT";
+BOOT:
+ {
+#ifdef dTHX
+ dTHX;
+#endif
+ HV *symbol_table = get_hv("$symbol_table", TRUE);
+#ifndef SYMBIAN
+ HV *${c_subname}_missing;
+#endif
+EOBOOT
+
+ my %iterator;
+
+ $found->{''}
+ = [map {{%$_, type=>'', invert_macro => 1}} @$notfound];
+
+ foreach my $type (sort keys %$found) {
+ my $struct = $type_to_struct{$type};
+ my $type_to_value = $self->type_to_C_value($type);
+ my $number_of_args = $type_num_args{$type};
+ die "Can't find structure definition for type $type"
+ unless defined $struct;
+
+ my $struct_type = $type ? lc($type) . '_s' : 'notfound_s';
+ print $c_fh "struct $struct_type $struct;\n";
+
+ my $array_name = 'values_for_' . ($type ? lc $type : 'notfound');
+ print $xs_fh <<"EOBOOT";
+
+ static const struct $struct_type $array_name\[] =
+ {
+EOBOOT
+
+
+ foreach my $item (@{$found->{$type}}) {
+ my ($name, $namelen, $value, $macro)
+ = $self->name_len_value_macro($item);
+
+ my $ifdef = $self->macro_to_ifdef($macro);
+ if (!$ifdef && $item->{invert_macro}) {
+ carp("Attempting to supply a default for '$name' which has no conditional macro");
+ next;
+ }
+ print $xs_fh $ifdef;
+ if ($item->{invert_macro}) {
+ print $xs_fh
+ " /* This is the default value: */\n" if $type;
+ print $xs_fh "#else\n";
+ }
+ print $xs_fh " { ", join (', ', "\"$name\"", $namelen,
+ &$type_to_value($value)), " },\n",
+ $self->macro_to_endif($macro);
+ }
+
+
+ # Terminate the list with a NULL
+ print $xs_fh " { NULL, 0", (", 0" x $number_of_args), " } };\n";
+
+ $iterator{$type} = "value_for_" . ($type ? lc $type : 'notfound');
+
+ print $xs_fh <<"EOBOOT";
+ const struct $struct_type *$iterator{$type} = $array_name;
+EOBOOT
+ }
+
+ delete $found->{''};
+
+ print $xs_fh <<"EOBOOT";
+#ifndef SYMBIAN
+ ${c_subname}_missing = get_missing_hash(aTHX);
+#endif
+EOBOOT
+
+ my $add_symbol_subname = $c_subname . '_add_symbol';
+ foreach my $type (sort keys %$found) {
+ print $xs_fh $self->boottime_iterator($type, $iterator{$type},
+ 'symbol_table',
+ $add_symbol_subname);
+ }
+
+ print $xs_fh <<"EOBOOT";
+ while (value_for_notfound->name) {
+EOBOOT
+
+ print $xs_fh $explosives ? <<"EXPLODE" : << "DONT";
+ SV *tripwire = newSV(0);
+
+ sv_magicext(tripwire, 0, PERL_MAGIC_ext, &not_defined_vtbl, 0, 0);
+ SvPV_set(tripwire, (char *)value_for_notfound->name);
+ if(value_for_notfound->namelen >= 0) {
+ SvCUR_set(tripwire, value_for_notfound->namelen);
+ } else {
+ SvCUR_set(tripwire, -value_for_notfound->namelen);
+ SvUTF8_on(tripwire);
+ }
+ SvPOKp_on(tripwire);
+ SvREADONLY_on(tripwire);
+ assert(SvLEN(tripwire) == 0);
+
+ $add_symbol_subname($athx symbol_table, value_for_notfound->name,
+ value_for_notfound->namelen, tripwire);
+EXPLODE
+
+ /* Need to add prototypes, else parsing will vary by platform. */
+ SV **sv = hv_fetch(symbol_table, value_for_notfound->name,
+ value_for_notfound->namelen, TRUE);
+ if (!sv) {
+ Perl_croak($athx
+ "Couldn't add key '%s' to %%$package_sprintf_safe\::",
+ value_for_notfound->name);
+ }
+ if (!SvOK(*sv) && SvTYPE(*sv) != SVt_PVGV) {
+ /* Nothing was here before, so mark a prototype of "" */
+ sv_setpvn(*sv, "", 0);
+ } else if (SvPOK(*sv) && SvCUR(*sv) == 0) {
+ /* There is already a prototype of "" - do nothing */
+ } else {
+ /* Someone has been here before us - have to make a real
+ typeglob. */
+ /* It turns out to be incredibly hard to deal with all the
+ corner cases of sub foo (); and reporting errors correctly,
+ so lets cheat a bit. Start with a constant subroutine */
+ CV *cv = newCONSTSUB(symbol_table, value_for_notfound->name,
+ &PL_sv_yes);
+ /* and then turn it into a non constant declaration only. */
+ SvREFCNT_dec(CvXSUBANY(cv).any_ptr);
+ CvCONST_off(cv);
+ CvXSUB(cv) = NULL;
+ CvXSUBANY(cv).any_ptr = NULL;
+ }
+#ifndef SYMBIAN
+ if (!hv_store(${c_subname}_missing, value_for_notfound->name,
+ value_for_notfound->namelen, &PL_sv_yes, 0))
+ Perl_croak($athx "Couldn't add key '%s' to missing_hash",
+ value_for_notfound->name);
+#endif
+DONT
+
+ print $xs_fh <<"EOBOOT";
+
+ ++value_for_notfound;
+ }
+EOBOOT
+
+ foreach my $item (@$trouble) {
+ my ($name, $namelen, $value, $macro)
+ = $self->name_len_value_macro($item);
+ my $ifdef = $self->macro_to_ifdef($macro);
+ my $type = $item->{type};
+ my $type_to_value = $self->type_to_C_value($type);
+
+ print $xs_fh $ifdef;
+ if ($item->{invert_macro}) {
+ print $xs_fh
+ " /* This is the default value: */\n" if $type;
+ print $xs_fh "#else\n";
+ }
+ my $generator = $type_to_sv{$type};
+ die "Can't find generator code for type $type"
+ unless defined $generator;
+
+ print $xs_fh " {\n";
+ # We need to use a temporary value because some really troublesome
+ # items use C pre processor directives in their values, and in turn
+ # these don't fit nicely in the macro-ised generator functions
+ my $counter = 0;
+ printf $xs_fh " %s temp%d;\n", $_, $counter++
+ foreach @{$type_temporary{$type}};
+
+ print $xs_fh " $item->{pre}\n" if $item->{pre};
+
+ # And because the code in pre might be both declarations and
+ # statements, we can't declare and assign to the temporaries in one.
+ $counter = 0;
+ printf $xs_fh " temp%d = %s;\n", $counter++, $_
+ foreach &$type_to_value($value);
+
+ my @tempvarnames = map {sprintf 'temp%d', $_} 0 .. $counter - 1;
+ printf $xs_fh <<"EOBOOT", $name, &$generator(@tempvarnames);
+ ${c_subname}_add_symbol($athx symbol_table, "%s",
+ $namelen, %s);
+EOBOOT
+ print $xs_fh " $item->{post}\n" if $item->{post};
+ print $xs_fh " }\n";
+
+ print $xs_fh $self->macro_to_endif($macro);
+ }
+
+ print $xs_fh <<EOBOOT;
+ /* As we've been creating subroutines, we better invalidate any cached
+ methods */
+ ++PL_sub_generation;
+ }
+EOBOOT
+
+ print $xs_fh $explosives ? <<"EXPLODE" : <<"DONT";
+
+void
+$xs_subname(sv)
+ INPUT:
+ SV * sv;
+ PPCODE:
+ sv = newSVpvf("Your vendor has not defined $package_sprintf_safe macro %" SVf
+ ", used", sv);
+ PUSHs(sv_2mortal(sv));
+EXPLODE
+
+void
+$xs_subname(sv)
+ PREINIT:
+ STRLEN len;
+ INPUT:
+ SV * sv;
+ const char * s = SvPV(sv, len);
+ PPCODE:
+#ifdef SYMBIAN
+ sv = newSVpvf("%"SVf" is not a valid $package_sprintf_safe macro", sv);
+#else
+ HV *${c_subname}_missing = get_missing_hash(aTHX);
+ if (hv_exists(${c_subname}_missing, s, SvUTF8(sv) ? -(I32)len : (I32)len)) {
+ sv = newSVpvf("Your vendor has not defined $package_sprintf_safe macro %" SVf
+ ", used", sv);
+ } else {
+ sv = newSVpvf("%"SVf" is not a valid $package_sprintf_safe macro",
+ sv);
+ }
+#endif
+ PUSHs(sv_2mortal(sv));
+DONT
+
+}
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Constant/Utils.pm b/gnu/usr.bin/perl/lib/ExtUtils/Constant/Utils.pm
index 3ef2228c871..067170157e3 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/Constant/Utils.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Constant/Utils.pm
@@ -54,7 +54,11 @@ sub C_stringify {
s/\t/\\t/g;
s/\f/\\f/g;
s/\a/\\a/g;
- s/([^\0-\177])/sprintf "\\%03o", ord $1/ge;
+ if (ord('A') == 193) { # EBCDIC has no ^\0-\177 workalike.
+ s/([[:^print:]])/sprintf "\\%03o", ord $1/ge;
+ } else {
+ s/([^\0-\177])/sprintf "\\%03o", ord $1/ge;
+ }
unless ($] < 5.006) {
# This will elicit a warning on 5.005_03 about [: :] being reserved unless
# I cheat
@@ -87,7 +91,11 @@ sub perl_stringify {
s/\a/\\a/g;
unless ($] < 5.006) {
if ($] > 5.007) {
- s/([^\0-\177])/sprintf "\\x{%X}", ord $1/ge;
+ if (ord('A') == 193) { # EBCDIC has no ^\0-\177 workalike.
+ s/([[:^print:]])/sprintf "\\x{%X}", ord $1/ge;
+ } else {
+ s/([^\0-\177])/sprintf "\\x{%X}", ord $1/ge;
+ }
} else {
# Grr 5.6.1. And I don't think I can use utf8; to force the regexp
# because 5.005_03 will fail.
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Constant/XS.pm b/gnu/usr.bin/perl/lib/ExtUtils/Constant/XS.pm
index 51244f6b2bf..010dfbd48f6 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/Constant/XS.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Constant/XS.pm
@@ -10,7 +10,7 @@ require ExtUtils::Constant::Base;
@ISA = qw(ExtUtils::Constant::Base Exporter);
@EXPORT_OK = qw(%XS_Constant %XS_TypeSet);
-$VERSION = '0.01';
+$VERSION = '0.02';
$is_perl56 = ($] < 5.007 && $] > 5.005_50);
@@ -143,6 +143,13 @@ sub macro_from_name {
$macro;
}
+sub macro_from_item {
+ my ($self, $item) = @_;
+ my $macro = $item->{macro};
+ $macro = $self->macro_from_name($item) unless defined $macro;
+ $macro;
+}
+
# Keep to the traditional perl source macro
sub memEQ {
"memEQ";
@@ -221,7 +228,7 @@ EOT
@items);
$result .= <<'EOT';
-print constant_types(); # macro defs
+print constant_types(), "\n"; # macro defs
EOT
$package = perl_stringify($package);
$result .=
@@ -239,7 +246,7 @@ EOT
$result .= ", $breakout" . ', @names) ) {
print $_, "\n"; # C constant subs
}
-print "#### XS Section:\n";
+print "\n#### XS Section:\n";
print XS_constant ("' . $package . '", $types);
__END__
*/
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Installed.pm b/gnu/usr.bin/perl/lib/ExtUtils/Installed.pm
index 8b0c53c4811..8e6513998bb 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/Installed.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Installed.pm
@@ -16,7 +16,8 @@ my $DOSISH = ($^O =~ /^(MSWin\d\d|os2|dos|mint)$/);
require VMS::Filespec if $Is_VMS;
use vars qw($VERSION);
-$VERSION = '0.08';
+$VERSION = '1.43';
+$VERSION = eval $VERSION;
sub _is_prefix {
my ($self, $path, $prefix) = @_;
@@ -41,16 +42,17 @@ sub _is_prefix {
return(0);
}
-sub _is_doc {
+sub _is_doc {
my ($self, $path) = @_;
- my $man1dir = $Config{man1direxp};
- my $man3dir = $Config{man3direxp};
+
+ my $man1dir = $self->{':private:'}{Config}{man1direxp};
+ my $man3dir = $self->{':private:'}{Config}{man3direxp};
return(($man1dir && $self->_is_prefix($path, $man1dir))
||
($man3dir && $self->_is_prefix($path, $man3dir))
? 1 : 0)
}
-
+
sub _is_type {
my ($self, $path, $type) = @_;
return 1 if $type eq "all";
@@ -58,7 +60,7 @@ sub _is_type {
return($self->_is_doc($path)) if $type eq "doc";
if ($type eq "prog") {
- return($self->_is_prefix($path, $Config{prefix} || $Config{prefixexp})
+ return($self->_is_prefix($path, $self->{':private:'}{Config}{prefix} || $self->{':private:'}{Config}{prefixexp})
&&
!($self->_is_doc($path))
? 1 : 0);
@@ -77,28 +79,67 @@ sub _is_under {
}
sub new {
- my ($class) = @_;
+ my ($class) = shift(@_);
$class = ref($class) || $class;
- my $self = {};
- my $archlib = $Config{archlibexp};
- my $sitearch = $Config{sitearchexp};
+ my %args = @_;
+
+ my $self = {};
+ if ($args{config_override}) {
+ eval {
+ $self->{':private:'}{Config} = { %{$args{config_override}} };
+ } or Carp::croak(
+ "The 'config_override' parameter must be a hash reference."
+ );
+ }
+ else {
+ $self->{':private:'}{Config} = \%Config;
+ }
+
+ for my $tuple ([inc_override => INC => [ @INC ] ],
+ [ extra_libs => EXTRA => [] ])
+ {
+ my ($arg,$key,$val)=@$tuple;
+ if ( $args{$arg} ) {
+ eval {
+ $self->{':private:'}{$key} = [ @{$args{$arg}} ];
+ } or Carp::croak(
+ "The '$arg' parameter must be an array reference."
+ );
+ }
+ elsif ($val) {
+ $self->{':private:'}{$key} = $val;
+ }
+ }
+ {
+ my %dupe;
+ @{$self->{':private:'}{INC}} = grep { -e $_ && !$dupe{$_}++ }
+ @{$self->{':private:'}{INC}}, @{$self->{':private:'}{EXTRA}};
+ }
+ my $perl5lib = defined $ENV{PERL5LIB} ? $ENV{PERL5LIB} : "";
+
+ my @dirs = ( $self->{':private:'}{Config}{archlibexp},
+ $self->{':private:'}{Config}{sitearchexp},
+ split(/\Q$Config{path_sep}\E/, $perl5lib),
+ @{$self->{':private:'}{EXTRA}},
+ );
+
# File::Find does not know how to deal with VMS filepaths.
if( $Is_VMS ) {
- $archlib = VMS::Filespec::unixify($archlib);
- $sitearch = VMS::Filespec::unixify($sitearch);
+ $_ = VMS::Filespec::unixify($_)
+ for @dirs;
}
if ($DOSISH) {
- $archlib =~ s|\\|/|g;
- $sitearch =~ s|\\|/|g;
+ s|\\|/|g for @dirs;
}
-
+ my $archlib = $dirs[0];
+
# Read the core packlist
$self->{Perl}{packlist} =
ExtUtils::Packlist->new( File::Spec->catfile($archlib, '.packlist') );
- $self->{Perl}{version} = $Config{version};
+ $self->{Perl}{version} = $self->{':private:'}{Config}{version};
# Read the module packlists
my $sub = sub {
@@ -107,31 +148,38 @@ sub new {
# Hack of the leading bits of the paths & convert to a module name
my $module = $File::Find::name;
-
- $module =~ s!\Q$archlib\E/?auto/(.*)/.packlist!$1!s or
- $module =~ s!\Q$sitearch\E/?auto/(.*)/.packlist!$1!s;
+ my $found;
+ for (@dirs) {
+ $found = $module =~ s!\Q$_\E/?auto/(.*)/.packlist!$1!s
+ and last;
+ }
+ unless ($found) {
+ # warn "Woah! \$_=$_\n\$module=$module\n\$File::Find::dir=$File::Find::dir\n",
+ # join ("\n",@dirs);
+ return;
+ }
my $modfile = "$module.pm";
$module =~ s!/!::!g;
# Find the top-level module file in @INC
$self->{$module}{version} = '';
- foreach my $dir (@INC) {
+ foreach my $dir (@{$self->{':private:'}{INC}}) {
my $p = File::Spec->catfile($dir, $modfile);
if (-r $p) {
$module = _module_name($p, $module) if $Is_VMS;
- require ExtUtils::MM;
$self->{$module}{version} = MM->parse_version($p);
last;
}
}
# Read the .packlist
- $self->{$module}{packlist} =
+ $self->{$module}{packlist} =
ExtUtils::Packlist->new($File::Find::name);
};
-
- my(@dirs) = grep { -e } ($archlib, $sitearch);
+ my %dupe;
+ @dirs= grep { -e $_ && !$dupe{$_}++ } @dirs;
+ $self->{':private:'}{LIBDIRS} = \@dirs;
find($sub, @dirs) if @dirs;
return(bless($self, $class));
@@ -171,7 +219,9 @@ sub modules {
my ($self) = @_;
# Bug/feature of sort in scalar context requires this.
- return wantarray ? sort keys %$self : keys %$self;
+ return wantarray
+ ? sort grep { not /^:private:$/ } keys %$self
+ : grep { not /^:private:$/ } keys %$self;
}
sub files {
@@ -186,7 +236,7 @@ sub files {
my (@files);
foreach my $file (keys(%{$self->{$module}{packlist}})) {
push(@files, $file)
- if ($self->_is_type($file, $type) &&
+ if ($self->_is_type($file, $type) &&
$self->_is_under($file, @under));
}
return(@files);
@@ -268,7 +318,8 @@ information from the .packlist files.
The new() function searches for all the installed .packlists on the system, and
stores their contents. The .packlists can be queried with the functions
-described below.
+described below. Where it searches by default is determined by the settings found
+in C<%Config::Config>, and what the value is of the PERL5LIB environment variable.
=head1 FUNCTIONS
@@ -276,8 +327,35 @@ described below.
=item new()
-This takes no parameters, and searches for all the installed .packlists on the
-system. The packlists are read using the ExtUtils::packlist module.
+This takes optional named parameters. Without parameters, this
+searches for all the installed .packlists on the system using
+information from C<%Config::Config> and the default module search
+paths C<@INC>. The packlists are read using the
+L<ExtUtils::Packlist> module.
+
+If the named parameter C<config_override> is specified,
+it should be a reference to a hash which contains all information
+usually found in C<%Config::Config>. For example, you can obtain
+the configuration information for a separate perl installation and
+pass that in.
+
+ my $yoda_cfg = get_fake_config('yoda');
+ my $yoda_inst = ExtUtils::Installed->new(config_override=>$yoda_cfg);
+
+Similarly, the parameter C<inc_override> may be a reference to an
+array which is used in place of the default module search paths
+from C<@INC>.
+
+ use Config;
+ my @dirs = split(/\Q$Config{path_sep}\E/, $ENV{PERL5LIB});
+ my $p5libs = ExtUtils::Installed->new(inc_override=>\@dirs);
+
+The parameter c<extra_libs> can be used to specify B<additional> paths to
+search for installed modules. For instance
+
+ my $installed = ExtUtils::Installed->new(extra_libs=>["/my/lib/path"]);
+
+This should only be necessary if C</my/lib/path> is not in PERL5LIB.
=item modules()
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Liblist/Kid.pm b/gnu/usr.bin/perl/lib/ExtUtils/Liblist/Kid.pm
index d67aa01963b..bef182b1bde 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/Liblist/Kid.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Liblist/Kid.pm
@@ -10,7 +10,7 @@ use 5.00503;
use strict;
use vars qw($VERSION);
-$VERSION = 1.30;
+$VERSION = 6.42;
use Config;
use Cwd 'cwd';
@@ -376,9 +376,7 @@ sub _vms_ext {
$verbose ||= 0;
my(@crtls,$crtlstr);
- my($dbgqual) = $self->{OPTIMIZE} || $Config{'optimize'} ||
- $self->{CCFLAGS} || $Config{'ccflags'};
- @crtls = ( ($dbgqual =~ m-/Debug-i ? $Config{'dbgprefix'} : '')
+ @crtls = ( ($Config{'ldflags'} =~ m-/Debug-i ? $Config{'dbgprefix'} : '')
. 'PerlShr/Share' );
push(@crtls, grep { not /\(/ } split /\s+/, $Config{'perllibs'});
push(@crtls, grep { not /\(/ } split /\s+/, $Config{'libc'});
@@ -390,7 +388,7 @@ sub _vms_ext {
if ($self->{PERL_SRC}) {
my($lib,$locspec,$type);
foreach $lib (@crtls) {
- if (($locspec,$type) = $lib =~ m-^([\w$\-]+)(/\w+)?- and $locspec =~ /perl/i) {
+ if (($locspec,$type) = $lib =~ m{^([\w\$-]+)(/\w+)?} and $locspec =~ /perl/i) {
if (lc $type eq '/share') { $locspec .= $Config{'exe_ext'}; }
elsif (lc $type eq '/library') { $locspec .= $Config{'lib_ext'}; }
else { $locspec .= $Config{'obj_ext'}; }
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM.pm
index 8aaa55f15f2..546b76dbcc1 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM.pm
@@ -3,7 +3,7 @@ package ExtUtils::MM;
use strict;
use ExtUtils::MakeMaker::Config;
use vars qw(@ISA $VERSION);
-$VERSION = '0.05';
+$VERSION = '6.42';
require ExtUtils::Liblist;
require ExtUtils::MakeMaker;
@@ -43,12 +43,19 @@ away.
sub DESTROY {}
}
+sub _is_win95 {
+ # miniperl might not have the Win32 functions available and we need
+ # to run in miniperl.
+ return defined &Win32::IsWin95 ? Win32::IsWin95()
+ : ! defined $ENV{SYSTEMROOT};
+}
+
my %Is = ();
$Is{VMS} = $^O eq 'VMS';
$Is{OS2} = $^O eq 'os2';
$Is{MacOS} = $^O eq 'MacOS';
if( $^O eq 'MSWin32' ) {
- Win32::IsWin95() ? $Is{Win95} = 1 : $Is{Win32} = 1;
+ _is_win95() ? $Is{Win95} = 1 : $Is{Win32} = 1;
}
$Is{UWIN} = $^O =~ /^uwin(-nt)?$/;
$Is{Cygwin} = $^O eq 'cygwin';
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_AIX.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_AIX.pm
index 7de7da557e0..f847303bae8 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_AIX.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_AIX.pm
@@ -2,7 +2,7 @@ package ExtUtils::MM_AIX;
use strict;
use vars qw($VERSION @ISA);
-$VERSION = '0.03';
+$VERSION = '6.42';
require ExtUtils::MM_Unix;
@ISA = qw(ExtUtils::MM_Unix);
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_BeOS.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_BeOS.pm
index 6d93ad4c7a6..d7812b3f91e 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_BeOS.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_BeOS.pm
@@ -1,5 +1,7 @@
package ExtUtils::MM_BeOS;
+use strict;
+
=head1 NAME
ExtUtils::MM_BeOS - methods to override UN*X behaviour in ExtUtils::MakeMaker
@@ -16,7 +18,7 @@ the semantics.
=over 4
-=cut
+=cut
use ExtUtils::MakeMaker::Config;
use File::Spec;
@@ -25,7 +27,7 @@ require ExtUtils::MM_Unix;
use vars qw(@ISA $VERSION);
@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
-$VERSION = '1.05';
+$VERSION = '6.42';
=item os_flavor
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_Cygwin.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_Cygwin.pm
index adb8d42047a..ca4d58d9ec6 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_Cygwin.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_Cygwin.pm
@@ -10,7 +10,7 @@ require ExtUtils::MM_Any;
require ExtUtils::MM_Unix;
@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
-$VERSION = '1.08';
+$VERSION = '6.42';
=head1 NAME
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_DOS.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_DOS.pm
index b985d00ca69..f47a72d1eff 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_DOS.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_DOS.pm
@@ -3,7 +3,7 @@ package ExtUtils::MM_DOS;
use strict;
use vars qw($VERSION @ISA);
-$VERSION = 0.02;
+$VERSION = 6.42;
require ExtUtils::MM_Any;
require ExtUtils::MM_Unix;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_MacOS.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_MacOS.pm
index de578f8be3f..32d5ffed5d1 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_MacOS.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_MacOS.pm
@@ -1,6 +1,9 @@
package ExtUtils::MM_MacOS;
-$VERSION = 1.08;
+use strict;
+
+use vars qw($VERSION);
+$VERSION = 6.42;
sub new {
die <<'UNSUPPORTED';
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_NW5.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_NW5.pm
index 6d9c492000f..222008a7fb8 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_NW5.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_NW5.pm
@@ -23,7 +23,7 @@ use ExtUtils::MakeMaker::Config;
use File::Basename;
use vars qw(@ISA $VERSION);
-$VERSION = '2.08';
+$VERSION = '6.42';
require ExtUtils::MM_Win32;
@ISA = qw(ExtUtils::MM_Win32);
@@ -34,7 +34,6 @@ $ENV{EMXSHELL} = 'sh'; # to run `commands`
my $BORLAND = $Config{'cc'} =~ /^bcc/i;
my $GCC = $Config{'cc'} =~ /^gcc/i;
-my $DMAKE = $Config{'make'} =~ /^dmake/i;
=item os_flavor
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_QNX.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_QNX.pm
index d975289eee9..98009bfc3ec 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_QNX.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_QNX.pm
@@ -2,7 +2,7 @@ package ExtUtils::MM_QNX;
use strict;
use vars qw($VERSION @ISA);
-$VERSION = '0.02';
+$VERSION = '6.42';
require ExtUtils::MM_Unix;
@ISA = qw(ExtUtils::MM_Unix);
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_UWIN.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_UWIN.pm
index 1667d552c8f..6be793010f0 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_UWIN.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_UWIN.pm
@@ -2,7 +2,7 @@ package ExtUtils::MM_UWIN;
use strict;
use vars qw($VERSION @ISA);
-$VERSION = 0.02;
+$VERSION = 6.42;
require ExtUtils::MM_Unix;
@ISA = qw(ExtUtils::MM_Unix);
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_VOS.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_VOS.pm
index 82f71ca2860..171a8b727eb 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_VOS.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_VOS.pm
@@ -2,7 +2,7 @@ package ExtUtils::MM_VOS;
use strict;
use vars qw($VERSION @ISA);
-$VERSION = '0.02';
+$VERSION = '6.42';
require ExtUtils::MM_Unix;
@ISA = qw(ExtUtils::MM_Unix);
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_Win95.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_Win95.pm
index d0e2cb2af32..7dbdee63324 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MM_Win95.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_Win95.pm
@@ -1,7 +1,9 @@
package ExtUtils::MM_Win95;
+use strict;
+
use vars qw($VERSION @ISA);
-$VERSION = '0.04';
+$VERSION = '6.42';
require ExtUtils::MM_Win32;
@ISA = qw(ExtUtils::MM_Win32);
@@ -22,7 +24,7 @@ ExtUtils::MM_Win95 - method to customize MakeMaker for Win9X
This is a subclass of ExtUtils::MM_Win32 containing changes necessary
to get MakeMaker playing nice with command.com and other Win9Xisms.
-=head2 Overriden methods
+=head2 Overridden methods
Most of these make up for limitations in the Win9x/nmake command shell.
Mostly its lack of &&.
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MY.pm b/gnu/usr.bin/perl/lib/ExtUtils/MY.pm
index 97ef42a15a3..d8de9aa7507 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MY.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MY.pm
@@ -4,7 +4,7 @@ use strict;
require ExtUtils::MM;
use vars qw(@ISA $VERSION);
-$VERSION = 0.01;
+$VERSION = 6.42;
@ISA = qw(ExtUtils::MM);
{
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/Config.pm b/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/Config.pm
index 52ae800f782..65f9d474750 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/Config.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/Config.pm
@@ -1,6 +1,6 @@
package ExtUtils::MakeMaker::Config;
-$VERSION = '0.02';
+$VERSION = '6.42';
use strict;
use Config ();
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/bytes.pm b/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/bytes.pm
index 5a2bf75f20e..41ae2077a8d 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/bytes.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/bytes.pm
@@ -1,7 +1,9 @@
package ExtUtils::MakeMaker::bytes;
+use strict;
+
use vars qw($VERSION);
-$VERSION = 0.01;
+$VERSION = 6.42;
my $Have_Bytes = eval q{require bytes; 1;};
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/vmsish.pm b/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/vmsish.pm
index 3380956e05c..f3d0ac8cf70 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/vmsish.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/MakeMaker/vmsish.pm
@@ -1,7 +1,9 @@
package ExtUtils::MakeMaker::vmsish;
+use strict;
+
use vars qw($VERSION);
-$VERSION = 0.01;
+$VERSION = 6.42;
my $IsVMS = $^O eq 'VMS';
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/PATCHING b/gnu/usr.bin/perl/lib/ExtUtils/PATCHING
index 30cb21f0449..eed536a9945 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/PATCHING
+++ b/gnu/usr.bin/perl/lib/ExtUtils/PATCHING
@@ -1,3 +1,8 @@
+"The easy way is always mined.
+ The important things are always simple.
+ The simple things are always hard."
+ -- Some of Murphy's Laws of Combat
+
This is a short set of guidelines for those patching
ExtUtils::MakeMaker. Its not an iron-clad set of rules, but just
things which make life easier when reading and integrating a patch.
@@ -101,7 +106,7 @@ Backwards Compatibility
- MakeMaker must be backwards compatible to 5.5.4 (5.005_04). Avoid any
obvious 5.6-isms (threads, warnings.pm, Unicode, our, v1.2.3, attributes
- open my $fh, lvalue subroutines, any new core modules, etc...).
+ open my $fh, lvalue subroutines, qr//, any new core modules, etc...).
- MakeMaker should avoid having module dependencies. Avoid using modules
which didn't come with 5.5.4 and avoid using features from newer
@@ -121,18 +126,26 @@ Cross-Platform Compatibility
and MMK to name the most common. Keep your make code as simple as
possible.
-- Avoid special variables (even $@).
+- Avoid special make variables (even $@).
- Format targets as "target : dependency", the spacing is important.
- Use $(NOECHO) instead of @.
+- Use - to tell make to ignore the exit code of a command. (Unfortunately,
+ some make variants don't honor an $(IGNORE) macro).
+
- Always put a space between $(NOECHO) and the command.
- Always put a space between - (ignore) and the command.
- Always put $(NOECHO) and - together, no space between them.
+ # Right
+ -$(NOECHO) command
+ $(NOECHO) command
+ - command
+
- Often when you patch ExtUtils::MM_Unix, similar patches must be done
to the other MM_* modules. If you can, please do this extra work
otherwise I have to. If you can't, that's ok. We can help.
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Packlist.pm b/gnu/usr.bin/perl/lib/ExtUtils/Packlist.pm
index 11ab637150b..04f267a0a3d 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/Packlist.pm
+++ b/gnu/usr.bin/perl/lib/ExtUtils/Packlist.pm
@@ -3,12 +3,22 @@ package ExtUtils::Packlist;
use 5.00503;
use strict;
use Carp qw();
-use vars qw($VERSION);
-$VERSION = '0.04';
+use Config;
+use vars qw($VERSION $Relocations);
+$VERSION = '1.43';
+$VERSION = eval $VERSION;
# Used for generating filehandle globs. IO::File might not be available!
my $fhname = "FH1";
+=begin _undocumented
+
+=item mkfh()
+
+Make a filehandle. Same kind of idea as Symbol::gensym().
+
+=cut
+
sub mkfh()
{
no strict;
@@ -17,6 +27,30 @@ use strict;
return($fh);
}
+=item __find_relocations
+
+Works out what absolute paths in the configuration have been located at run
+time relative to $^X, and generates a regexp that matches them
+
+=end _undocumented
+
+=cut
+
+sub __find_relocations
+{
+ my %paths;
+ while (my ($raw_key, $raw_val) = each %Config) {
+ my $exp_key = $raw_key . "exp";
+ next unless exists $Config{$exp_key};
+ next unless $raw_val =~ m!\.\.\./!;
+ $paths{$Config{$exp_key}}++;
+ }
+ # Longest prefixes go first in the alternatives
+ my $alternations = join "|", map {quotemeta $_}
+ sort {length $b <=> length $a} keys %paths;
+ qr/^($alternations)/o;
+}
+
sub new($$)
{
my ($class, $packfile) = @_;
@@ -90,28 +124,24 @@ my ($line);
while (defined($line = <$fh>))
{
chomp $line;
- my ($key, @kvs) = $line;
+ my ($key, $data) = $line;
if ($key =~ /^(.*?)( \w+=.*)$/)
{
$key = $1;
- @kvs = split(' ', $2);
- }
- $key =~ s!/\./!/!g; # Some .packlists have spurious '/./' bits in the paths
- if (! @kvs)
+ $data = { map { split('=', $_) } split(' ', $2)};
+
+ if ($Config{userelocatableinc} && $data->{relocate_as})
{
- $self->{data}->{$key} = undef;
+ require File::Spec;
+ require Cwd;
+ my ($vol, $dir) = File::Spec->splitpath($packfile);
+ my $newpath = File::Spec->catpath($vol, $dir, $data->{relocate_as});
+ $key = Cwd::realpath($newpath);
}
- else
- {
- my ($data) = {};
- foreach my $kv (@kvs)
- {
- my ($k, $v) = split('=', $kv);
- $data->{$k} = $v;
}
+ $key =~ s!/\./!/!g; # Some .packlists have spurious '/./' bits in the paths
$self->{data}->{$key} = $data;
}
- }
close($fh);
}
@@ -126,10 +156,33 @@ my $fh = mkfh();
open($fh, ">$packfile") || Carp::croak("Can't open file $packfile: $!");
foreach my $key (sort(keys(%{$self->{data}})))
{
+ my $data = $self->{data}->{$key};
+ if ($Config{userelocatableinc}) {
+ $Relocations ||= __find_relocations();
+ if ($packfile =~ $Relocations) {
+ # We are writing into a subdirectory of a run-time relocated
+ # path. Figure out if the this file is also within a subdir.
+ my $prefix = $1;
+ if (File::Spec->no_upwards(File::Spec->abs2rel($key, $prefix)))
+ {
+ # The relocated path is within the found prefix
+ my $packfile_prefix;
+ (undef, $packfile_prefix)
+ = File::Spec->splitpath($packfile);
+
+ my $relocate_as
+ = File::Spec->abs2rel($key, $packfile_prefix);
+
+ if (!ref $data) {
+ $data = {};
+ }
+ $data->{relocate_as} = $relocate_as;
+ }
+ }
+ }
print $fh ("$key");
- if (ref($self->{data}->{$key}))
+ if (ref($data))
{
- my $data = $self->{data}->{$key};
foreach my $k (sort(keys(%$data)))
{
print $fh (" $k=$data->{$k}");
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/ParseXS.pm b/gnu/usr.bin/perl/lib/ExtUtils/ParseXS.pm
new file mode 100644
index 00000000000..221d5a43b82
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/ParseXS.pm
@@ -0,0 +1,2052 @@
+package ExtUtils::ParseXS;
+
+use 5.006; # We use /??{}/ in regexes
+use Cwd;
+use Config;
+use File::Basename;
+use File::Spec;
+use Symbol;
+
+require Exporter;
+
+@ISA = qw(Exporter);
+@EXPORT_OK = qw(process_file);
+
+# use strict; # One of these days...
+
+my(@XSStack); # Stack of conditionals and INCLUDEs
+my($XSS_work_idx, $cpp_next_tmp);
+
+use vars qw($VERSION);
+$VERSION = '2.18_02';
+
+use vars qw(%input_expr %output_expr $ProtoUsed @InitFileCode $FH $proto_re $Overload $errors $Fallback
+ $cplusplus $hiertype $WantPrototypes $WantVersionChk $except $WantLineNumbers
+ $WantOptimize $process_inout $process_argtypes @tm
+ $dir $filename $filepathname %IncludedFiles
+ %type_kind %proto_letter
+ %targetable $BLOCK_re $lastline $lastline_no
+ $Package $Prefix @line @BootCode %args_match %defaults %var_types %arg_list @proto_arg
+ $processing_arg_with_types %argtype_seen @outlist %in_out %lengthof
+ $proto_in_this_xsub $scope_in_this_xsub $interface $prepush_done $interface_macro $interface_macro_set
+ $ProtoThisXSUB $ScopeThisXSUB $xsreturn
+ @line_no $ret_type $func_header $orig_args
+ ); # Add these just to get compilation to happen.
+
+
+sub process_file {
+
+ # Allow for $package->process_file(%hash) in the future
+ my ($pkg, %args) = @_ % 2 ? @_ : (__PACKAGE__, @_);
+
+ $ProtoUsed = exists $args{prototypes};
+
+ # Set defaults.
+ %args = (
+ # 'C++' => 0, # Doesn't seem to *do* anything...
+ hiertype => 0,
+ except => 0,
+ prototypes => 0,
+ versioncheck => 1,
+ linenumbers => 1,
+ optimize => 1,
+ prototypes => 0,
+ inout => 1,
+ argtypes => 1,
+ typemap => [],
+ output => \*STDOUT,
+ csuffix => '.c',
+ %args,
+ );
+
+ # Global Constants
+
+ my ($Is_VMS, $SymSet);
+ if ($^O eq 'VMS') {
+ $Is_VMS = 1;
+ # Establish set of global symbols with max length 28, since xsubpp
+ # will later add the 'XS_' prefix.
+ require ExtUtils::XSSymSet;
+ $SymSet = new ExtUtils::XSSymSet 28;
+ }
+ @XSStack = ({type => 'none'});
+ ($XSS_work_idx, $cpp_next_tmp) = (0, "XSubPPtmpAAAA");
+ @InitFileCode = ();
+ $FH = Symbol::gensym();
+ $proto_re = "[" . quotemeta('\$%&*@;[]') . "]" ;
+ $Overload = 0;
+ $errors = 0;
+ $Fallback = 'PL_sv_undef';
+
+ # Most of the 1500 lines below uses these globals. We'll have to
+ # clean this up sometime, probably. For now, we just pull them out
+ # of %args. -Ken
+
+ $cplusplus = $args{'C++'};
+ $hiertype = $args{hiertype};
+ $WantPrototypes = $args{prototypes};
+ $WantVersionChk = $args{versioncheck};
+ $except = $args{except} ? ' TRY' : '';
+ $WantLineNumbers = $args{linenumbers};
+ $WantOptimize = $args{optimize};
+ $process_inout = $args{inout};
+ $process_argtypes = $args{argtypes};
+ @tm = ref $args{typemap} ? @{$args{typemap}} : ($args{typemap});
+
+ for ($args{filename}) {
+ die "Missing required parameter 'filename'" unless $_;
+ $filepathname = $_;
+ ($dir, $filename) = (dirname($_), basename($_));
+ $filepathname =~ s/\\/\\\\/g;
+ $IncludedFiles{$_}++;
+ }
+
+ # Open the input file
+ open($FH, $args{filename}) or die "cannot open $args{filename}: $!\n";
+
+ # Open the output file if given as a string. If they provide some
+ # other kind of reference, trust them that we can print to it.
+ if (not ref $args{output}) {
+ open my($fh), "> $args{output}" or die "Can't create $args{output}: $!";
+ $args{outfile} = $args{output};
+ $args{output} = $fh;
+ }
+
+ # Really, we shouldn't have to chdir() or select() in the first
+ # place. For now, just save & restore.
+ my $orig_cwd = cwd();
+ my $orig_fh = select();
+
+ chdir($dir);
+ my $pwd = cwd();
+ my $csuffix = $args{csuffix};
+
+ if ($WantLineNumbers) {
+ my $cfile;
+ if ( $args{outfile} ) {
+ $cfile = $args{outfile};
+ } else {
+ $cfile = $args{filename};
+ $cfile =~ s/\.xs$/$csuffix/i or $cfile .= $csuffix;
+ }
+ tie(*PSEUDO_STDOUT, 'ExtUtils::ParseXS::CountLines', $cfile, $args{output});
+ select PSEUDO_STDOUT;
+ } else {
+ select $args{output};
+ }
+
+ foreach my $typemap (@tm) {
+ die "Can't find $typemap in $pwd\n" unless -r $typemap;
+ }
+
+ push @tm, standard_typemap_locations();
+
+ foreach my $typemap (@tm) {
+ next unless -f $typemap ;
+ # skip directories, binary files etc.
+ warn("Warning: ignoring non-text typemap file '$typemap'\n"), next
+ unless -T $typemap ;
+ open(TYPEMAP, $typemap)
+ or warn ("Warning: could not open typemap file '$typemap': $!\n"), next;
+ my $mode = 'Typemap';
+ my $junk = "" ;
+ my $current = \$junk;
+ while (<TYPEMAP>) {
+ next if /^\s* #/;
+ my $line_no = $. + 1;
+ if (/^INPUT\s*$/) {
+ $mode = 'Input'; $current = \$junk; next;
+ }
+ if (/^OUTPUT\s*$/) {
+ $mode = 'Output'; $current = \$junk; next;
+ }
+ if (/^TYPEMAP\s*$/) {
+ $mode = 'Typemap'; $current = \$junk; next;
+ }
+ if ($mode eq 'Typemap') {
+ chomp;
+ my $line = $_ ;
+ TrimWhitespace($_) ;
+ # skip blank lines and comment lines
+ next if /^$/ or /^#/ ;
+ my($type,$kind, $proto) = /^\s*(.*?\S)\s+(\S+)\s*($proto_re*)\s*$/ or
+ warn("Warning: File '$typemap' Line $. '$line' TYPEMAP entry needs 2 or 3 columns\n"), next;
+ $type = TidyType($type) ;
+ $type_kind{$type} = $kind ;
+ # prototype defaults to '$'
+ $proto = "\$" unless $proto ;
+ warn("Warning: File '$typemap' Line $. '$line' Invalid prototype '$proto'\n")
+ unless ValidProtoString($proto) ;
+ $proto_letter{$type} = C_string($proto) ;
+ } elsif (/^\s/) {
+ $$current .= $_;
+ } elsif ($mode eq 'Input') {
+ s/\s+$//;
+ $input_expr{$_} = '';
+ $current = \$input_expr{$_};
+ } else {
+ s/\s+$//;
+ $output_expr{$_} = '';
+ $current = \$output_expr{$_};
+ }
+ }
+ close(TYPEMAP);
+ }
+
+ foreach my $value (values %input_expr) {
+ $value =~ s/;*\s+\z//;
+ # Move C pre-processor instructions to column 1 to be strictly ANSI
+ # conformant. Some pre-processors are fussy about this.
+ $value =~ s/^\s+#/#/mg;
+ }
+ foreach my $value (values %output_expr) {
+ # And again.
+ $value =~ s/^\s+#/#/mg;
+ }
+
+ my ($cast, $size);
+ our $bal = qr[(?:(?>[^()]+)|\((??{ $bal })\))*]; # ()-balanced
+ $cast = qr[(?:\(\s*SV\s*\*\s*\)\s*)?]; # Optional (SV*) cast
+ $size = qr[,\s* (??{ $bal }) ]x; # Third arg (to setpvn)
+
+ foreach my $key (keys %output_expr) {
+ BEGIN { $^H |= 0x00200000 }; # Equivalent to: use re 'eval', but hardcoded so we can compile re.xs
+
+ my ($t, $with_size, $arg, $sarg) =
+ ($output_expr{$key} =~
+ m[^ \s+ sv_set ( [iunp] ) v (n)? # Type, is_setpvn
+ \s* \( \s* $cast \$arg \s* ,
+ \s* ( (??{ $bal }) ) # Set from
+ ( (??{ $size }) )? # Possible sizeof set-from
+ \) \s* ; \s* $
+ ]x);
+ $targetable{$key} = [$t, $with_size, $arg, $sarg] if $t;
+ }
+
+ my $END = "!End!\n\n"; # "impossible" keyword (multiple newline)
+
+ # Match an XS keyword
+ $BLOCK_re= '\s*(' . join('|', qw(
+ REQUIRE BOOT CASE PREINIT INPUT INIT CODE PPCODE OUTPUT
+ CLEANUP ALIAS ATTRS PROTOTYPES PROTOTYPE VERSIONCHECK INCLUDE
+ SCOPE INTERFACE INTERFACE_MACRO C_ARGS POSTCALL OVERLOAD FALLBACK
+ )) . "|$END)\\s*:";
+
+
+ our ($C_group_rex, $C_arg);
+ # Group in C (no support for comments or literals)
+ $C_group_rex = qr/ [({\[]
+ (?: (?> [^()\[\]{}]+ ) | (??{ $C_group_rex }) )*
+ [)}\]] /x ;
+ # Chunk in C without comma at toplevel (no comments):
+ $C_arg = qr/ (?: (?> [^()\[\]{},"']+ )
+ | (??{ $C_group_rex })
+ | " (?: (?> [^\\"]+ )
+ | \\.
+ )* " # String literal
+ | ' (?: (?> [^\\']+ ) | \\. )* ' # Char literal
+ )* /xs;
+
+ # Identify the version of xsubpp used
+ print <<EOM ;
+/*
+ * This file was generated automatically by ExtUtils::ParseXS version $VERSION from the
+ * contents of $filename. Do not edit this file, edit $filename instead.
+ *
+ * ANY CHANGES MADE HERE WILL BE LOST!
+ *
+ */
+
+EOM
+
+
+ print("#line 1 \"$filepathname\"\n")
+ if $WantLineNumbers;
+
+ firstmodule:
+ while (<$FH>) {
+ if (/^=/) {
+ my $podstartline = $.;
+ do {
+ if (/^=cut\s*$/) {
+ # We can't just write out a /* */ comment, as our embedded
+ # POD might itself be in a comment. We can't put a /**/
+ # comment inside #if 0, as the C standard says that the source
+ # file is decomposed into preprocessing characters in the stage
+ # before preprocessing commands are executed.
+ # I don't want to leave the text as barewords, because the spec
+ # isn't clear whether macros are expanded before or after
+ # preprocessing commands are executed, and someone pathological
+ # may just have defined one of the 3 words as a macro that does
+ # something strange. Multiline strings are illegal in C, so
+ # the "" we write must be a string literal. And they aren't
+ # concatenated until 2 steps later, so we are safe.
+ # - Nicholas Clark
+ print("#if 0\n \"Skipped embedded POD.\"\n#endif\n");
+ printf("#line %d \"$filepathname\"\n", $. + 1)
+ if $WantLineNumbers;
+ next firstmodule
+ }
+
+ } while (<$FH>);
+ # At this point $. is at end of file so die won't state the start
+ # of the problem, and as we haven't yet read any lines &death won't
+ # show the correct line in the message either.
+ die ("Error: Unterminated pod in $filename, line $podstartline\n")
+ unless $lastline;
+ }
+ last if ($Package, $Prefix) =
+ /^MODULE\s*=\s*[\w:]+(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/;
+
+ print $_;
+ }
+ unless (defined $_) {
+ warn "Didn't find a 'MODULE ... PACKAGE ... PREFIX' line\n";
+ exit 0; # Not a fatal error for the caller process
+ }
+
+ print <<"EOF";
+#ifndef PERL_UNUSED_VAR
+# define PERL_UNUSED_VAR(var) if (0) var = var
+#endif
+
+EOF
+
+ print 'ExtUtils::ParseXS::CountLines'->end_marker, "\n" if $WantLineNumbers;
+
+ $lastline = $_;
+ $lastline_no = $.;
+
+ PARAGRAPH:
+ while (fetch_para()) {
+ # Print initial preprocessor statements and blank lines
+ while (@line && $line[0] !~ /^[^\#]/) {
+ my $line = shift(@line);
+ print $line, "\n";
+ next unless $line =~ /^\#\s*((if)(?:n?def)?|elsif|else|endif)\b/;
+ my $statement = $+;
+ if ($statement eq 'if') {
+ $XSS_work_idx = @XSStack;
+ push(@XSStack, {type => 'if'});
+ } else {
+ death ("Error: `$statement' with no matching `if'")
+ if $XSStack[-1]{type} ne 'if';
+ if ($XSStack[-1]{varname}) {
+ push(@InitFileCode, "#endif\n");
+ push(@BootCode, "#endif");
+ }
+
+ my(@fns) = keys %{$XSStack[-1]{functions}};
+ if ($statement ne 'endif') {
+ # Hide the functions defined in other #if branches, and reset.
+ @{$XSStack[-1]{other_functions}}{@fns} = (1) x @fns;
+ @{$XSStack[-1]}{qw(varname functions)} = ('', {});
+ } else {
+ my($tmp) = pop(@XSStack);
+ 0 while (--$XSS_work_idx
+ && $XSStack[$XSS_work_idx]{type} ne 'if');
+ # Keep all new defined functions
+ push(@fns, keys %{$tmp->{other_functions}});
+ @{$XSStack[$XSS_work_idx]{functions}}{@fns} = (1) x @fns;
+ }
+ }
+ }
+
+ next PARAGRAPH unless @line;
+
+ if ($XSS_work_idx && !$XSStack[$XSS_work_idx]{varname}) {
+ # We are inside an #if, but have not yet #defined its xsubpp variable.
+ print "#define $cpp_next_tmp 1\n\n";
+ push(@InitFileCode, "#if $cpp_next_tmp\n");
+ push(@BootCode, "#if $cpp_next_tmp");
+ $XSStack[$XSS_work_idx]{varname} = $cpp_next_tmp++;
+ }
+
+ death ("Code is not inside a function"
+ ." (maybe last function was ended by a blank line "
+ ." followed by a statement on column one?)")
+ if $line[0] =~ /^\s/;
+
+ my ($class, $externC, $static, $ellipsis, $wantRETVAL, $RETVAL_no_return);
+ my (@fake_INPUT_pre); # For length(s) generated variables
+ my (@fake_INPUT);
+
+ # initialize info arrays
+ undef(%args_match);
+ undef(%var_types);
+ undef(%defaults);
+ undef(%arg_list) ;
+ undef(@proto_arg) ;
+ undef($processing_arg_with_types) ;
+ undef(%argtype_seen) ;
+ undef(@outlist) ;
+ undef(%in_out) ;
+ undef(%lengthof) ;
+ undef($proto_in_this_xsub) ;
+ undef($scope_in_this_xsub) ;
+ undef($interface);
+ undef($prepush_done);
+ $interface_macro = 'XSINTERFACE_FUNC' ;
+ $interface_macro_set = 'XSINTERFACE_FUNC_SET' ;
+ $ProtoThisXSUB = $WantPrototypes ;
+ $ScopeThisXSUB = 0;
+ $xsreturn = 0;
+
+ $_ = shift(@line);
+ while (my $kwd = check_keyword("REQUIRE|PROTOTYPES|FALLBACK|VERSIONCHECK|INCLUDE")) {
+ &{"${kwd}_handler"}() ;
+ next PARAGRAPH unless @line ;
+ $_ = shift(@line);
+ }
+
+ if (check_keyword("BOOT")) {
+ &check_cpp;
+ push (@BootCode, "#line $line_no[@line_no - @line] \"$filepathname\"")
+ if $WantLineNumbers && $line[0] !~ /^\s*#\s*line\b/;
+ push (@BootCode, @line, "") ;
+ next PARAGRAPH ;
+ }
+
+
+ # extract return type, function name and arguments
+ ($ret_type) = TidyType($_);
+ $RETVAL_no_return = 1 if $ret_type =~ s/^NO_OUTPUT\s+//;
+
+ # Allow one-line ANSI-like declaration
+ unshift @line, $2
+ if $process_argtypes
+ and $ret_type =~ s/^(.*?\w.*?)\s*\b(\w+\s*\(.*)/$1/s;
+
+ # a function definition needs at least 2 lines
+ blurt ("Error: Function definition too short '$ret_type'"), next PARAGRAPH
+ unless @line ;
+
+ $externC = 1 if $ret_type =~ s/^extern "C"\s+//;
+ $static = 1 if $ret_type =~ s/^static\s+//;
+
+ $func_header = shift(@line);
+ blurt ("Error: Cannot parse function definition from '$func_header'"), next PARAGRAPH
+ unless $func_header =~ /^(?:([\w:]*)::)?(\w+)\s*\(\s*(.*?)\s*\)\s*(const)?\s*(;\s*)?$/s;
+
+ ($class, $func_name, $orig_args) = ($1, $2, $3) ;
+ $class = "$4 $class" if $4;
+ ($pname = $func_name) =~ s/^($Prefix)?/$Packprefix/;
+ ($clean_func_name = $func_name) =~ s/^$Prefix//;
+ $Full_func_name = "${Packid}_$clean_func_name";
+ if ($Is_VMS) {
+ $Full_func_name = $SymSet->addsym($Full_func_name);
+ }
+
+ # Check for duplicate function definition
+ for my $tmp (@XSStack) {
+ next unless defined $tmp->{functions}{$Full_func_name};
+ Warn("Warning: duplicate function definition '$clean_func_name' detected");
+ last;
+ }
+ $XSStack[$XSS_work_idx]{functions}{$Full_func_name} ++ ;
+ %XsubAliases = %XsubAliasValues = %Interfaces = @Attributes = ();
+ $DoSetMagic = 1;
+
+ $orig_args =~ s/\\\s*/ /g; # process line continuations
+ my @args;
+
+ my %only_C_inlist; # Not in the signature of Perl function
+ if ($process_argtypes and $orig_args =~ /\S/) {
+ my $args = "$orig_args ,";
+ if ($args =~ /^( (??{ $C_arg }) , )* $ /x) {
+ @args = ($args =~ /\G ( (??{ $C_arg }) ) , /xg);
+ for ( @args ) {
+ s/^\s+//;
+ s/\s+$//;
+ my ($arg, $default) = / ( [^=]* ) ( (?: = .* )? ) /x;
+ my ($pre, $name) = ($arg =~ /(.*?) \s*
+ \b ( \w+ | length\( \s*\w+\s* \) )
+ \s* $ /x);
+ next unless defined($pre) && length($pre);
+ my $out_type = '';
+ my $inout_var;
+ if ($process_inout and s/^(IN|IN_OUTLIST|OUTLIST|OUT|IN_OUT)\s+//) {
+ my $type = $1;
+ $out_type = $type if $type ne 'IN';
+ $arg =~ s/^(IN|IN_OUTLIST|OUTLIST|OUT|IN_OUT)\s+//;
+ $pre =~ s/^(IN|IN_OUTLIST|OUTLIST|OUT|IN_OUT)\s+//;
+ }
+ my $islength;
+ if ($name =~ /^length\( \s* (\w+) \s* \)\z/x) {
+ $name = "XSauto_length_of_$1";
+ $islength = 1;
+ die "Default value on length() argument: `$_'"
+ if length $default;
+ }
+ if (length $pre or $islength) { # Has a type
+ if ($islength) {
+ push @fake_INPUT_pre, $arg;
+ } else {
+ push @fake_INPUT, $arg;
+ }
+ # warn "pushing '$arg'\n";
+ $argtype_seen{$name}++;
+ $_ = "$name$default"; # Assigns to @args
+ }
+ $only_C_inlist{$_} = 1 if $out_type eq "OUTLIST" or $islength;
+ push @outlist, $name if $out_type =~ /OUTLIST$/;
+ $in_out{$name} = $out_type if $out_type;
+ }
+ } else {
+ @args = split(/\s*,\s*/, $orig_args);
+ Warn("Warning: cannot parse argument list '$orig_args', fallback to split");
+ }
+ } else {
+ @args = split(/\s*,\s*/, $orig_args);
+ for (@args) {
+ if ($process_inout and s/^(IN|IN_OUTLIST|OUTLIST|IN_OUT|OUT)\s+//) {
+ my $out_type = $1;
+ next if $out_type eq 'IN';
+ $only_C_inlist{$_} = 1 if $out_type eq "OUTLIST";
+ push @outlist, $name if $out_type =~ /OUTLIST$/;
+ $in_out{$_} = $out_type;
+ }
+ }
+ }
+ if (defined($class)) {
+ my $arg0 = ((defined($static) or $func_name eq 'new')
+ ? "CLASS" : "THIS");
+ unshift(@args, $arg0);
+ ($report_args = "$arg0, $report_args") =~ s/^\w+, $/$arg0/;
+ }
+ my $extra_args = 0;
+ @args_num = ();
+ $num_args = 0;
+ my $report_args = '';
+ foreach my $i (0 .. $#args) {
+ if ($args[$i] =~ s/\.\.\.//) {
+ $ellipsis = 1;
+ if ($args[$i] eq '' && $i == $#args) {
+ $report_args .= ", ...";
+ pop(@args);
+ last;
+ }
+ }
+ if ($only_C_inlist{$args[$i]}) {
+ push @args_num, undef;
+ } else {
+ push @args_num, ++$num_args;
+ $report_args .= ", $args[$i]";
+ }
+ if ($args[$i] =~ /^([^=]*[^\s=])\s*=\s*(.*)/s) {
+ $extra_args++;
+ $args[$i] = $1;
+ $defaults{$args[$i]} = $2;
+ $defaults{$args[$i]} =~ s/"/\\"/g;
+ }
+ $proto_arg[$i+1] = '$' ;
+ }
+ $min_args = $num_args - $extra_args;
+ $report_args =~ s/"/\\"/g;
+ $report_args =~ s/^,\s+//;
+ my @func_args = @args;
+ shift @func_args if defined($class);
+
+ for (@func_args) {
+ s/^/&/ if $in_out{$_};
+ }
+ $func_args = join(", ", @func_args);
+ @args_match{@args} = @args_num;
+
+ $PPCODE = grep(/^\s*PPCODE\s*:/, @line);
+ $CODE = grep(/^\s*CODE\s*:/, @line);
+ # Detect CODE: blocks which use ST(n)= or XST_m*(n,v)
+ # to set explicit return values.
+ $EXPLICIT_RETURN = ($CODE &&
+ ("@line" =~ /(\bST\s*\([^;]*=) | (\bXST_m\w+\s*\()/x ));
+ $ALIAS = grep(/^\s*ALIAS\s*:/, @line);
+ $INTERFACE = grep(/^\s*INTERFACE\s*:/, @line);
+
+ $xsreturn = 1 if $EXPLICIT_RETURN;
+
+ $externC = $externC ? qq[extern "C"] : "";
+
+ # print function header
+ print Q(<<"EOF");
+#$externC
+#XS(XS_${Full_func_name}); /* prototype to pass -Wmissing-prototypes */
+#XS(XS_${Full_func_name})
+#[[
+##ifdef dVAR
+# dVAR; dXSARGS;
+##else
+# dXSARGS;
+##endif
+EOF
+ print Q(<<"EOF") if $ALIAS ;
+# dXSI32;
+EOF
+ print Q(<<"EOF") if $INTERFACE ;
+# dXSFUNCTION($ret_type);
+EOF
+ if ($ellipsis) {
+ $cond = ($min_args ? qq(items < $min_args) : 0);
+ } elsif ($min_args == $num_args) {
+ $cond = qq(items != $min_args);
+ } else {
+ $cond = qq(items < $min_args || items > $num_args);
+ }
+
+ print Q(<<"EOF") if $except;
+# char errbuf[1024];
+# *errbuf = '\0';
+EOF
+
+ if ($ALIAS)
+ { print Q(<<"EOF") if $cond }
+# if ($cond)
+# Perl_croak(aTHX_ "Usage: %s(%s)", GvNAME(CvGV(cv)), "$report_args");
+EOF
+ else
+ { print Q(<<"EOF") if $cond }
+# if ($cond)
+# Perl_croak(aTHX_ "Usage: %s(%s)", "$pname", "$report_args");
+EOF
+
+ # cv doesn't seem to be used, in most cases unless we go in
+ # the if of this else
+ print Q(<<"EOF");
+# PERL_UNUSED_VAR(cv); /* -W */
+EOF
+
+ #gcc -Wall: if an xsub has PPCODE is used
+ #it is possible none of ST, XSRETURN or XSprePUSH macros are used
+ #hence `ax' (setup by dXSARGS) is unused
+ #XXX: could breakup the dXSARGS; into dSP;dMARK;dITEMS
+ #but such a move could break third-party extensions
+ print Q(<<"EOF") if $PPCODE;
+# PERL_UNUSED_VAR(ax); /* -Wall */
+EOF
+
+ print Q(<<"EOF") if $PPCODE;
+# SP -= items;
+EOF
+
+ # Now do a block of some sort.
+
+ $condnum = 0;
+ $cond = ''; # last CASE: condidional
+ push(@line, "$END:");
+ push(@line_no, $line_no[-1]);
+ $_ = '';
+ &check_cpp;
+ while (@line) {
+ &CASE_handler if check_keyword("CASE");
+ print Q(<<"EOF");
+# $except [[
+EOF
+
+ # do initialization of input variables
+ $thisdone = 0;
+ $retvaldone = 0;
+ $deferred = "";
+ %arg_list = () ;
+ $gotRETVAL = 0;
+
+ INPUT_handler() ;
+ process_keyword("INPUT|PREINIT|INTERFACE_MACRO|C_ARGS|ALIAS|ATTRS|PROTOTYPE|SCOPE|OVERLOAD") ;
+
+ print Q(<<"EOF") if $ScopeThisXSUB;
+# ENTER;
+# [[
+EOF
+
+ if (!$thisdone && defined($class)) {
+ if (defined($static) or $func_name eq 'new') {
+ print "\tchar *";
+ $var_types{"CLASS"} = "char *";
+ &generate_init("char *", 1, "CLASS");
+ }
+ else {
+ print "\t$class *";
+ $var_types{"THIS"} = "$class *";
+ &generate_init("$class *", 1, "THIS");
+ }
+ }
+
+ # do code
+ if (/^\s*NOT_IMPLEMENTED_YET/) {
+ print "\n\tPerl_croak(aTHX_ \"$pname: not implemented yet\");\n";
+ $_ = '' ;
+ } else {
+ if ($ret_type ne "void") {
+ print "\t" . &map_type($ret_type, 'RETVAL') . ";\n"
+ if !$retvaldone;
+ $args_match{"RETVAL"} = 0;
+ $var_types{"RETVAL"} = $ret_type;
+ print "\tdXSTARG;\n"
+ if $WantOptimize and $targetable{$type_kind{$ret_type}};
+ }
+
+ if (@fake_INPUT or @fake_INPUT_pre) {
+ unshift @line, @fake_INPUT_pre, @fake_INPUT, $_;
+ $_ = "";
+ $processing_arg_with_types = 1;
+ INPUT_handler() ;
+ }
+ print $deferred;
+
+ process_keyword("INIT|ALIAS|ATTRS|PROTOTYPE|INTERFACE_MACRO|INTERFACE|C_ARGS|OVERLOAD") ;
+
+ if (check_keyword("PPCODE")) {
+ print_section();
+ death ("PPCODE must be last thing") if @line;
+ print "\tLEAVE;\n" if $ScopeThisXSUB;
+ print "\tPUTBACK;\n\treturn;\n";
+ } elsif (check_keyword("CODE")) {
+ print_section() ;
+ } elsif (defined($class) and $func_name eq "DESTROY") {
+ print "\n\t";
+ print "delete THIS;\n";
+ } else {
+ print "\n\t";
+ if ($ret_type ne "void") {
+ print "RETVAL = ";
+ $wantRETVAL = 1;
+ }
+ if (defined($static)) {
+ if ($func_name eq 'new') {
+ $func_name = "$class";
+ } else {
+ print "${class}::";
+ }
+ } elsif (defined($class)) {
+ if ($func_name eq 'new') {
+ $func_name .= " $class";
+ } else {
+ print "THIS->";
+ }
+ }
+ $func_name =~ s/^\Q$args{'s'}//
+ if exists $args{'s'};
+ $func_name = 'XSFUNCTION' if $interface;
+ print "$func_name($func_args);\n";
+ }
+ }
+
+ # do output variables
+ $gotRETVAL = 0; # 1 if RETVAL seen in OUTPUT section;
+ undef $RETVAL_code ; # code to set RETVAL (from OUTPUT section);
+ # $wantRETVAL set if 'RETVAL =' autogenerated
+ ($wantRETVAL, $ret_type) = (0, 'void') if $RETVAL_no_return;
+ undef %outargs ;
+ process_keyword("POSTCALL|OUTPUT|ALIAS|ATTRS|PROTOTYPE|OVERLOAD");
+
+ &generate_output($var_types{$_}, $args_match{$_}, $_, $DoSetMagic)
+ for grep $in_out{$_} =~ /OUT$/, keys %in_out;
+
+ # all OUTPUT done, so now push the return value on the stack
+ if ($gotRETVAL && $RETVAL_code) {
+ print "\t$RETVAL_code\n";
+ } elsif ($gotRETVAL || $wantRETVAL) {
+ my $t = $WantOptimize && $targetable{$type_kind{$ret_type}};
+ my $var = 'RETVAL';
+ my $type = $ret_type;
+
+ # 0: type, 1: with_size, 2: how, 3: how_size
+ if ($t and not $t->[1] and $t->[0] eq 'p') {
+ # PUSHp corresponds to setpvn. Treate setpv directly
+ my $what = eval qq("$t->[2]");
+ warn $@ if $@;
+
+ print "\tsv_setpv(TARG, $what); XSprePUSH; PUSHTARG;\n";
+ $prepush_done = 1;
+ }
+ elsif ($t) {
+ my $what = eval qq("$t->[2]");
+ warn $@ if $@;
+
+ my $size = $t->[3];
+ $size = '' unless defined $size;
+ $size = eval qq("$size");
+ warn $@ if $@;
+ print "\tXSprePUSH; PUSH$t->[0]($what$size);\n";
+ $prepush_done = 1;
+ }
+ else {
+ # RETVAL almost never needs SvSETMAGIC()
+ &generate_output($ret_type, 0, 'RETVAL', 0);
+ }
+ }
+
+ $xsreturn = 1 if $ret_type ne "void";
+ my $num = $xsreturn;
+ my $c = @outlist;
+ print "\tXSprePUSH;" if $c and not $prepush_done;
+ print "\tEXTEND(SP,$c);\n" if $c;
+ $xsreturn += $c;
+ generate_output($var_types{$_}, $num++, $_, 0, 1) for @outlist;
+
+ # do cleanup
+ process_keyword("CLEANUP|ALIAS|ATTRS|PROTOTYPE|OVERLOAD") ;
+
+ print Q(<<"EOF") if $ScopeThisXSUB;
+# ]]
+EOF
+ print Q(<<"EOF") if $ScopeThisXSUB and not $PPCODE;
+# LEAVE;
+EOF
+
+ # print function trailer
+ print Q(<<"EOF");
+# ]]
+EOF
+ print Q(<<"EOF") if $except;
+# BEGHANDLERS
+# CATCHALL
+# sprintf(errbuf, "%s: %s\\tpropagated", Xname, Xreason);
+# ENDHANDLERS
+EOF
+ if (check_keyword("CASE")) {
+ blurt ("Error: No `CASE:' at top of function")
+ unless $condnum;
+ $_ = "CASE: $_"; # Restore CASE: label
+ next;
+ }
+ last if $_ eq "$END:";
+ death(/^$BLOCK_re/o ? "Misplaced `$1:'" : "Junk at end of function");
+ }
+
+ print Q(<<"EOF") if $except;
+# if (errbuf[0])
+# Perl_croak(aTHX_ errbuf);
+EOF
+
+ if ($xsreturn) {
+ print Q(<<"EOF") unless $PPCODE;
+# XSRETURN($xsreturn);
+EOF
+ } else {
+ print Q(<<"EOF") unless $PPCODE;
+# XSRETURN_EMPTY;
+EOF
+ }
+
+ print Q(<<"EOF");
+#]]
+#
+EOF
+
+ my $newXS = "newXS" ;
+ my $proto = "" ;
+
+ # Build the prototype string for the xsub
+ if ($ProtoThisXSUB) {
+ $newXS = "newXSproto";
+
+ if ($ProtoThisXSUB eq 2) {
+ # User has specified empty prototype
+ }
+ elsif ($ProtoThisXSUB eq 1) {
+ my $s = ';';
+ if ($min_args < $num_args) {
+ $s = '';
+ $proto_arg[$min_args] .= ";" ;
+ }
+ push @proto_arg, "$s\@"
+ if $ellipsis ;
+
+ $proto = join ("", grep defined, @proto_arg);
+ }
+ else {
+ # User has specified a prototype
+ $proto = $ProtoThisXSUB;
+ }
+ $proto = qq{, "$proto"};
+ }
+
+ if (%XsubAliases) {
+ $XsubAliases{$pname} = 0
+ unless defined $XsubAliases{$pname} ;
+ while ( ($name, $value) = each %XsubAliases) {
+ push(@InitFileCode, Q(<<"EOF"));
+# cv = newXS(\"$name\", XS_$Full_func_name, file);
+# XSANY.any_i32 = $value ;
+EOF
+ push(@InitFileCode, Q(<<"EOF")) if $proto;
+# sv_setpv((SV*)cv$proto) ;
+EOF
+ }
+ }
+ elsif (@Attributes) {
+ push(@InitFileCode, Q(<<"EOF"));
+# cv = newXS(\"$pname\", XS_$Full_func_name, file);
+# apply_attrs_string("$Package", cv, "@Attributes", 0);
+EOF
+ }
+ elsif ($interface) {
+ while ( ($name, $value) = each %Interfaces) {
+ $name = "$Package\::$name" unless $name =~ /::/;
+ push(@InitFileCode, Q(<<"EOF"));
+# cv = newXS(\"$name\", XS_$Full_func_name, file);
+# $interface_macro_set(cv,$value) ;
+EOF
+ push(@InitFileCode, Q(<<"EOF")) if $proto;
+# sv_setpv((SV*)cv$proto) ;
+EOF
+ }
+ }
+ else {
+ push(@InitFileCode,
+ " ${newXS}(\"$pname\", XS_$Full_func_name, file$proto);\n");
+ }
+ }
+
+ if ($Overload) # make it findable with fetchmethod
+ {
+ print Q(<<"EOF");
+#XS(XS_${Packid}_nil); /* prototype to pass -Wmissing-prototypes */
+#XS(XS_${Packid}_nil)
+#{
+# XSRETURN_EMPTY;
+#}
+#
+EOF
+ unshift(@InitFileCode, <<"MAKE_FETCHMETHOD_WORK");
+ /* Making a sub named "${Package}::()" allows the package */
+ /* to be findable via fetchmethod(), and causes */
+ /* overload::Overloaded("${Package}") to return true. */
+ newXS("${Package}::()", XS_${Packid}_nil, file$proto);
+MAKE_FETCHMETHOD_WORK
+ }
+
+ # print initialization routine
+
+ print Q(<<"EOF");
+##ifdef __cplusplus
+#extern "C"
+##endif
+EOF
+
+ print Q(<<"EOF");
+#XS(boot_$Module_cname); /* prototype to pass -Wmissing-prototypes */
+#XS(boot_$Module_cname)
+EOF
+
+ print Q(<<"EOF");
+#[[
+##ifdef dVAR
+# dVAR; dXSARGS;
+##else
+# dXSARGS;
+##endif
+EOF
+
+ #-Wall: if there is no $Full_func_name there are no xsubs in this .xs
+ #so `file' is unused
+ print Q(<<"EOF") if $Full_func_name;
+# char* file = __FILE__;
+EOF
+
+ print Q("#\n");
+
+ print Q(<<"EOF");
+# PERL_UNUSED_VAR(cv); /* -W */
+# PERL_UNUSED_VAR(items); /* -W */
+EOF
+
+ print Q(<<"EOF") if $WantVersionChk ;
+# XS_VERSION_BOOTCHECK ;
+#
+EOF
+
+ print Q(<<"EOF") if defined $XsubAliases or defined $Interfaces ;
+# {
+# CV * cv ;
+#
+EOF
+
+ print Q(<<"EOF") if ($Overload);
+# /* register the overloading (type 'A') magic */
+# PL_amagic_generation++;
+# /* The magic for overload gets a GV* via gv_fetchmeth as */
+# /* mentioned above, and looks in the SV* slot of it for */
+# /* the "fallback" status. */
+# sv_setsv(
+# get_sv( "${Package}::()", TRUE ),
+# $Fallback
+# );
+EOF
+
+ print @InitFileCode;
+
+ print Q(<<"EOF") if defined $XsubAliases or defined $Interfaces ;
+# }
+EOF
+
+ if (@BootCode)
+ {
+ print "\n /* Initialisation Section */\n\n" ;
+ @line = @BootCode;
+ print_section();
+ print "\n /* End of Initialisation Section */\n\n" ;
+ }
+
+ if ($] >= 5.009) {
+ print <<'EOF';
+ if (PL_unitcheckav)
+ call_list(PL_scopestack_ix, PL_unitcheckav);
+EOF
+ }
+
+ print Q(<<"EOF");
+# XSRETURN_YES;
+#]]
+#
+EOF
+
+ warn("Please specify prototyping behavior for $filename (see perlxs manual)\n")
+ unless $ProtoUsed ;
+
+ chdir($orig_cwd);
+ select($orig_fh);
+ untie *PSEUDO_STDOUT if tied *PSEUDO_STDOUT;
+ close $FH;
+
+ return 1;
+}
+
+sub errors { $errors }
+
+sub standard_typemap_locations {
+ # Add all the default typemap locations to the search path
+ my @tm = qw(typemap);
+
+ my $updir = File::Spec->updir;
+ foreach my $dir (File::Spec->catdir(($updir) x 1), File::Spec->catdir(($updir) x 2),
+ File::Spec->catdir(($updir) x 3), File::Spec->catdir(($updir) x 4)) {
+
+ unshift @tm, File::Spec->catfile($dir, 'typemap');
+ unshift @tm, File::Spec->catfile($dir, lib => ExtUtils => 'typemap');
+ }
+ foreach my $dir (@INC) {
+ my $file = File::Spec->catfile($dir, ExtUtils => 'typemap');
+ unshift @tm, $file if -e $file;
+ }
+ return @tm;
+}
+
+sub TrimWhitespace
+{
+ $_[0] =~ s/^\s+|\s+$//go ;
+}
+
+sub TidyType
+ {
+ local ($_) = @_ ;
+
+ # rationalise any '*' by joining them into bunches and removing whitespace
+ s#\s*(\*+)\s*#$1#g;
+ s#(\*+)# $1 #g ;
+
+ # change multiple whitespace into a single space
+ s/\s+/ /g ;
+
+ # trim leading & trailing whitespace
+ TrimWhitespace($_) ;
+
+ $_ ;
+}
+
+# Input: ($_, @line) == unparsed input.
+# Output: ($_, @line) == (rest of line, following lines).
+# Return: the matched keyword if found, otherwise 0
+sub check_keyword {
+ $_ = shift(@line) while !/\S/ && @line;
+ s/^(\s*)($_[0])\s*:\s*(?:#.*)?/$1/s && $2;
+}
+
+sub print_section {
+ # the "do" is required for right semantics
+ do { $_ = shift(@line) } while !/\S/ && @line;
+
+ print("#line ", $line_no[@line_no - @line -1], " \"$filepathname\"\n")
+ if $WantLineNumbers && !/^\s*#\s*line\b/ && !/^#if XSubPPtmp/;
+ for (; defined($_) && !/^$BLOCK_re/o; $_ = shift(@line)) {
+ print "$_\n";
+ }
+ print 'ExtUtils::ParseXS::CountLines'->end_marker, "\n" if $WantLineNumbers;
+}
+
+sub merge_section {
+ my $in = '';
+
+ while (!/\S/ && @line) {
+ $_ = shift(@line);
+ }
+
+ for (; defined($_) && !/^$BLOCK_re/o; $_ = shift(@line)) {
+ $in .= "$_\n";
+ }
+ chomp $in;
+ return $in;
+ }
+
+sub process_keyword($)
+ {
+ my($pattern) = @_ ;
+ my $kwd ;
+
+ &{"${kwd}_handler"}()
+ while $kwd = check_keyword($pattern) ;
+ }
+
+sub CASE_handler {
+ blurt ("Error: `CASE:' after unconditional `CASE:'")
+ if $condnum && $cond eq '';
+ $cond = $_;
+ TrimWhitespace($cond);
+ print " ", ($condnum++ ? " else" : ""), ($cond ? " if ($cond)\n" : "\n");
+ $_ = '' ;
+}
+
+sub INPUT_handler {
+ for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
+ last if /^\s*NOT_IMPLEMENTED_YET/;
+ next unless /\S/; # skip blank lines
+
+ TrimWhitespace($_) ;
+ my $line = $_ ;
+
+ # remove trailing semicolon if no initialisation
+ s/\s*;$//g unless /[=;+].*\S/ ;
+
+ # Process the length(foo) declarations
+ if (s/^([^=]*)\blength\(\s*(\w+)\s*\)\s*$/$1 XSauto_length_of_$2=NO_INIT/x) {
+ print "\tSTRLEN\tSTRLEN_length_of_$2;\n";
+ $lengthof{$2} = $name;
+ # $islengthof{$name} = $1;
+ $deferred .= "\n\tXSauto_length_of_$2 = STRLEN_length_of_$2;";
+ }
+
+ # check for optional initialisation code
+ my $var_init = '' ;
+ $var_init = $1 if s/\s*([=;+].*)$//s ;
+ $var_init =~ s/"/\\"/g;
+
+ s/\s+/ /g;
+ my ($var_type, $var_addr, $var_name) = /^(.*?[^&\s])\s*(\&?)\s*\b(\w+)$/s
+ or blurt("Error: invalid argument declaration '$line'"), next;
+
+ # Check for duplicate definitions
+ blurt ("Error: duplicate definition of argument '$var_name' ignored"), next
+ if $arg_list{$var_name}++
+ or defined $argtype_seen{$var_name} and not $processing_arg_with_types;
+
+ $thisdone |= $var_name eq "THIS";
+ $retvaldone |= $var_name eq "RETVAL";
+ $var_types{$var_name} = $var_type;
+ # XXXX This check is a safeguard against the unfinished conversion of
+ # generate_init(). When generate_init() is fixed,
+ # one can use 2-args map_type() unconditionally.
+ if ($var_type =~ / \( \s* \* \s* \) /x) {
+ # Function pointers are not yet supported with &output_init!
+ print "\t" . &map_type($var_type, $var_name);
+ $name_printed = 1;
+ } else {
+ print "\t" . &map_type($var_type);
+ $name_printed = 0;
+ }
+ $var_num = $args_match{$var_name};
+
+ $proto_arg[$var_num] = ProtoString($var_type)
+ if $var_num ;
+ $func_args =~ s/\b($var_name)\b/&$1/ if $var_addr;
+ if ($var_init =~ /^[=;]\s*NO_INIT\s*;?\s*$/
+ or $in_out{$var_name} and $in_out{$var_name} =~ /^OUT/
+ and $var_init !~ /\S/) {
+ if ($name_printed) {
+ print ";\n";
+ } else {
+ print "\t$var_name;\n";
+ }
+ } elsif ($var_init =~ /\S/) {
+ &output_init($var_type, $var_num, $var_name, $var_init, $name_printed);
+ } elsif ($var_num) {
+ # generate initialization code
+ &generate_init($var_type, $var_num, $var_name, $name_printed);
+ } else {
+ print ";\n";
+ }
+ }
+}
+
+sub OUTPUT_handler {
+ for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
+ next unless /\S/;
+ if (/^\s*SETMAGIC\s*:\s*(ENABLE|DISABLE)\s*/) {
+ $DoSetMagic = ($1 eq "ENABLE" ? 1 : 0);
+ next;
+ }
+ my ($outarg, $outcode) = /^\s*(\S+)\s*(.*?)\s*$/s ;
+ blurt ("Error: duplicate OUTPUT argument '$outarg' ignored"), next
+ if $outargs{$outarg} ++ ;
+ if (!$gotRETVAL and $outarg eq 'RETVAL') {
+ # deal with RETVAL last
+ $RETVAL_code = $outcode ;
+ $gotRETVAL = 1 ;
+ next ;
+ }
+ blurt ("Error: OUTPUT $outarg not an argument"), next
+ unless defined($args_match{$outarg});
+ blurt("Error: No input definition for OUTPUT argument '$outarg' - ignored"), next
+ unless defined $var_types{$outarg} ;
+ $var_num = $args_match{$outarg};
+ if ($outcode) {
+ print "\t$outcode\n";
+ print "\tSvSETMAGIC(ST(" , $var_num-1 , "));\n" if $DoSetMagic;
+ } else {
+ &generate_output($var_types{$outarg}, $var_num, $outarg, $DoSetMagic);
+ }
+ delete $in_out{$outarg} # No need to auto-OUTPUT
+ if exists $in_out{$outarg} and $in_out{$outarg} =~ /OUT$/;
+ }
+}
+
+sub C_ARGS_handler() {
+ my $in = merge_section();
+
+ TrimWhitespace($in);
+ $func_args = $in;
+}
+
+sub INTERFACE_MACRO_handler() {
+ my $in = merge_section();
+
+ TrimWhitespace($in);
+ if ($in =~ /\s/) { # two
+ ($interface_macro, $interface_macro_set) = split ' ', $in;
+ } else {
+ $interface_macro = $in;
+ $interface_macro_set = 'UNKNOWN_CVT'; # catch later
+ }
+ $interface = 1; # local
+ $Interfaces = 1; # global
+}
+
+sub INTERFACE_handler() {
+ my $in = merge_section();
+
+ TrimWhitespace($in);
+
+ foreach (split /[\s,]+/, $in) {
+ my $name = $_;
+ $name =~ s/^$Prefix//;
+ $Interfaces{$name} = $_;
+ }
+ print Q(<<"EOF");
+# XSFUNCTION = $interface_macro($ret_type,cv,XSANY.any_dptr);
+EOF
+ $interface = 1; # local
+ $Interfaces = 1; # global
+}
+
+sub CLEANUP_handler() { print_section() }
+sub PREINIT_handler() { print_section() }
+sub POSTCALL_handler() { print_section() }
+sub INIT_handler() { print_section() }
+
+sub GetAliases
+ {
+ my ($line) = @_ ;
+ my ($orig) = $line ;
+ my ($alias) ;
+ my ($value) ;
+
+ # Parse alias definitions
+ # format is
+ # alias = value alias = value ...
+
+ while ($line =~ s/^\s*([\w:]+)\s*=\s*(\w+)\s*//) {
+ $alias = $1 ;
+ $orig_alias = $alias ;
+ $value = $2 ;
+
+ # check for optional package definition in the alias
+ $alias = $Packprefix . $alias if $alias !~ /::/ ;
+
+ # check for duplicate alias name & duplicate value
+ Warn("Warning: Ignoring duplicate alias '$orig_alias'")
+ if defined $XsubAliases{$alias} ;
+
+ Warn("Warning: Aliases '$orig_alias' and '$XsubAliasValues{$value}' have identical values")
+ if $XsubAliasValues{$value} ;
+
+ $XsubAliases = 1;
+ $XsubAliases{$alias} = $value ;
+ $XsubAliasValues{$value} = $orig_alias ;
+ }
+
+ blurt("Error: Cannot parse ALIAS definitions from '$orig'")
+ if $line ;
+ }
+
+sub ATTRS_handler ()
+ {
+ for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
+ next unless /\S/;
+ TrimWhitespace($_) ;
+ push @Attributes, $_;
+ }
+ }
+
+sub ALIAS_handler ()
+ {
+ for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
+ next unless /\S/;
+ TrimWhitespace($_) ;
+ GetAliases($_) if $_ ;
+ }
+ }
+
+sub OVERLOAD_handler()
+{
+ for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
+ next unless /\S/;
+ TrimWhitespace($_) ;
+ while ( s/^\s*([\w:"\\)\+\-\*\/\%\<\>\.\&\|\^\!\~\{\}\=]+)\s*//) {
+ $Overload = 1 unless $Overload;
+ my $overload = "$Package\::(".$1 ;
+ push(@InitFileCode,
+ " newXS(\"$overload\", XS_$Full_func_name, file$proto);\n");
+ }
+ }
+}
+
+sub FALLBACK_handler()
+{
+ # the rest of the current line should contain either TRUE,
+ # FALSE or UNDEF
+
+ TrimWhitespace($_) ;
+ my %map = (
+ TRUE => "PL_sv_yes", 1 => "PL_sv_yes",
+ FALSE => "PL_sv_no", 0 => "PL_sv_no",
+ UNDEF => "PL_sv_undef",
+ ) ;
+
+ # check for valid FALLBACK value
+ death ("Error: FALLBACK: TRUE/FALSE/UNDEF") unless exists $map{uc $_} ;
+
+ $Fallback = $map{uc $_} ;
+}
+
+
+sub REQUIRE_handler ()
+ {
+ # the rest of the current line should contain a version number
+ my ($Ver) = $_ ;
+
+ TrimWhitespace($Ver) ;
+
+ death ("Error: REQUIRE expects a version number")
+ unless $Ver ;
+
+ # check that the version number is of the form n.n
+ death ("Error: REQUIRE: expected a number, got '$Ver'")
+ unless $Ver =~ /^\d+(\.\d*)?/ ;
+
+ death ("Error: xsubpp $Ver (or better) required--this is only $VERSION.")
+ unless $VERSION >= $Ver ;
+ }
+
+sub VERSIONCHECK_handler ()
+ {
+ # the rest of the current line should contain either ENABLE or
+ # DISABLE
+
+ TrimWhitespace($_) ;
+
+ # check for ENABLE/DISABLE
+ death ("Error: VERSIONCHECK: ENABLE/DISABLE")
+ unless /^(ENABLE|DISABLE)/i ;
+
+ $WantVersionChk = 1 if $1 eq 'ENABLE' ;
+ $WantVersionChk = 0 if $1 eq 'DISABLE' ;
+
+ }
+
+sub PROTOTYPE_handler ()
+ {
+ my $specified ;
+
+ death("Error: Only 1 PROTOTYPE definition allowed per xsub")
+ if $proto_in_this_xsub ++ ;
+
+ for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
+ next unless /\S/;
+ $specified = 1 ;
+ TrimWhitespace($_) ;
+ if ($_ eq 'DISABLE') {
+ $ProtoThisXSUB = 0
+ } elsif ($_ eq 'ENABLE') {
+ $ProtoThisXSUB = 1
+ } else {
+ # remove any whitespace
+ s/\s+//g ;
+ death("Error: Invalid prototype '$_'")
+ unless ValidProtoString($_) ;
+ $ProtoThisXSUB = C_string($_) ;
+ }
+ }
+
+ # If no prototype specified, then assume empty prototype ""
+ $ProtoThisXSUB = 2 unless $specified ;
+
+ $ProtoUsed = 1 ;
+
+ }
+
+sub SCOPE_handler ()
+ {
+ death("Error: Only 1 SCOPE declaration allowed per xsub")
+ if $scope_in_this_xsub ++ ;
+
+ for (; !/^$BLOCK_re/o; $_ = shift(@line)) {
+ next unless /\S/;
+ TrimWhitespace($_) ;
+ if ($_ =~ /^DISABLE/i) {
+ $ScopeThisXSUB = 0
+ } elsif ($_ =~ /^ENABLE/i) {
+ $ScopeThisXSUB = 1
+ }
+ }
+
+ }
+
+sub PROTOTYPES_handler ()
+ {
+ # the rest of the current line should contain either ENABLE or
+ # DISABLE
+
+ TrimWhitespace($_) ;
+
+ # check for ENABLE/DISABLE
+ death ("Error: PROTOTYPES: ENABLE/DISABLE")
+ unless /^(ENABLE|DISABLE)/i ;
+
+ $WantPrototypes = 1 if $1 eq 'ENABLE' ;
+ $WantPrototypes = 0 if $1 eq 'DISABLE' ;
+ $ProtoUsed = 1 ;
+
+ }
+
+sub INCLUDE_handler ()
+ {
+ # the rest of the current line should contain a valid filename
+
+ TrimWhitespace($_) ;
+
+ death("INCLUDE: filename missing")
+ unless $_ ;
+
+ death("INCLUDE: output pipe is illegal")
+ if /^\s*\|/ ;
+
+ # simple minded recursion detector
+ death("INCLUDE loop detected")
+ if $IncludedFiles{$_} ;
+
+ ++ $IncludedFiles{$_} unless /\|\s*$/ ;
+
+ # Save the current file context.
+ push(@XSStack, {
+ type => 'file',
+ LastLine => $lastline,
+ LastLineNo => $lastline_no,
+ Line => \@line,
+ LineNo => \@line_no,
+ Filename => $filename,
+ Filepathname => $filepathname,
+ Handle => $FH,
+ }) ;
+
+ $FH = Symbol::gensym();
+
+ # open the new file
+ open ($FH, "$_") or death("Cannot open '$_': $!") ;
+
+ print Q(<<"EOF");
+#
+#/* INCLUDE: Including '$_' from '$filename' */
+#
+EOF
+
+ $filepathname = $filename = $_ ;
+
+ # Prime the pump by reading the first
+ # non-blank line
+
+ # skip leading blank lines
+ while (<$FH>) {
+ last unless /^\s*$/ ;
+ }
+
+ $lastline = $_ ;
+ $lastline_no = $. ;
+
+ }
+
+sub PopFile()
+ {
+ return 0 unless $XSStack[-1]{type} eq 'file' ;
+
+ my $data = pop @XSStack ;
+ my $ThisFile = $filename ;
+ my $isPipe = ($filename =~ /\|\s*$/) ;
+
+ -- $IncludedFiles{$filename}
+ unless $isPipe ;
+
+ close $FH ;
+
+ $FH = $data->{Handle} ;
+ # $filename is the leafname, which for some reason isused for diagnostic
+ # messages, whereas $filepathname is the full pathname, and is used for
+ # #line directives.
+ $filename = $data->{Filename} ;
+ $filepathname = $data->{Filepathname} ;
+ $lastline = $data->{LastLine} ;
+ $lastline_no = $data->{LastLineNo} ;
+ @line = @{ $data->{Line} } ;
+ @line_no = @{ $data->{LineNo} } ;
+
+ if ($isPipe and $? ) {
+ -- $lastline_no ;
+ print STDERR "Error reading from pipe '$ThisFile': $! in $filename, line $lastline_no\n" ;
+ exit 1 ;
+ }
+
+ print Q(<<"EOF");
+#
+#/* INCLUDE: Returning to '$filename' from '$ThisFile' */
+#
+EOF
+
+ return 1 ;
+ }
+
+sub ValidProtoString ($)
+ {
+ my($string) = @_ ;
+
+ if ( $string =~ /^$proto_re+$/ ) {
+ return $string ;
+ }
+
+ return 0 ;
+ }
+
+sub C_string ($)
+ {
+ my($string) = @_ ;
+
+ $string =~ s[\\][\\\\]g ;
+ $string ;
+ }
+
+sub ProtoString ($)
+ {
+ my ($type) = @_ ;
+
+ $proto_letter{$type} or "\$" ;
+ }
+
+sub check_cpp {
+ my @cpp = grep(/^\#\s*(?:if|e\w+)/, @line);
+ if (@cpp) {
+ my ($cpp, $cpplevel);
+ for $cpp (@cpp) {
+ if ($cpp =~ /^\#\s*if/) {
+ $cpplevel++;
+ } elsif (!$cpplevel) {
+ Warn("Warning: #else/elif/endif without #if in this function");
+ print STDERR " (precede it with a blank line if the matching #if is outside the function)\n"
+ if $XSStack[-1]{type} eq 'if';
+ return;
+ } elsif ($cpp =~ /^\#\s*endif/) {
+ $cpplevel--;
+ }
+ }
+ Warn("Warning: #if without #endif in this function") if $cpplevel;
+ }
+}
+
+
+sub Q {
+ my($text) = @_;
+ $text =~ s/^#//gm;
+ $text =~ s/\[\[/{/g;
+ $text =~ s/\]\]/}/g;
+ $text;
+}
+
+# Read next xsub into @line from ($lastline, <$FH>).
+sub fetch_para {
+ # parse paragraph
+ death ("Error: Unterminated `#if/#ifdef/#ifndef'")
+ if !defined $lastline && $XSStack[-1]{type} eq 'if';
+ @line = ();
+ @line_no = () ;
+ return PopFile() if !defined $lastline;
+
+ if ($lastline =~
+ /^MODULE\s*=\s*([\w:]+)(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/) {
+ $Module = $1;
+ $Package = defined($2) ? $2 : ''; # keep -w happy
+ $Prefix = defined($3) ? $3 : ''; # keep -w happy
+ $Prefix = quotemeta $Prefix ;
+ ($Module_cname = $Module) =~ s/\W/_/g;
+ ($Packid = $Package) =~ tr/:/_/;
+ $Packprefix = $Package;
+ $Packprefix .= "::" if $Packprefix ne "";
+ $lastline = "";
+ }
+
+ for (;;) {
+ # Skip embedded PODs
+ while ($lastline =~ /^=/) {
+ while ($lastline = <$FH>) {
+ last if ($lastline =~ /^=cut\s*$/);
+ }
+ death ("Error: Unterminated pod") unless $lastline;
+ $lastline = <$FH>;
+ chomp $lastline;
+ $lastline =~ s/^\s+$//;
+ }
+ if ($lastline !~ /^\s*#/ ||
+ # CPP directives:
+ # ANSI: if ifdef ifndef elif else endif define undef
+ # line error pragma
+ # gcc: warning include_next
+ # obj-c: import
+ # others: ident (gcc notes that some cpps have this one)
+ $lastline =~ /^#[ \t]*(?:(?:if|ifn?def|elif|else|endif|define|undef|pragma|error|warning|line\s+\d+|ident)\b|(?:include(?:_next)?|import)\s*["<].*[>"])/) {
+ last if $lastline =~ /^\S/ && @line && $line[-1] eq "";
+ push(@line, $lastline);
+ push(@line_no, $lastline_no) ;
+ }
+
+ # Read next line and continuation lines
+ last unless defined($lastline = <$FH>);
+ $lastline_no = $.;
+ my $tmp_line;
+ $lastline .= $tmp_line
+ while ($lastline =~ /\\$/ && defined($tmp_line = <$FH>));
+
+ chomp $lastline;
+ $lastline =~ s/^\s+$//;
+ }
+ pop(@line), pop(@line_no) while @line && $line[-1] eq "";
+ 1;
+}
+
+sub output_init {
+ local($type, $num, $var, $init, $name_printed) = @_;
+ local($arg) = "ST(" . ($num - 1) . ")";
+
+ if ( $init =~ /^=/ ) {
+ if ($name_printed) {
+ eval qq/print " $init\\n"/;
+ } else {
+ eval qq/print "\\t$var $init\\n"/;
+ }
+ warn $@ if $@;
+ } else {
+ if ( $init =~ s/^\+// && $num ) {
+ &generate_init($type, $num, $var, $name_printed);
+ } elsif ($name_printed) {
+ print ";\n";
+ $init =~ s/^;//;
+ } else {
+ eval qq/print "\\t$var;\\n"/;
+ warn $@ if $@;
+ $init =~ s/^;//;
+ }
+ $deferred .= eval qq/"\\n\\t$init\\n"/;
+ warn $@ if $@;
+ }
+}
+
+sub Warn
+ {
+ # work out the line number
+ my $line_no = $line_no[@line_no - @line -1] ;
+
+ print STDERR "@_ in $filename, line $line_no\n" ;
+ }
+
+sub blurt
+ {
+ Warn @_ ;
+ $errors ++
+ }
+
+sub death
+ {
+ Warn @_ ;
+ exit 1 ;
+ }
+
+sub generate_init {
+ local($type, $num, $var) = @_;
+ local($arg) = "ST(" . ($num - 1) . ")";
+ local($argoff) = $num - 1;
+ local($ntype);
+ local($tk);
+
+ $type = TidyType($type) ;
+ blurt("Error: '$type' not in typemap"), return
+ unless defined($type_kind{$type});
+
+ ($ntype = $type) =~ s/\s*\*/Ptr/g;
+ ($subtype = $ntype) =~ s/(?:Array)?(?:Ptr)?$//;
+ $tk = $type_kind{$type};
+ $tk =~ s/OBJ$/REF/ if $func_name =~ /DESTROY$/;
+ if ($tk eq 'T_PV' and exists $lengthof{$var}) {
+ print "\t$var" unless $name_printed;
+ print " = ($type)SvPV($arg, STRLEN_length_of_$var);\n";
+ die "default value not supported with length(NAME) supplied"
+ if defined $defaults{$var};
+ return;
+ }
+ $type =~ tr/:/_/ unless $hiertype;
+ blurt("Error: No INPUT definition for type '$type', typekind '$type_kind{$type}' found"), return
+ unless defined $input_expr{$tk} ;
+ $expr = $input_expr{$tk};
+ if ($expr =~ /DO_ARRAY_ELEM/) {
+ blurt("Error: '$subtype' not in typemap"), return
+ unless defined($type_kind{$subtype});
+ blurt("Error: No INPUT definition for type '$subtype', typekind '$type_kind{$subtype}' found"), return
+ unless defined $input_expr{$type_kind{$subtype}} ;
+ $subexpr = $input_expr{$type_kind{$subtype}};
+ $subexpr =~ s/\$type/\$subtype/g;
+ $subexpr =~ s/ntype/subtype/g;
+ $subexpr =~ s/\$arg/ST(ix_$var)/g;
+ $subexpr =~ s/\n\t/\n\t\t/g;
+ $subexpr =~ s/is not of (.*\")/[arg %d] is not of $1, ix_$var + 1/g;
+ $subexpr =~ s/\$var/${var}[ix_$var - $argoff]/;
+ $expr =~ s/DO_ARRAY_ELEM/$subexpr/;
+ }
+ if ($expr =~ m#/\*.*scope.*\*/#i) { # "scope" in C comments
+ $ScopeThisXSUB = 1;
+ }
+ if (defined($defaults{$var})) {
+ $expr =~ s/(\t+)/$1 /g;
+ $expr =~ s/ /\t/g;
+ if ($name_printed) {
+ print ";\n";
+ } else {
+ eval qq/print "\\t$var;\\n"/;
+ warn $@ if $@;
+ }
+ if ($defaults{$var} eq 'NO_INIT') {
+ $deferred .= eval qq/"\\n\\tif (items >= $num) {\\n$expr;\\n\\t}\\n"/;
+ } else {
+ $deferred .= eval qq/"\\n\\tif (items < $num)\\n\\t $var = $defaults{$var};\\n\\telse {\\n$expr;\\n\\t}\\n"/;
+ }
+ warn $@ if $@;
+ } elsif ($ScopeThisXSUB or $expr !~ /^\s*\$var =/) {
+ if ($name_printed) {
+ print ";\n";
+ } else {
+ eval qq/print "\\t$var;\\n"/;
+ warn $@ if $@;
+ }
+ $deferred .= eval qq/"\\n$expr;\\n"/;
+ warn $@ if $@;
+ } else {
+ die "panic: do not know how to handle this branch for function pointers"
+ if $name_printed;
+ eval qq/print "$expr;\\n"/;
+ warn $@ if $@;
+ }
+}
+
+sub generate_output {
+ local($type, $num, $var, $do_setmagic, $do_push) = @_;
+ local($arg) = "ST(" . ($num - ($num != 0)) . ")";
+ local($argoff) = $num - 1;
+ local($ntype);
+
+ $type = TidyType($type) ;
+ if ($type =~ /^array\(([^,]*),(.*)\)/) {
+ print "\t$arg = sv_newmortal();\n";
+ print "\tsv_setpvn($arg, (char *)$var, $2 * sizeof($1));\n";
+ print "\tSvSETMAGIC($arg);\n" if $do_setmagic;
+ } else {
+ blurt("Error: '$type' not in typemap"), return
+ unless defined($type_kind{$type});
+ blurt("Error: No OUTPUT definition for type '$type', typekind '$type_kind{$type}' found"), return
+ unless defined $output_expr{$type_kind{$type}} ;
+ ($ntype = $type) =~ s/\s*\*/Ptr/g;
+ $ntype =~ s/\(\)//g;
+ ($subtype = $ntype) =~ s/(?:Array)?(?:Ptr)?$//;
+ $expr = $output_expr{$type_kind{$type}};
+ if ($expr =~ /DO_ARRAY_ELEM/) {
+ blurt("Error: '$subtype' not in typemap"), return
+ unless defined($type_kind{$subtype});
+ blurt("Error: No OUTPUT definition for type '$subtype', typekind '$type_kind{$subtype}' found"), return
+ unless defined $output_expr{$type_kind{$subtype}} ;
+ $subexpr = $output_expr{$type_kind{$subtype}};
+ $subexpr =~ s/ntype/subtype/g;
+ $subexpr =~ s/\$arg/ST(ix_$var)/g;
+ $subexpr =~ s/\$var/${var}[ix_$var]/g;
+ $subexpr =~ s/\n\t/\n\t\t/g;
+ $expr =~ s/DO_ARRAY_ELEM\n/$subexpr/;
+ eval "print qq\a$expr\a";
+ warn $@ if $@;
+ print "\t\tSvSETMAGIC(ST(ix_$var));\n" if $do_setmagic;
+ } elsif ($var eq 'RETVAL') {
+ if ($expr =~ /^\t\$arg = new/) {
+ # We expect that $arg has refcnt 1, so we need to
+ # mortalize it.
+ eval "print qq\a$expr\a";
+ warn $@ if $@;
+ print "\tsv_2mortal(ST($num));\n";
+ print "\tSvSETMAGIC(ST($num));\n" if $do_setmagic;
+ } elsif ($expr =~ /^\s*\$arg\s*=/) {
+ # We expect that $arg has refcnt >=1, so we need
+ # to mortalize it!
+ eval "print qq\a$expr\a";
+ warn $@ if $@;
+ print "\tsv_2mortal(ST(0));\n";
+ print "\tSvSETMAGIC(ST(0));\n" if $do_setmagic;
+ } else {
+ # Just hope that the entry would safely write it
+ # over an already mortalized value. By
+ # coincidence, something like $arg = &sv_undef
+ # works too.
+ print "\tST(0) = sv_newmortal();\n";
+ eval "print qq\a$expr\a";
+ warn $@ if $@;
+ # new mortals don't have set magic
+ }
+ } elsif ($do_push) {
+ print "\tPUSHs(sv_newmortal());\n";
+ $arg = "ST($num)";
+ eval "print qq\a$expr\a";
+ warn $@ if $@;
+ print "\tSvSETMAGIC($arg);\n" if $do_setmagic;
+ } elsif ($arg =~ /^ST\(\d+\)$/) {
+ eval "print qq\a$expr\a";
+ warn $@ if $@;
+ print "\tSvSETMAGIC($arg);\n" if $do_setmagic;
+ }
+ }
+}
+
+sub map_type {
+ my($type, $varname) = @_;
+
+ # C++ has :: in types too so skip this
+ $type =~ tr/:/_/ unless $hiertype;
+ $type =~ s/^array\(([^,]*),(.*)\).*/$1 */s;
+ if ($varname) {
+ if ($varname && $type =~ / \( \s* \* (?= \s* \) ) /xg) {
+ (substr $type, pos $type, 0) = " $varname ";
+ } else {
+ $type .= "\t$varname";
+ }
+ }
+ $type;
+}
+
+
+#########################################################
+package
+ ExtUtils::ParseXS::CountLines;
+use strict;
+use vars qw($SECTION_END_MARKER);
+
+sub TIEHANDLE {
+ my ($class, $cfile, $fh) = @_;
+ $cfile =~ s/\\/\\\\/g;
+ $SECTION_END_MARKER = qq{#line --- "$cfile"};
+
+ return bless {buffer => '',
+ fh => $fh,
+ line_no => 1,
+ }, $class;
+}
+
+sub PRINT {
+ my $self = shift;
+ for (@_) {
+ $self->{buffer} .= $_;
+ while ($self->{buffer} =~ s/^([^\n]*\n)//) {
+ my $line = $1;
+ ++ $self->{line_no};
+ $line =~ s|^\#line\s+---(?=\s)|#line $self->{line_no}|;
+ print {$self->{fh}} $line;
+ }
+ }
+}
+
+sub PRINTF {
+ my $self = shift;
+ my $fmt = shift;
+ $self->PRINT(sprintf($fmt, @_));
+}
+
+sub DESTROY {
+ # Not necessary if we're careful to end with a "\n"
+ my $self = shift;
+ print {$self->{fh}} $self->{buffer};
+}
+
+sub UNTIE {
+ # This sub does nothing, but is neccessary for references to be released.
+}
+
+sub end_marker {
+ return $SECTION_END_MARKER;
+}
+
+
+1;
+__END__
+
+=head1 NAME
+
+ExtUtils::ParseXS - converts Perl XS code into C code
+
+=head1 SYNOPSIS
+
+ use ExtUtils::ParseXS qw(process_file);
+
+ process_file( filename => 'foo.xs' );
+
+ process_file( filename => 'foo.xs',
+ output => 'bar.c',
+ 'C++' => 1,
+ typemap => 'path/to/typemap',
+ hiertype => 1,
+ except => 1,
+ prototypes => 1,
+ versioncheck => 1,
+ linenumbers => 1,
+ optimize => 1,
+ prototypes => 1,
+ );
+=head1 DESCRIPTION
+
+C<ExtUtils::ParseXS> will compile XS code into C code by embedding the constructs
+necessary to let C functions manipulate Perl values and creates the glue
+necessary to let Perl access those functions. The compiler uses typemaps to
+determine how to map C function parameters and variables to Perl values.
+
+The compiler will search for typemap files called I<typemap>. It will use
+the following search path to find default typemaps, with the rightmost
+typemap taking precedence.
+
+ ../../../typemap:../../typemap:../typemap:typemap
+
+=head1 EXPORT
+
+None by default. C<process_file()> may be exported upon request.
+
+
+=head1 FUNCTIONS
+
+=over 4
+
+=item process_xs()
+
+This function processes an XS file and sends output to a C file.
+Named parameters control how the processing is done. The following
+parameters are accepted:
+
+=over 4
+
+=item B<C++>
+
+Adds C<extern "C"> to the C code. Default is false.
+
+=item B<hiertype>
+
+Retains C<::> in type names so that C++ hierachical types can be
+mapped. Default is false.
+
+=item B<except>
+
+Adds exception handling stubs to the C code. Default is false.
+
+=item B<typemap>
+
+Indicates that a user-supplied typemap should take precedence over the
+default typemaps. A single typemap may be specified as a string, or
+multiple typemaps can be specified in an array reference, with the
+last typemap having the highest precedence.
+
+=item B<prototypes>
+
+Generates prototype code for all xsubs. Default is false.
+
+=item B<versioncheck>
+
+Makes sure at run time that the object file (derived from the C<.xs>
+file) and the C<.pm> files have the same version number. Default is
+true.
+
+=item B<linenumbers>
+
+Adds C<#line> directives to the C output so error messages will look
+like they came from the original XS file. Default is true.
+
+=item B<optimize>
+
+Enables certain optimizations. The only optimization that is currently
+affected is the use of I<target>s by the output C code (see L<perlguts>).
+Not optimizing may significantly slow down the generated code, but this is the way
+B<xsubpp> of 5.005 and earlier operated. Default is to optimize.
+
+=item B<inout>
+
+Enable recognition of C<IN>, C<OUT_LIST> and C<INOUT_LIST>
+declarations. Default is true.
+
+=item B<argtypes>
+
+Enable recognition of ANSI-like descriptions of function signature.
+Default is true.
+
+=item B<s>
+
+I have no clue what this does. Strips function prefixes?
+
+=back
+
+=item errors()
+
+This function returns the number of [a certain kind of] errors
+encountered during processing of the XS file.
+
+=back
+
+=head1 AUTHOR
+
+Based on xsubpp code, written by Larry Wall.
+
+Maintained by Ken Williams, <ken@mathforum.org>
+
+=head1 COPYRIGHT
+
+Copyright 2002-2003 Ken Williams. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+Based on the ExtUtils::xsubpp code by Larry Wall and the Perl 5
+Porters, which was released under the same license terms.
+
+=head1 SEE ALSO
+
+L<perl>, ExtUtils::xsubpp, ExtUtils::MakeMaker, L<perlxs>, L<perlxstut>.
+
+=cut
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/XSTest.pm b/gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/XSTest.pm
new file mode 100644
index 00000000000..988ef472e84
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/XSTest.pm
@@ -0,0 +1,8 @@
+package XSTest;
+
+require DynaLoader;
+@ISA = qw(Exporter DynaLoader);
+$VERSION = '0.01';
+bootstrap XSTest $VERSION;
+
+1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/XSTest.xs b/gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/XSTest.xs
new file mode 100644
index 00000000000..699c7341aa6
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/XSTest.xs
@@ -0,0 +1,67 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+void
+xstest_something (char * some_thing)
+{
+ some_thing = some_thing;
+}
+
+void
+xstest_something2 (char * some_thing)
+{
+ some_thing = some_thing;
+}
+
+
+MODULE = XSTest PACKAGE = XSTest PREFIX = xstest_
+
+PROTOTYPES: DISABLE
+
+int
+is_even(input)
+ int input
+ CODE:
+ RETVAL = (input % 2 == 0);
+ OUTPUT:
+ RETVAL
+
+void
+xstest_something (myclass, some_thing)
+ char * some_thing
+ C_ARGS:
+ some_thing
+
+void
+xstest_something2 (some_thing)
+ char * some_thing
+
+void
+xstest_something3 (myclass, some_thing)
+ SV * myclass
+ char * some_thing
+ PREINIT:
+ int i = 0;
+ PPCODE:
+ /* it's up to us clear these warnings */
+ myclass = myclass;
+ some_thing = some_thing;
+ i = i;
+ XSRETURN_UNDEF;
+
+int
+consts (myclass)
+ SV * myclass
+ ALIAS:
+ const_one = 1
+ const_two = 2
+ const_three = 3
+ CODE:
+ /* it's up to us clear these warnings */
+ myclass = myclass;
+ ix = ix;
+ RETVAL = 1;
+ OUTPUT:
+ RETVAL
+
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/basic.t b/gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/basic.t
new file mode 100644
index 00000000000..9b5319e56a5
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/ParseXS/t/basic.t
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+
+BEGIN {
+ if ($ENV{PERL_CORE}) {
+ chdir 't' if -d 't';
+ chdir '../lib/ExtUtils/ParseXS'
+ or die "Can't chdir to lib/ExtUtils/ParseXS: $!";
+ @INC = qw(../.. ../../.. .);
+ }
+}
+use strict;
+use Test;
+BEGIN { plan tests => 10 };
+use DynaLoader;
+use ExtUtils::ParseXS qw(process_file);
+use ExtUtils::CBuilder;
+ok(1); # If we made it this far, we're loaded.
+
+chdir 't' or die "Can't chdir to t/, $!";
+
+use Carp; $SIG{__WARN__} = \&Carp::cluck;
+
+#########################
+
+# Try sending to filehandle
+tie *FH, 'Foo';
+process_file( filename => 'XSTest.xs', output => \*FH, prototypes => 1 );
+ok tied(*FH)->content, '/is_even/', "Test that output contains some text";
+
+my $source_file = 'XSTest.c';
+
+# Try sending to file
+process_file(filename => 'XSTest.xs', output => $source_file, prototypes => 0);
+ok -e $source_file, 1, "Create an output file";
+
+# TEST doesn't like extraneous output
+my $quiet = $ENV{PERL_CORE} && !$ENV{HARNESS_ACTIVE};
+
+# Try to compile the file! Don't get too fancy, though.
+my $b = ExtUtils::CBuilder->new(quiet => $quiet);
+if ($b->have_compiler) {
+ my $module = 'XSTest';
+
+ my $obj_file = $b->compile( source => $source_file );
+ ok $obj_file;
+ ok -e $obj_file, 1, "Make sure $obj_file exists";
+
+ my $lib_file = $b->link( objects => $obj_file, module_name => $module );
+ ok $lib_file;
+ ok -e $lib_file, 1, "Make sure $lib_file exists";
+
+ eval {require XSTest};
+ ok $@, '';
+ ok XSTest::is_even(8);
+ ok !XSTest::is_even(9);
+
+ # Win32 needs to close the DLL before it can unlink it, but unfortunately
+ # dl_unload_file was missing on Win32 prior to perl change #24679!
+ if ($^O eq 'MSWin32' and defined &DynaLoader::dl_unload_file) {
+ for (my $i = 0; $i < @DynaLoader::dl_modules; $i++) {
+ if ($DynaLoader::dl_modules[$i] eq $module) {
+ DynaLoader::dl_unload_file($DynaLoader::dl_librefs[$i]);
+ last;
+ }
+ }
+ }
+ 1 while unlink $obj_file;
+ 1 while unlink $lib_file;
+} else {
+ skip "Skipped can't find a C compiler & linker", 1 for 1..7;
+}
+
+1 while unlink $source_file;
+
+#####################################################################
+
+sub Foo::TIEHANDLE { bless {}, 'Foo' }
+sub Foo::PRINT { shift->{buf} .= join '', @_ }
+sub Foo::content { shift->{buf} }
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/README b/gnu/usr.bin/perl/lib/ExtUtils/README
index 81bc190d673..9586c0ba173 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/README
+++ b/gnu/usr.bin/perl/lib/ExtUtils/README
@@ -32,8 +32,8 @@ Every stable MakeMaker release is tested at least on:
MacOS X
Linux/x86
-ActivePerl on Windows 98
-Cygwin on Windows 98
+ActivePerl on Windows
+Cygwin
OpenVMS
Covering the major portability flavors MakeMaker has to cover.
@@ -44,13 +44,14 @@ Known Problems:
(See http://rt.cpan.org for a full list of open problems.)
-ActivePerl likely broken if installed in C:\Program Files or other
-prefix with a space in the name.
+Windows will likely be broken if Perl is installed in C:\Program Files or
+other prefix with a space in the name.
Using the MMS utility on VMS causes lots of extra newlines. Unknown
why this is so, might be a bug in MMS. Problem not seen with MMK.
+GNU make does not work with MakeMaker on Windows.
-See TODO for details.
-Please report any bugs via http://rt.cpan.org or to makemaker@perl.org.
+Please report any bugs via http://rt.cpan.org.
+Send questions and discussion to makemaker@perl.org
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/TODO b/gnu/usr.bin/perl/lib/ExtUtils/TODO
index 80c69f6282b..fe5a703a2bf 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/TODO
+++ b/gnu/usr.bin/perl/lib/ExtUtils/TODO
@@ -1,3 +1,6 @@
+This TODO list is out of date. See http://rt.cpan.org for the real list.
+
+
Rethink MM_Win32 tests.
Investigate one method per make target.
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Constant.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Constant.t
index f440da4b16f..7c997fe21ba 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/Constant.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Constant.t
@@ -15,7 +15,7 @@ BEGIN {
# use warnings;
use strict;
use ExtUtils::MakeMaker;
-use ExtUtils::Constant qw (constant_types C_constant XS_constant autoload);
+use ExtUtils::Constant qw (C_constant autoload);
use File::Spec;
use Cwd;
@@ -85,6 +85,30 @@ END {
chdir $dir or die $!;
push @INC, '../../lib', '../../../lib';
+package TieOut;
+
+sub TIEHANDLE {
+ my $class = shift;
+ bless(\( my $ref = ''), $class);
+}
+
+sub PRINT {
+ my $self = shift;
+ $$self .= join('', @_);
+}
+
+sub PRINTF {
+ my $self = shift;
+ $$self .= sprintf shift, @_;
+}
+
+sub read {
+ my $self = shift;
+ return substr($$self, 0, length($$self), '');
+}
+
+package main;
+
sub check_for_bonus_files {
my $dir = shift;
my %expect = map {($^O eq 'VMS' ? lc($_) : $_), 1} @_;
@@ -210,38 +234,45 @@ sub build_and_run {
}
$realtest++;
- # -x is busted on Win32 < 5.6.1, so we emulate it.
- my $regen;
- if( $^O eq 'MSWin32' && $] <= 5.006001 ) {
- open(REGENTMP, ">regentmp") or die $!;
- open(XS, "$package.xs") or die $!;
- my $saw_shebang;
- while(<XS>) {
- $saw_shebang++ if /^#!.*/i ;
- print REGENTMP $_ if $saw_shebang;
- }
- close XS; close REGENTMP;
- $regen = `$runperl regentmp`;
- unlink 'regentmp';
- }
- else {
- $regen = `$runperl -x $package.xs`;
- }
- if ($?) {
- print "not ok $realtest # $runperl -x $package.xs failed: $?\n";
- } else {
- print "ok $realtest - regen\n";
- }
- $realtest++;
-
- if ($expect eq $regen) {
- print "ok $realtest - regen worked\n";
+ if (defined $expect) {
+ # -x is busted on Win32 < 5.6.1, so we emulate it.
+ my $regen;
+ if( $^O eq 'MSWin32' && $] <= 5.006001 ) {
+ open(REGENTMP, ">regentmp") or die $!;
+ open(XS, "$package.xs") or die $!;
+ my $saw_shebang;
+ while(<XS>) {
+ $saw_shebang++ if /^#!.*/i ;
+ print REGENTMP $_ if $saw_shebang;
+ }
+ close XS; close REGENTMP;
+ $regen = `$runperl regentmp`;
+ unlink 'regentmp';
+ }
+ else {
+ $regen = `$runperl -x $package.xs`;
+ }
+ if ($?) {
+ print "not ok $realtest # $runperl -x $package.xs failed: $?\n";
+ } else {
+ print "ok $realtest - regen\n";
+ }
+ $realtest++;
+
+ if ($expect eq $regen) {
+ print "ok $realtest - regen worked\n";
+ } else {
+ print "not ok $realtest - regen worked\n";
+ # open FOO, ">expect"; print FOO $expect;
+ # open FOO, ">regen"; print FOO $regen; close FOO;
+ }
+ $realtest++;
} else {
- print "not ok $realtest - regen worked\n";
- # open FOO, ">expect"; print FOO $expect;
- # open FOO, ">regen"; print FOO $regen; close FOO;
+ for (0..1) {
+ print "ok $realtest # skip no regen or expect for this set of tests\n";
+ $realtest++;
+ }
}
- $realtest++;
my $makeclean = "$make clean";
print "# make = '$makeclean'\n";
@@ -320,16 +351,32 @@ sub MANIFEST {
}
sub write_and_run_extension {
- my ($name, $items, $export_names, $package, $header, $testfile, $num_tests)
- = @_;
- my $types = {};
- my $constant_types = constant_types(); # macro defs
- my $C_constant = join "\n",
- C_constant ($package, undef, "IV", $types, undef, undef, @$items);
- my $XS_constant = XS_constant ($package, $types); # XS for ExtTest::constant
+ my ($name, $items, $export_names, $package, $header, $testfile, $num_tests,
+ $wc_args) = @_;
+
+ my $c = tie *C, 'TieOut';
+ my $xs = tie *XS, 'TieOut';
+
+ ExtUtils::Constant::WriteConstants(C_FH => \*C,
+ XS_FH => \*XS,
+ NAME => $package,
+ NAMES => $items,
+ @$wc_args,
+ );
+
+ my $C_code = $c->read();
+ my $XS_code = $xs->read();
- my $expect = $constant_types . $C_constant .
- "\n#### XS Section:\n" . $XS_constant;
+ undef $c;
+ undef $xs;
+
+ untie *C;
+ untie *XS;
+
+ # Don't check the regeneration code if we specify extra arguments to
+ # WriteConstants. (Fix this to give finer grained control if needed)
+ my $expect;
+ $expect = $C_code . "\n#### XS Section:\n" . $XS_code unless $wc_args;
print "# $name\n# $dir/$subdir being created...\n";
mkdir $subdir, 0777 or die "mkdir: $!\n";
@@ -345,23 +392,23 @@ sub write_and_run_extension {
close FH or die "close $header_name: $!\n";
################ XS
- my $xs = "$package.xs";
- push @files, $xs;
- open FH, ">$xs" or die "open >$xs: $!\n";
+ my $xs_name = "$package.xs";
+ push @files, $xs_name;
+ open FH, ">$xs_name" or die "open >$xs_name: $!\n";
- print FH <<'EOT';
+ print FH <<"EOT";
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
+#include "$header_name"
+
+
+$C_code
+MODULE = $package PACKAGE = $package
+PROTOTYPES: ENABLE
+$XS_code;
EOT
- # XXX Here doc these:
- print FH "#include \"$header_name\"\n\n";
- print FH $constant_types;
- print FH $C_constant, "\n";
- print FH "MODULE = $package PACKAGE = $package\n";
- print FH "PROTOTYPES: ENABLE\n";
- print FH $XS_constant;
close FH or die "close $xs: $!\n";
################ PM
@@ -435,6 +482,7 @@ EOT
chdir $updir or die "chdir '$updir': $!";
++$subdir;
}
+
# Tests are arrayrefs of the form
# $name, [items], [export_names], $package, $header, $testfile, $num_tests
my @tests;
@@ -448,9 +496,9 @@ sub start_tests {
$here = $dummytest;
}
sub end_tests {
- my ($name, $items, $export_names, $header, $testfile) = @_;
+ my ($name, $items, $export_names, $header, $testfile, $args) = @_;
push @tests, [$name, $items, $export_names, $package, $header, $testfile,
- $dummytest - $here];
+ $dummytest - $here, $args];
$dummytest += $after_tests;
}
@@ -467,6 +515,9 @@ my @common_items = (
{name=>$pound, type=>"PV", value=>'"Sterling"', macro=>1},
);
+my @args = undef;
+push @args, [PROXYSUBS => 1] if $] > 5.009002;
+foreach my $args (@args)
{
# Simple tests
start_tests();
@@ -526,122 +577,146 @@ EOT
# Exporter::Heavy (currently) isn't able to export the last 3 of these:
push @items, @common_items;
- # XXX there are hardwired still.
- my $test_body = <<'EOT';
+ my $test_body = <<"EOT";
+
+my \$test = $dummytest;
+
+EOT
+
+ $test_body .= <<'EOT';
# What follows goes to the temporary file.
# IV
my $five = FIVE;
if ($five == 5) {
- print "ok 5\n";
+ print "ok $test\n";
} else {
- print "not ok 5 # \$five\n";
+ print "not ok $test # \$five\n";
}
+$test++;
# PV
-print OK6;
+if (OK6 eq "ok 6\n") {
+ print "ok $test\n";
+} else {
+ print "not ok $test # \$five\n";
+}
+$test++;
# PVN containing embedded \0s
$_ = OK7;
s/.*\0//s;
+s/7/$test/;
+$test++;
print;
# NV
my $farthing = FARTHING;
if ($farthing == 0.25) {
- print "ok 8\n";
+ print "ok $test\n";
} else {
- print "not ok 8 # $farthing\n";
+ print "not ok $test # $farthing\n";
}
+$test++;
# UV
my $not_zero = NOT_ZERO;
if ($not_zero > 0 && $not_zero == ~0) {
- print "ok 9\n";
+ print "ok $test\n";
} else {
- print "not ok 9 # \$not_zero=$not_zero ~0=" . (~0) . "\n";
+ print "not ok $test # \$not_zero=$not_zero ~0=" . (~0) . "\n";
}
+$test++;
# Value includes a "*/" in an attempt to bust out of a C comment.
# Also tests custom cpp #if clauses
my $close = CLOSE;
if ($close eq '*/') {
- print "ok 10\n";
+ print "ok $test\n";
} else {
- print "not ok 10 # \$close='$close'\n";
+ print "not ok $test # \$close='$close'\n";
}
+$test++;
# Default values if macro not defined.
my $answer = ANSWER;
if ($answer == 42) {
- print "ok 11\n";
+ print "ok $test\n";
} else {
- print "not ok 11 # What do you get if you multiply six by nine? '$answer'\n";
+ print "not ok $test # What do you get if you multiply six by nine? '$answer'\n";
}
+$test++;
# not defined macro
my $notdef = eval { NOTDEF; };
if (defined $notdef) {
- print "not ok 12 # \$notdef='$notdef'\n";
+ print "not ok $test # \$notdef='$notdef'\n";
} elsif ($@ !~ /Your vendor has not defined ExtTest macro NOTDEF/) {
- print "not ok 12 # \$@='$@'\n";
+ print "not ok $test # \$@='$@'\n";
} else {
- print "ok 12\n";
+ print "ok $test\n";
}
+$test++;
# not a macro
my $notthere = eval { &ExtTest::NOTTHERE; };
if (defined $notthere) {
- print "not ok 13 # \$notthere='$notthere'\n";
+ print "not ok $test # \$notthere='$notthere'\n";
} elsif ($@ !~ /NOTTHERE is not a valid ExtTest macro/) {
chomp $@;
- print "not ok 13 # \$@='$@'\n";
+ print "not ok $test # \$@='$@'\n";
} else {
- print "ok 13\n";
+ print "ok $test\n";
}
+$test++;
# Truth
my $yes = Yes;
if ($yes) {
- print "ok 14\n";
+ print "ok $test\n";
} else {
- print "not ok 14 # $yes='\$yes'\n";
+ print "not ok $test # $yes='\$yes'\n";
}
+$test++;
# Falsehood
my $no = No;
if (defined $no and !$no) {
- print "ok 15\n";
+ print "ok $test\n";
} else {
- print "not ok 15 # \$no=" . defined ($no) ? "'$no'\n" : "undef\n";
+ print "not ok $test # \$no=" . defined ($no) ? "'$no'\n" : "undef\n";
}
+$test++;
# Undef
my $undef = Undef;
unless (defined $undef) {
- print "ok 16\n";
+ print "ok $test\n";
} else {
- print "not ok 16 # \$undef='$undef'\n";
+ print "not ok $test # \$undef='$undef'\n";
}
+$test++;
# invalid macro (chosen to look like a mix up between No and SW)
$notdef = eval { &ExtTest::So };
if (defined $notdef) {
- print "not ok 17 # \$notdef='$notdef'\n";
+ print "not ok $test # \$notdef='$notdef'\n";
} elsif ($@ !~ /^So is not a valid ExtTest macro/) {
- print "not ok 17 # \$@='$@'\n";
+ print "not ok $test # \$@='$@'\n";
} else {
- print "ok 17\n";
+ print "ok $test\n";
}
+$test++;
# invalid defined macro
$notdef = eval { &ExtTest::EW };
if (defined $notdef) {
- print "not ok 18 # \$notdef='$notdef'\n";
+ print "not ok $test # \$notdef='$notdef'\n";
} elsif ($@ !~ /^EW is not a valid ExtTest macro/) {
- print "not ok 18 # \$@='$@'\n";
+ print "not ok $test # \$@='$@'\n";
} else {
- print "ok 18\n";
+ print "ok $test\n";
}
+$test++;
my %compass = (
EOT
@@ -669,26 +744,29 @@ while (my ($point, $bearing) = each %compass) {
}
}
if ($fail) {
- print "not ok 19\n";
+ print "not ok $test\n";
} else {
- print "ok 19\n";
+ print "ok $test\n";
}
+$test++;
EOT
$test_body .= <<"EOT";
my \$rfc1149 = RFC1149;
if (\$rfc1149 ne "$parent_rfc1149") {
- print "not ok 20 # '\$rfc1149' ne '$parent_rfc1149'\n";
+ print "not ok \$test # '\$rfc1149' ne '$parent_rfc1149'\n";
} else {
- print "ok 20\n";
+ print "ok \$test\n";
}
+\$test++;
if (\$rfc1149 != 1149) {
- printf "not ok 21 # %d != 1149\n", \$rfc1149;
+ printf "not ok \$test # %d != 1149\n", \$rfc1149;
} else {
- print "ok 21\n";
+ print "ok \$test\n";
}
+\$test++;
EOT
@@ -696,14 +774,16 @@ $test_body .= <<'EOT';
# test macro=>1
my $open = OPEN;
if ($open eq '/*') {
- print "ok 22\n";
+ print "ok $test\n";
} else {
- print "not ok 22 # \$open='$open'\n";
+ print "not ok $test # \$open='$open'\n";
}
+$test++;
EOT
$dummytest+=18;
- end_tests("Simple tests", \@items, \@export_names, $header, $test_body);
+ end_tests("Simple tests", \@items, \@export_names, $header, $test_body,
+ $args);
}
if ($do_utf_tests) {
@@ -787,7 +867,7 @@ foreach (["perl", "rules", "rules"],
) {
# Flag an expected error with a reference for the expect string.
my ($string, $expect, $expect_bytes) = @$_;
- (my $name = $string) =~ s/([^ -~])/sprintf '\x{%X}', ord $1/ges;
+ (my $name = $string) =~ s/([^ !"#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~])/sprintf '\x{%X}', ord $1/ges;
print "# \"$name\" => \'$expect\'\n";
# Try to force this to be bytes if possible.
if ($better_than_56) {
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Embed.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Embed.t
index 010d05a827d..e3321ecd471 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/Embed.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Embed.t
@@ -31,11 +31,14 @@ my $libperl_copied;
my $testlib;
my @cmd;
my (@cmd2) if $^O eq 'VMS';
-
+# Don't use ccopts() here as we may want to overwrite an existing
+# perl with a new one with inconsistent header files, meaning
+# the usual value for perl_inc(), which is used by ccopts(),
+# will be wrong.
if ($^O eq 'VMS') {
push(@cmd,$cc,"/Obj=$obj");
my (@incs) = ($inc);
- my $crazy = ccopts();
+ my $crazy = ccflags();
if ($crazy =~ s#/inc[^=/]*=([\w\$\_\-\.\[\]\:]+)##i) {
push(@incs,$1);
}
@@ -60,7 +63,14 @@ if ($^O eq 'VMS') {
else {
push(@cmd,$cc,'-o' => $exe);
}
- push(@cmd,"-I$inc",ccopts(),'embed_test.c');
+ if ($^O eq 'dec_osf' && !defined $Config{usedl}) {
+ # The -non_shared is needed in case of -Uusedl or otherwise
+ # the test application will try to use libperl.so
+ # instead of libperl.a.
+ push @cmd, "-non_shared";
+ }
+
+ push(@cmd,"-I$inc",ccflags(),'embed_test.c');
if ($^O eq 'MSWin32') {
$inc = File::Spec->catdir($inc,'win32');
push(@cmd,"-I$inc");
@@ -73,7 +83,9 @@ if ($^O eq 'VMS') {
push(@cmd,"-L$lib",File::Spec->catfile($lib,$Config{'libperl'}),$Config{'libc'});
}
}
- else { # Not MSWin32.
+ elsif ($^O eq 'os390' && $Config{usedl}) {
+ # Nothing for OS/390 (z/OS) dynamic.
+ } else { # Not MSWin32 or OS/390 (z/OS) dynamic.
push(@cmd,"-L$lib",'-lperl');
local $SIG{__WARN__} = sub {
warn $_[0] unless $_[0] =~ /No library found for .*perl/
@@ -135,13 +147,13 @@ print "# embed_test = $embed_test\n";
$status = system($embed_test);
print (($status? 'not ':'')."ok 9 # system returned $status\n");
unlink($exe,"embed_test.c",$obj);
+unlink("$exe.manifest") if $cl and $Config{'ccversion'} =~ /^(\d+)/ and $1 >= 14;
unlink("$exe$Config{exe_ext}") if $skip_exe;
unlink("embed_test.map","embed_test.lis") if $^O eq 'VMS';
unlink(glob("./*.dll")) if $^O eq 'cygwin';
unlink($testlib) if $libperl_copied;
-# gcc -g -I.. -L../ -o perl_test perl_test.c -lperl `../perl -I../lib -MExtUtils::Embed -I../ -e ccopts -e ldopts`
-
+# gcc -g -I.. -L../ -o perl_test perl_test.c -lperl `../perl -I../lib -MExtUtils::Embed -I../ -e ccflags -e ldopts`
__END__
/* perl_test.c */
@@ -158,7 +170,12 @@ static struct perl_vars *my_plvarsp;
struct perl_vars* Perl_GetVarsPrivate(void) { return my_plvarsp; }
#endif
+#ifdef NO_ENV_ARRAY_IN_MAIN
+extern char **environ;
+int main(int argc, char **argv)
+#else
int main(int argc, char **argv, char **env)
+#endif
{
PerlInterpreter *my_perl;
#ifdef PERL_GLOBAL_STRUCT
@@ -171,7 +188,11 @@ int main(int argc, char **argv, char **env)
(void)argc; /* PERL_SYS_INIT3 may #define away their use */
(void)argv;
+#ifdef NO_ENV_ARRAY_IN_MAIN
+ PERL_SYS_INIT3(&argc,&argv,&environ);
+#else
PERL_SYS_INIT3(&argc,&argv,&env);
+#endif
my_perl = perl_alloc();
@@ -181,7 +202,11 @@ int main(int argc, char **argv, char **env)
my_puts("ok 3");
+#ifdef NO_ENV_ARRAY_IN_MAIN
+ perl_parse(my_perl, NULL, (sizeof(cmds)/sizeof(char *))-1, cmds, environ);
+#else
perl_parse(my_perl, NULL, (sizeof(cmds)/sizeof(char *))-1, cmds, env);
+#endif
my_puts("ok 4");
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/FIRST_MAKEFILE.t b/gnu/usr.bin/perl/lib/ExtUtils/t/FIRST_MAKEFILE.t
index 731dd34d929..00e6082403b 100755
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/FIRST_MAKEFILE.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/FIRST_MAKEFILE.t
@@ -36,5 +36,5 @@ cmp_ok( $?, '==', 0, 'Makefile.PL exited with zero' ) || diag @mpl_out;
ok( -e 'jakefile', 'FIRST_MAKEFILE honored' );
-ok( grep(/^Writing jakefile for Big::Dummy/, @mpl_out) == 1,
+ok( grep(/^Writing jakefile(?:\.)? for Big::Dummy/, @mpl_out) == 1,
'Makefile.PL output looks right' );
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/INSTALL_BASE.t b/gnu/usr.bin/perl/lib/ExtUtils/t/INSTALL_BASE.t
new file mode 100644
index 00000000000..cac65f266f0
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/INSTALL_BASE.t
@@ -0,0 +1,81 @@
+#!/usr/bin/perl -w
+
+# Tests INSTALL_BASE
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't' if -d 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib';
+ }
+}
+
+use strict;
+use File::Path;
+use Config;
+
+use Test::More tests => 21;
+use MakeMaker::Test::Utils;
+use MakeMaker::Test::Setup::BFD;
+
+my $Is_VMS = $^O eq 'VMS';
+
+my $perl = which_perl();
+
+chdir 't';
+perl_lib;
+
+ok( setup_recurs(), 'setup' );
+END {
+ ok( chdir File::Spec->updir );
+ ok( teardown_recurs(), 'teardown' );
+}
+
+ok( chdir('Big-Dummy'), "chdir'd to Big-Dummy") || diag("chdir failed; $!");
+
+my @mpl_out = run(qq{$perl Makefile.PL "INSTALL_BASE=../dummy-install"});
+END { rmtree '../dummy-install'; }
+
+cmp_ok( $?, '==', 0, 'Makefile.PL exited with zero' ) ||
+ diag(@mpl_out);
+
+my $makefile = makefile_name();
+ok( grep(/^Writing $makefile for Big::Dummy/,
+ @mpl_out) == 1,
+ 'Makefile.PL output looks right');
+
+my $make = make_run();
+run("$make"); # this is necessary due to a dmake bug.
+my $install_out = run("$make install");
+is( $?, 0, ' make install exited normally' ) || diag $install_out;
+like( $install_out, qr/^Installing /m );
+like( $install_out, qr/^Writing /m );
+
+ok( -r '../dummy-install', ' install dir created' );
+
+my @installed_files =
+ ('../dummy-install/lib/perl5/Big/Dummy.pm',
+ '../dummy-install/lib/perl5/Big/Liar.pm',
+ '../dummy-install/bin/program',
+ "../dummy-install/lib/perl5/$Config{archname}/perllocal.pod",
+ "../dummy-install/lib/perl5/$Config{archname}/auto/Big/Dummy/.packlist"
+ );
+
+foreach my $file (@installed_files) {
+ ok( -e $file, " $file installed" );
+ ok( -r $file, " $file readable" );
+}
+
+
+# nmake outputs its damned logo
+# Send STDERR off to oblivion.
+open(SAVERR, ">&STDERR") or die $!;
+open(STDERR, ">".File::Spec->devnull) or die $!;
+
+my $realclean_out = run("$make realclean");
+is( $?, 0, 'realclean' ) || diag($realclean_out);
+
+open(STDERR, ">&SAVERR") or die $!;
+close SAVERR;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Install.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Install.t
index 6058811c265..ae8d7811047 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/Install.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Install.t
@@ -17,7 +17,7 @@ use TieOut;
use File::Path;
use File::Spec;
-use Test::More tests => 32;
+use Test::More tests => 38;
use MakeMaker::Test::Setup::BFD;
@@ -72,13 +72,14 @@ install( { 'blib/lib' => 'install-test/lib/perl',
} );
ok( -d 'install-test/lib/perl', 'install made dir' );
ok( -r 'install-test/lib/perl/Big/Dummy.pm', ' .pm file installed' );
+ok(!-r 'install-test/lib/perl/Big/Dummy.SKIP', ' ignored .SKIP file' );
ok( -r 'install-test/packlist', ' packlist exists' );
open(PACKLIST, 'install-test/packlist' );
my %packlist = map { chomp; ($_ => 1) } <PACKLIST>;
close PACKLIST;
-# On case-insensitive filesystems (ie. VMS), the keys of the packlist might
+# On case-insensitive filesystems (ie. VMS), the keys of the packlist might
# be lowercase. :(
my $native_dummy = File::Spec->catfile(qw(install-test lib perl Big Dummy.pm));
is( keys %packlist, 1 );
@@ -97,13 +98,32 @@ ok( -r 'install-test/packlist', ' packlist exists' );
ok( -r 'install-test/lib/perl/Big/Dummy.pm', ' UNINST=1 preserved same' );
-
-# Test UNINST=1 removing other versions in other dirs.
chmod 0644, 'blib/lib/Big/Dummy.pm' or die $!;
open(DUMMY, ">>blib/lib/Big/Dummy.pm") or die $!;
print DUMMY "Extra stuff\n";
close DUMMY;
+
+# Test UNINST=0 does not remove other versions in other dirs.
+{
+ ok( -r 'install-test/lib/perl/Big/Dummy.pm', 'different install exists' );
+
+ local @INC = ('install-test/lib/perl');
+ local $ENV{PERL5LIB} = '';
+ install( { 'blib/lib' => 'install-test/other_lib/perl',
+ read => 'install-test/packlist',
+ write => 'install-test/packlist'
+ },
+ 0, 0, 0);
+ ok( -d 'install-test/other_lib/perl', 'install made other dir' );
+ ok( -r 'install-test/other_lib/perl/Big/Dummy.pm', ' .pm file installed' );
+ ok( -r 'install-test/packlist', ' packlist exists' );
+ ok( -r 'install-test/lib/perl/Big/Dummy.pm',
+ ' UNINST=0 left different' );
+}
+
+
+# Test UNINST=1 removing other versions in other dirs.
{
local @INC = ('install-test/lib/perl');
local $ENV{PERL5LIB} = '';
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Installed.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Installed.t
index ba35deb691b..f820ef49c61 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/Installed.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Installed.t
@@ -21,7 +21,7 @@ use File::Path;
use File::Basename;
use File::Spec;
-use Test::More tests => 46;
+use Test::More tests => 63;
BEGIN { use_ok( 'ExtUtils::Installed' ) }
@@ -30,6 +30,10 @@ my $mandirs = !!$Config{man1direxp} + !!$Config{man3direxp};
# saves having to qualify package name for class methods
my $ei = bless( {}, 'ExtUtils::Installed' );
+# Make sure meta info is available
+$ei->{':private:'}{Config} = \%Config;
+$ei->{':private:'}{INC} = \@INC;
+
# _is_prefix
ok( $ei->_is_prefix('foo/bar', 'foo'),
'_is_prefix() should match valid path prefix' );
@@ -53,7 +57,7 @@ foreach my $path (qw( man1dir man3dir )) {
# VMS 5.6.1 doesn't seem to have $Config{prefixexp}
my $prefix = $Config{prefix} || $Config{prefixexp};
-# You can concatenate /foo but not foo:, which defaults in the current
+# You can concatenate /foo but not foo:, which defaults in the current
# directory
$prefix = VMS::Filespec::unixify($prefix) if $Is_VMS;
@@ -65,7 +69,7 @@ ok( $ei->_is_type( File::Spec->catfile($prefix, 'bar'), 'prog'),
SKIP: {
skip('no man directories on this system', 1) unless $mandirs;
- is( $ei->_is_type('bar', 'doc'), 0,
+ is( $ei->_is_type('bar', 'doc'), 0,
'... should not find doc file outside path' );
}
@@ -100,10 +104,10 @@ FAKE
close FAKEMOD;
+my $fake_mod_dir = File::Spec->catdir(cwd(), 'auto', 'FakeMod');
{
# avoid warning and death by localizing glob
local *ExtUtils::Installed::Config;
- my $fake_mod_dir = File::Spec->catdir(cwd(), 'auto', 'FakeMod');
%ExtUtils::Installed::Config = (
%Config,
archlibexp => cwd(),
@@ -116,31 +120,98 @@ close FAKEMOD;
my $realei = ExtUtils::Installed->new();
isa_ok( $realei, 'ExtUtils::Installed' );
isa_ok( $realei->{Perl}{packlist}, 'ExtUtils::Packlist' );
- is( $realei->{Perl}{version}, $Config{version},
+ is( $realei->{Perl}{version}, $Config{version},
'new() should set Perl version from %Config' );
ok( exists $realei->{FakeMod}, 'new() should find modules with .packlists');
isa_ok( $realei->{FakeMod}{packlist}, 'ExtUtils::Packlist' );
- is( $realei->{FakeMod}{version}, '1.1.1',
+ is( $realei->{FakeMod}{version}, '1.1.1',
+ '... should find version in modules' );
+}
+
+# Now try this using PERL5LIB
+{
+ local $ENV{PERL5LIB} = join $Config{path_sep}, $fake_mod_dir;
+ local *ExtUtils::Installed::Config;
+ %ExtUtils::Installed::Config = (
+ %Config,
+ archlibexp => cwd(),
+ sitearchexp => cwd(),
+ );
+
+ my $realei = ExtUtils::Installed->new();
+ isa_ok( $realei, 'ExtUtils::Installed' );
+ isa_ok( $realei->{Perl}{packlist}, 'ExtUtils::Packlist' );
+ is( $realei->{Perl}{version}, $Config{version},
+ 'new() should set Perl version from %Config' );
+
+ ok( exists $realei->{FakeMod},
+ 'new() should find modules with .packlists using PERL5LIB'
+ );
+ isa_ok( $realei->{FakeMod}{packlist}, 'ExtUtils::Packlist' );
+ is( $realei->{FakeMod}{version}, '1.1.1',
+ '... should find version in modules' );
+}
+
+# Do the same thing as the last block, but with overrides for
+# %Config and @INC.
+{
+ my $config_override = { %Config::Config };
+ $config_override->{archlibexp} = cwd();
+ $config_override->{sitearchexp} = $fake_mod_dir;
+ $config_override->{version} = 'fake_test_version';
+
+ my @inc_override = (@INC, $fake_mod_dir);
+
+ my $realei = ExtUtils::Installed->new(
+ 'config_override' => $config_override,
+ 'inc_override' => \@inc_override,
+ );
+ isa_ok( $realei, 'ExtUtils::Installed' );
+ isa_ok( $realei->{Perl}{packlist}, 'ExtUtils::Packlist' );
+ is( $realei->{Perl}{version}, 'fake_test_version',
+ 'new(config_override => HASH) overrides %Config' );
+
+ ok( exists $realei->{FakeMod}, 'new() with overrides should find modules with .packlists');
+ isa_ok( $realei->{FakeMod}{packlist}, 'ExtUtils::Packlist' );
+ is( $realei->{FakeMod}{version}, '1.1.1',
+ '... should find version in modules' );
+}
+
+# Check if extra_libs works.
+{
+ my $realei = ExtUtils::Installed->new(
+ 'extra_libs' => [ cwd() ],
+ );
+ isa_ok( $realei, 'ExtUtils::Installed' );
+ isa_ok( $realei->{Perl}{packlist}, 'ExtUtils::Packlist' );
+ ok( exists $realei->{FakeMod},
+ 'new() with extra_libs should find modules with .packlists');
+
+ #{ use Data::Dumper; local $realei->{':private:'}{Config};
+ # warn Dumper($realei); }
+
+ isa_ok( $realei->{FakeMod}{packlist}, 'ExtUtils::Packlist' );
+ is( $realei->{FakeMod}{version}, '1.1.1',
'... should find version in modules' );
}
# modules
$ei->{$_} = 1 for qw( abc def ghi );
-is( join(' ', $ei->modules()), 'abc def ghi',
+is( join(' ', $ei->modules()), 'abc def ghi',
'modules() should return sorted keys' );
# This didn't work for a long time due to a sort in scalar context oddity.
is( $ei->modules, 3, 'modules() in scalar context' );
# files
-$ei->{goodmod} = {
- packlist => {
- ($Config{man1direxp} ?
- (File::Spec->catdir($Config{man1direxp}, 'foo') => 1) :
+$ei->{goodmod} = {
+ packlist => {
+ ($Config{man1direxp} ?
+ (File::Spec->catdir($Config{man1direxp}, 'foo') => 1) :
()),
- ($Config{man3direxp} ?
- (File::Spec->catdir($Config{man3direxp}, 'bar') => 1) :
+ ($Config{man3direxp} ?
+ (File::Spec->catdir($Config{man3direxp}, 'bar') => 1) :
()),
File::Spec->catdir($prefix, 'foobar') => 1,
foobaz => 1,
@@ -154,8 +225,8 @@ like( $@, qr/type must be/,'files() should croak given bad type' );
my @files;
SKIP: {
- skip('no man directory man1dir on this system', 2)
- unless $Config{man1direxp};
+ skip('no man directory man1dir on this system', 2)
+ unless $Config{man1direxp};
@files = $ei->files('goodmod', 'doc', $Config{man1direxp});
is( scalar @files, 1, '... should find doc file under given dir' );
is( (grep { /foo$/ } @files), 1, '... checking file name' );
@@ -190,22 +261,22 @@ is( scalar @dirs, 2 + $mandirs, '... should find all files files() would, again'
is( join(' ', @files), join(' ', @dirs), '... should sort output' );
# directory_tree
-my $expectdirs =
- ($mandirs == 2) &&
+my $expectdirs =
+ ($mandirs == 2) &&
(dirname($Config{man1direxp}) eq dirname($Config{man3direxp}))
? 3 : 2;
-
+
SKIP: {
skip('no man directories on this system', 1) unless $mandirs;
@dirs = $ei->directory_tree('goodmod', 'doc', $Config{man1direxp} ?
dirname($Config{man1direxp}) : dirname($Config{man3direxp}));
- is( scalar @dirs, $expectdirs,
+ is( scalar @dirs, $expectdirs,
'directory_tree() should report intermediate dirs to those requested' );
}
my $fakepak = Fakepak->new(102);
-$ei->{yesmod} = {
+$ei->{yesmod} = {
version => 101,
packlist => $fakepak,
};
@@ -213,20 +284,20 @@ $ei->{yesmod} = {
# these should all croak
foreach my $sub (qw( validate packlist version )) {
eval { $ei->$sub('nomod') };
- like( $@, qr/nomod is not installed/,
+ like( $@, qr/nomod is not installed/,
"$sub() should croak when asked about uninstalled module" );
}
# validate
-is( $ei->validate('yesmod'), 'validated',
+is( $ei->validate('yesmod'), 'validated',
'validate() should return results of packlist validate() call' );
# packlist
-is( ${ $ei->packlist('yesmod') }, 102,
+is( ${ $ei->packlist('yesmod') }, 102,
'packlist() should report installed mod packlist' );
# version
-is( $ei->version('yesmod'), 101,
+is( $ei->version('yesmod'), 101,
'version() should report installed mod version' );
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_NW5.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_NW5.t
index 13359d17fbc..f8a3635331c 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_NW5.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_NW5.t
@@ -16,7 +16,7 @@ use Test::More;
BEGIN {
if ($^O =~ /NetWare/i) {
- plan tests => 40;
+ plan tests => 39;
} else {
plan skip_all => 'This is not NW5';
}
@@ -254,21 +254,6 @@ unlink "${script_name}$script_ext" if -f "${script_name}$script_ext";
'tool_autosplit()' );
}
-# tools_other()
-{
- ( my $mm_w32 = bless { }, 'MM' )->init_others();
-
- my $bin_sh = ( $Config{make} =~ /^dmake/i
- ? "" : ($Config{sh} || 'cmd /c') . "\n" );
- $bin_sh = "SHELL = $bin_sh" if $bin_sh;
-
- my $tools = join "\n", map "$_ = $mm_w32->{ $_ }"
- => qw(CHMOD CP LD MV NOOP RM_F RM_RF TEST_F TOUCH UMASK_NULL DEV_NULL);
-
- like( $mm_w32->tools_other(),
- qr/^\Q$bin_sh$tools/m,
- 'tools_other()' );
-};
# xs_o() should look into that
# top_targets() should look into that
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Unix.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Unix.t
index f9b07f8c0cc..ffcfd295de3 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Unix.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Unix.t
@@ -18,7 +18,7 @@ BEGIN {
plan skip_all => 'Non-Unix platform';
}
else {
- plan tests => 110;
+ plan tests => 109;
}
}
@@ -176,11 +176,6 @@ chmod 0755, "command";
ok ($t->maybe_command('command'), "executable file is a command");
unlink "command";
-###############################################################################
-# nicetext (dummy method)
-
-is ($t->nicetext('LOTR'),'LOTR','nicetext');
-
###############################################################################
# perl_script (on unix any ordinary, readable file)
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_VMS.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_VMS.t
index dcc5ed6230a..406b17f2ba2 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_VMS.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_VMS.t
@@ -56,7 +56,6 @@ BEGIN {
test_via_harness
test_via_script
makeaperl
- nicetext
));
}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Win32.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Win32.t
index 7acde33a949..866c135bc56 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Win32.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Win32.t
@@ -37,6 +37,7 @@ my $MM = bless {
MAKEFILE => 'Makefile',
RM_RF => 'rm -rf',
MV => 'mv',
+ MAKE => $Config{make}
}, 'MM';
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Manifest.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Manifest.t
index bba68439ad2..e8732ad9fc1 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/Manifest.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Manifest.t
@@ -13,12 +13,13 @@ chdir 't';
use strict;
-use Test::More tests => 49;
+use Test::More tests => 66;
use Cwd;
use File::Spec;
use File::Path;
use File::Find;
+use Config;
my $Is_VMS = $^O eq 'VMS';
@@ -46,7 +47,7 @@ sub read_manifest {
}
sub catch_warning {
- my $warn;
+ my $warn = '';
local $SIG{__WARN__} = sub { $warn .= $_[0] };
return join('', $_[0]->() ), $warn;
}
@@ -71,8 +72,14 @@ ok( mkdir( 'mantest', 0777 ), 'make mantest directory' );
ok( chdir( 'mantest' ), 'chdir() to mantest' );
ok( add_file('foo'), 'add a temporary file' );
+# This ensures the -x check for manicopy means something
+# Some platforms don't have chmod or an executable bit, in which case
+# this call will do nothing or fail, but on the platforms where chmod()
+# works, we test the executable bit is copied
+chmod( 0744, 'foo') if $Config{'chmod'};
+
# there shouldn't be a MANIFEST there
-my ($res, $warn) = catch_warning( \&mkmanifest );
+my ($res, $warn) = catch_warning( \&mkmanifest );
# Canonize the order.
$warn = join("", map { "$_|" }
sort { lc($a) cmp lc($b) } split /\r?\n/, $warn);
@@ -97,10 +104,10 @@ like( $warn, qr/^Not in MANIFEST: bar/, 'warning that bar has been added' );
is( $res, 'bar', 'bar reported as new' );
# now quiet the warning that bar was added and test again
-($res, $warn) = do { local $ExtUtils::Manifest::Quiet = 1;
- catch_warning( \&skipcheck )
+($res, $warn) = do { local $ExtUtils::Manifest::Quiet = 1;
+ catch_warning( \&skipcheck )
};
-ok( ! defined $warn, 'disabled warnings' );
+is( $warn, '', 'disabled warnings' );
# add a skip file with a rule to skip itself (and the nonexistent glob '*baz*')
add_file( 'MANIFEST.SKIP', "baz\n.SKIP" );
@@ -164,7 +171,7 @@ is( ExtUtils::Manifest::maniread()->{none}, '#none',
ok( mkdir( 'copy', 0777 ), 'made copy directory' );
$files = maniread();
eval { (undef, $warn) = catch_warning( sub {
- manicopy( $files, 'copy', 'cp' ) })
+ manicopy( $files, 'copy', 'cp' ) })
};
like( $@, qr/^Can't read none: /, 'croaked about none' );
@@ -179,7 +186,7 @@ like($warn, qr/^Skipping MANIFEST.SKIP/i, 'warned about MANIFEST.SKIP' );
local $ExtUtils::Manifest::MANIFEST = 'albatross';
($res, $warn) = catch_warning( \&mkmanifest );
like( $warn, qr/Added to albatross: /, 'using a new manifest file' );
-
+
# add the new file to the list of files to be deleted
$Files{'albatross'}++;
}
@@ -200,7 +207,7 @@ add_file( 'MANIFEST' => "foobar\n" );
add_file( 'foobar' => '123' );
($res, $warn) = catch_warning( \&manicheck );
is( $res, '', 'MANIFEST overrides MANIFEST.SKIP' );
-is( $warn, undef, 'MANIFEST overrides MANIFEST.SKIP, no warnings' );
+is( $warn, '', 'MANIFEST overrides MANIFEST.SKIP, no warnings' );
$files = maniread;
ok( !$files->{wibble}, 'MANIFEST in good state' );
@@ -211,6 +218,41 @@ is( $files->{wibble}, '', 'maniadd() with undef comment' );
is( $files->{yarrow}, 'hock',' with comment' );
is( $files->{foobar}, '', ' preserved old entries' );
+# test including an external manifest.skip file in MANIFEST.SKIP
+{
+ maniadd({ foo => undef , albatross => undef,
+ 'mymanifest.skip' => undef, 'mydefault.skip' => undef});
+ add_file('mymanifest.skip' => "^foo\n");
+ add_file('mydefault.skip' => "^my\n");
+ $ExtUtils::Manifest::DEFAULT_MSKIP =
+ File::Spec->catfile($cwd, qw(mantest mydefault.skip));
+ my $skip = File::Spec->catfile($cwd, qw(mantest mymanifest.skip));
+ add_file('MANIFEST.SKIP' =>
+ "albatross\n#!include $skip\n#!include_default");
+ my ($res, $warn) = catch_warning( \&skipcheck );
+ for (qw(albatross foo foobar mymanifest.skip mydefault.skip)) {
+ like( $warn, qr/Skipping \b$_\b/,
+ "Skipping $_" );
+ }
+ ($res, $warn) = catch_warning( \&mkmanifest );
+ for (qw(albatross foo foobar mymanifest.skip mydefault.skip)) {
+ like( $warn, qr/Removed from MANIFEST: \b$_\b/,
+ "Removed $_ from MANIFEST" );
+ }
+ my $files = maniread;
+ ok( ! exists $files->{albatross}, 'albatross excluded via MANIFEST.SKIP' );
+ ok( exists $files->{yarrow}, 'yarrow included in MANIFEST' );
+ ok( exists $files->{bar}, 'bar included in MANIFEST' );
+ ok( ! exists $files->{foobar}, 'foobar excluded via mymanifest.skip' );
+ ok( ! exists $files->{foo}, 'foo excluded via mymanifest.skip' );
+ ok( ! exists $files->{'mymanifest.skip'},
+ 'mymanifest.skip excluded via mydefault.skip' );
+ ok( ! exists $files->{'mydefault.skip'},
+ 'mydefault.skip excluded via mydefault.skip' );
+ my $extsep = $Is_VMS ? '_' : '.';
+ $Files{"$_.bak"}++ for ('MANIFEST', "MANIFEST${extsep}SKIP");
+}
+
add_file('MANIFEST' => 'Makefile.PL');
maniadd({ foo => 'bar' });
$files = maniread;
@@ -221,8 +263,8 @@ my %expect = ( 'makefile.pl' => '',
);
is_deeply( $files, \%expect, 'maniadd() vs MANIFEST without trailing newline');
-add_file('MANIFEST' => 'Makefile.PL');
-maniadd({ foo => 'bar' });
+#add_file('MANIFEST' => 'Makefile.PL');
+#maniadd({ foo => 'bar' });
SKIP: {
chmod( 0400, 'MANIFEST' );
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Packlist.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Packlist.t
index 58eaf8f6795..cb73e00d14b 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/Packlist.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Packlist.t
@@ -39,7 +39,7 @@ is( ExtUtils::Packlist::FETCH($pl, 'foo'), 'bar', 'check FETCH()' );
# test FIRSTKEY and NEXTKEY
SKIP: {
$pl->{data}{bar} = 'baz';
- skip('not enough keys to test FIRSTKEY', 2)
+ skip('not enough keys to test FIRSTKEY', 2)
unless keys %{ $pl->{data} } > 2;
# get the first and second key
@@ -50,9 +50,9 @@ SKIP: {
for (keys %{ $pl->{data} } ) {
last if $i++;
}
-
+
# finally, see if it really can get the first key again
- is( ExtUtils::Packlist::FIRSTKEY($pl), $first,
+ is( ExtUtils::Packlist::FIRSTKEY($pl), $first,
'FIRSTKEY() should be consistent' );
is( ExtUtils::Packlist::NEXTKEY($pl), $second,
@@ -155,9 +155,9 @@ SKIP: {
is( ExtUtils::Packlist::validate($pl), 1,
'validate() should find missing files' );
ExtUtils::Packlist::validate($pl, 1);
- ok( !exists $pl->{data}{fake},
+ ok( !exists $pl->{data}{fake},
'validate() should remove missing files when prompted' );
-
+
# one more new() test, to see if it calls read() successfully
$pl = ExtUtils::Packlist->new('eplist');
}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/WriteEmptyMakefile.t b/gnu/usr.bin/perl/lib/ExtUtils/t/WriteEmptyMakefile.t
new file mode 100644
index 00000000000..a5de6f16c94
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/WriteEmptyMakefile.t
@@ -0,0 +1,40 @@
+#!/usr/bin/perl -w
+
+# This is a test of WriteEmptyMakefile.
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't' if -d 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib';
+ }
+}
+
+chdir 't';
+
+use strict;
+use Test::More tests => 5;
+
+use ExtUtils::MakeMaker qw(WriteEmptyMakefile);
+use TieOut;
+
+can_ok __PACKAGE__, 'WriteEmptyMakefile';
+
+eval { WriteEmptyMakefile("something"); };
+like $@, qr/Need an even number of args/;
+
+
+{
+ ok( my $stdout = tie *STDOUT, 'TieOut' );
+
+ ok !-e 'wibble';
+ END { 1 while unlink 'wibble' }
+
+ WriteEmptyMakefile(
+ NAME => "Foo",
+ FIRST_MAKEFILE => "wibble",
+ );
+ ok -e 'wibble';
+}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/basic.t b/gnu/usr.bin/perl/lib/ExtUtils/t/basic.t
index ba476876263..64352d85cbd 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/basic.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/basic.t
@@ -15,8 +15,9 @@ BEGIN {
use strict;
use Config;
+use ExtUtils::MakeMaker;
-use Test::More tests => 80;
+use Test::More tests => 83;
use MakeMaker::Test::Utils;
use MakeMaker::Test::Setup::BFD;
use File::Find;
@@ -30,6 +31,9 @@ delete @ENV{qw(PREFIX LIB MAKEFLAGS)};
my $perl = which_perl();
my $Is_VMS = $^O eq 'VMS';
+# GNV logical interferes with testing
+$ENV{'bin'} = '[.bin]' if $Is_VMS;
+
chdir 't';
perl_lib;
@@ -102,7 +106,9 @@ like( $ppd_html, qr{^\s*<DEPENDENCY NAME="strict" VERSION="0,0,0,0" />}m,
' <DEPENDENCY>' );
like( $ppd_html, qr{^\s*<OS NAME="$Config{osname}" />}m,
' <OS>' );
-like( $ppd_html, qr{^\s*<ARCHITECTURE NAME="$Config{archname}" />}m,
+my $archname = $Config{archname};
+$archname .= "-". substr($Config{version},0,3) if $] >= 5.008;
+like( $ppd_html, qr{^\s*<ARCHITECTURE NAME="$archname" />}m,
' <ARCHITECTURE>');
like( $ppd_html, qr{^\s*<CODEBASE HREF="" />}m, ' <CODEBASE>');
like( $ppd_html, qr{^\s*</IMPLEMENTATION>}m, ' </IMPLEMENTATION>');
@@ -244,6 +250,27 @@ ok( !-f 'META.yml', 'META.yml not written to source dir' );
ok( -f $meta_yml, 'META.yml written to dist dir' );
ok( !-e "META_new.yml", 'temp META.yml file not left around' );
+ok open META, $meta_yml or diag $!;
+my $meta = join '', <META>;
+ok close META;
+
+is $meta, <<"END";
+--- #YAML:1.0
+name: Big-Dummy
+version: 0.01
+abstract: Try "our" hot dog's
+license: ~
+author:
+ - Michael G Schwern <schwern\@pobox.com>
+generated_by: ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION
+distribution_type: module
+requires:
+ strict: 0
+meta-spec:
+ url: http://module-build.sourceforge.net/META-spec-v1.3.html
+ version: 1.3
+END
+
my $manifest = maniread("$distdir/MANIFEST");
# VMS is non-case preserving, so we can't know what the MANIFEST will
# look like. :(
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/build_man.t b/gnu/usr.bin/perl/lib/ExtUtils/t/build_man.t
new file mode 100644
index 00000000000..4a544fbb53d
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/build_man.t
@@ -0,0 +1,86 @@
+#!/usr/bin/perl -w
+
+# Test if MakeMaker declines to build man pages under the right conditions.
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't' if -d 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib';
+ }
+}
+
+use strict;
+use Test::More tests => 9;
+
+use File::Spec;
+use TieOut;
+use MakeMaker::Test::Utils;
+use MakeMaker::Test::Setup::BFD;
+
+use ExtUtils::MakeMaker;
+use ExtUtils::MakeMaker::Config;
+
+# Simulate an installation which has man page generation turned off to
+# ensure these tests will still work.
+$Config{installman3dir} = 'none';
+
+chdir 't';
+
+perl_lib();
+
+ok( setup_recurs(), 'setup' );
+END {
+ ok( chdir File::Spec->updir );
+ ok( teardown_recurs(), 'teardown' );
+}
+
+ok( chdir 'Big-Dummy', "chdir'd to Big-Dummy" ) ||
+ diag("chdir failed: $!");
+
+ok( my $stdout = tie *STDOUT, 'TieOut' );
+
+{
+ local $Config{installman3dir} = File::Spec->catdir(qw(t lib));
+
+ my $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION_FROM => 'lib/Big/Dummy.pm',
+ );
+
+ ok( keys %{ $mm->{MAN3PODS} } );
+}
+
+{
+ my $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION_FROM => 'lib/Big/Dummy.pm',
+ INSTALLMAN3DIR => 'none'
+ );
+
+ ok( !keys %{ $mm->{MAN3PODS} } );
+}
+
+
+{
+ my $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION_FROM => 'lib/Big/Dummy.pm',
+ MAN3PODS => {}
+ );
+
+ is_deeply( $mm->{MAN3PODS}, { } );
+}
+
+
+{
+ my $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION_FROM => 'lib/Big/Dummy.pm',
+ MAN3PODS => { "Foo.pm" => "Foo.1" }
+ );
+
+ is_deeply( $mm->{MAN3PODS}, { "Foo.pm" => "Foo.1" } );
+}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/cd.t b/gnu/usr.bin/perl/lib/ExtUtils/t/cd.t
new file mode 100644
index 00000000000..9d62d139e7c
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/cd.t
@@ -0,0 +1,67 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = ('../lib', 'lib/');
+ }
+ else {
+ unshift @INC, 't/lib/';
+ }
+}
+chdir 't';
+
+my $Is_VMS = $^O eq 'VMS';
+
+use File::Spec;
+
+use Test::More tests => 4;
+
+my @cd_args = ("some/dir", "command1", "command2");
+
+{
+ package Test::MM_Win32;
+ use ExtUtils::MM_Win32;
+ @ISA = qw(ExtUtils::MM_Win32);
+
+ my $mm = bless {}, 'Test::MM_Win32';
+
+ {
+ local *make = sub { "nmake" };
+
+ my @dirs = (File::Spec->updir) x 2;
+ my $expected_updir = File::Spec->catdir(@dirs);
+
+ ::is $mm->cd(@cd_args),
+qq{cd some/dir
+ command1
+ command2
+ cd $expected_updir};
+ }
+
+ {
+ local *make = sub { "dmake" };
+
+ ::is $mm->cd(@cd_args),
+q{cd some/dir && command1
+ cd some/dir && command2};
+ }
+}
+
+{
+ is +ExtUtils::MM_Unix->cd(@cd_args),
+q{cd some/dir && command1
+ cd some/dir && command2};
+}
+
+SKIP: {
+ skip("VMS' cd requires vmspath which is only on VMS", 1) unless $Is_VMS;
+
+ use ExtUtils::MM_VMS;
+ is +ExtUtils::MM_VMS->cd(@cd_args),
+q{startdir = F$Environment("Default")
+ Set Default [.some.dir]
+ command1
+ command2
+ Set Default 'startdir'};
+}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/eu_command.t b/gnu/usr.bin/perl/lib/ExtUtils/t/eu_command.t
new file mode 100644
index 00000000000..2d2fdbae223
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/eu_command.t
@@ -0,0 +1,295 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = ('../lib', 'lib/');
+ }
+ else {
+ unshift @INC, 't/lib/';
+ }
+}
+chdir 't';
+
+BEGIN {
+ $Testfile = 'testfile.foo';
+}
+
+BEGIN {
+ 1 while unlink $Testfile, 'newfile';
+ # forcibly remove ecmddir/temp2, but don't import mkpath
+ use File::Path ();
+ File::Path::rmtree( 'ecmddir' );
+}
+
+BEGIN {
+ use Test::More tests => 41;
+ use File::Spec;
+}
+
+BEGIN {
+ # bad neighbor, but test_f() uses exit()
+ *CORE::GLOBAL::exit = ''; # quiet 'only once' warning.
+ *CORE::GLOBAL::exit = sub (;$) { return $_[0] };
+ use_ok( 'ExtUtils::Command' );
+}
+
+{
+ # concatenate this file with itself
+ # be extra careful the regex doesn't match itself
+ use TieOut;
+ my $out = tie *STDOUT, 'TieOut';
+ my $self = $0;
+ unless (-f $self) {
+ my ($vol, $dirs, $file) = File::Spec->splitpath($self);
+ my @dirs = File::Spec->splitdir($dirs);
+ unshift(@dirs, File::Spec->updir);
+ $dirs = File::Spec->catdir(@dirs);
+ $self = File::Spec->catpath($vol, $dirs, $file);
+ }
+ @ARGV = ($self, $self);
+
+ cat();
+ is( scalar( $$out =~ s/use_ok\( 'ExtUtils::Command'//g), 2,
+ 'concatenation worked' );
+
+ # the truth value here is reversed -- Perl true is shell false
+ @ARGV = ( $Testfile );
+ is( test_f(), 1, 'testing non-existent file' );
+
+ @ARGV = ( $Testfile );
+ is( ! test_f(), '', 'testing non-existent file' );
+
+ # these are destructive, have to keep setting @ARGV
+ @ARGV = ( $Testfile );
+ touch();
+
+ @ARGV = ( $Testfile );
+ is( test_f(), 0, 'testing touch() and test_f()' );
+ is_deeply( \@ARGV, [$Testfile], 'test_f preserves @ARGV' );
+
+ @ARGV = ( $Testfile );
+ ok( -e $ARGV[0], 'created!' );
+
+ my ($now) = time;
+ utime ($now, $now, $ARGV[0]);
+ sleep 2;
+
+ # Just checking modify time stamp, access time stamp is set
+ # to the beginning of the day in Win95.
+ # There's a small chance of a 1 second flutter here.
+ my $stamp = (stat($ARGV[0]))[9];
+ cmp_ok( abs($now - $stamp), '<=', 1, 'checking modify time stamp' ) ||
+ diag "mtime == $stamp, should be $now";
+
+ @ARGV = qw(newfile);
+ touch();
+
+ my $new_stamp = (stat('newfile'))[9];
+ cmp_ok( abs($new_stamp - $stamp), '>=', 2, 'newer file created' );
+
+ @ARGV = ('newfile', $Testfile);
+ eqtime();
+
+ $stamp = (stat($Testfile))[9];
+ cmp_ok( abs($new_stamp - $stamp), '<=', 1, 'eqtime' );
+
+ # eqtime use to clear the contents of the file being equalized!
+ open(FILE, ">>$Testfile") || die $!;
+ print FILE "Foo";
+ close FILE;
+
+ @ARGV = ('newfile', $Testfile);
+ eqtime();
+ ok( -s $Testfile, "eqtime doesn't clear the file being equalized" );
+
+ SKIP: {
+ if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' ||
+ $^O eq 'NetWare' || $^O eq 'dos' || $^O eq 'cygwin' ||
+ $^O eq 'MacOS'
+ ) {
+ skip( "different file permission semantics on $^O", 3);
+ }
+
+ # change a file to execute-only
+ @ARGV = ( '0100', $Testfile );
+ ExtUtils::Command::chmod();
+
+ is( ((stat($Testfile))[2] & 07777) & 0700,
+ 0100, 'change a file to execute-only' );
+
+ # change a file to read-only
+ @ARGV = ( '0400', $Testfile );
+ ExtUtils::Command::chmod();
+
+ is( ((stat($Testfile))[2] & 07777) & 0700,
+ ($^O eq 'vos' ? 0500 : 0400), 'change a file to read-only' );
+
+ # change a file to write-only
+ @ARGV = ( '0200', $Testfile );
+ ExtUtils::Command::chmod();
+
+ is( ((stat($Testfile))[2] & 07777) & 0700,
+ ($^O eq 'vos' ? 0700 : 0200), 'change a file to write-only' );
+ }
+
+ # change a file to read-write
+ @ARGV = ( '0600', $Testfile );
+ my @orig_argv = @ARGV;
+ ExtUtils::Command::chmod();
+ is_deeply( \@ARGV, \@orig_argv, 'chmod preserves @ARGV' );
+
+ is( ((stat($Testfile))[2] & 07777) & 0700,
+ ($^O eq 'vos' ? 0700 : 0600), 'change a file to read-write' );
+
+
+ SKIP: {
+ if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' ||
+ $^O eq 'NetWare' || $^O eq 'dos' || $^O eq 'cygwin' ||
+ $^O eq 'MacOS'
+ ) {
+ skip( "different file permission semantics on $^O", 5);
+ }
+
+ @ARGV = ('testdir');
+ mkpath;
+ ok( -e 'testdir' );
+
+ # change a dir to execute-only
+ @ARGV = ( '0100', 'testdir' );
+ ExtUtils::Command::chmod();
+
+ is( ((stat('testdir'))[2] & 07777) & 0700,
+ 0100, 'change a dir to execute-only' );
+
+ # change a dir to read-only
+ @ARGV = ( '0400', 'testdir' );
+ ExtUtils::Command::chmod();
+
+ is( ((stat('testdir'))[2] & 07777) & 0700,
+ ($^O eq 'vos' ? 0500 : 0400), 'change a dir to read-only' );
+
+ # change a dir to write-only
+ @ARGV = ( '0200', 'testdir' );
+ ExtUtils::Command::chmod();
+
+ is( ((stat('testdir'))[2] & 07777) & 0700,
+ ($^O eq 'vos' ? 0700 : 0200), 'change a dir to write-only' );
+
+ @ARGV = ('testdir');
+ rm_rf;
+ ok( ! -e 'testdir', 'rm_rf can delete a read-only dir' );
+ }
+
+
+ # mkpath
+ my $test_dir = File::Spec->join( 'ecmddir', 'temp2' );
+ @ARGV = ( $test_dir );
+ ok( ! -e $ARGV[0], 'temp directory not there yet' );
+ is( test_d(), 1, 'testing non-existent directory' );
+
+ @ARGV = ( $test_dir );
+ mkpath();
+ ok( -e $ARGV[0], 'temp directory created' );
+ is( test_d(), 0, 'testing existing dir' );
+
+ @ARGV = ( $test_dir );
+ # copy a file to a nested subdirectory
+ unshift @ARGV, $Testfile;
+ @orig_argv = @ARGV;
+ cp();
+ is_deeply( \@ARGV, \@orig_argv, 'cp preserves @ARGV' );
+
+ ok( -e File::Spec->join( 'ecmddir', 'temp2', $Testfile ), 'copied okay' );
+
+ # cp should croak if destination isn't directory (not a great warning)
+ @ARGV = ( $Testfile ) x 3;
+ eval { cp() };
+
+ like( $@, qr/Too many arguments/, 'cp croaks on error' );
+
+ # move a file to a subdirectory
+ @ARGV = ( $Testfile, 'ecmddir' );
+ @orig_argv = @ARGV;
+ ok( mv() );
+ is_deeply( \@ARGV, \@orig_argv, 'mv preserves @ARGV' );
+
+ ok( ! -e $Testfile, 'moved file away' );
+ ok( -e File::Spec->join( 'ecmddir', $Testfile ), 'file in new location' );
+
+ # mv should also croak with the same wacky warning
+ @ARGV = ( $Testfile ) x 3;
+
+ eval { mv() };
+ like( $@, qr/Too many arguments/, 'mv croaks on error' );
+
+ # Test expand_wildcards()
+ {
+ my $file = $Testfile;
+ @ARGV = ();
+ chdir 'ecmddir';
+
+ # % means 'match one character' on VMS. Everything else is ?
+ my $match_char = $^O eq 'VMS' ? '%' : '?';
+ ($ARGV[0] = $file) =~ s/.\z/$match_char/;
+
+ # this should find the file
+ ExtUtils::Command::expand_wildcards();
+
+ is_deeply( \@ARGV, [$file], 'expanded wildcard ? successfully' );
+
+ # try it with the asterisk now
+ ($ARGV[0] = $file) =~ s/.{3}\z/\*/;
+ ExtUtils::Command::expand_wildcards();
+
+ is_deeply( \@ARGV, [$file], 'expanded wildcard * successfully' );
+
+ chdir File::Spec->updir;
+ }
+
+ # remove some files
+ my @files = @ARGV = ( File::Spec->catfile( 'ecmddir', $Testfile ),
+ File::Spec->catfile( 'ecmddir', 'temp2', $Testfile ) );
+ rm_f();
+
+ ok( ! -e $_, "removed $_ successfully" ) for (@ARGV);
+
+ # rm_f dir
+ @ARGV = my $dir = File::Spec->catfile( 'ecmddir' );
+ rm_rf();
+ ok( ! -e $dir, "removed $dir successfully" );
+}
+
+{
+ { local @ARGV = 'd2utest'; mkpath; }
+ open(FILE, '>d2utest/foo');
+ binmode(FILE);
+ print FILE "stuff\015\012and thing\015\012";
+ close FILE;
+
+ open(FILE, '>d2utest/bar');
+ binmode(FILE);
+ my $bin = "\c@\c@\c@\c@\c@\c@\cA\c@\c@\c@\015\012".
+ "\@\c@\cA\c@\c@\c@8__LIN\015\012";
+ print FILE $bin;
+ close FILE;
+
+ local @ARGV = 'd2utest';
+ ExtUtils::Command::dos2unix();
+
+ open(FILE, 'd2utest/foo');
+ is( join('', <FILE>), "stuff\012and thing\012", 'dos2unix' );
+ close FILE;
+
+ open(FILE, 'd2utest/bar');
+ binmode(FILE);
+ ok( -B 'd2utest/bar' );
+ is( join('', <FILE>), $bin, 'dos2unix preserves binaries');
+ close FILE;
+}
+
+END {
+ 1 while unlink $Testfile, 'newfile';
+ File::Path::rmtree( 'ecmddir' );
+ File::Path::rmtree( 'd2utest' );
+}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/fixin.t b/gnu/usr.bin/perl/lib/ExtUtils/t/fixin.t
new file mode 100644
index 00000000000..69c0ac722b8
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/fixin.t
@@ -0,0 +1,45 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = ('../lib', 'lib/');
+ }
+ else {
+ unshift @INC, 't/lib/';
+ }
+}
+chdir 't';
+
+use File::Spec;
+
+use Test::More tests => 6;
+
+use TieOut;
+use MakeMaker::Test::Utils;
+use MakeMaker::Test::Setup::BFD;
+
+use ExtUtils::MakeMaker;
+
+chdir 't';
+
+perl_lib();
+
+ok( setup_recurs(), 'setup' );
+END {
+ ok( chdir File::Spec->updir );
+ ok( teardown_recurs(), 'teardown' );
+}
+
+ok( chdir 'Big-Dummy', "chdir'd to Big-Dummy" ) ||
+ diag("chdir failed: $!");
+
+# [rt.cpan.org 26234]
+{
+ local $/ = "foo";
+ local $\ = "bar";
+ MY->fixin("bin/program");
+ is $/, "foo", '$/ not clobbered';
+ is $\, "bar", '$\ not clobbered';
+}
+
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/make.t b/gnu/usr.bin/perl/lib/ExtUtils/t/make.t
new file mode 100644
index 00000000000..3a1626028f9
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/make.t
@@ -0,0 +1,24 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't';
+ @INC = ('../lib', 'lib/');
+ }
+ else {
+ unshift @INC, 't/lib/';
+ }
+}
+
+use Test::More tests => 3;
+
+use ExtUtils::MakeMaker;
+
+my $MM = bless { MAKE => "nmake6" }, "MM";
+is $MM->make, 'nmake';
+
+$MM->{MAKE} = 'GNUmake';
+is $MM->make, 'gmake';
+
+$MM->{MAKE} = 'MMS';
+is $MM->make, 'mms';
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/maketext_filter.t b/gnu/usr.bin/perl/lib/ExtUtils/t/maketext_filter.t
new file mode 100644
index 00000000000..ed3a44d6013
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/maketext_filter.t
@@ -0,0 +1,65 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+ }
+ else {
+ unshift @INC, 't/lib';
+ }
+}
+chdir 't';
+
+use Test::More tests => 6;
+
+use ExtUtils::MakeMaker;
+use ExtUtils::MM_VMS;
+
+sub test_filter {
+ my($text, $vms_text) = @_;
+
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ is( ExtUtils::MM_Any->maketext_filter($text), $text, 'default filter' );
+ is( ExtUtils::MM_VMS->maketext_filter($text), $vms_text, 'VMS filter' );
+}
+
+
+# VMS filter puts a space after the target
+test_filter(<<'END', <<'VMS');
+foo: bar
+ thing: splat
+END
+foo : bar
+ thing: splat
+VMS
+
+
+# And it does it for all targets
+test_filter(<<'END', <<'VMS');
+foo: bar
+ thing: splat
+
+up: down
+ yes
+END
+foo : bar
+ thing: splat
+
+up : down
+ yes
+VMS
+
+
+# And it doesn't mess with macros
+test_filter(<<'END', <<'VMS');
+CLASS=Foo: Bar
+
+target: stuff
+ $(PROGRAM) And::Stuff
+END
+CLASS=Foo: Bar
+
+target : stuff
+ $(PROGRAM) And::Stuff
+VMS
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/parse_version.t b/gnu/usr.bin/perl/lib/ExtUtils/t/parse_version.t
index 8d2a8d0c505..74621734334 100755
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/parse_version.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/parse_version.t
@@ -11,24 +11,63 @@ BEGIN {
}
chdir 't';
-use Test::More tests => 10;
+use Test::More;
use ExtUtils::MakeMaker;
-my %versions = ('$VERSION = 0.02' => 0.02,
- '$VERSION = 0.0' => 0.0,
- '$VERSION = -1.0' => -1.0,
- '$VERSION = undef' => 'undef',
- '$wibble = 1.0' => 'undef',
+my $Has_Version = eval 'require version; "version"->import; 1';
+
+my %versions = (q[$VERSION = '1.00'] => '1.00',
+ q[*VERSION = \'1.01'] => '1.01',
+ q[($VERSION) = q$Revision: 1.1.1.2 $ =~ /(\d+)/g;] => 32208,
+ q[$FOO::VERSION = '1.10';] => '1.10',
+ q[*FOO::VERSION = \'1.11';] => '1.11',
+ '$VERSION = 0.02' => 0.02,
+ '$VERSION = 0.0' => 0.0,
+ '$VERSION = -1.0' => -1.0,
+ '$VERSION = undef' => 'undef',
+ '$wibble = 1.0' => 'undef',
+ q[my $VERSION = '1.01'] => 'undef',
+ q[local $VERISON = '1.02'] => 'undef',
+ q[local $FOO::VERSION = '1.30'] => 'undef',
+ q[our $VERSION = '1.23';] => '1.23',
);
+if( $Has_Version ) {
+ $versions{q[use version; $VERSION = qv("1.2.3");]} = qv("1.2.3");
+ $versions{q[$VERSION = qv("1.2.3")]} = qv("1.2.3");
+}
+
+plan tests => (2 * keys %versions) + 4;
+
while( my($code, $expect) = each %versions ) {
+ is( parse_version_string($code), $expect, $code );
+}
+
+
+sub parse_version_string {
+ my $code = shift;
+
open(FILE, ">VERSION.tmp") || die $!;
print FILE "$code\n";
close FILE;
$_ = 'foo';
- is( MM->parse_version('VERSION.tmp'), $expect, $code );
+ my $version = MM->parse_version('VERSION.tmp');
is( $_, 'foo', '$_ not leaked by parse_version' );
-
+
unlink "VERSION.tmp";
+
+ return $version;
+}
+
+
+# This is a specific test to see if a version subroutine in the $VERSION
+# declaration confuses later calls to the version class.
+# [rt.cpan.org 30747]
+SKIP: {
+ skip "need version.pm", 4 unless $Has_Version;
+ is parse_version_string(q[ $VERSION = '1.00'; sub version { $VERSION } ]),
+ '1.00';
+ is parse_version_string(q[ use version; $VERSION = version->new("1.2.3") ]),
+ qv("1.2.3");
}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/pm.t b/gnu/usr.bin/perl/lib/ExtUtils/t/pm.t
new file mode 100644
index 00000000000..1f6952710c0
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/pm.t
@@ -0,0 +1,47 @@
+#!/usr/bin/perl -w
+
+# Test that MakeMaker honors user's PM override.
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't' if -d 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib';
+ }
+}
+
+use strict;
+use Test::More tests => 6;
+
+use TieOut;
+use MakeMaker::Test::Utils;
+use MakeMaker::Test::Setup::BFD;
+
+use ExtUtils::MakeMaker;
+
+chdir 't';
+
+perl_lib();
+
+ok( setup_recurs(), 'setup' );
+END {
+ ok( chdir File::Spec->updir );
+ ok( teardown_recurs(), 'teardown' );
+}
+
+ok( chdir 'Big-Dummy', "chdir'd to Big-Dummy" ) ||
+ diag("chdir failed: $!");
+
+ok( my $stdout = tie *STDOUT, 'TieOut' );
+
+{
+ my $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION_FROM => 'lib/Big/Dummy.pm',
+ PM => { 'wibble' => 'woof' }
+ );
+
+ is_deeply( $mm->{PM}, { wibble => 'woof' } );
+}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/prereq.t b/gnu/usr.bin/perl/lib/ExtUtils/t/prereq.t
new file mode 100644
index 00000000000..c690a55a02e
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/prereq.t
@@ -0,0 +1,133 @@
+#!/usr/bin/perl -w
+
+# This is a test of the verification of the arguments to
+# WriteMakefile.
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't' if -d 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib';
+ }
+}
+
+use strict;
+use Test::More tests => 13;
+
+use TieOut;
+use MakeMaker::Test::Utils;
+use MakeMaker::Test::Setup::BFD;
+
+use ExtUtils::MakeMaker;
+
+chdir 't';
+
+perl_lib();
+
+ok( setup_recurs(), 'setup' );
+END {
+ ok( chdir File::Spec->updir );
+ ok( teardown_recurs(), 'teardown' );
+}
+
+ok( chdir 'Big-Dummy', "chdir'd to Big-Dummy" ) ||
+ diag("chdir failed: $!");
+
+{
+ ok( my $stdout = tie *STDOUT, 'TieOut' );
+ my $warnings = '';
+ local $SIG{__WARN__} = sub {
+ $warnings .= join '', @_;
+ };
+
+ WriteMakefile(
+ NAME => 'Big::Dummy',
+ PREREQ_PM => {
+ strict => 0
+ }
+ );
+ is $warnings, '';
+
+ $warnings = '';
+ WriteMakefile(
+ NAME => 'Big::Dummy',
+ PREREQ_PM => {
+ strict => 99999
+ }
+ );
+ is $warnings,
+ sprintf("Warning: prerequisite strict 99999 not found. We have %s.\n",
+ strict->VERSION);
+
+ $warnings = '';
+ WriteMakefile(
+ NAME => 'Big::Dummy',
+ PREREQ_PM => {
+ "I::Do::Not::Exist" => 0,
+ }
+ );
+ is $warnings,
+ "Warning: prerequisite I::Do::Not::Exist 0 not found.\n";
+
+ $warnings = '';
+ WriteMakefile(
+ NAME => 'Big::Dummy',
+ PREREQ_PM => {
+ "I::Do::Not::Exist" => 0,
+ "strict" => 99999,
+ }
+ );
+ is $warnings,
+ "Warning: prerequisite I::Do::Not::Exist 0 not found.\n".
+ sprintf("Warning: prerequisite strict 99999 not found. We have %s.\n",
+ strict->VERSION);
+
+ $warnings = '';
+ eval {
+ WriteMakefile(
+ NAME => 'Big::Dummy',
+ PREREQ_PM => {
+ "I::Do::Not::Exist" => 0,
+ "Nor::Do::I" => 0,
+ "strict" => 99999,
+ },
+ PREREQ_FATAL => 1,
+ );
+ };
+
+ is $warnings, '';
+ is $@, <<'END', "PREREQ_FATAL";
+MakeMaker FATAL: prerequisites not found.
+ I::Do::Not::Exist not installed
+ Nor::Do::I not installed
+ strict 99999
+
+Please install these modules first and rerun 'perl Makefile.PL'.
+END
+
+
+ $warnings = '';
+ eval {
+ WriteMakefile(
+ NAME => 'Big::Dummy',
+ PREREQ_PM => {
+ "I::Do::Not::Exist" => 0,
+ },
+ CONFIGURE => sub {
+ require I::Do::Not::Exist;
+ },
+ PREREQ_FATAL => 1,
+ );
+ };
+
+ is $warnings, '';
+ is $@, <<'END', "PREREQ_FATAL happens before CONFIGURE";
+MakeMaker FATAL: prerequisites not found.
+ I::Do::Not::Exist not installed
+
+Please install these modules first and rerun 'perl Makefile.PL'.
+END
+
+}
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/recurs.t b/gnu/usr.bin/perl/lib/ExtUtils/t/recurs.t
index 53bdf478dc1..17da39ee398 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/recurs.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/recurs.t
@@ -15,7 +15,7 @@ BEGIN {
use strict;
use Config;
-use Test::More tests => 25;
+use Test::More tests => 26;
use MakeMaker::Test::Utils;
use MakeMaker::Test::Setup::Recurs;
@@ -111,3 +111,12 @@ ok( open(MAKEFILE, $submakefile) ) || diag("Can't open $submakefile: $!");
'prepend .. not stomping WriteMakefile args' )
}
close MAKEFILE;
+
+
+{
+ # Quiet "make test" failure noise
+ close *STDERR;
+
+ my $test_out = run("$make test");
+ isnt $?, 0, 'test failure in a subdir causes make to fail';
+} \ No newline at end of file
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/revision.t b/gnu/usr.bin/perl/lib/ExtUtils/t/revision.t
new file mode 100644
index 00000000000..896b1914ca0
--- /dev/null
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/revision.t
@@ -0,0 +1,23 @@
+#!/usr/bin/perl -w
+
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir 't' if -d 't';
+ @INC = ('../lib', 'lib');
+ }
+ else {
+ unshift @INC, 't/lib';
+ }
+}
+
+use Test::More tests => 4;
+
+BEGIN {
+ use_ok 'ExtUtils::MakeMaker';
+ use_ok 'ExtUtils::MM_VMS';
+}
+
+# Why 1? Because a common mistake is for the regex to run in scalar context
+# thus getting the count of captured elements (1) rather than the value of $1
+cmp_ok $ExtUtils::MakeMaker::Revision, '>', 1;
+cmp_ok $ExtUtils::MM_VMS::Revision, '>', 1;
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/writemakefile_args.t b/gnu/usr.bin/perl/lib/ExtUtils/t/writemakefile_args.t
index a19a5ee644b..da274d6cc7c 100644
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/writemakefile_args.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/writemakefile_args.t
@@ -14,7 +14,7 @@ BEGIN {
}
use strict;
-use Test::More tests => 16;
+use Test::More tests => 28;
use TieOut;
use MakeMaker::Test::Utils;
@@ -53,7 +53,7 @@ ok( chdir 'Big-Dummy', "chdir'd to Big-Dummy" ) ||
};
is( $warnings, <<VERIFY );
-WARNING: MAN3PODS takes a hash reference not a string/number.
+WARNING: MAN3PODS takes a HASH reference not a string/number.
Please inform the author.
VERIFY
@@ -67,7 +67,7 @@ VERIFY
};
is( $warnings, <<VERIFY );
-WARNING: AUTHOR takes a string/number not a code reference.
+WARNING: AUTHOR takes a string/number not a CODE reference.
Please inform the author.
VERIFY
@@ -105,7 +105,7 @@ VERIFY
};
# We'll get warnings about the bogus libs, that's ok.
- like( $warnings, qr{^WARNING: LIBS takes a array reference or string/number not a hash reference}m );
+ like( $warnings, qr{^WARNING: LIBS takes a ARRAY reference or string/number not a HASH reference}m );
$warnings = '';
@@ -120,4 +120,75 @@ VERIFY
is( $mm->{WIBBLE}, 'something' );
is_deeply( $mm->{wump}, { foo => 42 } );
-}
+
+
+ # Test VERSION
+ $warnings = '';
+ eval {
+ $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION => [1,2,3],
+ );
+ };
+ like( $warnings, qr{^WARNING: VERSION takes a version object or string/number} );
+
+ $warnings = '';
+ eval {
+ $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION => 1.002_003,
+ );
+ };
+ is( $warnings, '' );
+ is( $mm->{VERSION}, '1.002003' );
+
+ $warnings = '';
+ eval {
+ $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION => '1.002_003',
+ );
+ };
+ is( $warnings, '' );
+ is( $mm->{VERSION}, '1.002_003' );
+
+
+ $warnings = '';
+ eval {
+ $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION => bless {}, "Some::Class",
+ );
+ };
+ like( $warnings, '/^WARNING: VERSION takes a version object or string/number not a Some::Class object/' );
+
+
+ SKIP: {
+ skip("Can't test version objects",6) unless eval { require version };
+ version->import;
+
+ my $version = version->new("1.2.3");
+ $warnings = '';
+ eval {
+ $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION => $version,
+ );
+ };
+ is( $warnings, '' );
+ isa_ok( $mm->{VERSION}, 'version' );
+ is( $mm->{VERSION}, $version );
+
+ $warnings = '';
+ $version = qv('1.2.3');
+ eval {
+ $mm = WriteMakefile(
+ NAME => 'Big::Dummy',
+ VERSION => $version,
+ );
+ };
+ is( $warnings, '' );
+ isa_ok( $mm->{VERSION}, 'version' );
+ is( $mm->{VERSION}, $version );
+ }
+} \ No newline at end of file
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/xs.t b/gnu/usr.bin/perl/lib/ExtUtils/t/xs.t
index 62d29eae798..1cadc109b77 100755
--- a/gnu/usr.bin/perl/lib/ExtUtils/t/xs.t
+++ b/gnu/usr.bin/perl/lib/ExtUtils/t/xs.t
@@ -13,12 +13,49 @@ chdir 't';
use Test::More;
use MakeMaker::Test::Utils;
+use MakeMaker::Test::Setup::XS;
+use File::Find;
+use File::Spec;
+use File::Path;
if( have_compiler() ) {
- plan tests => 1;
+ plan tests => 7;
}
else {
plan skip_all => "ExtUtils::CBuilder not installed or couldn't find a compiler";
}
-pass("You have a compiler, isn't that great?");
+my $Is_VMS = $^O eq 'VMS';
+my $perl = which_perl();
+
+# GNV logical interferes with testing
+$ENV{'bin'} = '[.bin]' if $Is_VMS;
+
+chdir 't';
+
+perl_lib;
+
+$| = 1;
+
+ok( setup_xs(), 'setup' );
+END {
+ ok( chdir File::Spec->updir );
+ ok( teardown_xs(), 'teardown' );
+}
+
+ok( chdir('XS-Test'), "chdir'd to XS-Test" ) ||
+ diag("chdir failed: $!");
+
+my @mpl_out = run(qq{$perl Makefile.PL});
+
+cmp_ok( $?, '==', 0, 'Makefile.PL exited with zero' ) ||
+ diag(@mpl_out);
+
+my $make = make_run();
+my $make_out = run("$make");
+is( $?, 0, ' make exited normally' ) ||
+ diag $make_out;
+
+my $test_out = run("$make");
+is( $?, 0, ' make test exited normally' ) ||
+ diag $test_out;