diff options
author | 2002-10-27 22:14:39 +0000 | |
---|---|---|
committer | 2002-10-27 22:14:39 +0000 | |
commit | 55745691c11d58794cc2bb4d620ee3985f4381e6 (patch) | |
tree | d570f77ae0fda2ab3c9daa80b06a330c16cfe79f /gnu/usr.bin/perl/lib/ExtUtils | |
parent | remove MD bits from test. (diff) | |
download | wireguard-openbsd-55745691c11d58794cc2bb4d620ee3985f4381e6.tar.xz wireguard-openbsd-55745691c11d58794cc2bb4d620ee3985f4381e6.zip |
stock perl 5.8.0 from CPAN
Diffstat (limited to 'gnu/usr.bin/perl/lib/ExtUtils')
44 files changed, 8688 insertions, 176 deletions
diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Changes b/gnu/usr.bin/perl/lib/ExtUtils/Changes new file mode 100644 index 00000000000..39bd0c8555f --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/Changes @@ -0,0 +1,402 @@ +6.03 Wed Jun 19 17:06:14 EDT 2002 + - Documented that we're clamping down on cargo-cult MakeMaker + programming. + - Eased up the parameter verification to leave errant values alone. + - Doug MacEachern documented LDDLFLAGS and added to known parameters. + - Possible fix for XS compiles on Cygwin for pre 5.8 perls. + +6.02 Sat Jun 15 19:46:06 EDT 2002 + - ExtUtils::Installed->modules() was broken in scalar context + - Sync bleadperl 16922: Netware updates from Ananth Kesari. + - Sync bleadperl 16922: MM_NW5 tests + - Sync bleadperl 16938 & 16974: MM_MacOS->macify fixes from pudge. + - Sync bleadperl 16989 & 16942: Small test fixes for MacPerl from pudge. + - Improved WriteMakefile param verification to differenciate between + parameters which don't exist and those that just take strings/numbers. + [RT #707] + * Documented TEST_VERBOSE + +6.01 Thu May 30 14:48:57 EDT 2002 + - MacOS Classic fixes from Pudge: recursive make repair, + post_initialize() now used, DEFINE & INC work with relative paths, + removed dead hybrid method/function call code. + * WriteMakefile now a bit more tolerant of wrong arguments, it will + warn and try to soldier on rather than just vomiting. + - Netware whitespace nits (bleadperl@16811) + - Netware Perl version number tag when building dynamic libraries + needs to match the current perl version instead of being hard coded + (a mutation of bleadperl@16851) + - OS/2 bug in TEST_F target found by John Poltorak (bleadperl@16839) + - README in 6.00 still declared this as alpha. + +6.00 Sat May 25 17:14:09 EDT 2002 + - VMS 8-level limit test tweak (bleadperl@16764) + * Here goes nothing. + +5.96_01 Wed May 22 19:11:09 EDT 2002 + - Fixed ExtUtils::testlib so it doesn't taint @INC. + - Fixed ExtUtils::Command so it groks % shell wildcard on VMS. + [RT 625] + - MM now depends on Test::Harness 2.00 on VMS else tests with -T + won't work, command line too long. + - Added Craig's patch to fix limited level VMSs in the core. + +5.95_01 Sat May 18 14:40:12 EDT 2002 + - Fixed ExtUtils::testlib so it has a reasonable chance of working + under taint mode. + +5.94_02 Fri May 17 17:16:04 EDT 2002 + - Fixing Manifest.t test for relative @INC when core testing. + +5.94_01 Fri May 17 14:53:54 EDT 2002 + - Small NetWare change from Novell. + - worked around 5.005_03's lack of a $Config{siteprefix} and + $Config{sitebin}. + - Small cross compilation changes (bleadperl 16582, 16548) + + [[ Test Fixes ]] + - Fixing ExtUtils::Command tests for VMS shell wildcard differences. + - Fixing ExtUtils::Installed tests so they don't go looking at already + installed installed lists. + +5.93_01 Mon May 6 00:54:39 EDT 2002 + - fixed basic.t for limited depth VMS systems + * MM_BeOS was totally hosed by a typo. + - Made the ExtUtils::Command docs clear about how things come + from @ARGV not @_. + - Quieted nmake banners in disttest + + * Backporting to 5.005_03 + - 'require 5.006' statements to 5.00503 + - Removing uses of File::Spec::Functions + - Adding MODE arg to mkdir() + - Changing uses of 'our' to 'use vars' + - Changing uses of 'no warnings' to 'local $SIG{__WARN__}' + - Changing 3-arg opens to 2-arg + - Changing 'open my $fh' to 'open FH' + - 5.005_03's File::Find doesn't have 'no_chdir' + +5.92_01 Mon Apr 29 23:09:38 EDT 2002 + - Fixing case of modules with no .pm files on VMS. + - LDLOADLIBS fix for NetBSD and easier overriding (bleadperl 16233) + * syncing in MM_MacOS from pudge. + - syncing in NetWare fixes (16266 & 16190) + - Cleaning up MM_NW5.pm somewhat. + +5.91_02 Wed Apr 24 01:29:56 EDT 2002 + - Adjustments to tests for inclusion in the core. + +5.91_01 Wed Apr 24 00:11:06 EDT 2002 + [[ API Changes ]] + * A failing Makefile.PL in a subdir will now kill the whole + makefile making process. + * "make install PREFIX=something" will no longer work. Sorry. + - Now supporting the usevendorprefix %Config setting + - Tests now guaranteed to run in alphabetical order. + - Allowing $VERSION = 0. + + [[ Bug Fixes ]] + - Missing prerequisite warning malformatted. + - INSTALL*MAN*DIR and INST_MAN*DIR weren't allowed on the command + line. + * For years now skipcheck() has been returning a different + value than what was documented. + - Partially reversing Ken's "speed up ExtUtils::Manifest" patch + from 5.51_01 so MANIFEST overrides MANIFEST.SKIP. + * Fixed PREFIXification so it works on Win32. + * Fixed PREFIXification so it works on VMS. + - Fixed INSTALLMAN*DIR=none on VMS. + * NetWare fixes (bleadperl@16076) + - Craig Berry fixed some macro corruption on VMS. + - Systems configured to not have man pages now honored thanks to + Paul Green + - Hack to allow 5.6.X versions of ExtUtils::Embed use MY implicitly. + - Moved use of glob out of MM_Unix so MacPerl could build + + [[ Test Changes ]] + - Shortening directory levels to accomodate old VMS's + - was using a slightly wrong prefix for the prefix tests + + [[ Doc Fixes ]] + - Documenting VERBINST + +5.90_01 Thu Apr 11 01:11:54 EDT 2002 + [[ API Changes ]] + * Implementation of the new PREFIX logic. + * Added new INSTALL targets: + INSTALLSITEBIN + INSTALLSITEMAN1DIR INSTALLSITEMAN3DIR + INSTALLVENDORMAN1DIR INSTALLVENDORMAN3DIR + INSTALLVENDORBIN INSTALLVENDORLIB INSTALLVENDORARCH + SITEPREFIX VENDORPREFIX + * INSTALLDIRS=site now properly using $Config{siteprefixexp} + (Thieved from Debian. Thanks!) + * Added INSTALLDIRS=vendor & support for vendor directories + (Thieved from Debian. Thanks!) + + [[ Bug Fixes ]] + - nmake syntax nits from Mattia Barbon + - ExtUtils::Packlist fix for files with spaces in them from Jan Dubois + (bleadperl@15800) + - Old, old, old dmake bug in MM_Win32->pm_to_blib fixed by Nick + (bleadperl 15847) + + [[ Internals ]] + - Purging leftover PDP compiler flags. + +5.55_03 Sat Apr 6 21:57:01 EST 2002 + - Reversing "fix" for RT 444. It wasn't really fixed and it + caused havoc with Compress::Zlib and Tk. + +5.55_02 Sat Apr 6 03:09:15 EST 2002 + [[ Bug Fixes ]] + - Craig Berry fixed install on VMS (again, I munged the last patch) + - MakeMaker might not be recognizing it's in PERL_SRC on Win32. + Made safer. + - For some reason MM_VMS was using $Config{arch} instead of + $Config{archname} + - Fix (well, hack) for creating ABSPERL on VMS. + - Quieting some warnings revealed by ExtUtils::Constant + - test_via_script had a typo and forgot INST_ARCHLIB + + [[ Test Fixes ]] + - INST.t has to tell MakeMaker it's in the PERL_CORE + - Fixing expected values of INST_* when building the core. + +5.55_01 Thu Apr 4 23:58:06 EST 2002 + [[ API Changes ]] + * Long deprecated INST_EXE completely removed. + - Removing TEST_LIBS constant (never seen in a stable MM anyway) + - Added $default argument to prefixify() for safer prefixification. + + [[ Bug Fixes ]] + - $mm->{PERM_*} were not being set + - fixin() redundantly chmod'ing scripts. Let the Makefile do that. + - The above means MM_Unix will now compile cleanly under strict + * init_dirscan's search for Makefile.PL's will no longer look + inside a distdir. + * Fixed running tests when there are t/'s in subdirs. + - MM_DOS inheriting from MM_Unix instead of MM_Win32. DJGPP + appears to be unix-like (bleadperl@15650) + - Escaping constants with # in them so they're not confused as + make comments (bleadperl) + * ExtUtils::MM_Win95 didn't return a true value + - Fixing disttest when perl is a relative path. + * Fixed disttest & tests in subdirs on Win95 + - Fixed recursive Makefile.PL scan on VMS so it skips the distdir + - Fixed a bug when an alternative MAKEFILE is specified and you're + using something other than a Makefile.PL (RT 444) + - Quieting uninit warning when there are no tests. + + [[ Doc Fixes ]] + - Documented INSTALLMAN*DIR == 'none' feature. + + [[ Test Fixes ]] + - Paul Green's which_perl patch to build a proper Perl on systems + that use command extensions. + - basic.t's Makefile.PL PREFIX call wasn't properly quoted for VMS + (Craig Berry) + - little initialization glitch in MM_Win32.t + + [[ Internals ]] + - INST_* constants moved to init_INST + - INSTALL* constants moved to inst_INSTALL + * Internal warning supression removed. + - Temporarily turning off SelfLoader in MM_Unix so warnings + have the right line numbers. + +5.54_01 Sat Mar 30 02:32:44 EST 2002 + [[ New Features ]] + * Added FULLPERLRUN and FULLPERLRUNINST + + [[ Bug Fixes ]] + - hint files were made a little too noisy in 5.53_01 + + [[ Test Fixes ]] + - adjusting for NFS time drift + - basic.t was finding the wrong perl in the core + + [[ Internals ]] + - FULLPERL* PERL* setup moved to init_PERL + +5.53_02 Fri Mar 29 04:47:44 EST 2002 + - Adjusted for Perl core. Synced into bleadperl. + +5.53_01 Fri Mar 29 00:13:02 EST 2002 + [[ Bug Fixes ]] + - Removed duplicate NAME macro definition + - Fixed makemakerdflt target for VMS + * bleadperl@11460 introduced a bug with recursive Makefile.PL's not + having '.' in @INC. PDL should build now. + * MANIFEST.SKIP only working on file names, not full relative paths. + Only since 5.51_01 (RT 413) + * make test TEST_VERBOSE=1 was busted by 5.50_01 (RT 423) + * Error messages from dying Makefile.PL's and hint files were + accidentally supressed in 5.48_04. Fixed. + * Makefile.PL's are supposed to be run in package main. 5.48_04 + broke this. Fixed. + * Fixing installing on VMS. + +5.52_01 Tue Mar 26 00:24:26 EST 2002 + [[ Bug Fixes ]] + * ActivePerl 5.6.1/build 631 now 100% + - Fixed some SelfLoader warnings + * ExtUtils::MM_Win32 not subclassed off of ExtUtils::MM_Any properly + - Bug in local $ENV{FOO} was causing failures in MM_Win32 tests. + Compensating for the bug. + - $Config{prefixexp} is sometimes bad on ActivePerl, compensating + - Accidentally left htmlifypods tests in MM_Win32 tests + + [[ Doc Changes ]] + - Expanding Known Good list + - Adding Known Programs to README + +5.51_01 Mon Mar 18 01:37:02 EST 2002 + [[ API Changes ]] + - Removing xsubpp and typemap from the distribution. These are not + Perl version independent files and should not be upgraded. + - Removing ExtUtils::Embed. Version specific module and should + not be updated. + - Removing ExtUtils::Constant. Not directly tied to MakeMaker. + Will be distributed seperately by Nick Clark. + + [[ New Features ]] + * realclean now deletes 'dist' directory. + + [[ Bug Fixes ]] + * Fixing ExtUtils::Installed for VMS + * Fixed it so MakeMaker can build itself without needing an eariler + version installed + * Fixed ExtUtils::Installed so packlists work on VMS + * ExtUtils::MM_VMS test had a stupid typo that prevented most + of the tests from running. + - Fixing VMS so 'mmk' is always 'mmk all' (bleadperl 15218) + - ExtUtils::MM_Any->catfile was calling catdir + - Added Ken William's "speed up ExtUtils::Manifest" patch. + - Added Nick Clark's return value of manifest routines patch + (bleadperl@14978) + - Merging in bleadperl changes (14438, 14453, 14611, 14612, 14622, + 14655, 14677, 14688, 14902, 15023, 15187, 15367) + - bleadperl change 15325 (VMS 'mmk all' hack) rejected. + - ExtUtils::MM_Any->test_via_harness() now using -MExtUtils::testlib + instead of -I's. This keeps the command line shorter on VMS, but + it means TEST_LIB doesn't work anymore. May prove problematic. + - PERLRUN now uses FULLPERL instead of PERL. This avoids + accidental use of miniperl. May cause problems in the core. + - Fixed test_via_harness() on VMS so it uses PERLRUN. + - ExtUtils::Manifest wrongly handling MANIFEST on VMS. + - ExtUtils::Manifest::maniskip broken due to misuse of /o on a regex. + +5.50_01 Mon Mar 4 23:44:48 EST 2002 + [[ API Changes ]] + htmlifypods and all HTML targets have been removed. It didn't + work properly. A target for HTMLifying of docs will be + added sometime in the future (read: send a patch). + - Deprecated ROOTEXT variable removed (its been deprecated for + more than five years). + - Removed ExtUtils::Miniperl from the CPAN distribution. Can't + see how its useful outside the core. + + [[ New Features ]] + * Emacs backup files (ie. *~) are no longer copied into blib + (this means you won't get Foo.pm~ accidentally installed anymore). + - prefixify() now returns if the prefixification worked or not. + - added the Perl patchlevel info to the description embedded in DLLs + (Ilya Zakharevich perl change 14810) + + [[ Bug Fixes ]] + * 5.49_01 broke anything that depended on the MM class to be loaded + with ExtUtils::MakeMaker, like CPAN. Temporarily fixed. + * Many places wrongfully assume MM methods can be called as class + methods! Inside and outside of MakeMaker. + * DOS now acts like Win32 instead of Unix. This should be less wrong. + - Netware tweak from Ananth Kesari (perl change 14780) + + [[ Doc Changes ]] + * made the docs about the behavior of PREFIX a bit more vague + reflecting its odd behavior. + - Replaced references to %Config with things people are more likely + to understand in PREFIX & LIB docs. + - Put PREFIX before LIB in the docs. + + [[ Internal Refactorings ]] + - File::Spec wrappers consolidated in MM_Any + - test_via_harness/script consolidated in MM_Any + * Added ExtUtils::Command::MM to replace large -e "one-liners" + * Added ExtUtils::MM_UWIN, took UWIN specific code out of MM_Unix. + * Added ExtUtils::MM_DOS, took some DOS specific code out of MM_Unix + - Added a dist() override to MM_OS2. + - Took the OS/2 specific code out of MM_Unix's dist() + - Starting to quote as many command line switches as possible + to make VMS have to override less of MM_Unix. + +5.49_01 Mon Feb 4 00:42:40 EST 2002 + - Default TEST_LIBS now contains absolute paths, so tests can + chdir without breaking @INC. + - Some bug fixes in MM_Win32 were missing in MM_NW5. + - LLIBPERL was not being set. + - Gisle Aas fixed a warning in prompt when the user hits ctrl-D + or pipes STDIN to /dev/null. + - VMS's test is now a proper ->can check. + - Stray newline in Command.t causing havoc (bleadperl 14441) + + * Lots of internal changes. Everything from here on is an internal + change. + - Broke ExtUtils::Liblist::Kid out into its own .pm. Temporary. + - Broke MM and MY out into their own .pm's. Possibly temporary. + - Broke ExtUtils::MM_Win95 out of ExtUtils::MM_Win32. MM_Win95 + is now an MM_Win32 subclass. + - Removed wrapper methods from ExtUtils::Liblist that were + defering File::Spec loading. Almost everything uses File::Spec + - Changed most of the 'our's to 'use vars' in prep for 5.005_03 + backporting + - Changed ExtUtils::MakeMaker->import(...) cargo-cultery in MM_* + modules to proper "use ExtUtils::MakeMaker qw(...)" + - All non-Unix MM_* modules now directly inherit from MM_Unix. + They did this before, but in a round-about way. + - MM_* modules no longer directly muck with @MM::ISA. Instead + @MM::ISA does that itself. + - Removed unnecessary require of Exporter in many MM_* modules. + - MM_Cygwin was using an MM_Unix function directly without have + explicitly required MM_Unix. + - Most of MM_NW5 was redundant with MM_Win32. So MM_NW5 is now + a subclass of Win32 and the reduendant code has been deleted. + - Replaced lots of calls to File::Spec->updir, curdir and rootdir + with a global in MM_Unix. Should make things a bit faster. + - Untabified ExtUtils::MakeMaker. I hate tabs. + - "Which MM subclass should I use" logic moved from EU::MakeMaker + to EU::MM. + - Deprecated EU::MakeMaker::Version_check deleted. + +5.48_04 Mon Jan 21 19:28:38 EST 2002 + - No longer requiring Test::More + - Now tested to work with a clean 5.6.1 + - Stripped out $Revision based $VERSIONs. + - Rolled in patches from p5p, vmsperl & VOS (14325, 14338, 14360, 14364) + * hint files now run in a safer context. Only $self is available. + - ExtUtils::testlib now provides absolute paths into @INC. + No longer obsolete + - Little test fixes + +5.48_03 Thu Jan 17 23:44:38 EST 2002 + * moved bin/inst to bin/instmodsh + * Some Win32 backporting fixes. The -x switch doesn't seem to + work on Win32/5.6.1. + * Bug on Win32. MAKEMAKER variable not set properly. + * _02 broke hints files. Now fixed. + - Minor prereq error formatting glitch + - ExtUtils::testlib no longer a thin wrapper around blib, now a + thin wrapper around lib like it was. blib is noisy on 5.6.1. + - Nick and chromatic found and fixed some warnings in the tests + +5.48_02 Wed Jan 16 19:11:26 EST 2002 + - Fixed some Win32 warnings. Needs more work. + +5.48_01 Wed Jan 16 15:10:28 EST 2002 + * Adapted from bleadperl@14303 + * Backported to 5.6.1 + - inst and xsubpp moved out of lib/ and into bin/ + - ExtUtils::testlib obsoleted. Now a thin wrapper around blib.pm + ***--> Non-Unix platforms not tested at all! Please test and report + back. Tests probably only need minor fixes. + diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Command/MM.pm b/gnu/usr.bin/perl/lib/ExtUtils/Command/MM.pm new file mode 100644 index 00000000000..9eb7d292993 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/Command/MM.pm @@ -0,0 +1,61 @@ +package ExtUtils::Command::MM; + +use strict; + +require 5.005_03; +require Exporter; +use vars qw($VERSION @ISA @EXPORT); +@ISA = qw(Exporter); + +@EXPORT = qw(test_harness); +$VERSION = '0.01'; + +=head1 NAME + +ExtUtils::Command::MM - Commands for the MM's to use in Makefiles + +=head1 SYNOPSIS + + perl -MExtUtils::Command::MM -e "function" files... + + +=head1 DESCRIPTION + +B<FOR INTERNAL USE ONLY!> The interface is not stable. + +ExtUtils::Command::MM encapsulates code which would otherwise have to +be done with large "one" liners. + +They all read their input from @ARGV unless otherwise noted. + +Any $(FOO) used in the examples are make variables, not Perl. + +=over 4 + +=item B<test_harness> + + test_harness($verbose, @test_libs); + +Runs the tests on @ARGV via Test::Harness passing through the $verbose +flag. Any @test_libs will be unshifted onto the test's @INC. + +@test_libs are run in alphabetical order. + +=cut + +sub test_harness { + require Test::Harness; + require File::Spec; + + $Test::Harness::verbose = shift; + + local @INC = @INC; + unshift @INC, map { File::Spec->rel2abs($_) } @_; + Test::Harness::runtests(sort { lc $a cmp lc $b } @ARGV); +} + +=back + +=cut + +1; diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Constant.pm b/gnu/usr.bin/perl/lib/ExtUtils/Constant.pm new file mode 100644 index 00000000000..1268ce02ba9 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/Constant.pm @@ -0,0 +1,1326 @@ +package ExtUtils::Constant; +use vars qw (@ISA $VERSION %XS_Constant %XS_TypeSet @EXPORT_OK %EXPORT_TAGS); +$VERSION = '0.12'; + +=head1 NAME + +ExtUtils::Constant - generate XS code to import C header constants + +=head1 SYNOPSIS + + use ExtUtils::Constant qw (WriteConstants); + WriteConstants( + NAME => 'Foo', + NAMES => [qw(FOO BAR BAZ)], + ); + # Generates wrapper code to make the values of the constants FOO BAR BAZ + # available to perl + +=head1 DESCRIPTION + +ExtUtils::Constant facilitates generating C and XS wrapper code to allow +perl modules to AUTOLOAD constants defined in C library header files. +It is principally used by the C<h2xs> utility, on which this code is based. +It doesn't contain the routines to scan header files to extract these +constants. + +=head1 USAGE + +Generally one only needs to call the C<WriteConstants> function, and then + + #include "const-c.inc" + +in the C section of C<Foo.xs> + + INCLUDE const-xs.inc + +in the XS section of C<Foo.xs>. + +For greater flexibility use C<constant_types()>, C<C_constant> and +C<XS_constant>, with which C<WriteConstants> is implemented. + +Currently this module understands the following types. h2xs may only know +a subset. The sizes of the numeric types are chosen by the C<Configure> +script at compile time. + +=over 4 + +=item IV + +signed integer, at least 32 bits. + +=item UV + +unsigned integer, the same size as I<IV> + +=item NV + +floating point type, probably C<double>, possibly C<long double> + +=item PV + +NUL terminated string, length will be determined with C<strlen> + +=item PVN + +A fixed length thing, given as a [pointer, length] pair. If you know the +length of a string at compile time you may use this instead of I<PV> + +=item SV + +A B<mortal> SV. + +=item YES + +Truth. (C<PL_sv_yes>) The value is not needed (and ignored). + +=item NO + +Defined Falsehood. (C<PL_sv_no>) The value is not needed (and ignored). + +=item UNDEF + +C<undef>. The value of the macro is not needed. + +=back + +=head1 FUNCTIONS + +=over 4 + +=cut + +if ($] >= 5.006) { + eval "use warnings; 1" or die $@; +} +use strict; +use Carp; + +use Exporter; +use Text::Wrap; +$Text::Wrap::huge = 'overflow'; +$Text::Wrap::columns = 80; + +@ISA = 'Exporter'; + +%EXPORT_TAGS = ( 'all' => [ qw( + XS_constant constant_types return_clause memEQ_clause C_stringify + C_constant autoload WriteConstants WriteMakefileSnippet +) ] ); + +@EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); + +# '' is used as a flag to indicate non-ascii macro names, and hence the need +# to pass in the utf8 on/off flag. +%XS_Constant = ( + '' => '', + IV => 'PUSHi(iv)', + UV => 'PUSHu((UV)iv)', + NV => 'PUSHn(nv)', + PV => 'PUSHp(pv, strlen(pv))', + PVN => 'PUSHp(pv, iv)', + SV => 'PUSHs(sv)', + YES => 'PUSHs(&PL_sv_yes)', + NO => 'PUSHs(&PL_sv_no)', + UNDEF => '', # implicit undef +); + +%XS_TypeSet = ( + IV => '*iv_return =', + UV => '*iv_return = (IV)', + NV => '*nv_return =', + PV => '*pv_return =', + PVN => ['*pv_return =', '*iv_return = (IV)'], + SV => '*sv_return = ', + YES => undef, + NO => undef, + UNDEF => undef, +); + + +=item C_stringify NAME + +A function which returns a 7 bit ASCII correctly \ escaped version of the +string passed suitable for C's "" or ''. It will die if passed Unicode +characters. + +=cut + +# Hopefully make a happy C identifier. +sub C_stringify { + local $_ = shift; + return unless defined $_; + confess "Wide character in '$_' intended as a C identifier" if tr/\0-\377//c; + s/\\/\\\\/g; + s/([\"\'])/\\$1/g; # Grr. fix perl mode. + s/\n/\\n/g; # Ensure newlines don't end up in octal + s/\r/\\r/g; + s/\t/\\t/g; + s/\f/\\f/g; + s/\a/\\a/g; + 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 + my $cheat = '([[:^print:]])'; + s/$cheat/sprintf "\\%03o", ord $1/ge; + } else { + require POSIX; + s/([^A-Za-z0-9_])/POSIX::isprint($1) ? $1 : sprintf "\\%03o", ord $1/ge; + } + $_; +} + +=item perl_stringify NAME + +A function which returns a 7 bit ASCII correctly \ escaped version of the +string passed suitable for a perl "" string. + +=cut + +# Hopefully make a happy perl identifier. +sub perl_stringify { + local $_ = shift; + return unless defined $_; + s/\\/\\\\/g; + s/([\"\'])/\\$1/g; # Grr. fix perl mode. + s/\n/\\n/g; # Ensure newlines don't end up in octal + s/\r/\\r/g; + s/\t/\\t/g; + s/\f/\\f/g; + s/\a/\\a/g; + s/([^\0-\177])/sprintf "\\x{%X}", ord $1/ge; + unless ($] < 5.006) { + # This will elicit a warning on 5.005_03 about [: :] being reserved unless + # I cheat + my $cheat = '([[:^print:]])'; + s/$cheat/sprintf "\\%03o", ord $1/ge; + } else { + require POSIX; + s/([^A-Za-z0-9_])/POSIX::isprint($1) ? $1 : sprintf "\\%03o", ord $1/ge; + } + $_; +} + +=item constant_types + +A function returning a single scalar with C<#define> definitions for the +constants used internally between the generated C and XS functions. + +=cut + +sub constant_types () { + my $start = 1; + my @lines; + push @lines, "#define PERL_constant_NOTFOUND\t$start\n"; $start++; + push @lines, "#define PERL_constant_NOTDEF\t$start\n"; $start++; + foreach (sort keys %XS_Constant) { + next if $_ eq ''; + push @lines, "#define PERL_constant_IS$_\t$start\n"; $start++; + } + push @lines, << 'EOT'; + +#ifndef NVTYPE +typedef double NV; /* 5.6 and later define NVTYPE, and typedef NV to it. */ +#endif +#ifndef aTHX_ +#define aTHX_ /* 5.6 or later define this for threading support. */ +#endif +#ifndef pTHX_ +#define pTHX_ /* 5.6 or later define this for threading support. */ +#endif +EOT + + return join '', @lines; +} + +=item memEQ_clause NAME, CHECKED_AT, INDENT + +A function to return a suitable C C<if> statement to check whether I<NAME> +is equal to the C variable C<name>. If I<CHECKED_AT> is defined, then it +is used to avoid C<memEQ> for short names, or to generate a comment to +highlight the position of the character in the C<switch> statement. + +=cut + +sub memEQ_clause { +# if (memEQ(name, "thingy", 6)) { + # Which could actually be a character comparison or even "" + my ($name, $checked_at, $indent) = @_; + $indent = ' ' x ($indent || 4); + my $len = length $name; + + if ($len < 2) { + return $indent . "{\n" if (defined $checked_at and $checked_at == 0); + # We didn't switch, drop through to the code for the 2 character string + $checked_at = 1; + } + if ($len < 3 and defined $checked_at) { + my $check; + if ($checked_at == 1) { + $check = 0; + } elsif ($checked_at == 0) { + $check = 1; + } + if (defined $check) { + my $char = C_stringify (substr $name, $check, 1); + return $indent . "if (name[$check] == '$char') {\n"; + } + } + # Could optimise a memEQ on 3 to 2 single character checks here + $name = C_stringify ($name); + my $body = $indent . "if (memEQ(name, \"$name\", $len)) {\n"; + $body .= $indent . "/* ". (' ' x $checked_at) . '^' + . (' ' x ($len - $checked_at + length $len)) . " */\n" + if defined $checked_at; + return $body; +} + +=item assign INDENT, TYPE, PRE, POST, VALUE... + +A function to return a suitable assignment clause. If I<TYPE> is aggregate +(eg I<PVN> expects both pointer and length) then there should be multiple +I<VALUE>s for the components. I<PRE> and I<POST> if defined give snippets +of C code to proceed and follow the assignment. I<PRE> will be at the start +of a block, so variables may be defined in it. + +=cut + +# Hmm. value undef to to NOTDEF? value () to do NOTFOUND? + +sub assign { + my $indent = shift; + my $type = shift; + my $pre = shift; + my $post = shift || ''; + my $clause; + my $close; + if ($pre) { + chomp $pre; + $clause = $indent . "{\n$pre"; + $clause .= ";" unless $pre =~ /;$/; + $clause .= "\n"; + $close = "$indent}\n"; + $indent .= " "; + } + confess "undef \$type" unless defined $type; + confess "Can't generate code for type $type" unless exists $XS_TypeSet{$type}; + my $typeset = $XS_TypeSet{$type}; + if (ref $typeset) { + die "Type $type is aggregate, but only single value given" + if @_ == 1; + foreach (0 .. $#$typeset) { + $clause .= $indent . "$typeset->[$_] $_[$_];\n"; + } + } elsif (defined $typeset) { + die "Aggregate value given for type $type" + if @_ > 1; + $clause .= $indent . "$typeset $_[0];\n"; + } + chomp $post; + if (length $post) { + $clause .= "$post"; + $clause .= ";" unless $post =~ /;$/; + $clause .= "\n"; + } + $clause .= "${indent}return PERL_constant_IS$type;\n"; + $clause .= $close if $close; + return $clause; +} + +=item return_clause + +return_clause ITEM, INDENT + +A function to return a suitable C<#ifdef> clause. I<ITEM> is a hashref +(as passed to C<C_constant> and C<match_clause>. I<INDENT> is the number +of spaces to indent, defaulting to 6. + +=cut + +sub return_clause ($$) { +##ifdef thingy +# *iv_return = thingy; +# return PERL_constant_ISIV; +##else +# return PERL_constant_NOTDEF; +##endif + my ($item, $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)}; + $value = $name unless defined $value; + $macro = $name unless defined $macro; + + $macro = $value unless defined $macro; + $indent = ' ' x ($indent || 6); + unless ($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"; + } + + # *iv_return = thingy; + # return PERL_constant_ISIV; + $clause .= assign ($indent, $type, $pre, $post, + ref $value ? @$value : $value); + + if (ref $macro or $macro ne "1") { + ##else + $clause .= "#else\n"; + + # return PERL_constant_NOTDEF; + if (!defined $default) { + $clause .= "${indent}return PERL_constant_NOTDEF;\n"; + } else { + my @default = ref $default ? @$default : $default; + $type = shift @default; + $clause .= assign ($indent, $type, $def_pre, $def_post, @default); + } + + ##endif + if (ref $macro) { + $clause .= $macro->[1]; + } else { + $clause .= "#endif\n"; + } + } + return $clause; +} + +=pod + +XXX document me + +=cut + +sub match_clause { + # $offset defined if we have checked an offset. + my ($item, $offset, $indent) = @_; + $indent = ' ' x ($indent || 4); + my $body = ''; + my ($no, $yes, $either, $name, $inner_indent); + if (ref $item eq 'ARRAY') { + ($yes, $no) = @$item; + $either = $yes || $no; + confess "$item is $either expecting hashref in [0] || [1]" + unless ref $either eq 'HASH'; + $name = $either->{name}; + } else { + confess "$item->{name} has utf8 flag '$item->{utf8}', should be false" + if $item->{utf8}; + $name = $item->{name}; + $inner_indent = $indent; + } + + $body .= memEQ_clause ($name, $offset, length $indent); + if ($yes) { + $body .= $indent . " if (utf8) {\n"; + } elsif ($no) { + $body .= $indent . " if (!utf8) {\n"; + } + if ($either) { + $body .= return_clause ($either, 4 + length $indent); + if ($yes and $no) { + $body .= $indent . " } else {\n"; + $body .= return_clause ($no, 4 + length $indent); + } + $body .= $indent . " }"; + } else { + $body .= return_clause ($item, 2 + length $indent); + } + $body .= $indent . "}\n"; +} + +=item switch_clause INDENT, NAMELEN, ITEMHASH, ITEM... + +An internal function to generate a suitable C<switch> clause, called by +C<C_constant> I<ITEM>s are in the hash ref format as given in the description +of C<C_constant>, and must all have the names of the same length, given by +I<NAMELEN> (This is not checked). I<ITEMHASH> is a reference to a hash, +keyed by name, values being the hashrefs in the I<ITEM> list. +(No parameters are modified, and there can be keys in the I<ITEMHASH> that +are not in the list of I<ITEM>s without causing problems). + +=cut + +sub switch_clause { + my ($indent, $comment, $namelen, $items, @items) = @_; + $indent = ' ' x ($indent || 2); + + my @names = sort map {$_->{name}} @items; + my $leader = $indent . '/* '; + my $follower = ' ' x length $leader; + my $body = $indent . "/* Names all of length $namelen. */\n"; + if ($comment) { + $body = wrap ($leader, $follower, $comment) . "\n"; + $leader = $follower; + } + my @safe_names = @names; + foreach (@safe_names) { + next unless tr/A-Za-z0-9_//c; + $_ = '"' . perl_stringify ($_) . '"'; + # Ensure that the enclosing C comment doesn't end + # by turning */ into *" . "/ + s!\*\/!\*"."/!gs; + # gcc -Wall doesn't like finding /* inside a comment + s!\/\*!/"."\*!gs; + } + $body .= wrap ($leader, $follower, join (" ", @safe_names) . " */") . "\n"; + # Figure out what to switch on. + # (RMS, Spread of jump table, Position, Hashref) + my @best = (1e38, ~0); + foreach my $i (0 .. ($namelen - 1)) { + my ($min, $max) = (~0, 0); + my %spread; + foreach (@names) { + my $char = substr $_, $i, 1; + my $ord = ord $char; + $max = $ord if $ord > $max; + $min = $ord if $ord < $min; + push @{$spread{$char}}, $_; + # warn "$_ $char"; + } + # I'm going to pick the character to split on that minimises the root + # mean square of the number of names in each case. Normally this should + # be the one with the most keys, but it may pick a 7 where the 8 has + # one long linear search. I'm not sure if RMS or just sum of squares is + # actually better. + # $max and $min are for the tie-breaker if the root mean squares match. + # Assuming that the compiler may be building a jump table for the + # switch() then try to minimise the size of that jump table. + # Finally use < not <= so that if it still ties the earliest part of + # the string wins. Because if that passes but the memEQ fails, it may + # only need the start of the string to bin the choice. + # I think. But I'm micro-optimising. :-) + my $ss; + $ss += @$_ * @$_ foreach values %spread; + my $rms = sqrt ($ss / keys %spread); + if ($rms < $best[0] || ($rms == $best[0] && ($max - $min) < $best[1])) { + @best = ($rms, $max - $min, $i, \%spread); + } + } + die "Internal error. Failed to pick a switch point for @names" + unless defined $best[2]; + # use Data::Dumper; print Dumper (@best); + my ($offset, $best) = @best[2,3]; + $body .= $indent . "/* Offset $offset gives the best switch position. */\n"; + $body .= $indent . "switch (name[$offset]) {\n"; + foreach my $char (sort keys %$best) { + $body .= $indent . "case '" . C_stringify ($char) . "':\n"; + foreach my $name (sort @{$best->{$char}}) { + my $thisone = $items->{$name}; + # warn "You are here"; + $body .= match_clause ($thisone, $offset, 2 + length $indent); + } + $body .= $indent . " break;\n"; + } + $body .= $indent . "}\n"; + return $body; +} + +=item params WHAT + +An internal function. I<WHAT> should be a hashref of types the constant +function will return. I<params> returns a hashref keyed IV NV PV SV to show +which combination of pointers will be needed in the C argument list. + +=cut + +sub params { + my $what = shift; + foreach (sort keys %$what) { + warn "ExtUtils::Constant doesn't know how to handle values of type $_" unless defined $XS_Constant{$_}; + } + my $params = {}; + $params->{''} = 1 if $what->{''}; + $params->{IV} = 1 if $what->{IV} || $what->{UV} || $what->{PVN}; + $params->{NV} = 1 if $what->{NV}; + $params->{PV} = 1 if $what->{PV} || $what->{PVN}; + $params->{SV} = 1 if $what->{SV}; + return $params; +} + +=item dump_names + +dump_names DEFAULT_TYPE, TYPES, INDENT, OPTIONS, ITEM... + +An internal function to generate the embedded perl code that will regenerate +the constant subroutines. I<DEFAULT_TYPE>, I<TYPES> and I<ITEM>s are the +same as for C_constant. I<INDENT> is treated as number of spaces to indent +by. I<OPTIONS> is a hashref of options. Currently only C<declare_types> is +recognised. If the value is true a C<$types> is always declared in the perl +code generated, if defined and false never declared, and if undefined C<$types> +is only declared if the values in I<TYPES> as passed in cannot be inferred from +I<DEFAULT_TYPES> and the I<ITEM>s. + +=cut + +sub dump_names { + my ($default_type, $what, $indent, $options, @items) = @_; + my $declare_types = $options->{declare_types}; + $indent = ' ' x ($indent || 0); + + my $result; + my (@simple, @complex, %used_types); + foreach (@items) { + my $type; + if (ref $_) { + $type = $_->{type} || $default_type; + if ($_->{utf8}) { + # For simplicity always skip the bytes case, and reconstitute this entry + # from its utf8 twin. + next if $_->{utf8} eq 'no'; + # Copy the hashref, as we don't want to mess with the caller's hashref. + $_ = {%$_}; + utf8::decode ($_->{name}); + delete $_->{utf8}; + } + } else { + $_ = {name=>$_}; + $type = $default_type; + } + $used_types{$type}++; + if ($type eq $default_type and 0 == ($_->{name} =~ tr/A-Za-z0-9_//c) + and !defined ($_->{macro}) and !defined ($_->{value}) + and !defined ($_->{default}) and !defined ($_->{pre}) + and !defined ($_->{post}) and !defined ($_->{def_pre}) + and !defined ($_->{def_post})) { + # It's the default type, and the name consists only of A-Za-z0-9_ + push @simple, $_->{name}; + } else { + push @complex, $_; + } + } + + if (!defined $declare_types) { + # Do they pass in any types we weren't already using? + foreach (keys %$what) { + next if $used_types{$_}; + $declare_types++; # Found one in $what that wasn't used. + last; # And one is enough to terminate this loop + } + } + if ($declare_types) { + $result = $indent . 'my $types = {map {($_, 1)} qw(' + . join (" ", sort keys %$what) . ")};\n"; + } + $result .= wrap ($indent . "my \@names = (qw(", + $indent . " ", join (" ", sort @simple) . ")"); + if (@complex) { + foreach my $item (sort {$a->{name} cmp $b->{name}} @complex) { + my $name = perl_stringify $item->{name}; + my $line = ",\n$indent {name=>\"$name\""; + $line .= ", type=>\"$item->{type}\"" if defined $item->{type}; + foreach my $thing (qw (macro value default pre post def_pre def_post)) { + my $value = $item->{$thing}; + if (defined $value) { + if (ref $value) { + $line .= ", $thing=>[\"" + . join ('", "', map {perl_stringify $_} @$value) . '"]'; + } else { + $line .= ", $thing=>\"" . perl_stringify($value) . "\""; + } + } + } + $line .= "}"; + # Ensure that the enclosing C comment doesn't end + # by turning */ into *" . "/ + $line =~ s!\*\/!\*" . "/!gs; + # gcc -Wall doesn't like finding /* inside a comment + $line =~ s!\/\*!/" . "\*!gs; + $result .= $line; + } + } + $result .= ");\n"; + + $result; +} + + +=item dogfood + +dogfood PACKAGE, SUBNAME, DEFAULT_TYPE, TYPES, INDENT, BREAKOUT, ITEM... + +An internal function to generate the embedded perl code that will regenerate +the constant subroutines. Parameters are the same as for C_constant. + +=cut + +sub dogfood { + my ($package, $subname, $default_type, $what, $indent, $breakout, @items) + = @_; + my $result = <<"EOT"; + /* When generated this function returned values for the list of names given + in this section of perl code. Rather than manually editing these functions + to add or remove constants, which would result in this comment and section + of code becoming inaccurate, we recommend that you edit this section of + code, and use it to regenerate a new set of constant functions which you + then use to replace the originals. + + Regenerate these constant functions by feeding this entire source file to + perl -x + +#!$^X -w +use ExtUtils::Constant qw (constant_types C_constant XS_constant); + +EOT + $result .= dump_names ($default_type, $what, 0, {declare_types=>1}, @items); + $result .= <<'EOT'; + +print constant_types(); # macro defs +EOT + $package = perl_stringify($package); + $result .= + "foreach (C_constant (\"$package\", '$subname', '$default_type', \$types, "; + # The form of the indent parameter isn't defined. (Yet) + if (defined $indent) { + require Data::Dumper; + $Data::Dumper::Terse=1; + $Data::Dumper::Terse=1; # Not used once. :-) + chomp ($indent = Data::Dumper::Dumper ($indent)); + $result .= $indent; + } else { + $result .= 'undef'; + } + $result .= ", $breakout" . ', @names) ) { + print $_, "\n"; # C constant subs +} +print "#### XS Section:\n"; +print XS_constant ("' . $package . '", $types); +__END__ + */ + +'; + + $result; +} + +=item C_constant + +C_constant PACKAGE, SUBNAME, DEFAULT_TYPE, TYPES, INDENT, BREAKOUT, ITEM... + +A function that returns a B<list> of C subroutine definitions that return +the value and type of constants when passed the name by the XS wrapper. +I<ITEM...> gives a list of constant names. Each can either be a string, +which is taken as a C macro name, or a reference to a hash with the following +keys + +=over 8 + +=item name + +The name of the constant, as seen by the perl code. + +=item type + +The type of the constant (I<IV>, I<NV> etc) + +=item value + +A C expression for the value of the constant, or a list of C expressions if +the type is aggregate. This defaults to the I<name> if not given. + +=item macro + +The C pre-processor macro to use in the C<#ifdef>. This defaults to the +I<name>, and is mainly used if I<value> is an C<enum>. If a reference an +array is passed then the first element is used in place of the C<#ifdef> +line, and the second element in place of the C<#endif>. This allows +pre-processor constructions such as + + #if defined (foo) + #if !defined (bar) + ... + #endif + #endif + +to be used to determine if a constant is to be defined. + +A "macro" 1 signals that the constant is always defined, so the C<#if>/C<#endif> +test is omitted. + +=item default + +Default value to use (instead of C<croak>ing with "your vendor has not +defined...") to return if the macro isn't defined. Specify a reference to +an array with type followed by value(s). + +=item pre + +C code to use before the assignment of the value of the constant. This allows +you to use temporary variables to extract a value from part of a C<struct> +and return this as I<value>. This C code is places at the start of a block, +so you can declare variables in it. + +=item post + +C code to place between the assignment of value (to a temporary) and the +return from the function. This allows you to clear up anything in I<pre>. +Rarely needed. + +=item def_pre +=item def_post + +Equivalents of I<pre> and I<post> for the default value. + +=item utf8 + +Generated internally. Is zero or undefined if name is 7 bit ASCII, +"no" if the name is 8 bit (and so should only match if SvUTF8() is false), +"yes" if the name is utf8 encoded. + +The internals automatically clone any name with characters 128-255 but none +256+ (ie one that could be either in bytes or utf8) into a second entry +which is utf8 encoded. + +=back + +I<PACKAGE> is the name of the package, and is only used in comments inside the +generated C code. + +The next 5 arguments can safely be given as C<undef>, and are mainly used +for recursion. I<SUBNAME> defaults to C<constant> if undefined. + +I<DEFAULT_TYPE> is the type returned by C<ITEM>s that don't specify their +type. In turn it defaults to I<IV>. I<TYPES> should be given either as a comma +separated list of types that the C subroutine C<constant> will generate or as +a reference to a hash. I<DEFAULT_TYPE> will be added to the list if not +present, as will any types given in the list of I<ITEM>s. The resultant list +should be the same list of types that C<XS_constant> is given. [Otherwise +C<XS_constant> and C<C_constant> may differ in the number of parameters to the +constant function. I<INDENT> is currently unused and ignored. In future it may +be used to pass in information used to change the C indentation style used.] +The best way to maintain consistency is to pass in a hash reference and let +this function update it. + +I<BREAKOUT> governs when child functions of I<SUBNAME> are generated. If there +are I<BREAKOUT> or more I<ITEM>s with the same length of name, then the code +to switch between them is placed into a function named I<SUBNAME>_I<LEN>, for +example C<constant_5> for names 5 characters long. The default I<BREAKOUT> is +3. A single C<ITEM> is always inlined. + +=cut + +# The parameter now BREAKOUT was previously documented as: +# +# I<NAMELEN> if defined signals that all the I<name>s of the I<ITEM>s are of +# this length, and that the constant name passed in by perl is checked and +# also of this length. It is used during recursion, and should be C<undef> +# unless the caller has checked all the lengths during code generation, and +# the generated subroutine is only to be called with a name of this length. +# +# As you can see it now performs this function during recursion by being a +# scalar reference. + +sub C_constant { + my ($package, $subname, $default_type, $what, $indent, $breakout, @items) + = @_; + $package ||= 'Foo'; + $subname ||= 'constant'; + # I'm not using this. But a hashref could be used for full formatting without + # breaking this API + # $indent ||= 0; + + my ($namelen, $items); + if (ref $breakout) { + # We are called recursively. We trust @items to be normalised, $what to + # be a hashref, and pinch %$items from our parent to save recalculation. + ($namelen, $items) = @$breakout; + } else { + $breakout ||= 3; + $default_type ||= 'IV'; + if (!ref $what) { + # Convert line of the form IV,UV,NV to hash + $what = {map {$_ => 1} split /,\s*/, ($what || '')}; + # 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)) { + 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 "ExtUtils::Constant doesn't know how to handle values of type $_ used in macro $name" unless defined $XS_Constant{$item->{type}}; + if ($name !~ tr/\0-\177//c) { + # 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"; + } + if ($name !~ tr/\0-\377//c) { + $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. + utf8::encode($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; + # use Data::Dumper; print Dumper @items; + } + my $params = params ($what); + + my ($body, @subs) = "static int\n$subname (pTHX_ const char *name"; + $body .= ", STRLEN len" unless defined $namelen; + $body .= ", int utf8" if $params->{''}; + $body .= ", IV *iv_return" if $params->{IV}; + $body .= ", NV *nv_return" if $params->{NV}; + $body .= ", const char **pv_return" if $params->{PV}; + $body .= ", SV **sv_return" if $params->{SV}; + $body .= ") {\n"; + + if (defined $namelen) { + # We are a child subroutine. Print the simple description + my $comment = 'When generated this function returned values for the list' + . ' of names given here. However, subsequent manual editing may have' + . ' added or removed some.'; + $body .= switch_clause (2, $comment, $namelen, $items, @items); + } else { + # We are the top level. + $body .= " /* Initially switch on the length of the name. */\n"; + $body .= dogfood ($package, $subname, $default_type, $what, $indent, + $breakout, @items); + $body .= " switch (len) {\n"; + # Need to group names of the same length + my @by_length; + foreach (@items) { + push @{$by_length[length $_->{name}]}, $_; + } + foreach my $i (0 .. $#by_length) { + next unless $by_length[$i]; # None of this length + $body .= " case $i:\n"; + if (@{$by_length[$i]} == 1) { + $body .= match_clause ($by_length[$i]->[0]); + } elsif (@{$by_length[$i]} < $breakout) { + $body .= switch_clause (4, '', $i, $items, @{$by_length[$i]}); + } else { + # Only use the minimal set of parameters actually needed by the types + # of the names of this length. + my $what = {}; + foreach (@{$by_length[$i]}) { + $what->{$_->{type}} = 1; + $what->{''} = 1 if $_->{utf8}; + } + $params = params ($what); + push @subs, C_constant ($package, "${subname}_$i", $default_type, $what, + $indent, [$i, $items], @{$by_length[$i]}); + $body .= " return ${subname}_$i (aTHX_ name"; + $body .= ", utf8" if $params->{''}; + $body .= ", iv_return" if $params->{IV}; + $body .= ", nv_return" if $params->{NV}; + $body .= ", pv_return" if $params->{PV}; + $body .= ", sv_return" if $params->{SV}; + $body .= ");\n"; + } + $body .= " break;\n"; + } + $body .= " }\n"; + } + $body .= " return PERL_constant_NOTFOUND;\n}\n"; + return (@subs, $body); +} + +=item XS_constant PACKAGE, TYPES, SUBNAME, C_SUBNAME + +A function to generate the XS code to implement the perl subroutine +I<PACKAGE>::constant used by I<PACKAGE>::AUTOLOAD to load constants. +This XS code is a wrapper around a C subroutine usually generated by +C<C_constant>, and usually named C<constant>. + +I<TYPES> should be given either as a comma separated list of types that the +C subroutine C<constant> will generate or as a reference to a hash. It should +be the same list of types as C<C_constant> was given. +[Otherwise C<XS_constant> and C<C_constant> may have different ideas about +the number of parameters passed to the C function C<constant>] + +You can call the perl visible subroutine something other than C<constant> if +you give the parameter I<SUBNAME>. The C subroutine it calls defaults to +the name of the perl visible subroutine, unless you give the parameter +I<C_SUBNAME>. + +=cut + +sub XS_constant { + my $package = shift; + my $what = shift; + my $subname = shift; + my $C_subname = shift; + $subname ||= 'constant'; + $C_subname ||= $subname; + + if (!ref $what) { + # Convert line of the form IV,UV,NV to hash + $what = {map {$_ => 1} split /,\s*/, ($what)}; + } + my $params = params ($what); + my $type; + + my $xs = <<"EOT"; +void +$subname(sv) + PREINIT: +#ifdef dXSTARG + dXSTARG; /* Faster if we have it. */ +#else + dTARGET; +#endif + STRLEN len; + int type; +EOT + + if ($params->{IV}) { + $xs .= " IV iv;\n"; + } else { + $xs .= " /* IV\t\tiv;\tUncomment this if you need to return IVs */\n"; + } + if ($params->{NV}) { + $xs .= " NV nv;\n"; + } else { + $xs .= " /* NV\t\tnv;\tUncomment this if you need to return NVs */\n"; + } + if ($params->{PV}) { + $xs .= " const char *pv;\n"; + } else { + $xs .= + " /* const char\t*pv;\tUncomment this if you need to return PVs */\n"; + } + + $xs .= << 'EOT'; + INPUT: + SV * sv; + const char * s = SvPV(sv, len); +EOT + if ($params->{''}) { + $xs .= << 'EOT'; + INPUT: + int utf8 = SvUTF8(sv); +EOT + } + $xs .= << 'EOT'; + PPCODE: +EOT + + if ($params->{IV} xor $params->{NV}) { + $xs .= << "EOT"; + /* Change this to $C_subname(aTHX_ s, len, &iv, &nv); + if you need to return both NVs and IVs */ +EOT + } + $xs .= " type = $C_subname(aTHX_ s, len"; + $xs .= ', utf8' if $params->{''}; + $xs .= ', &iv' if $params->{IV}; + $xs .= ', &nv' if $params->{NV}; + $xs .= ', &pv' if $params->{PV}; + $xs .= ', &sv' if $params->{SV}; + $xs .= ");\n"; + + $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)); + PUSHs(sv); + break; + case PERL_constant_NOTDEF: + sv = sv_2mortal(newSVpvf( + "Your vendor has not defined $package macro %s, used", s)); + PUSHs(sv); + break; +EOT + + foreach $type (sort keys %XS_Constant) { + # '' marks utf8 flag needed. + next if $type eq ''; + $xs .= "\t/* Uncomment this if you need to return ${type}s\n" + unless $what->{$type}; + $xs .= " case PERL_constant_IS$type:\n"; + if (length $XS_Constant{$type}) { + $xs .= << "EOT"; + EXTEND(SP, 1); + PUSHs(&PL_sv_undef); + $XS_Constant{$type}; +EOT + } else { + # Do nothing. return (), which will be correctly interpreted as + # (undef, undef) + } + $xs .= " break;\n"; + unless ($what->{$type}) { + chop $xs; # Yes, another need for chop not chomp. + $xs .= " */\n"; + } + } + $xs .= << "EOT"; + default: + sv = sv_2mortal(newSVpvf( + "Unexpected return type %d while processing $package macro %s, used", + type, s)); + PUSHs(sv); + } +EOT + + return $xs; +} + + +=item autoload PACKAGE, VERSION, AUTOLOADER + +A function to generate the AUTOLOAD subroutine for the module I<PACKAGE> +I<VERSION> is the perl version the code should be backwards compatible with. +It defaults to the version of perl running the subroutine. If I<AUTOLOADER> +is true, the AUTOLOAD subroutine falls back on AutoLoader::AUTOLOAD for all +names that the constant() routine doesn't recognise. + +=cut + +# ' # Grr. syntax highlighters that don't grok pod. + +sub autoload { + my ($module, $compat_version, $autoloader) = @_; + $compat_version ||= $]; + croak "Can't maintain compatibility back as far as version $compat_version" + if $compat_version < 5; + my $func = "sub AUTOLOAD {\n" + . " # This AUTOLOAD is used to 'autoload' constants from the constant()\n" + . " # XS function."; + $func .= " If a constant is not found then control is passed\n" + . " # to the AUTOLOAD in AutoLoader." if $autoloader; + + + $func .= "\n\n" + . " my \$constname;\n"; + $func .= + " our \$AUTOLOAD;\n" if ($compat_version >= 5.006); + + $func .= <<"EOT"; + (\$constname = \$AUTOLOAD) =~ s/.*:://; + croak "&${module}::constant not defined" if \$constname eq 'constant'; + my (\$error, \$val) = constant(\$constname); +EOT + + if ($autoloader) { + $func .= <<'EOT'; + if ($error) { + if ($error =~ /is not a valid/) { + $AutoLoader::AUTOLOAD = $AUTOLOAD; + goto &AutoLoader::AUTOLOAD; + } else { + croak $error; + } + } +EOT + } else { + $func .= + " if (\$error) { croak \$error; }\n"; + } + + $func .= <<'END'; + { + no strict 'refs'; + # Fixed between 5.005_53 and 5.005_61 +#XXX if ($] >= 5.00561) { +#XXX *$AUTOLOAD = sub () { $val }; +#XXX } +#XXX else { + *$AUTOLOAD = sub { $val }; +#XXX } + } + goto &$AUTOLOAD; +} + +END + + return $func; +} + + +=item WriteMakefileSnippet + +WriteMakefileSnippet ATTRIBUTE =E<gt> VALUE [, ...] + +A function to generate perl code for Makefile.PL that will regenerate +the constant subroutines. Parameters are named as passed to C<WriteConstants>, +with the addition of C<INDENT> to specify the number of leading spaces +(default 2). + +Currently only C<INDENT>, C<NAME>, C<DEFAULT_TYPE>, C<NAMES>, C<C_FILE> and +C<XS_FILE> are recognised. + +=cut + +sub WriteMakefileSnippet { + my %args = @_; + my $indent = $args{INDENT} || 2; + + my $result = <<"EOT"; +ExtUtils::Constant::WriteConstants( + NAME => '$args{NAME}', + NAMES => \\\@names, + DEFAULT_TYPE => '$args{DEFAULT_TYPE}', +EOT + foreach (qw (C_FILE XS_FILE)) { + next unless exists $args{$_}; + $result .= sprintf " %-12s => '%s',\n", + $_, $args{$_}; + } + $result .= <<'EOT'; + ); +EOT + + $result =~ s/^/' 'x$indent/gem; + return dump_names ($args{DEFAULT_TYPE}, undef, $indent, undef, + @{$args{NAMES}}) + . $result; +} + +=item WriteConstants ATTRIBUTE =E<gt> VALUE [, ...] + +Writes a file of C code and a file of XS code which you should C<#include> +and C<INCLUDE> in the C and XS sections respectively of your module's XS +code. You probaby want to do this in your C<Makefile.PL>, so that you can +easily edit the list of constants without touching the rest of your module. +The attributes supported are + +=over 4 + +=item NAME + +Name of the module. This must be specified + +=item DEFAULT_TYPE + +The default type for the constants. If not specified C<IV> is assumed. + +=item BREAKOUT_AT + +The names of the constants are grouped by length. Generate child subroutines +for each group with this number or more names in. + +=item NAMES + +An array of constants' names, either scalars containing names, or hashrefs +as detailed in L<"C_constant">. + +=item C_FILE + +The name of the file to write containing the C code. The default is +C<const-c.inc>. The C<-> in the name ensures that the file can't be +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_FILE + +The name of the file to write containing the XS code. The default is +C<const-xs.inc>. + +=item SUBNAME + +The perl visible name of the XS subroutine generated which will return the +constants. The default is C<constant>. + +=item C_SUBNAME + +The name of the C subroutine generated which will return the constants. +The default is I<SUBNAME>. Child subroutines have C<_> and the name +length appended, so constants with 10 character names would be in +C<constant_10> with the default I<XS_SUBNAME>. + +=back + +=cut + +sub WriteConstants { + my %ARGS = + ( # defaults + C_FILE => 'const-c.inc', + XS_FILE => 'const-xs.inc', + SUBNAME => 'constant', + DEFAULT_TYPE => 'IV', + @_); + + $ARGS{C_SUBNAME} ||= $ARGS{SUBNAME}; # No-one sane will have C_SUBNAME eq '0' + + croak "Module name not specified" unless length $ARGS{NAME}; + + open my $c_fh, ">$ARGS{C_FILE}" or die "Can't open $ARGS{C_FILE}: $!"; + open my $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 implents indent style rules with it. + foreach (C_constant ($ARGS{NAME}, $ARGS{C_SUBNAME}, $ARGS{DEFAULT_TYPE}, + $types, undef, $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}); + + close $c_fh or warn "Error closing $ARGS{C_FILE}: $!"; + close $xs_fh or warn "Error closing $ARGS{XS_FILE}: $!"; +} + +1; +__END__ + +=back + +=head1 AUTHOR + +Nicholas Clark <nick@ccl4.org> based on the code in C<h2xs> by Larry Wall and +others + +=cut diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Installed.pm b/gnu/usr.bin/perl/lib/ExtUtils/Installed.pm index 6961c6fdd47..1375a8299fd 100644 --- a/gnu/usr.bin/perl/lib/ExtUtils/Installed.pm +++ b/gnu/usr.bin/perl/lib/ExtUtils/Installed.pm @@ -1,6 +1,6 @@ package ExtUtils::Installed; -use 5.005_64; +use 5.00503; use strict; use Carp qw(); use ExtUtils::Packlist; @@ -8,170 +8,195 @@ use ExtUtils::MakeMaker; use Config; use File::Find; use File::Basename; -our $VERSION = '0.02'; - -sub _is_type($$$) -{ -my ($self, $path, $type) = @_; -return(1) if ($type eq "all"); -if ($type eq "doc") - { - return(substr($path, 0, length($Config{installman1dir})) - eq $Config{installman1dir} - || - substr($path, 0, length($Config{installman3dir})) - eq $Config{installman3dir} - ? 1 : 0) - } -if ($type eq "prog") - { - return(substr($path, 0, length($Config{prefix})) eq $Config{prefix} - && - substr($path, 0, length($Config{installman1dir})) - ne $Config{installman1dir} - && - substr($path, 0, length($Config{installman3dir})) - ne $Config{installman3dir} - ? 1 : 0); - } -return(0); +use File::Spec; +require VMS::Filespec if $^O eq 'VMS'; + +use vars qw($VERSION); +$VERSION = '0.06'; + +my $DOSISH = ($^O =~ /^(MSWin\d\d|os2|dos|mint)$/); + +sub _is_prefix { + my ($self, $path, $prefix) = @_; + return unless defined $prefix && defined $path; + + if( $^O eq 'VMS' ) { + $prefix = VMS::Filespec::unixify($prefix); + $path = VMS::Filespec::unixify($path); + } + return 1 if substr($path, 0, length($prefix)) eq $prefix; + + if ($DOSISH) { + $path =~ s|\\|/|g; + $prefix =~ s|\\|/|g; + return 1 if $path =~ m{^\Q$prefix\E}i; + } + return(0); } -sub _is_under($$;) -{ -my ($self, $path, @under) = @_; -$under[0] = "" if (! @under); -foreach my $dir (@under) - { - return(1) if (substr($path, 0, length($dir)) eq $dir); - } -return(0); +sub _is_doc { + my ($self, $path) = @_; + my $man1dir = $Config{man1direxp}; + my $man3dir = $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"; + + return($self->_is_doc($path)) if $type eq "doc"; + + if ($type eq "prog") { + return($self->_is_prefix($path, $Config{prefix} || $Config{prefixexp}) + && + !($self->_is_doc($path)) + ? 1 : 0); + } + return(0); +} + +sub _is_under { + my ($self, $path, @under) = @_; + $under[0] = "" if (! @under); + foreach my $dir (@under) { + return(1) if ($self->_is_prefix($path, $dir)); + } -sub new($) -{ -my ($class) = @_; -$class = ref($class) || $class; -my $self = {}; - -# Read the core packlist -$self->{Perl}{packlist} = - ExtUtils::Packlist->new("$Config{installarchlib}/.packlist"); -$self->{Perl}{version} = $Config{version}; - -# Read the module packlists -my $sub = sub - { - # Only process module .packlists - return if ($_) ne ".packlist" || $File::Find::dir eq $Config{installarchlib}; - - # Hack of the leading bits of the paths & convert to a module name - my $module = $File::Find::name; - $module =~ s!$Config{archlib}/auto/(.*)/.packlist!$1!s; - $module =~ s!$Config{sitearch}/auto/(.*)/.packlist!$1!s; - my $modfile = "$module.pm"; - $module =~ s!/!::!g; - - # Find the top-level module file in @INC - $self->{$module}{version} = ''; - foreach my $dir (@INC) - { - my $p = MM->catfile($dir, $modfile); - if (-f $p) - { - $self->{$module}{version} = MM->parse_version($p); - last; - } - } - - # Read the .packlist - $self->{$module}{packlist} = ExtUtils::Packlist->new($File::Find::name); - }; -find($sub, $Config{archlib}, $Config{sitearch}); - -return(bless($self, $class)); + return(0); } -sub modules($) -{ -my ($self) = @_; -return(sort(keys(%$self))); +sub new { + my ($class) = @_; + $class = ref($class) || $class; + my $self = {}; + + my $archlib = $Config{archlibexp}; + my $sitearch = $Config{sitearchexp}; + + # File::Find does not know how to deal with VMS filepaths. + if( $^O eq 'VMS' ) { + $archlib = VMS::Filespec::unixify($archlib); + $sitearch = VMS::Filespec::unixify($sitearch); + } + + if ($DOSISH) { + $archlib =~ s|\\|/|g; + $sitearch =~ s|\\|/|g; + } + + # Read the core packlist + $self->{Perl}{packlist} = + ExtUtils::Packlist->new( File::Spec->catfile($archlib, '.packlist') ); + $self->{Perl}{version} = $Config{version}; + + # Read the module packlists + my $sub = sub { + # Only process module .packlists + return if ($_) ne ".packlist" || $File::Find::dir eq $archlib; + + # 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 $modfile = "$module.pm"; + $module =~ s!/!::!g; + + # Find the top-level module file in @INC + $self->{$module}{version} = ''; + foreach my $dir (@INC) { + my $p = File::Spec->catfile($dir, $modfile); + if (-f $p) { + require ExtUtils::MM; + $self->{$module}{version} = MM->parse_version($p); + last; + } + } + + # Read the .packlist + $self->{$module}{packlist} = + ExtUtils::Packlist->new($File::Find::name); + }; + + my(@dirs) = grep { -e } ($archlib, $sitearch); + find($sub, @dirs) if @dirs; + + return(bless($self, $class)); } -sub files($$;$) -{ -my ($self, $module, $type, @under) = @_; - -# Validate arguments -Carp::croak("$module is not installed") if (! exists($self->{$module})); -$type = "all" if (! defined($type)); -Carp::croak('type must be "all", "prog" or "doc"') - if ($type ne "all" && $type ne "prog" && $type ne "doc"); - -my (@files); -foreach my $file (keys(%{$self->{$module}{packlist}})) - { - push(@files, $file) - if ($self->_is_type($file, $type) && $self->_is_under($file, @under)); - } -return(@files); +sub modules { + my ($self) = @_; + + # Bug/feature of sort in scalar context requires this. + return wantarray ? sort keys %$self : keys %$self; } -sub directories($$;$) -{ -my ($self, $module, $type, @under) = @_; -my (%dirs); -foreach my $file ($self->files($module, $type, @under)) - { - $dirs{dirname($file)}++; - } -return(sort(keys(%dirs))); +sub files { + my ($self, $module, $type, @under) = @_; + + # Validate arguments + Carp::croak("$module is not installed") if (! exists($self->{$module})); + $type = "all" if (! defined($type)); + Carp::croak('type must be "all", "prog" or "doc"') + if ($type ne "all" && $type ne "prog" && $type ne "doc"); + + my (@files); + foreach my $file (keys(%{$self->{$module}{packlist}})) { + push(@files, $file) + if ($self->_is_type($file, $type) && + $self->_is_under($file, @under)); + } + return(@files); } -sub directory_tree($$;$) -{ -my ($self, $module, $type, @under) = @_; -my (%dirs); -foreach my $dir ($self->directories($module, $type, @under)) - { - $dirs{$dir}++; - my ($last) = (""); - while ($last ne $dir) - { - $last = $dir; - $dir = dirname($dir); - last if (! $self->_is_under($dir, @under)); - $dirs{$dir}++; - } - } -return(sort(keys(%dirs))); +sub directories { + my ($self, $module, $type, @under) = @_; + my (%dirs); + foreach my $file ($self->files($module, $type, @under)) { + $dirs{dirname($file)}++; + } + return sort keys %dirs; } -sub validate($;$) -{ -my ($self, $module, $remove) = @_; -Carp::croak("$module is not installed") if (! exists($self->{$module})); -return($self->{$module}{packlist}->validate($remove)); +sub directory_tree { + my ($self, $module, $type, @under) = @_; + my (%dirs); + foreach my $dir ($self->directories($module, $type, @under)) { + $dirs{$dir}++; + my ($last) = (""); + while ($last ne $dir) { + $last = $dir; + $dir = dirname($dir); + last if !$self->_is_under($dir, @under); + $dirs{$dir}++; + } + } + return(sort(keys(%dirs))); } -sub packlist($$) -{ -my ($self, $module) = @_; -Carp::croak("$module is not installed") if (! exists($self->{$module})); -return($self->{$module}{packlist}); +sub validate { + my ($self, $module, $remove) = @_; + Carp::croak("$module is not installed") if (! exists($self->{$module})); + return($self->{$module}{packlist}->validate($remove)); } -sub version($$) -{ -my ($self, $module) = @_; -Carp::croak("$module is not installed") if (! exists($self->{$module})); -return($self->{$module}{version}); +sub packlist { + my ($self, $module) = @_; + Carp::croak("$module is not installed") if (! exists($self->{$module})); + return($self->{$module}{packlist}); } -sub DESTROY -{ +sub version { + my ($self, $module) = @_; + Carp::croak("$module is not installed") if (! exists($self->{$module})); + return($self->{$module}{version}); } + 1; __END__ @@ -208,7 +233,7 @@ described below. =head1 FUNCTIONS -=over +=over 4 =item new() @@ -225,7 +250,7 @@ is given the special name 'Perl'. This takes one mandatory parameter, the name of a module. It returns a list of all the filenames from the package. To obtain a list of core perl files, use the module name 'Perl'. Additional parameters are allowed. The first is one -of the strings "prog", "man" or "all", to select either just program files, +of the strings "prog", "doc" or "all", to select either just program files, just manual files or all files. The remaining parameters are a list of directories. The filenames returned will be restricted to those under the specified directories. @@ -234,7 +259,7 @@ specified directories. This takes one mandatory parameter, the name of a module. It returns a list of all the directories from the package. Additional parameters are allowed. The -first is one of the strings "prog", "man" or "all", to select either just +first is one of the strings "prog", "doc" or "all", to select either just program directories, just manual directories or all directories. The remaining parameters are a list of directories. The directories returned will be restricted to those under the specified directories. This method returns only @@ -242,7 +267,7 @@ the leaf directories that contain files from the specified module. =item directory_tree() -This is identical in operation to directory(), except that it includes all the +This is identical in operation to directories(), except that it includes all the intermediate directories back up to the specified directories. =item validate() diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Liblist/Kid.pm b/gnu/usr.bin/perl/lib/ExtUtils/Liblist/Kid.pm new file mode 100644 index 00000000000..a7e4c2d6f65 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/Liblist/Kid.pm @@ -0,0 +1,531 @@ +package ExtUtils::Liblist::Kid; + +# XXX Splitting this out into its own .pm is a temporary solution. + +# This kid package is to be used by MakeMaker. It will not work if +# $self is not a Makemaker. + +use 5.00503; +# Broken out of MakeMaker from version 4.11 + +use vars qw($VERSION); +$VERSION = 1.29; + +use Config; +use Cwd 'cwd'; +use File::Basename; +use File::Spec; + +sub ext { + if ($^O eq 'VMS') { return &_vms_ext; } + elsif($^O eq 'MSWin32') { return &_win32_ext; } + else { return &_unix_os2_ext; } +} + +sub _unix_os2_ext { + my($self,$potential_libs, $verbose, $give_libs) = @_; + if ($^O =~ 'os2' and $Config{perllibs}) { + # Dynamic libraries are not transitive, so we may need including + # the libraries linked against perl.dll again. + + $potential_libs .= " " if $potential_libs; + $potential_libs .= $Config{perllibs}; + } + return ("", "", "", "", ($give_libs ? [] : ())) unless $potential_libs; + warn "Potential libraries are '$potential_libs':\n" if $verbose; + + my($so) = $Config{'so'}; + my($libs) = $Config{'perllibs'}; + my $Config_libext = $Config{lib_ext} || ".a"; + + + # compute $extralibs, $bsloadlibs and $ldloadlibs from + # $potential_libs + # this is a rewrite of Andy Dougherty's extliblist in perl + + my(@searchpath); # from "-L/path" entries in $potential_libs + my(@libpath) = split " ", $Config{'libpth'}; + my(@ldloadlibs, @bsloadlibs, @extralibs, @ld_run_path, %ld_run_path_seen); + my(@libs, %libs_seen); + my($fullname, $thislib, $thispth, @fullname); + my($pwd) = cwd(); # from Cwd.pm + my($found) = 0; + + foreach $thislib (split ' ', $potential_libs){ + + # Handle possible linker path arguments. + if ($thislib =~ s/^(-[LR]|-Wl,-R)//){ # save path flag type + my($ptype) = $1; + unless (-d $thislib){ + warn "$ptype$thislib ignored, directory does not exist\n" + if $verbose; + next; + } + my($rtype) = $ptype; + if (($ptype eq '-R') or ($ptype eq '-Wl,-R')) { + if ($Config{'lddlflags'} =~ /-Wl,-R/) { + $rtype = '-Wl,-R'; + } elsif ($Config{'lddlflags'} =~ /-R/) { + $rtype = '-R'; + } + } + unless (File::Spec->file_name_is_absolute($thislib)) { + warn "Warning: $ptype$thislib changed to $ptype$pwd/$thislib\n"; + $thislib = $self->catdir($pwd,$thislib); + } + push(@searchpath, $thislib); + push(@extralibs, "$ptype$thislib"); + push(@ldloadlibs, "$rtype$thislib"); + next; + } + + # Handle possible library arguments. + unless ($thislib =~ s/^-l//){ + warn "Unrecognized argument in LIBS ignored: '$thislib'\n"; + next; + } + + my($found_lib)=0; + foreach $thispth (@searchpath, @libpath){ + + # Try to find the full name of the library. We need this to + # determine whether it's a dynamically-loadable library or not. + # This tends to be subject to various os-specific quirks. + # For gcc-2.6.2 on linux (March 1995), DLD can not load + # .sa libraries, with the exception of libm.sa, so we + # deliberately skip them. + if (@fullname = + $self->lsdir($thispth,"^\Qlib$thislib.$so.\E[0-9]+")){ + # Take care that libfoo.so.10 wins against libfoo.so.9. + # Compare two libraries to find the most recent version + # number. E.g. if you have libfoo.so.9.0.7 and + # libfoo.so.10.1, first convert all digits into two + # decimal places. Then we'll add ".00" to the shorter + # strings so that we're comparing strings of equal length + # Thus we'll compare libfoo.so.09.07.00 with + # libfoo.so.10.01.00. Some libraries might have letters + # in the version. We don't know what they mean, but will + # try to skip them gracefully -- we'll set any letter to + # '0'. Finally, sort in reverse so we can take the + # first element. + + #TODO: iterate through the directory instead of sorting + + $fullname = "$thispth/" . + (sort { my($ma) = $a; + my($mb) = $b; + $ma =~ tr/A-Za-z/0/s; + $ma =~ s/\b(\d)\b/0$1/g; + $mb =~ tr/A-Za-z/0/s; + $mb =~ s/\b(\d)\b/0$1/g; + while (length($ma) < length($mb)) { $ma .= ".00"; } + while (length($mb) < length($ma)) { $mb .= ".00"; } + # Comparison deliberately backwards + $mb cmp $ma;} @fullname)[0]; + } elsif (-f ($fullname="$thispth/lib$thislib.$so") + && (($Config{'dlsrc'} ne "dl_dld.xs") || ($thislib eq "m"))){ + } elsif (-f ($fullname="$thispth/lib${thislib}_s$Config_libext") + && (! $Config{'archname'} =~ /RM\d\d\d-svr4/) + && ($thislib .= "_s") ){ # we must explicitly use _s version + } elsif (-f ($fullname="$thispth/lib$thislib$Config_libext")){ + } elsif (-f ($fullname="$thispth/$thislib$Config_libext")){ + } elsif (-f ($fullname="$thispth/Slib$thislib$Config_libext")){ + } elsif ($^O eq 'dgux' + && -l ($fullname="$thispth/lib$thislib$Config_libext") + && readlink($fullname) =~ /^elink:/s) { + # Some of DG's libraries look like misconnected symbolic + # links, but development tools can follow them. (They + # look like this: + # + # libm.a -> elink:${SDE_PATH:-/usr}/sde/\ + # ${TARGET_BINARY_INTERFACE:-m88kdgux}/usr/lib/libm.a + # + # , the compilation tools expand the environment variables.) + } else { + warn "$thislib not found in $thispth\n" if $verbose; + next; + } + warn "'-l$thislib' found at $fullname\n" if $verbose; + my($fullnamedir) = dirname($fullname); + push @ld_run_path, $fullnamedir + unless $ld_run_path_seen{$fullnamedir}++; + push @libs, $fullname unless $libs_seen{$fullname}++; + $found++; + $found_lib++; + + # Now update library lists + + # what do we know about this library... + my $is_dyna = ($fullname !~ /\Q$Config_libext\E\z/); + my $in_perl = ($libs =~ /\B-l\Q$ {thislib}\E\b/s); + + # Do not add it into the list if it is already linked in + # with the main perl executable. + # We have to special-case the NeXT, because math and ndbm + # are both in libsys_s + unless ($in_perl || + ($Config{'osname'} eq 'next' && + ($thislib eq 'm' || $thislib eq 'ndbm')) ){ + push(@extralibs, "-l$thislib"); + } + + # We might be able to load this archive file dynamically + if ( ($Config{'dlsrc'} =~ /dl_next/ && $Config{'osvers'} lt '4_0') + || ($Config{'dlsrc'} =~ /dl_dld/) ) + { + # We push -l$thislib instead of $fullname because + # it avoids hardwiring a fixed path into the .bs file. + # Mkbootstrap will automatically add dl_findfile() to + # the .bs file if it sees a name in the -l format. + # USE THIS, when dl_findfile() is fixed: + # push(@bsloadlibs, "-l$thislib"); + # OLD USE WAS while checking results against old_extliblist + push(@bsloadlibs, "$fullname"); + } else { + if ($is_dyna){ + # For SunOS4, do not add in this shared library if + # it is already linked in the main perl executable + push(@ldloadlibs, "-l$thislib") + unless ($in_perl and $^O eq 'sunos'); + } else { + push(@ldloadlibs, "-l$thislib"); + } + } + last; # found one here so don't bother looking further + } + warn "Note (probably harmless): " + ."No library found for -l$thislib\n" + unless $found_lib>0; + } + + unless( $found ) { + return ('','','','', ($give_libs ? \@libs : ())); + } + else { + return ("@extralibs", "@bsloadlibs", "@ldloadlibs", + join(":",@ld_run_path), ($give_libs ? \@libs : ())); + } +} + +sub _win32_ext { + + require Text::ParseWords; + + my($self, $potential_libs, $verbose, $give_libs) = @_; + + # If user did not supply a list, we punt. + # (caller should probably use the list in $Config{libs}) + return ("", "", "", "", ($give_libs ? [] : ())) unless $potential_libs; + + my $cc = $Config{cc}; + my $VC = 1 if $cc =~ /^cl/i; + my $BC = 1 if $cc =~ /^bcc/i; + my $GC = 1 if $cc =~ /^gcc/i; + my $so = $Config{'so'}; + my $libs = $Config{'perllibs'}; + my $libpth = $Config{'libpth'}; + my $libext = $Config{'lib_ext'} || ".lib"; + my(@libs, %libs_seen); + + if ($libs and $potential_libs !~ /:nodefault/i) { + # If Config.pm defines a set of default libs, we always + # tack them on to the user-supplied list, unless the user + # specified :nodefault + + $potential_libs .= " " if $potential_libs; + $potential_libs .= $libs; + } + warn "Potential libraries are '$potential_libs':\n" if $verbose; + + # normalize to forward slashes + $libpth =~ s,\\,/,g; + $potential_libs =~ s,\\,/,g; + + # compute $extralibs from $potential_libs + + my @searchpath; # from "-L/path" in $potential_libs + my @libpath = Text::ParseWords::quotewords('\s+', 0, $libpth); + my @extralibs; + my $pwd = cwd(); # from Cwd.pm + my $lib = ''; + my $found = 0; + my $search = 1; + my($fullname, $thislib, $thispth); + + # add "$Config{installarchlib}/CORE" to default search path + push @libpath, "$Config{installarchlib}/CORE"; + + if ($VC and exists $ENV{LIB} and $ENV{LIB}) { + push @libpath, split /;/, $ENV{LIB}; + } + + foreach (Text::ParseWords::quotewords('\s+', 0, $potential_libs)){ + + $thislib = $_; + + # see if entry is a flag + if (/^:\w+$/) { + $search = 0 if lc eq ':nosearch'; + $search = 1 if lc eq ':search'; + warn "Ignoring unknown flag '$thislib'\n" + if $verbose and !/^:(no)?(search|default)$/i; + next; + } + + # if searching is disabled, do compiler-specific translations + unless ($search) { + s/^-l(.+)$/$1.lib/ unless $GC; + s/^-L/-libpath:/ if $VC; + push(@extralibs, $_); + $found++; + next; + } + + # handle possible linker path arguments + if (s/^-L// and not -d) { + warn "$thislib ignored, directory does not exist\n" + if $verbose; + next; + } + elsif (-d) { + unless (File::Spec->file_name_is_absolute($_)) { + warn "Warning: '$thislib' changed to '-L$pwd/$_'\n"; + $_ = $self->catdir($pwd,$_); + } + push(@searchpath, $_); + next; + } + + # handle possible library arguments + if (s/^-l// and $GC and !/^lib/i) { + $_ = "lib$_"; + } + $_ .= $libext if !/\Q$libext\E$/i; + + my $secondpass = 0; + LOOKAGAIN: + + # look for the file itself + if (-f) { + warn "'$thislib' found as '$_'\n" if $verbose; + $found++; + push(@extralibs, $_); + next; + } + + my $found_lib = 0; + foreach $thispth (@searchpath, @libpath){ + unless (-f ($fullname="$thispth\\$_")) { + warn "'$thislib' not found as '$fullname'\n" if $verbose; + next; + } + warn "'$thislib' found as '$fullname'\n" if $verbose; + $found++; + $found_lib++; + push(@extralibs, $fullname); + push @libs, $fullname unless $libs_seen{$fullname}++; + last; + } + + # do another pass with (or without) leading 'lib' if they used -l + if (!$found_lib and $thislib =~ /^-l/ and !$secondpass++) { + if ($GC) { + goto LOOKAGAIN if s/^lib//i; + } + elsif (!/^lib/i) { + $_ = "lib$_"; + goto LOOKAGAIN; + } + } + + # give up + warn "Note (probably harmless): " + ."No library found for '$thislib'\n" + unless $found_lib>0; + + } + + return ('','','','', ($give_libs ? \@libs : ())) unless $found; + + # make sure paths with spaces are properly quoted + @extralibs = map { (/\s/ && !/^".*"$/) ? qq["$_"] : $_ } @extralibs; + @libs = map { (/\s/ && !/^".*"$/) ? qq["$_"] : $_ } @libs; + $lib = join(' ',@extralibs); + + # normalize back to backward slashes (to help braindead tools) + # XXX this may break equally braindead GNU tools that don't understand + # backslashes, either. Seems like one can't win here. Cursed be CP/M. + $lib =~ s,/,\\,g; + + warn "Result: $lib\n" if $verbose; + wantarray ? ($lib, '', $lib, '', ($give_libs ? \@libs : ())) : $lib; +} + + +sub _vms_ext { + my($self, $potential_libs,$verbose,$give_libs) = @_; + my(@crtls,$crtlstr); + my($dbgqual) = $self->{OPTIMIZE} || $Config{'optimize'} || + $self->{CCFLAS} || $Config{'ccflags'}; + @crtls = ( ($dbgqual =~ m-/Debug-i ? $Config{'dbgprefix'} : '') + . 'PerlShr/Share' ); + push(@crtls, grep { not /\(/ } split /\s+/, $Config{'perllibs'}); + push(@crtls, grep { not /\(/ } split /\s+/, $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 .= $Config{'exe_ext'}; } + elsif (lc $type eq '/library') { $locspec .= $Config{'lib_ext'}; } + else { $locspec .= $Config{'obj_ext'}; } + $locspec = $self->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) = @Config{'so','lib_ext','obj_ext'}; + # List of common Unix library names and there VMS equivalents + # (VMS equivalent of '' indicates that the library is automatially + # 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 ($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(' ',$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 = $self->fixpath($dir,1); + } + else { + $dir = $self->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,$name,$test,$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) { + foreach $dir (@dirs) { + my($type); + + $name = "$dir$variant"; + warn "\tChecking $name\n" if $verbose > 2; + if (-f ($test = VMS::Filespec::rmsexpand($name))) { + # It's got its own suffix, so we'll have to figure out the type + if ($test =~ /(?:$so|exe)$/i) { $type = 'SHR'; } + elsif ($test =~ /(?:$lib_ext|olb)$/i) { $type = 'OLB'; } + elsif ($test =~ /(?:$obj_ext|obj)$/i) { + warn "Note (probably harmless): " + ."Plain object file $test found in library list\n"; + $type = 'OBJ'; + } + else { + warn "Note (probably harmless): " + ."Unknown library type for $test; assuming shared\n"; + $type = 'SHR'; + } + } + elsif (-f ($test = VMS::Filespec::rmsexpand($name,$so)) or + -f ($test = VMS::Filespec::rmsexpand($name,'.exe'))) { + $type = 'SHR'; + $name = $test unless $test =~ /exe;?\d*$/i; + } + elsif (not length($ctype) and # If we've got a lib already, don't bother + ( -f ($test = VMS::Filespec::rmsexpand($name,$lib_ext)) or + -f ($test = VMS::Filespec::rmsexpand($name,'.olb')))) { + $type = 'OLB'; + $name = $test unless $test =~ /olb;?\d*$/i; + } + elsif (not length($ctype) and # If we've got a lib already, don't bother + ( -f ($test = VMS::Filespec::rmsexpand($name,$obj_ext)) or + -f ($test = VMS::Filespec::rmsexpand($name,'.obj')))) { + warn "Note (probably harmless): " + ."Plain object file $test found in library list\n"; + $type = 'OBJ'; + $name = $test unless $test =~ /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 $test), 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/MANIFEST.SKIP b/gnu/usr.bin/perl/lib/ExtUtils/MANIFEST.SKIP new file mode 100644 index 00000000000..61dde53cedb --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MANIFEST.SKIP @@ -0,0 +1,17 @@ +# Avoid version control files. +\bRCS\b +\bCVS\b +,v$ + +# Avoid Makemaker generated and utility files. +^MANIFEST\.bak +^Makefile$ +^blib/ +^MakeMaker-\d +^pm_to_blib$ + +# Avoid temp and backup files. +~$ +\.old$ +\#$ +^\.# diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM.pm new file mode 100644 index 00000000000..2c23263c9ca --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MM.pm @@ -0,0 +1,80 @@ +package ExtUtils::MM; + +use strict; +use Config; +use vars qw(@ISA $VERSION); +$VERSION = 0.04; + +require ExtUtils::Liblist; +require ExtUtils::MakeMaker; + +@ISA = qw(ExtUtils::Liblist ExtUtils::MakeMaker); + +=head1 NAME + +ExtUtils::MM - OS adjusted ExtUtils::MakeMaker subclass + +=head1 SYNOPSIS + + require ExtUtils::MM; + my $mm = MM->new(...); + +=head1 DESCRIPTION + +B<FOR INTERNAL USE ONLY> + +ExtUtils::MM is a subclass of ExtUtils::MakeMaker which automatically +chooses the appropriate OS specific subclass for you +(ie. ExtUils::MM_Unix, etc...). + +It also provides a convenient alias via the MM class (I didn't want +MakeMaker modules outside of ExtUtils/). + +This class might turn out to be a temporary solution, but MM won't go +away. + +=cut + +{ + # Convenient alias. + package MM; + use vars qw(@ISA); + @ISA = qw(ExtUtils::MM); + sub DESTROY {} +} + +my %Is = (); +$Is{VMS} = 1 if $^O eq 'VMS'; +$Is{OS2} = 1 if $^O eq 'os2'; +$Is{MacOS} = 1 if $^O eq 'MacOS'; +if( $^O eq 'MSWin32' ) { + Win32::IsWin95() ? $Is{Win95} = 1 : $Is{Win32} = 1; +} +$Is{UWIN} = 1 if $^O eq 'uwin'; +$Is{Cygwin} = 1 if $^O eq 'cygwin'; +$Is{NW5} = 1 if $Config{osname} eq 'NetWare'; # intentional +$Is{BeOS} = 1 if $^O =~ /beos/i; # XXX should this be that loose? +$Is{DOS} = 1 if $^O eq 'dos'; + +$Is{Unix} = 1 if !keys %Is; + +if( $Is{NW5} ) { + $^O = 'NetWare'; + delete $Is{Win32}; +} + +_assert( keys %Is == 1 ); +my($OS) = keys %Is; + + +my $class = "ExtUtils::MM_$OS"; +eval "require $class" unless $INC{"ExtUtils/MM_$OS.pm"}; +die $@ if $@; +unshift @ISA, $class; + + +sub _assert { + my $sanity = shift; + die sprintf "Assert failed at %s line %d\n", (caller)[1,2] unless $sanity; + return; +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_Any.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_Any.pm new file mode 100644 index 00000000000..fb48ae2831a --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_Any.pm @@ -0,0 +1,180 @@ +package ExtUtils::MM_Any; + +use strict; +use vars qw($VERSION @ISA); +$VERSION = 0.04; + +use Config; +use File::Spec; + + +=head1 NAME + +ExtUtils::MM_Any - Platform agnostic MM methods + +=head1 SYNOPSIS + + FOR INTERNAL USE ONLY! + + package ExtUtils::MM_SomeOS; + + # Temporarily, you have to subclass both. Put MM_Any first. + require ExtUtils::MM_Any; + require ExtUtils::MM_Unix; + @ISA = qw(ExtUtils::MM_Any ExtUtils::Unix); + +=head1 DESCRIPTION + +B<FOR INTERNAL USE ONLY!> + +ExtUtils::MM_Any is a superclass for the ExtUtils::MM_* set of +modules. It contains methods which are either inherently +cross-platform or are written in a cross-platform manner. + +Subclass off of ExtUtils::MM_Any I<and> ExtUtils::MM_Unix. This is a +temporary solution. + +B<THIS MAY BE TEMPORARY!> + +=head1 Inherently Cross-Platform Methods + +These are methods which are by their nature cross-platform and should +always be cross-platform. + +=head2 File::Spec wrappers B<DEPRECATED> + +The following methods are deprecated wrappers around File::Spec +functions. They exist from before File::Spec did and in fact are from +which File::Spec sprang. + +They are all deprecated. Please use File::Spec directly. + +=over 4 + +=item canonpath + +=cut + +sub canonpath { + shift; + return File::Spec->canonpath(@_);; +} + +=item catdir + +=cut + +sub catdir { + shift; + return File::Spec->catdir(@_); +} + +=item catfile + +=cut + +sub catfile { + shift; + return File::Spec->catfile(@_); +} + +=item curdir + +=cut + +my $Curdir = File::Spec->curdir; +sub curdir { + return $Curdir; +} + +=item file_name_is_absolute + +=cut + +sub file_name_is_absolute { + shift; + return File::Spec->file_name_is_absolute(@_); +} + +=item path + +=cut + +sub path { + return File::Spec->path(); +} + +=item rootdir + +=cut + +my $Rootdir = File::Spec->rootdir; +sub rootdir { + return $Rootdir; +} + +=item updir + +=cut + +my $Updir = File::Spec->updir; +sub updir { + return $Updir; +} + +=back + +=head1 Thought To Be Cross-Platform Methods + +These are methods which are thought to be cross-platform by virtue of +having been written in a way to avoid incompatibilities. + +=over 4 + +=item test_via_harness + + my $command = $mm->test_via_harness($perl, $tests); + +Returns a $command line which runs the given set of $tests with +Test::Harness and the given $perl. + +Used on the t/*.t files. + +=cut + +sub test_via_harness { + my($self, $perl, $tests) = @_; + + return qq{\t$perl "-MExtUtils::Command::MM" }. + qq{"-e" "test_harness(\$(TEST_VERBOSE), '\$(INST_LIB)', '\$(INST_ARCHLIB)')" $tests\n}; +} + +=item test_via_script + + my $command = $mm->test_via_script($perl, $script); + +Returns a $command line which just runs a single test without +Test::Harness. No checks are done on the results, they're just +printed. + +Used for test.pl, since they don't always follow Test::Harness +formatting. + +=cut + +sub test_via_script { + my($self, $perl, $script) = @_; + return qq{\t$perl "-I\$(INST_LIB)" "-I\$(INST_ARCHLIB)" $script\n}; +} + +=back + +=head1 AUTHOR + +Michael G Schwern <schwern@pobox.com> with code from ExtUtils::MM_Unix +and ExtUtils::MM_Win32. + + +=cut + +1; diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_BeOS.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_BeOS.pm new file mode 100644 index 00000000000..5118747bae7 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_BeOS.pm @@ -0,0 +1,48 @@ +package ExtUtils::MM_BeOS; + +=head1 NAME + +ExtUtils::MM_BeOS - methods to override UN*X behaviour in ExtUtils::MakeMaker + +=head1 SYNOPSIS + + use ExtUtils::MM_BeOS; # Done internally by ExtUtils::MakeMaker if needed + +=head1 DESCRIPTION + +See ExtUtils::MM_Unix for a documentation of the methods provided +there. This package overrides the implementation of these methods, not +the semantics. + +=over 4 + +=cut + +use Config; +use File::Spec; +require ExtUtils::MM_Any; +require ExtUtils::MM_Unix; + +use vars qw(@ISA $VERSION); +@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix ); +$VERSION = 1.03; + + +=item perl_archive + +This is internal method that returns path to libperl.a equivalent +to be linked to dynamic extensions. UNIX does not have one, but at +least BeOS has one. + +=cut + +sub perl_archive + { + return File::Spec->catdir('$(PERL_INC)',$Config{libperl}); + } + +=back + +1; +__END__ + diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_Cygwin.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_Cygwin.pm index 439c67ccadc..3c37ffd9f7e 100644 --- a/gnu/usr.bin/perl/lib/ExtUtils/MM_Cygwin.pm +++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_Cygwin.pm @@ -1,27 +1,25 @@ package ExtUtils::MM_Cygwin; -use Config; -#use Cwd; -#use File::Basename; -require Exporter; +use strict; +use vars qw($VERSION @ISA); -Exporter::import('ExtUtils::MakeMaker', - qw( $Verbose &neatvalue)); +use Config; +use File::Spec; -unshift @MM::ISA, 'ExtUtils::MM_Cygwin'; +require ExtUtils::MM_Any; +require ExtUtils::MM_Unix; +@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix ); -sub canonpath { - my($self,$path) = @_; - $path =~ s|\\|/|g; - return $self->ExtUtils::MM_Unix::canonpath($path); -} +$VERSION = 1.04; sub cflags { my($self,$libperl)=@_; return $self->{CFLAGS} if $self->{CFLAGS}; - my $base =$self->ExtUtils::MM_Unix::cflags($libperl); + return '' unless $self->needs_linking(); + + my $base = $self->SUPER::cflags($libperl); foreach (split /\n/, $base) { - / *= */ and $self->{$`} = $'; + /^(\S*)\s*=\s*(\S*)$/ and $self->{$1} = $2; }; $self->{CCFLAGS} .= " -DUSEIMPORTLIB" if ($Config{useshrplib} eq 'true'); @@ -29,8 +27,6 @@ sub cflags { CCFLAGS = $self->{CCFLAGS} OPTIMIZE = $self->{OPTIMIZE} PERLTYPE = $self->{PERLTYPE} -LARGE = $self->{LARGE} -SPLIT = $self->{SPLIT} }; } @@ -42,9 +38,9 @@ sub manifypods { my($dist); my($pod2man_exe); if (defined $self->{PERL_SRC}) { - $pod2man_exe = $self->catfile($self->{PERL_SRC},'pod','pod2man'); + $pod2man_exe = File::Spec->catfile($self->{PERL_SRC},'pod','pod2man'); } else { - $pod2man_exe = $self->catfile($Config{scriptdirexp},'pod2man'); + $pod2man_exe = File::Spec->catfile($Config{scriptdirexp},'pod2man'); } unless ($self->perl_script($pod2man_exe)) { # No pod2man but some MAN3PODS to be installed @@ -56,18 +52,19 @@ Warning: I could not locate your pod2man program. Please make sure, END $pod2man_exe = "-S pod2man"; } - my(@m); + my(@m) = (); push @m, qq[POD2MAN_EXE = $pod2man_exe\n], qq[POD2MAN = \$(PERL) -we '%m=\@ARGV;for (keys %m){' \\\n], q[-e 'next if -e $$m{$$_} && -M $$m{$$_} < -M $$_ && -M $$m{$$_} < -M "], $self->{MAKEFILE}, q[";' \\ -e 'print "Manifying $$m{$$_}\n"; $$m{$$_} =~ s/::/./g;' \\ --e 'system(qq[$$^X ].q["-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" $(POD2MAN_EXE) ].qq[$$_>$$m{$$_}])==0 or warn "Couldn\\047t install $$m{$$_}\n";' \\ +-e 'system(qq[$(PERLRUN) $(POD2MAN_EXE) ].qq[$$_>$$m{$$_}])==0 or warn "Couldn\\047t install $$m{$$_}\n";' \\ -e 'chmod(oct($(PERM_RW))), $$m{$$_} or warn "chmod $(PERM_RW) $$m{$$_}: $$!\n";}' ]; push @m, "\nmanifypods : pure_all "; - push @m, join " \\\n\t", keys %{$self->{MAN1PODS}}, keys %{$self->{MAN3PODS}}; + push @m, join " \\\n\t", keys %{$self->{MAN1PODS}}, + keys %{$self->{MAN3PODS}}; push(@m,"\n"); if (%{$self->{MAN1PODS}} || %{$self->{MAN3PODS}}) { @@ -79,9 +76,16 @@ q[-e 'next if -e $$m{$$_} && -M $$m{$$_} < -M $$_ && -M $$m{$$_} < -M "], join('', @m); } -sub perl_archive -{ - return '$(PERL_INC)' .'/'. ("$Config{libperl}" or "libperl.a"); +sub perl_archive { + if ($Config{useshrplib} eq 'true') { + my $libperl = '$(PERL_INC)' .'/'. "$Config{libperl}"; + if( $] >= 5.007 ) { + $libperl =~ s/a$/dll.a/; + } + return $libperl; + } else { + return '$(PERL_INC)' .'/'. ("$Config{libperl}" or "libperl.a"); + } } 1; @@ -99,7 +103,7 @@ ExtUtils::MM_Cygwin - methods to override UN*X behaviour in ExtUtils::MakeMaker See ExtUtils::MM_Unix for a documentation of the methods provided there. -=over +=over 4 =item canonpath diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_DOS.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_DOS.pm new file mode 100644 index 00000000000..7af868eeca4 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_DOS.pm @@ -0,0 +1,55 @@ +package ExtUtils::MM_DOS; + +use strict; +use vars qw($VERSION @ISA); + +$VERSION = 0.01; + +require ExtUtils::MM_Any; +require ExtUtils::MM_Unix; +@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix ); + + +=head1 NAME + +ExtUtils::MM_DOS - DOS specific subclass of ExtUtils::MM_Unix + +=head1 SYNOPSIS + + Don't use this module directly. + Use ExtUtils::MM and let it choose. + +=head1 DESCRIPTION + +This is a subclass of ExtUtils::MM_Unix which contains functionality +for DOS. + +Unless otherwise stated, it works just like ExtUtils::MM_Unix + +=head2 Overridden methods + +=over 4 + +=item B<replace_manpage_separator> + +=cut + +sub replace_manpage_separator { + my($self, $man) = @_; + + $man =~ s,/+,__,g; + return $man; +} + +=back + +=head1 AUTHOR + +Michael G Schwern <schwern@pobox.com> with code from ExtUtils::MM_Unix + +=head1 SEE ALSO + +L<ExtUtils::MM_Unix>, L<ExtUtils::MakeMaker> + +=cut +1; diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_MacOS.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_MacOS.pm new file mode 100644 index 00000000000..576d7447303 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_MacOS.pm @@ -0,0 +1,940 @@ +# MM_MacOS.pm +# MakeMaker default methods for MacOS +# This package is inserted into @ISA of MakeMaker's MM before the +# built-in ExtUtils::MM_Unix methods if MakeMaker.pm is run under MacOS. +# +# Author: Matthias Neeracher <neeracher@mac.com> +# Maintainer: Chris Nandor <pudge@pobox.com> + +package ExtUtils::MM_MacOS; +require ExtUtils::MM_Any; +require ExtUtils::MM_Unix; +@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix ); + +use vars qw($VERSION); +$VERSION = '1.03'; + +use Config; +use Cwd 'cwd'; +require Exporter; +use File::Basename; +use File::Spec; +use vars qw(%make_data); + +my $Mac_FS = eval { require Mac::FileSpec::Unixish }; + +use ExtUtils::MakeMaker qw($Verbose &neatvalue); + +=head1 NAME + +ExtUtils::MM_MacOS - methods to override UN*X behaviour in ExtUtils::MakeMaker + +=head1 SYNOPSIS + + use ExtUtils::MM_MacOS; # Done internally by ExtUtils::MakeMaker if needed + +=head1 DESCRIPTION + +MM_MacOS currently only produces an approximation to the correct Makefile. + +=cut + +sub new { + my($class,$self) = @_; + my($key); + my($cwd) = cwd(); + + print STDOUT "Mac MakeMaker (v$ExtUtils::MakeMaker::VERSION)\n" if $Verbose; + if (-f "MANIFEST" && ! -f "Makefile.mk"){ + ExtUtils::MakeMaker::check_manifest(); + } + + mkdir("Obj", 0777) unless -d "Obj"; + + $self = {} unless (defined $self); + + check_hints($self); + + my(%initial_att) = %$self; # record initial attributes + + if (defined $self->{CONFIGURE}) { + if (ref $self->{CONFIGURE} eq 'CODE') { + $self = { %$self, %{&{$self->{CONFIGURE}}}}; + } else { + Carp::croak "Attribute 'CONFIGURE' to WriteMakefile() not a code reference\n"; + } + } + + my $newclass = ++$ExtUtils::MakeMaker::PACKNAME; + local @ExtUtils::MakeMaker::Parent = @ExtUtils::MakeMaker::Parent; # Protect against non-local exits + { + no strict 'refs'; + print "Blessing Object into class [$newclass]\n" if $Verbose>=2; + ExtUtils::MakeMaker::mv_all_methods("MY",$newclass); + bless $self, $newclass; + push @Parent, $self; + require ExtUtils::MY; + @{"$newclass\:\:ISA"} = 'MM'; + } + + $ExtUtils::MakeMaker::Recognized_Att_Keys{$_} = 1 + for map { $_ . 'Optimize' } qw(MWC MWCPPC MWC68K MPW MRC MRC SC); + + if (defined $ExtUtils::MakeMaker::Parent[-2]){ + $self->{PARENT} = $ExtUtils::MakeMaker::Parent[-2]; + my $key; + for $key (@ExtUtils::MakeMaker::Prepend_parent) { + next unless defined $self->{PARENT}{$key}; + $self->{$key} = $self->{PARENT}{$key}; + unless ($^O eq 'VMS' && $key =~ /PERL$/) { + $self->{$key} = $self->catdir("..",$self->{$key}) + unless $self->file_name_is_absolute($self->{$key}); + } else { + # PERL or FULLPERL will be a command verb or even a + # command with an argument instead of a full file + # specification under VMS. So, don't turn the command + # into a filespec, but do add a level to the path of + # the argument if not already absolute. + my @cmd = split /\s+/, $self->{$key}; + $cmd[1] = $self->catfile('[-]',$cmd[1]) + unless (@cmd < 2) || $self->file_name_is_absolute($cmd[1]); + $self->{$key} = join(' ', @cmd); + } + } + if ($self->{PARENT}) { + $self->{PARENT}->{CHILDREN}->{$newclass} = $self; + foreach my $opt (qw(POLLUTE PERL_CORE)) { + if (exists $self->{PARENT}->{$opt} + and not exists $self->{$opt}) + { + # inherit, but only if already unspecified + $self->{$opt} = $self->{PARENT}->{$opt}; + } + } + } + my @fm = grep /^FIRST_MAKEFILE=/, @ARGV; + $self->parse_args(@fm) if @fm; + } else { + $self->parse_args(split(' ', $ENV{PERL_MM_OPT} || ''),@ARGV); + } + + $self->{NAME} ||= $self->guess_name; + + ($self->{NAME_SYM} = $self->{NAME}) =~ s/\W+/_/g; + + $self->init_main(); + $self->init_dirscan(); + $self->init_others(); + + push @{$self->{RESULT}}, <<END; +# This Makefile is for the $self->{NAME} extension to perl. +# +# It was generated automatically by MakeMaker version +# $VERSION (Revision: $Revision) from the contents of +# Makefile.PL. Don't edit this file, edit Makefile.PL instead. +# +# ANY CHANGES MADE HERE WILL BE LOST! +# +# MakeMaker Parameters: +END + + foreach $key (sort keys %initial_att){ + my($v) = neatvalue($initial_att{$key}); + $v =~ s/(CODE|HASH|ARRAY|SCALAR)\([\dxa-f]+\)/$1\(...\)/; + $v =~ tr/\n/ /s; + push @{$self->{RESULT}}, "# $key => $v"; + } + + # turn the SKIP array into a SKIPHASH hash + my (%skip,$skip); + for $skip (@{$self->{SKIP} || []}) { + $self->{SKIPHASH}{$skip} = 1; + } + delete $self->{SKIP}; # free memory + + # We skip many sections for MacOS, but we don't say anything about it in the Makefile + for (qw/ const_config tool_autosplit + tool_xsubpp tools_other dist macro depend post_constants + pasthru c_o xs_c xs_o top_targets linkext + dynamic_bs dynamic_lib static_lib manifypods + installbin subdirs dist_basics dist_core + dist_dir dist_test dist_ci install force perldepend makefile + staticmake test pm_to_blib selfdocument + const_loadlibs const_cccmd + /) + { + $self->{SKIPHASH}{$_} = 2; + } + push @ExtUtils::MakeMaker::MM_Sections, "rulez" + unless grep /rulez/, @ExtUtils::MakeMaker::MM_Sections; + + if ($self->{PARENT}) { + for (qw/install dist dist_basics dist_core dist_dir dist_test dist_ci/) { + $self->{SKIPHASH}{$_} = 1; + } + } + + # We run all the subdirectories now. They don't have much to query + # from the parent, but the parent has to query them: if they need linking! + unless ($self->{NORECURS}) { + $self->eval_in_subdirs if @{$self->{DIR}}; + } + + my $section; + foreach $section ( @ExtUtils::MakeMaker::MM_Sections ){ + next if ($self->{SKIPHASH}{$section} == 2); + print "Processing Makefile '$section' section\n" if ($Verbose >= 2); + $self->{ABSTRACT_FROM} = macify($self->{ABSTRACT_FROM}) + if $self->{ABSTRACT_FROM}; + my($skipit) = $self->skipcheck($section); + if ($skipit){ + push @{$self->{RESULT}}, "\n# --- MakeMaker $section section $skipit."; + } else { + my(%a) = %{$self->{$section} || {}}; + push @{$self->{RESULT}}, "\n# --- MakeMaker $section section:"; + push @{$self->{RESULT}}, "# " . join ", ", %a if $Verbose && %a; + push @{$self->{RESULT}}, $self->nicetext($self->$section( %a )); + } + } + + push @{$self->{RESULT}}, "\n# End."; + pop @Parent; + + $ExtUtils::MM_MacOS::make_data{$cwd} = $self; + $self; +} + +sub skipcheck { + my($self) = shift; + my($section) = @_; + return 'skipped' if $self->{SKIPHASH}{$section}; + return ''; +} + +=item maybe_command + +Returns true, if the argument is likely to be a command. + +=cut + +sub maybe_command { + my($self,$file) = @_; + return $file if ! -d $file; + return; +} + +=item guess_name + +Guess the name of this package by examining the working directory's +name. MakeMaker calls this only if the developer has not supplied a +NAME attribute. + +=cut + +sub guess_name { + my($self) = @_; + my $name = cwd(); + $name =~ s/.*:// unless ($name =~ s/^.*:ext://); + $name =~ s#:#::#g; + $name =~ s#[\-_][\d.\-]+$##; # this is new with MM 5.00 + $name; +} + +=item macify + +Translate relative path names into Mac names. + +=cut + +sub macify { + my($unix) = @_; + my(@mac); + + foreach (split(/[ \t\n]+/, $unix)) { + if (m|/|) { + if ($Mac_FS) { # should always be true + $_ = Mac::FileSpec::Unixish::nativize($_); + } else { + s|^\./||; + s|/|:|g; + $_ = ":$_"; + } + } + push(@mac, $_); + } + + return "@mac"; +} + +=item patternify + +Translate to Mac names & patterns + +=cut + +sub patternify { + my($unix) = @_; + my(@mac); + + foreach (split(/[ \t\n]+/, $unix)) { + if (m|/|) { + $_ = ":$_"; + s|/|:|g; + s|\*|Å|g; + $_ = "'$_'" if /[?Å]/; + push(@mac, $_); + } + } + + return "@mac"; +} + +=item init_main + +Initializes some of NAME, FULLEXT, BASEEXT, ROOTEXT, DLBASE, PERL_SRC, +PERL_LIB, PERL_ARCHLIB, PERL_INC, INSTALLDIRS, INST_*, INSTALL*, +PREFIX, CONFIG, AR, AR_STATIC_ARGS, LD, OBJ_EXT, LIB_EXT, MAP_TARGET, +LIBPERL_A, VERSION_FROM, VERSION, DISTNAME, VERSION_SYM. + +=cut + +sub init_main { + my($self) = @_; + + # --- Initialize Module Name and Paths + + # NAME = The perl module name for this extension (eg DBD::Oracle). + # FULLEXT = Pathname for extension directory (eg DBD/Oracle). + # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. + # ROOTEXT = Directory part of FULLEXT with trailing :. + ($self->{FULLEXT} = + $self->{NAME}) =~ s!::!:!g ; #eg. BSD:Foo:Socket + ($self->{BASEEXT} = + $self->{NAME}) =~ s!.*::!! ; #eg. Socket + ($self->{ROOTEXT} = + $self->{FULLEXT}) =~ s#:?\Q$self->{BASEEXT}\E$## ; #eg. BSD:Foo + $self->{ROOTEXT} .= ":" if ($self->{ROOTEXT}); + + # --- Initialize PERL_LIB, INST_LIB, PERL_SRC + + # *Real* information: where did we get these two from? ... + my $inc_config_dir = dirname($INC{'Config.pm'}); + my $inc_carp_dir = dirname($INC{'Carp.pm'}); + + unless ($self->{PERL_SRC}){ + my($dir); + foreach $dir (qw(:: ::: :::: ::::: ::::::)){ + if (-f "${dir}perl.h") { + $self->{PERL_SRC}=$dir ; + last; + } + } + if (!$self->{PERL_SRC} && -f "$ENV{MACPERL}CORE:perl:perl.h") { + # Mac pathnames may be very nasty, so we'll install symlinks + unlink(":PerlCore", ":PerlLib"); + symlink("$ENV{MACPERL}CORE:", "PerlCore"); + symlink("$ENV{MACPERL}lib:", "PerlLib"); + $self->{PERL_SRC} = ":PerlCore:perl:" ; + $self->{PERL_LIB} = ":PerlLib:"; + } + } + if ($self->{PERL_SRC}){ + $self->{MACPERL_SRC} = File::Spec->catdir("$self->{PERL_SRC}","macos:"); + $self->{MACPERL_LIB} ||= File::Spec->catdir("$self->{MACPERL_SRC}","lib"); + $self->{PERL_LIB} ||= File::Spec->catdir("$self->{PERL_SRC}","lib"); + $self->{PERL_ARCHLIB} = $self->{PERL_LIB}; + $self->{PERL_INC} = $self->{PERL_SRC}; + $self->{MACPERL_INC} = $self->{MACPERL_SRC}; + } else { +# hmmmmmmm ... ? + $self->{PERL_LIB} ||= "$ENV{MACPERL}site_perl"; + $self->{PERL_ARCHLIB} = $self->{PERL_LIB}; + $self->{PERL_INC} = $ENV{MACPERL}; +# die <<END; +#On MacOS, we need to build under the Perl source directory or have the MacPerl SDK +#installed in the MacPerl folder. +#END + } + + $self->{INSTALLDIRS} = "perl"; + $self->{INST_LIB} = $self->{INST_ARCHLIB} = $self->{PERL_LIB}; + $self->{INST_MAN1DIR} = $self->{INSTALLMAN1DIR} = "none"; + $self->{MAN1EXT} ||= $Config::Config{man1ext}; + $self->{INST_MAN3DIR} = $self->{INSTALLMAN3DIR} = "none"; + $self->{MAN3EXT} ||= $Config::Config{man3ext}; + $self->{MAP_TARGET} ||= "perl"; + + # make a simple check if we find Exporter + # hm ... do we really care? at all? +# warn "Warning: PERL_LIB ($self->{PERL_LIB}) seems not to be a perl library directory +# (Exporter.pm not found)" +# unless -f File::Spec->catfile("$self->{PERL_LIB}","Exporter.pm") || +# $self->{NAME} eq "ExtUtils::MakeMaker"; + + # Determine VERSION and VERSION_FROM + ($self->{DISTNAME}=$self->{NAME}) =~ s#(::)#-#g unless $self->{DISTNAME}; + if ($self->{VERSION_FROM}){ + local *FH; + open(FH,macify($self->{VERSION_FROM})) or + die "Could not open '$self->{VERSION_FROM}' (attribute VERSION_FROM): $!"; + while (<FH>) { + chop; + next unless /\$([\w:]*\bVERSION)\b.*=/; + local $ExtUtils::MakeMaker::module_version_variable = $1; + my($eval) = "$_;"; + eval $eval; + die "Could not eval '$eval': $@" if $@; + if ($self->{VERSION} = $ {$ExtUtils::MakeMaker::module_version_variable}){ + print "$self->{NAME} VERSION is $self->{VERSION} (from $self->{VERSION_FROM})\n" if $Verbose; + } else { + # XXX this should probably croak + print "WARNING: Setting VERSION via file '$self->{VERSION_FROM}' failed\n"; + } + last; + } + close FH; + } + + if ($self->{VERSION}) { + $self->{VERSION} =~ s/^\s+//; + $self->{VERSION} =~ s/\s+$//; + } + + $self->{VERSION} = "0.10" unless $self->{VERSION}; + ($self->{VERSION_SYM} = $self->{VERSION}) =~ s/\W/_/g; + + + # Graham Barr and Paul Marquess had some ideas how to ensure + # version compatibility between the *.pm file and the + # corresponding *.xs file. The bottomline was, that we need an + # XS_VERSION macro that defaults to VERSION: + $self->{XS_VERSION} ||= $self->{VERSION}; + + # --- Initialize Perl Binary Locations + + # Find Perl 5. The only contract here is that both 'PERL' and 'FULLPERL' + # will be working versions of perl 5. miniperl has priority over perl + # for PERL to ensure that $(PERL) is usable while building ./ext/* + my ($component,@defpath); + foreach $component ($self->{PERL_SRC}, File::Spec->path(), $Config::Config{binexp}) { + push @defpath, $component if defined $component; + } + $self->{PERL} = "$self->{PERL_SRC}miniperl"; + $self->{FULLPERL} = "$self->{PERL_SRC}perl"; + $self->{MAKEFILE} = "Makefile.mk"; +} + +=item init_others + +Initializes LDLOADLIBS, LIBS + +=cut + +sub init_others { # --- Initialize Other Attributes + my($self) = shift; + + if ( !$self->{OBJECT} ) { + # init_dirscan should have found out, if we have C files + $self->{OBJECT} = ""; + $self->{OBJECT} = "$self->{BASEEXT}.c" if @{$self->{C}||[]}; + } else { + $self->{OBJECT} =~ s/\$\(O_FILES\)/@{$self->{C}||[]}/; + } + my($src); + foreach (split(/[ \t\n]+/, $self->{OBJECT})) { + if (/^$self->{BASEEXT}\.o(bj)?$/) { + $src .= " $self->{BASEEXT}.c"; + } elsif (/^(.*\..*)\.o$/) { + $src .= " $1"; + } elsif (/^(.*)(\.o(bj)?|\$\(OBJ_EXT\))$/) { + if (-f "$1.cp") { + $src .= " $1.cp"; + } else { + $src .= " $1.c"; + } + } else { + $src .= " $_"; + } + } + $self->{SOURCE} = $src; +} + + +=item init_dirscan + +Initializes DIR, XS, PM, C, O_FILES, H, PL_FILES, MAN*PODS, EXE_FILES. + +=cut + +sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) + my($self) = @_; + my($name, %dir, %xs, %c, %h, %ignore, %pl_files, %manifypods); + local(%pm); #the sub in find() has to see this hash + + # in case we don't find it below! + if ($self->{VERSION_FROM}) { + my $version_from = macify($self->{VERSION_FROM}); + $pm{$version_from} = File::Spec->catfile('$(INST_LIBDIR)', + $version_from); + } + + $ignore{'test.pl'} = 1; + foreach $name ($self->lsdir(":")){ + next if ($name =~ /^\./ or $ignore{$name}); + next unless $self->libscan($name); + if (-d $name){ + $dir{$name} = $name if (-f ":$name:Makefile.PL"); + } elsif ($name =~ /\.xs$/){ + my($c); ($c = $name) =~ s/\.xs$/.c/; + $xs{$name} = $c; + $c{$c} = 1; + } elsif ($name =~ /\.c(p|pp|xx|c)?$/i){ # .c .C .cpp .cxx .cc .cp + $c{$name} = 1 + unless $name =~ m/perlmain\.c/; # See MAP_TARGET + } elsif ($name =~ /\.h$/i){ + $h{$name} = 1; + } elsif ($name =~ /\.(p[ml]|pod)$/){ + $pm{$name} = File::Spec->catfile('$(INST_LIBDIR)',$name); + } elsif ($name =~ /\.PL$/ && $name ne "Makefile.PL") { + ($pl_files{$name} = $name) =~ s/\.PL$// ; + } + } + + # Some larger extensions often wish to install a number of *.pm/pl + # files into the library in various locations. + + # The attribute PMLIBDIRS holds an array reference which lists + # subdirectories which we should search for library files to + # install. PMLIBDIRS defaults to [ 'lib', $self->{BASEEXT} ]. We + # recursively search through the named directories (skipping any + # which don't exist or contain Makefile.PL files). + + # For each *.pm or *.pl file found $self->libscan() is called with + # the default installation path in $_[1]. The return value of + # libscan defines the actual installation location. The default + # libscan function simply returns the path. The file is skipped + # if libscan returns false. + + # The default installation location passed to libscan in $_[1] is: + # + # ./*.pm => $(INST_LIBDIR)/*.pm + # ./xyz/... => $(INST_LIBDIR)/xyz/... + # ./lib/... => $(INST_LIB)/... + # + # In this way the 'lib' directory is seen as the root of the actual + # perl library whereas the others are relative to INST_LIBDIR + # (which includes ROOTEXT). This is a subtle distinction but one + # that's important for nested modules. + + $self->{PMLIBDIRS} = ['lib', $self->{BASEEXT}] + unless $self->{PMLIBDIRS}; + + #only existing directories that aren't in $dir are allowed + + my (@pmlibdirs) = map { macify ($_) } @{$self->{PMLIBDIRS}}; + my ($pmlibdir); + @{$self->{PMLIBDIRS}} = (); + foreach $pmlibdir (@pmlibdirs) { + -d $pmlibdir && !$dir{$pmlibdir} && push @{$self->{PMLIBDIRS}}, $pmlibdir; + } + + if (@{$self->{PMLIBDIRS}}){ + print "Searching PMLIBDIRS: @{$self->{PMLIBDIRS}}\n" + if ($Verbose >= 2); + require File::Find; + File::Find::find(sub { + if (-d $_){ + if ($_ eq "CVS" || $_ eq "RCS"){ + $File::Find::prune = 1; + } + return; + } + my($path, $prefix) = ($File::Find::name, '$(INST_LIBDIR)'); + my($striplibpath,$striplibname); + $prefix = '$(INST_LIB)' if (($striplibpath = $path) =~ s:^(\W*)lib\W:$1:); + ($striplibname,$striplibpath) = fileparse($striplibpath); + my($inst) = File::Spec->catfile($prefix,$striplibpath,$striplibname); + local($_) = $inst; # for backwards compatibility + $inst = $self->libscan($inst); + print "libscan($path) => '$inst'\n" if ($Verbose >= 2); + return unless $inst; + $pm{$path} = $inst; + }, @{$self->{PMLIBDIRS}}); + } + + $self->{DIR} = [sort keys %dir] unless $self->{DIR}; + $self->{XS} = \%xs unless $self->{XS}; + $self->{PM} = \%pm unless $self->{PM}; + $self->{C} = [sort keys %c] unless $self->{C}; + $self->{H} = [sort keys %h] unless $self->{H}; + $self->{PL_FILES} = \%pl_files unless $self->{PL_FILES}; + + # Set up names of manual pages to generate from pods + unless ($self->{MAN1PODS}) { + $self->{MAN1PODS} = {}; + } + unless ($self->{MAN3PODS}) { + $self->{MAN3PODS} = {}; + } +} + +=item libscan (o) + +Takes a path to a file that is found by init_dirscan and returns false +if we don't want to include this file in the library. Mainly used to +exclude RCS, CVS, and SCCS directories from installation. + +=cut + +# '; + +sub libscan { + my($self,$path) = @_; + return '' if $path =~ m/:(RCS|CVS|SCCS):/ ; + $path; +} + +=item constants (o) + +Initializes lots of constants and .SUFFIXES and .PHONY + +=cut + +sub constants { + my($self) = @_; + my(@m,$tmp); + + for $tmp (qw/ + NAME DISTNAME NAME_SYM VERSION VERSION_SYM XS_VERSION + INST_LIB INST_ARCHLIB PERL_LIB PERL_SRC MACPERL_SRC MACPERL_LIB PERL FULLPERL + XSPROTOARG MACLIBS_68K MACLIBS_PPC MACLIBS_SC MACLIBS_MRC MACLIBS_ALL_68K MACLIBS_ALL_PPC MACLIBS_SHARED SOURCE TYPEMAPS + / ) { + next unless defined $self->{$tmp}; + if ($tmp eq 'TYPEMAPS' && ref $self->{$tmp}) { + push @m, sprintf "$tmp = %s\n", join " ", @{$self->{$tmp}}; + } else { + push @m, "$tmp = $self->{$tmp}\n"; + } + } + + push @m, q{ +MODULES = }.join(" \\\n\t", sort keys %{$self->{PM}})."\n"; + push @m, "PMLIBDIRS = @{$self->{PMLIBDIRS}}\n" if @{$self->{PMLIBDIRS}}; + + push @m, ' + +.INCLUDE : $(MACPERL_SRC)BuildRules.mk + +'; + + push @m, qq{ +VERSION_MACRO = VERSION +DEFINE_VERSION = -d \$(VERSION_MACRO)="¶"\$(VERSION)¶"" +XS_VERSION_MACRO = XS_VERSION +XS_DEFINE_VERSION = -d \$(XS_VERSION_MACRO)="¶"\$(XS_VERSION)¶"" +}; + + $self->{DEFINE} .= " \$(XS_DEFINE_VERSION) \$(DEFINE_VERSION)"; + + push @m, qq{ +MAKEMAKER = $INC{'ExtUtils/MakeMaker.pm'} +MM_VERSION = $ExtUtils::MakeMaker::VERSION +}; + + push @m, q{ +# FULLEXT = Pathname for extension directory (eg DBD:Oracle). +# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. +# ROOTEXT = Directory part of FULLEXT (eg DBD) +# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. +}; + + if ($self->{DEFINE}) { + $self->{DEFINE} =~ s/-D/-d /g; # Preprocessor definitions may be useful + $self->{DEFINE} =~ s/-I\S+/_include($1)/eg; # UN*X includes probably are not useful + } + if ($self->{INC}) { + $self->{INC} =~ s/-I(\S+)/_include($1)/eg; # UN*X includes probably are not useful + } + for $tmp (qw/ + FULLEXT BASEEXT ROOTEXT DEFINE INC + / ) { + next unless defined $self->{$tmp}; + push @m, "$tmp = $self->{$tmp}\n"; + } + + push @m, " +# Handy lists of source code files: +XS_FILES= ".join(" \\\n\t", sort keys %{$self->{XS}})." +C_FILES = ".join(" \\\n\t", @{$self->{C}})." +H_FILES = ".join(" \\\n\t", @{$self->{H}})." +"; + + push @m, ' + +.INCLUDE : $(MACPERL_SRC)ExtBuildRules.mk +'; + + join('',@m); +} + +=item static (o) + +Defines the static target. + +=cut + +sub static { +# --- Static Loading Sections --- + + my($self) = shift; + my($extlib) = $self->{MYEXTLIB} ? "\nstatic :: myextlib\n" : ""; + ' +all :: static + +install :: do_install_static + +install_static :: do_install_static +' . $extlib; +} + +=item dlsyms (o) + +Used by MacOS to define DL_FUNCS and DL_VARS and write the *.exp +files. + +=cut + +sub dlsyms { + my($self,%attribs) = @_; + + return '' unless !$self->{SKIPHASH}{'dynamic'}; + + my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {}; + my($vars) = $attribs{DL_VARS} || $self->{DL_VARS} || []; + my(@m); + + push(@m," +dynamic :: $self->{BASEEXT}.exp + +") unless $self->{SKIPHASH}{'dynamic'}; + + my($extlib) = $self->{MYEXTLIB} ? " myextlib" : ""; + + push(@m," +$self->{BASEEXT}.exp: Makefile.PL$extlib +", qq[\t\$(PERL) "-I\$(PERL_LIB)" -e 'use ExtUtils::Mksymlists; ], + 'Mksymlists("NAME" => "',$self->{NAME},'", "DL_FUNCS" => ', + neatvalue($funcs),', "DL_VARS" => ', neatvalue($vars), ');\' +'); + + join('',@m); +} + +=item dynamic (o) + +Defines the dynamic target. + +=cut + +sub dynamic { +# --- dynamic Loading Sections --- + + my($self) = shift; + ' +all :: dynamic + +install :: do_install_dynamic + +install_dynamic :: do_install_dynamic +'; +} + + +=item clean (o) + +Defines the clean target. + +=cut + +sub clean { +# --- Cleanup and Distribution Sections --- + + my($self, %attribs) = @_; + my(@m,$dir); + push(@m, ' +# Delete temporary files but do not touch installed files. We don\'t delete +# the Makefile here so a later make realclean still has a makefile to use. + +clean :: +'); + # clean subdirectories first + for $dir (@{$self->{DIR}}) { + push @m, +" Set OldEcho \{Echo\} + Set Echo 0 + Directory $dir + If \"\`Exists -f $self->{MAKEFILE}\`\" != \"\" + \$(MAKE) clean + End + Set Echo \{OldEcho\} + "; + } + + my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files + push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES}; + push @m, "\t\$(RM_RF) @otherfiles\n"; + # See realclean and ext/utils/make_ext for usage of Makefile.old + push(@m, + "\t\$(MV) $self->{MAKEFILE} $self->{MAKEFILE}.old\n"); + push(@m, + "\t$attribs{POSTOP}\n") if $attribs{POSTOP}; + join("", @m); +} + +=item realclean (o) + +Defines the realclean target. + +=cut + +sub realclean { + my($self, %attribs) = @_; + my(@m); + push(@m,' +# Delete temporary files (via clean) and also delete installed files +realclean purge :: clean +'); + # realclean subdirectories first (already cleaned) + my $sub = +" Set OldEcho \{Echo\} + Set Echo 0 + Directory %s + If \"\`Exists -f %s\`\" != \"\" + \$(MAKE) realclean + End + Set Echo \{OldEcho\} + "; + foreach(@{$self->{DIR}}){ + push(@m, sprintf($sub,$_,"$self->{MAKEFILE}.old","-f $self->{MAKEFILE}.old")); + push(@m, sprintf($sub,$_,"$self->{MAKEFILE}",'')); + } + my(@otherfiles) = ($self->{MAKEFILE}, + "$self->{MAKEFILE}.old"); # Makefiles last + push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES}; + push(@m, "\t\$(RM_RF) @otherfiles\n") if @otherfiles; + push(@m, "\t$attribs{POSTOP}\n") if $attribs{POSTOP}; + join("", @m); +} + +=item rulez (o) + +=cut + +sub rulez { + my($self) = shift; + qq' +install install_static install_dynamic :: +\t\$(MACPERL_SRC)PerlInstall -l \$(PERL_LIB) + +.INCLUDE : \$(MACPERL_SRC)BulkBuildRules.mk +'; +} + +sub xsubpp_version +{ + return $ExtUtils::MakeMaker::Version; +} + + +=item processPL (o) + +Defines targets to run *.PL files. + +=cut + +sub processPL { + my($self) = shift; + return "" unless $self->{PL_FILES}; + my(@m, $plfile); + foreach $plfile (sort keys %{$self->{PL_FILES}}) { + my $list = ref($self->{PL_FILES}->{$plfile}) + ? $self->{PL_FILES}->{$plfile} + : [$self->{PL_FILES}->{$plfile}]; + foreach $target (@$list) { + push @m, " +ProcessPL :: $target +\t$self->{NOECHO}\$(NOOP) + +$target :: $plfile +\t\$(PERL) -I\$(MACPERL_LIB) -I\$(PERL_LIB) $plfile $target +"; + } + } + join "", @m; +} + +sub cflags { + my($self,$libperl) = @_; + my $optimize; + + for (map { $_ . "Optimize" } qw(MWC MWCPPC MWC68K MPW MRC MRC SC)) { + $optimize .= "$_ = $self->{$_}" if exists $self->{$_}; + } + + return $self->{CFLAGS} = $optimize; +} + +sub _include { # for Unix-style includes, with -I instead of -i + my($inc) = @_; + require File::Spec::Unix; + + # allow only relative paths + if (File::Spec::Unix->file_name_is_absolute($inc)) { + return ''; + } else { + return '-i ' . macify($inc); + } +} + +# yes, these are just copies of the same routines in +# MakeMaker.pm, but with paths changed. +sub check_hints { + my($self) = @_; + # We allow extension-specific hints files. + + return unless -d ":hints"; + + # First we look for the best hintsfile we have + my($hint)="${^O}_$Config{osvers}"; + $hint =~ s/\./_/g; + $hint =~ s/_$//; + return unless $hint; + + # Also try without trailing minor version numbers. + while (1) { + last if -f ":hints:$hint.pl"; # found + } continue { + last unless $hint =~ s/_[^_]*$//; # nothing to cut off + } + my $hint_file = ":hints:$hint.pl"; + + return unless -f $hint_file; # really there + + _run_hintfile($self, $hint_file); +} + +sub _run_hintfile { + no strict 'vars'; + local($self) = shift; # make $self available to the hint file. + my($hint_file) = shift; + + local $@; + print STDERR "Processing hints file $hint_file\n"; + my $ret = do $hint_file; + unless( defined $ret ) { + print STDERR $@ if $@; + } +} +1; + +__END__ diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_NW5.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_NW5.pm new file mode 100644 index 00000000000..7f13dd0ee70 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_NW5.pm @@ -0,0 +1,373 @@ +package ExtUtils::MM_NW5; + +=head1 NAME + +ExtUtils::MM_NW5 - methods to override UN*X behaviour in ExtUtils::MakeMaker + +=head1 SYNOPSIS + + use ExtUtils::MM_NW5; # Done internally by ExtUtils::MakeMaker if needed + +=head1 DESCRIPTION + +See ExtUtils::MM_Unix for a documentation of the methods provided +there. This package overrides the implementation of these methods, not +the semantics. + +=over + +=cut + +use strict; +use Config; +use File::Basename; + +use vars qw(@ISA $VERSION); +$VERSION = '2.05'; + +require ExtUtils::MM_Win32; +@ISA = qw(ExtUtils::MM_Win32); + +use ExtUtils::MakeMaker qw( &neatvalue ); + +$ENV{EMXSHELL} = 'sh'; # to run `commands` + +my $BORLAND = 1 if $Config{'cc'} =~ /^bcc/i; +my $GCC = 1 if $Config{'cc'} =~ /^gcc/i; +my $DMAKE = 1 if $Config{'make'} =~ /^dmake/i; + + +sub init_others { + my ($self) = @_; + $self->SUPER::init_others(@_); + + # incpath is copied to makefile var INCLUDE in constants sub, here just + # make it empty + my $libpth = $Config{'libpth'}; + $libpth =~ s( )(;); + $self->{'LIBPTH'} = $libpth; + $self->{'BASE_IMPORT'} = $Config{'base_import'}; + + # Additional import file specified from Makefile.pl + if($self->{'base_import'}) { + $self->{'BASE_IMPORT'} .= ', ' . $self->{'base_import'}; + } + + $self->{'NLM_VERSION'} = $Config{'nlm_version'}; + $self->{'MPKTOOL'} = $Config{'mpktool'}; + $self->{'TOOLPATH'} = $Config{'toolpath'}; +} + + +=item constants (o) + +Initializes lots of constants and .SUFFIXES and .PHONY + +=cut + +sub const_cccmd { + my($self,$libperl)=@_; + return $self->{CONST_CCCMD} if $self->{CONST_CCCMD}; + return '' unless $self->needs_linking(); + return $self->{CONST_CCCMD} = <<'MAKE_FRAG'; +CCCMD = $(CC) $(CCFLAGS) $(INC) $(OPTIMIZE) \ + $(PERLTYPE) $(MPOLLUTE) -o $@ \ + -DVERSION=\"$(VERSION)\" -DXS_VERSION=\"$(XS_VERSION)\" +MAKE_FRAG + +} + +sub constants { + my($self) = @_; + my(@m,$tmp); + +# Added LIBPTH, BASE_IMPORT, ABSTRACT, NLM_VERSION BOOT_SYMBOL, NLM_SHORT_NAME +# for NETWARE + + for $tmp (qw/ + + AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION + VERSION_SYM XS_VERSION INST_BIN INST_LIB + INST_ARCHLIB INST_SCRIPT PREFIX INSTALLDIRS + INSTALLPRIVLIB INSTALLARCHLIB INSTALLSITELIB + INSTALLSITEARCH INSTALLBIN INSTALLSCRIPT PERL_LIB + PERL_ARCHLIB SITELIBEXP SITEARCHEXP LIBPERL_A MYEXTLIB + FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC + PERL_INC PERL FULLPERL LIBPTH BASE_IMPORT PERLRUN + FULLPERLRUN PERLRUNINST FULLPERLRUNINST + FULL_AR PERL_CORE NLM_VERSION MPKTOOL TOOLPATH + + / ) { + next unless defined $self->{$tmp}; + push @m, "$tmp = $self->{$tmp}\n"; + } + + (my $boot = $self->{'NAME'}) =~ s/:/_/g; + $self->{'BOOT_SYMBOL'}=$boot; + push @m, "BOOT_SYMBOL = $self->{'BOOT_SYMBOL'}\n"; + + # If the final binary name is greater than 8 chars, + # truncate it here. + if(length($self->{'BASEEXT'}) > 8) { + $self->{'NLM_SHORT_NAME'} = substr($self->{'BASEEXT'},0,8); + push @m, "NLM_SHORT_NAME = $self->{'NLM_SHORT_NAME'}\n"; + } + + push @m, qq{ +VERSION_MACRO = VERSION +DEFINE_VERSION = -D\$(VERSION_MACRO)=\\\"\$(VERSION)\\\" +XS_VERSION_MACRO = XS_VERSION +XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\" +}; + + # Get the include path and replace the spaces with ; + # Copy this to makefile as INCLUDE = d:\...;d:\; + (my $inc = $Config{'incpath'}) =~ s/([ ]*)-I/;/g; + + # Get the additional include path from the user through the command prompt + # and append to INCLUDE +# $self->{INC} = ''; + push @m, "INC = $self->{'INC'}\n"; + + push @m, qq{ +INCLUDE = $inc; +}; + + # Set the path to CodeWarrior binaries which might not have been set in + # any other place + push @m, qq{ +PATH = \$(PATH);\$(TOOLPATH) +}; + + push @m, qq{ +MAKEMAKER = $INC{'ExtUtils/MakeMaker.pm'} +MM_VERSION = $ExtUtils::MakeMaker::VERSION +}; + + push @m, q{ +# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle). +# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle) +# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar) +# DLBASE = Basename part of dynamic library. May be just equal BASEEXT. +}; + + for $tmp (qw/ + FULLEXT BASEEXT PARENT_NAME DLBASE VERSION_FROM INC DEFINE OBJECT + LDFROM LINKTYPE + / ) { + next unless defined $self->{$tmp}; + push @m, "$tmp = $self->{$tmp}\n"; + } + + push @m, " +# Handy lists of source code files: +XS_FILES= ".join(" \\\n\t", sort keys %{$self->{XS}})." +C_FILES = ".join(" \\\n\t", @{$self->{C}})." +O_FILES = ".join(" \\\n\t", @{$self->{O_FILES}})." +H_FILES = ".join(" \\\n\t", @{$self->{H}})." +MAN1PODS = ".join(" \\\n\t", sort keys %{$self->{MAN1PODS}})." +MAN3PODS = ".join(" \\\n\t", sort keys %{$self->{MAN3PODS}})." +"; + + for $tmp (qw/ + INST_MAN1DIR INSTALLMAN1DIR MAN1EXT + INST_MAN3DIR INSTALLMAN3DIR MAN3EXT + /) { + next unless defined $self->{$tmp}; + push @m, "$tmp = $self->{$tmp}\n"; + } + + push @m, qq{ +.USESHELL : +} if $DMAKE; + + push @m, q{ +.NO_CONFIG_REC: Makefile +} if $ENV{CLEARCASE_ROOT}; + + # why not q{} ? -- emacs + push @m, qq{ +# work around a famous dec-osf make(1) feature(?): +makemakerdflt: all + +.SUFFIXES: .xs .c .C .cpp .cxx .cc \$(OBJ_EXT) + +.PHONY: all config static dynamic test linkext manifest + +# Where is the Config information that we are using/depend on +CONFIGDEP = \$(PERL_ARCHLIB)\\Config.pm \$(PERL_INC)\\config.h +}; + + my @parentdir = split(/::/, $self->{PARENT_NAME}); + push @m, q{ +# Where to put things: +INST_LIBDIR = }. File::Spec->catdir('$(INST_LIB)',@parentdir) .q{ +INST_ARCHLIBDIR = }. File::Spec->catdir('$(INST_ARCHLIB)',@parentdir) .q{ + +INST_AUTODIR = }. File::Spec->catdir('$(INST_LIB)','auto','$(FULLEXT)') .q{ +INST_ARCHAUTODIR = }. File::Spec->catdir('$(INST_ARCHLIB)','auto','$(FULLEXT)') .q{ +}; + + if ($self->has_link_code()) { + push @m, ' +INST_STATIC = $(INST_ARCHAUTODIR)\$(BASEEXT)$(LIB_EXT) +INST_DYNAMIC = $(INST_ARCHAUTODIR)\$(DLBASE).$(DLEXT) +INST_BOOT = $(INST_ARCHAUTODIR)\$(BASEEXT).bs +'; + } else { + push @m, ' +INST_STATIC = +INST_DYNAMIC = +INST_BOOT = +'; + } + + $tmp = $self->export_list; + push @m, " +EXPORT_LIST = $tmp +"; + $tmp = $self->perl_archive; + push @m, " +PERL_ARCHIVE = $tmp +"; + + push @m, q{ +TO_INST_PM = }.join(" \\\n\t", sort keys %{$self->{PM}}).q{ + +PM_TO_BLIB = }.join(" \\\n\t", %{$self->{PM}}).q{ +}; + + join('',@m); +} + + +=item static_lib (o) + +=cut + +sub static_lib { + my($self) = @_; + + return '' unless $self->has_link_code; + + my $m = <<'END'; +$(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)\.exists + $(RM_RF) $@ +END + + # If this extension has it's own library (eg SDBM_File) + # then copy that to $(INST_STATIC) and add $(OBJECT) into it. + $m .= <<'END' if $self->{MYEXTLIB}; + $self->{CP} $(MYEXTLIB) $@ +END + + my $ar_arg; + if( $BORLAND ) { + $ar_arg = '$@ $(OBJECT:^"+")'; + } + elsif( $GCC ) { + $ar_arg = '-ru $@ $(OBJECT)'; + } + else { + $ar_arg = '-type library -o $@ $(OBJECT)'; + } + + $m .= sprintf <<'END', $ar_arg; + $(AR) %s + $(NOECHO)echo "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)\extralibs.ld + $(CHMOD) 755 $@ +END + + $m .= <<'END' if $self->{PERL_SRC}; + $(NOECHO)echo "$(EXTRALIBS)" >> $(PERL_SRC)\ext.libs + + +END + $m .= $self->dir_target('$(INST_ARCHAUTODIR)'); + return $m; +} + +=item dynamic_lib (o) + +Defines how to produce the *.so (or equivalent) files. + +=cut + +sub dynamic_lib { + my($self, %attribs) = @_; + return '' unless $self->needs_linking(); #might be because of a subdir + + return '' unless $self->has_link_code; + + my($otherldflags) = $attribs{OTHERLDFLAGS} || ($BORLAND ? 'c0d32.obj': ''); + my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || ""; + my($ldfrom) = '$(LDFROM)'; + + (my $boot = $self->{NAME}) =~ s/:/_/g; + + my $m = <<'MAKE_FRAG'; +# This section creates the dynamically loadable $(INST_DYNAMIC) +# from $(OBJECT) and possibly $(MYEXTLIB). +OTHERLDFLAGS = '.$otherldflags.' +INST_DYNAMIC_DEP = '.$inst_dynamic_dep.' + +# Create xdc data for an MT safe NLM in case of mpk build +$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) + @echo Export boot_$(BOOT_SYMBOL) > $(BASEEXT).def + @echo $(BASE_IMPORT) >> $(BASEEXT).def + @echo Import @$(PERL_INC)\perl.imp >> $(BASEEXT).def +MAKE_FRAG + + + if ( $self->{CCFLAGS} =~ m/ -DMPK_ON /) { + $m .= <<'MAKE_FRAG'; + $(MPKTOOL) $(XDCFLAGS) $(BASEEXT).xdc + @echo xdcdata $(BASEEXT).xdc >> $(BASEEXT).def +MAKE_FRAG + } + + # Reconstruct the X.Y.Z version. + my $version = join '.', map { sprintf "%d", $_ } + $] =~ /(\d)\.(\d{3})(\d{2})/; + $m .= sprintf ' $(LD) $(LDFLAGS) $(OBJECT:.obj=.obj) -desc "Perl %s Extension ($(BASEEXT)) XS_VERSION: $(XS_VERSION)" -nlmversion $(NLM_VERSION)', $version; + + # Taking care of long names like FileHandle, ByteLoader, SDBM_File etc + if($self->{NLM_SHORT_NAME}) { + # In case of nlms with names exceeding 8 chars, build nlm in the + # current dir, rename and move to auto\lib. + $m .= q{ -o $(NLM_SHORT_NAME).$(DLEXT)} + } else { + $m .= q{ -o $(INST_AUTODIR)\\$(BASEEXT).$(DLEXT)} + } + + # Add additional lib files if any (SDBM_File) + $m .= q{ $(MYEXTLIB) } if $self->{MYEXTLIB}; + + $m .= q{ $(PERL_INC)\Main.lib -commandfile $(BASEEXT).def}."\n"; + + if($self->{NLM_SHORT_NAME}) { + $m .= <<'MAKE_FRAG'; + if exist $(INST_AUTODIR)\$(NLM_SHORT_NAME).$(DLEXT) del $(INST_AUTODIR)\$(NLM_SHORT_NAME).$(DLEXT) + move $(NLM_SHORT_NAME).$(DLEXT) $(INST_AUTODIR) +MAKE_FRAG + } + + $m .= <<'MAKE_FRAG'; + + $(CHMOD) 755 $@ +MAKE_FRAG + + $m .= $self->dir_target('$(INST_ARCHAUTODIR)'); + + return $m; +} + + +1; +__END__ + +=back + +=cut + + diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_UWIN.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_UWIN.pm new file mode 100644 index 00000000000..59384a22841 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_UWIN.pm @@ -0,0 +1,52 @@ +package ExtUtils::MM_UWIN; + +use strict; +use vars qw($VERSION @ISA); +$VERSION = 0.01; + +require ExtUtils::MM_Unix; +@ISA = qw(ExtUtils::MM_Unix); + + +=head1 NAME + +ExtUtils::MM_UWIN - U/WIN specific subclass of ExtUtils::MM_Unix + +=head1 SYNOPSIS + + Don't use this module directly. + Use ExtUtils::MM and let it choose. + +=head1 DESCRIPTION + +This is a subclass of ExtUtils::MM_Unix which contains functionality for +the AT&T U/WIN UNIX on Windows environment. + +Unless otherwise stated it works just like ExtUtils::MM_Unix + +=head2 Overridden methods + +=over 4 + +=item B<replace_manpage_separator> + +=cut + +sub replace_manpage_separator { + my($self, $man) = @_; + + $man =~ s,/+,.,g; + return $man; +} + +=back + +=head1 AUTHOR + +Michael G Schwern <schwern@pobox.com> with code from ExtUtils::MM_Unix + +=head1 SEE ALSO + +L<ExtUtils::MM_Win32>, L<ExtUtils::MakeMaker> + +1; diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MM_Win95.pm b/gnu/usr.bin/perl/lib/ExtUtils/MM_Win95.pm new file mode 100644 index 00000000000..010900f5c36 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MM_Win95.pm @@ -0,0 +1,71 @@ +package ExtUtils::MM_Win95; + +use vars qw($VERSION @ISA); +$VERSION = 0.02; + +require ExtUtils::MM_Win32; +@ISA = qw(ExtUtils::MM_Win32); +use Config; + +=head1 NAME + +ExtUtils::MM_Win95 - method to customize MakeMaker for Win9X + +=head1 SYNOPSIS + + You should not be using this module directly. + +=head1 DESCRIPTION + +This is a subclass of ExtUtils::MM_Win32 containing changes necessary +to get MakeMaker playing nice with command.com and other Win9Xisms. + +=cut + +sub dist_test { + my($self) = shift; + return q{ +disttest : distdir + cd $(DISTVNAME) + $(ABSPERLRUN) Makefile.PL + $(MAKE) $(PASTHRU) + $(MAKE) test $(PASTHRU) + cd .. +}; +} + +sub xs_c { + my($self) = shift; + return '' unless $self->needs_linking(); + ' +.xs.c: + $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) \\ + $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.c + ' +} + +sub xs_cpp { + my($self) = shift; + return '' unless $self->needs_linking(); + ' +.xs.cpp: + $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) \\ + $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.cpp + '; +} + +# many makes are too dumb to use xs_c then c_o +sub xs_o { + my($self) = shift; + return '' unless $self->needs_linking(); + # having to choose between .xs -> .c -> .o and .xs -> .o confuses dmake + return '' if $Config{make} eq 'dmake'; + ' +.xs$(OBJ_EXT): + $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) \\ + $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.c + $(CCCMD) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $*.c + '; +} + +1; diff --git a/gnu/usr.bin/perl/lib/ExtUtils/MY.pm b/gnu/usr.bin/perl/lib/ExtUtils/MY.pm new file mode 100644 index 00000000000..97ef42a15a3 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/MY.pm @@ -0,0 +1,42 @@ +package ExtUtils::MY; + +use strict; +require ExtUtils::MM; + +use vars qw(@ISA $VERSION); +$VERSION = 0.01; +@ISA = qw(ExtUtils::MM); + +{ + package MY; + use vars qw(@ISA); + @ISA = qw(ExtUtils::MY); +} + +sub DESTROY {} + + +=head1 NAME + +ExtUtils::MY - ExtUtils::MakeMaker subclass for customization + +=head1 SYNOPSIS + + # in your Makefile.PL + sub MY::whatever { + ... + } + +=head1 DESCRIPTION + +B<FOR INTERNAL USE ONLY> + +ExtUtils::MY is a subclass of ExtUtils::MM. Its provided in your +Makefile.PL for you to add and override MakeMaker functionality. + +It also provides a convenient alias via the MY class. + +ExtUtils::MY might turn out to be a temporary solution, but MY won't +go away. + +=cut diff --git a/gnu/usr.bin/perl/lib/ExtUtils/Packlist.pm b/gnu/usr.bin/perl/lib/ExtUtils/Packlist.pm index 88ea206196e..11ab637150b 100644 --- a/gnu/usr.bin/perl/lib/ExtUtils/Packlist.pm +++ b/gnu/usr.bin/perl/lib/ExtUtils/Packlist.pm @@ -1,9 +1,10 @@ package ExtUtils::Packlist; -use 5.005_64; +use 5.00503; use strict; use Carp qw(); -our $VERSION = '0.03'; +use vars qw($VERSION); +$VERSION = '0.04'; # Used for generating filehandle globs. IO::File might not be available! my $fhname = "FH1"; @@ -89,7 +90,12 @@ my ($line); while (defined($line = <$fh>)) { chomp $line; - my ($key, @kvs) = split(' ', $line); + my ($key, @kvs) = $line; + if ($key =~ /^(.*?)( \w+=.*)$/) + { + $key = $1; + @kvs = split(' ', $2); + } $key =~ s!/\./!/!g; # Some .packlists have spurious '/./' bits in the paths if (! @kvs) { @@ -200,7 +206,7 @@ filename followed by the key=value pairs from the hash. Reading back the =head1 FUNCTIONS -=over +=over 4 =item new() diff --git a/gnu/usr.bin/perl/lib/ExtUtils/instmodsh b/gnu/usr.bin/perl/lib/ExtUtils/instmodsh new file mode 100644 index 00000000000..cbf2d01194a --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/instmodsh @@ -0,0 +1,139 @@ +#!/usr/local/bin/perl -w + +use strict; +use IO::File; +use ExtUtils::Packlist; +use ExtUtils::Installed; + +use vars qw($Inst @Modules); + +################################################################################ + +sub do_module($) +{ +my ($module) = @_; +my $help = <<EOF; +Available commands are: + f [all|prog|doc] - List installed files of a given type + d [all|prog|doc] - List the directories used by a module + v - Validate the .packlist - check for missing files + t <tarfile> - Create a tar archive of the module + q - Quit the module +EOF +print($help); +while (1) + { + print("$module cmd? "); + my $reply = <STDIN>; chomp($reply); + CASE: + { + $reply =~ /^f\s*/ and do + { + my $class = (split(' ', $reply))[1]; + $class = 'all' if (! $class); + my @files; + if (eval { @files = $Inst->files($module, $class); }) + { + print("$class files in $module are:\n ", + join("\n ", @files), "\n"); + last CASE; + } + else + { print($@); } + }; + $reply =~ /^d\s*/ and do + { + my $class = (split(' ', $reply))[1]; + $class = 'all' if (! $class); + my @dirs; + if (eval { @dirs = $Inst->directories($module, $class); }) + { + print("$class directories in $module are:\n ", + join("\n ", @dirs), "\n"); + last CASE; + } + else + { print($@); } + }; + $reply =~ /^t\s*/ and do + { + my $file = (split(' ', $reply))[1]; + my $tmp = "/tmp/inst.$$"; + if (my $fh = IO::File->new($tmp, "w")) + { + $fh->print(join("\n", $Inst->files($module))); + $fh->close(); + system("tar cvf $file -I $tmp"); + unlink($tmp); + last CASE; + } + else { print("Can't open $file: $!\n"); } + last CASE; + }; + $reply eq 'v' and do + { + if (my @missing = $Inst->validate($module)) + { + print("Files missing from $module are:\n ", + join("\n ", @missing), "\n"); + } + else + { + print("$module has no missing files\n"); + } + last CASE; + }; + $reply eq 'q' and do + { + return; + }; + # Default + print($help); + } + } +} + +################################################################################ + +sub toplevel() +{ +my $help = <<EOF; +Available commands are: + l - List all installed modules + m <module> - Select a module + q - Quit the program +EOF +print($help); +while (1) + { + print("cmd? "); + my $reply = <STDIN>; chomp($reply); + CASE: + { + $reply eq 'l' and do + { + print("Installed modules are:\n ", join("\n ", @Modules), "\n"); + last CASE; + }; + $reply =~ /^m\s+/ and do + { + do_module((split(' ', $reply))[1]); + last CASE; + }; + $reply eq 'q' and do + { + exit(0); + }; + # Default + print($help); + } + } +} + +################################################################################ + +$Inst = ExtUtils::Installed->new(); +@Modules = $Inst->modules(); +toplevel(); + +################################################################################ diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/00setup_dummy.t b/gnu/usr.bin/perl/lib/ExtUtils/t/00setup_dummy.t new file mode 100644 index 00000000000..2d5b1ee5c1b --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/00setup_dummy.t @@ -0,0 +1,109 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use strict; +use Test::More tests => 9; +use File::Basename; +use File::Path; +use File::Spec; + +my %Files = ( + 'Big-Dummy/lib/Big/Dummy.pm' => <<'END', +package Big::Dummy; + +$VERSION = 0.01; + +1; +END + + 'Big-Dummy/Makefile.PL' => <<'END', +use ExtUtils::MakeMaker; + +printf "Current package is: %s\n", __PACKAGE__; + +WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + PREREQ_PM => {}, +); +END + + 'Big-Dummy/t/compile.t' => <<'END', +print "1..2\n"; + +print eval "use Big::Dummy; 1;" ? "ok 1\n" : "not ok 1\n"; +print "ok 2 - TEST_VERBOSE\n"; +END + + 'Big-Dummy/Liar/t/sanity.t' => <<'END', +print "1..3\n"; + +print eval "use Big::Dummy; 1;" ? "ok 1\n" : "not ok 1\n"; +print eval "use Big::Liar; 1;" ? "ok 2\n" : "not ok 2\n"; +print "ok 3 - TEST_VERBOSE\n"; +END + + 'Big-Dummy/Liar/lib/Big/Liar.pm' => <<'END', +package Big::Liar; + +$VERSION = 0.01; + +1; +END + + 'Big-Dummy/Liar/Makefile.PL' => <<'END', +use ExtUtils::MakeMaker; + +my $mm = WriteMakefile( + NAME => 'Big::Liar', + VERSION_FROM => 'lib/Big/Liar.pm', + _KEEP_AFTER_FLUSH => 1 + ); + +print "Big::Liar's vars\n"; +foreach my $key (qw(INST_LIB INST_ARCHLIB)) { + print "$key = $mm->{$key}\n"; +} +END + + 'Problem-Module/Makefile.PL' => <<'END', +use ExtUtils::MakeMaker; + +WriteMakefile( + NAME => 'Problem::Module', +); +END + + 'Problem-Module/subdir/Makefile.PL' => <<'END', +printf "\@INC %s .\n", (grep { $_ eq '.' } @INC) ? "has" : "doesn't have"; + +warn "I think I'm going to be sick\n"; +die "YYYAaaaakkk\n"; +END + + ); + +while(my($file, $text) = each %Files) { + # Convert to a relative, native file path. + $file = File::Spec->catfile(File::Spec->curdir, split m{\/}, $file); + + my $dir = dirname($file); + mkpath $dir; + open(FILE, ">$file"); + print FILE $text; + close FILE; + + ok( -e $file, "$file created" ); +} + + +pass("Setup done"); diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Command.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Command.t new file mode 100644 index 00000000000..ff9eec1da42 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Command.t @@ -0,0 +1,192 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't'; + @INC = ('../lib', 'lib/'); + } + else { + unshift @INC, 't/lib/'; + } +} +chdir 't'; + +BEGIN { + 1 while unlink 'ecmdfile'; + # forcibly remove ecmddir/temp2, but don't import mkpath + use File::Path (); + File::Path::rmtree( 'ecmddir' ); +} + +BEGIN { + use Test::More tests => 24; + use File::Spec; +} + +{ + # bad neighbor, but test_f() uses exit() + *CORE::GLOBAL::exit = ''; # quiet 'only once' warning. + *CORE::GLOBAL::exit = sub { return @_ }; + + use_ok( 'ExtUtils::Command' ); + + # get a file in the current directory, replace last char with wildcard + my $file; + { + local *DIR; + opendir(DIR, File::Spec->curdir()); + while ($file = readdir(DIR)) { + $file =~ s/\.\z// if $^O eq 'VMS'; + last if $file =~ /^\w/; + } + } + + + # % 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( scalar @ARGV, 1, 'found one file' ); + like( $ARGV[0], qr/$file/, 'expanded wildcard ? successfully' ); + + # try it with the asterisk now + ($ARGV[0] = $file) =~ s/.{3}\z/\*/; + ExtUtils::Command::expand_wildcards(); + + ok( (grep { qr/$file/ } @ARGV), 'expanded wildcard * successfully' ); + + # 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 C false + @ARGV = ( 'ecmdfile' ); + ok( test_f(), 'testing non-existent file' ); + + @ARGV = ( 'ecmdfile' ); + cmp_ok( ! test_f(), '==', (-f 'ecmdfile'), 'testing non-existent file' ); + + # these are destructive, have to keep setting @ARGV + @ARGV = ( 'ecmdfile' ); + touch(); + + @ARGV = ( 'ecmdfile' ); + ok( test_f(), 'now creating that file' ); + + @ARGV = ( 'ecmdfile' ); + 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"; + + 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, 'ecmdfile' ); + ExtUtils::Command::chmod(); + + is( ((stat('ecmdfile'))[2] & 07777) & 0700, + 0100, 'change a file to execute-only' ); + + # change a file to read-only + @ARGV = ( 0400, 'ecmdfile' ); + ExtUtils::Command::chmod(); + + is( ((stat('ecmdfile'))[2] & 07777) & 0700, + ($^O eq 'vos' ? 0500 : 0400), 'change a file to read-only' ); + + # change a file to write-only + @ARGV = ( 0200, 'ecmdfile' ); + ExtUtils::Command::chmod(); + + is( ((stat('ecmdfile'))[2] & 07777) & 0700, + ($^O eq 'vos' ? 0700 : 0200), 'change a file to write-only' ); + } + + # change a file to read-write + @ARGV = ( 0600, 'ecmdfile' ); + ExtUtils::Command::chmod(); + + is( ((stat('ecmdfile'))[2] & 07777) & 0700, + ($^O eq 'vos' ? 0700 : 0600), 'change a file to read-write' ); + + # mkpath + @ARGV = ( File::Spec->join( 'ecmddir', 'temp2' ) ); + ok( ! -e $ARGV[0], 'temp directory not there yet' ); + + mkpath(); + ok( -e $ARGV[0], 'temp directory created' ); + + # copy a file to a nested subdirectory + unshift @ARGV, 'ecmdfile'; + cp(); + + ok( -e File::Spec->join( 'ecmddir', 'temp2', 'ecmdfile' ), 'copied okay' ); + + # cp should croak if destination isn't directory (not a great warning) + @ARGV = ( 'ecmdfile' ) x 3; + eval { cp() }; + + like( $@, qr/Too many arguments/, 'cp croaks on error' ); + + # move a file to a subdirectory + @ARGV = ( 'ecmdfile', 'ecmddir' ); + mv(); + + ok( ! -e 'ecmdfile', 'moved file away' ); + ok( -e File::Spec->join( 'ecmddir', 'ecmdfile' ), 'file in new location' ); + + # mv should also croak with the same wacky warning + @ARGV = ( 'ecmdfile' ) x 3; + + eval { mv() }; + like( $@, qr/Too many arguments/, 'mv croaks on error' ); + + # remove some files + my @files = @ARGV = ( File::Spec->catfile( 'ecmddir', 'ecmdfile' ), + File::Spec->catfile( 'ecmddir', 'temp2', 'ecmdfile' ) ); + 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" ); +} + +END { + 1 while unlink 'ecmdfile'; + File::Path::rmtree( 'ecmddir' ); +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Constant.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Constant.t new file mode 100644 index 00000000000..25d705585e2 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Constant.t @@ -0,0 +1,703 @@ +#!/usr/bin/perl -w + +print "1..51\n"; + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } +} + +# use warnings; +use strict; +use ExtUtils::MakeMaker; +use ExtUtils::Constant qw (constant_types C_constant XS_constant autoload); +use Config; +use File::Spec::Functions qw(catfile rel2abs); +# Because were are going to be changing directory before running Makefile.PL +my $perl; +$perl = rel2abs( $^X ) unless $] < 5.006; # Hack. Until 5.00503 has rel2abs +# ExtUtils::Constant::C_constant uses $^X inside a comment, and we want to +# compare output to ensure that it is the same. We were probably run as ./perl +# whereas we will run the child with the full path in $perl. So make $^X for +# us the same as our child will see. +$^X = $perl; + +print "# perl=$perl\n"; +my $runperl = "$perl \"-I../../lib\""; + +$| = 1; + +my $dir = "ext-$$"; +my @files; + +print "# $dir being created...\n"; +mkdir $dir, 0777 or die "mkdir: $!\n"; + +my $output = "output"; + +# For debugging set this to 1. +my $keep_files = 0; + +END { + use File::Path; + print "# $dir being removed...\n"; + rmtree($dir) unless $keep_files; +} + +my $package = "ExtTest"; + +# Test the code that generates 1 and 2 letter name comparisons. +my %compass = ( +N => 0, 'NE' => 45, E => 90, SE => 135, S => 180, SW => 225, W => 270, NW => 315 +); + +my $parent_rfc1149 = + 'A Standard for the Transmission of IP Datagrams on Avian Carriers'; +# Check that 8 bit and unicode names don't cause problems. +my $pound; +if (ord('A') == 193) { # EBCDIC platform + $pound = chr 177; # A pound sign. (Currency) +} else { # ASCII platform + $pound = chr 163; # A pound sign. (Currency) +} +my $inf = chr 0x221E; +# Check that we can distiguish the pathological case of a string, and the +# utf8 representation of that string. +my $pound_bytes = my $pound_utf8 = $pound . '1'; +utf8::encode ($pound_bytes); + +my @names = ("FIVE", {name=>"OK6", type=>"PV",}, + {name=>"OK7", type=>"PVN", + value=>['"not ok 7\\n\\0ok 7\\n"', 15]}, + {name => "FARTHING", type=>"NV"}, + {name => "NOT_ZERO", type=>"UV", value=>"~(UV)0"}, + {name => "OPEN", type=>"PV", value=>'"/*"', macro=>1}, + {name => "CLOSE", type=>"PV", value=>'"*/"', + macro=>["#if 1\n", "#endif\n"]}, + {name => "ANSWER", default=>["UV", 42]}, "NOTDEF", + {name => "Yes", type=>"YES"}, + {name => "No", type=>"NO"}, + {name => "Undef", type=>"UNDEF"}, +# OK. It wasn't really designed to allow the creation of dual valued constants. +# It was more for INADDR_ANY INADDR_BROADCAST INADDR_LOOPBACK INADDR_NONE + {name=>"RFC1149", type=>"SV", value=>"sv_2mortal(temp_sv)", + pre=>"SV *temp_sv = newSVpv(RFC1149, 0); " + . "(void) SvUPGRADE(temp_sv,SVt_PVIV); SvIOK_on(temp_sv); " + . "SvIVX(temp_sv) = 1149;"}, + {name=>"perl", type=>"PV",}, +); + +push @names, $_ foreach keys %compass; + +# Automatically compile the list of all the macro names, and make them +# exported constants. +my @names_only = map {(ref $_) ? $_->{name} : $_} @names; + +# Exporter::Heavy (currently) isn't able to export these names: +push @names, ({name=>"*/", type=>"PV", value=>'"CLOSE"', macro=>1}, + {name=>"/*", type=>"PV", value=>'"OPEN"', macro=>1}, + {name=>$pound, type=>"PV", value=>'"Sterling"', macro=>1}, + {name=>$inf, type=>"PV", value=>'"Infinity"', macro=>1}, + {name=>$pound_utf8, type=>"PV", value=>'"1 Pound"', macro=>1}, + {name=>$pound_bytes, type=>"PV", value=>'"1 Pound (as bytes)"', + macro=>1}, + ); + +=pod + +The above set of names seems to produce a suitably bad set of compile +problems on a Unicode naive version of ExtUtils::Constant (ie 0.11): + +nick@thinking-cap 15439-32-utf$ PERL_CORE=1 ./perl lib/ExtUtils/t/Constant.t +1..33 +# perl=/stuff/perl5/15439-32-utf/perl +# ext-30370 being created... +Wide character in print at lib/ExtUtils/t/Constant.t line 140. +ok 1 +ok 2 +# make = 'make' +ExtTest.xs: In function `constant_1': +ExtTest.xs:80: warning: multi-character character constant +ExtTest.xs:80: warning: case value out of range +ok 3 + +=cut + +my $types = {}; +my $constant_types = constant_types(); # macro defs +my $C_constant = join "\n", + C_constant ($package, undef, "IV", $types, undef, undef, @names); +my $XS_constant = XS_constant ($package, $types); # XS for ExtTest::constant + +################ Header +my $header = catfile($dir, "test.h"); +push @files, "test.h"; +open FH, ">$header" or die "open >$header: $!\n"; +print FH <<"EOT"; +#define FIVE 5 +#define OK6 "ok 6\\n" +#define OK7 1 +#define FARTHING 0.25 +#define NOT_ZERO 1 +#define Yes 0 +#define No 1 +#define Undef 1 +#define RFC1149 "$parent_rfc1149" +#undef NOTDEF +#define perl "rules" +EOT + +while (my ($point, $bearing) = each %compass) { + print FH "#define $point $bearing\n" +} +close FH or die "close $header: $!\n"; + +################ XS +my $xs = catfile($dir, "$package.xs"); +push @files, "$package.xs"; +open FH, ">$xs" or die "open >$xs: $!\n"; + +print FH <<'EOT'; +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +EOT + +print FH "#include \"test.h\"\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 +my $pm = catfile($dir, "$package.pm"); +push @files, "$package.pm"; +open FH, ">$pm" or die "open >$pm: $!\n"; +print FH "package $package;\n"; +print FH "use $];\n"; + +print FH <<'EOT'; + +use strict; +EOT +printf FH "use warnings;\n" unless $] < 5.006; +print FH <<'EOT'; +use Carp; + +require Exporter; +require DynaLoader; +use vars qw ($VERSION @ISA @EXPORT_OK $AUTOLOAD); + +$VERSION = '0.01'; +@ISA = qw(Exporter DynaLoader); +@EXPORT_OK = qw( +EOT + +# Print the names of all our autoloaded constants +print FH "\t$_\n" foreach (@names_only); +print FH ");\n"; +# Print the AUTOLOAD subroutine ExtUtils::Constant generated for us +print FH autoload ($package, $]); +print FH "bootstrap $package \$VERSION;\n1;\n__END__\n"; +close FH or die "close $pm: $!\n"; + +################ test.pl +my $testpl = catfile($dir, "test.pl"); +push @files, "test.pl"; +open FH, ">$testpl" or die "open >$testpl: $!\n"; + +print FH "use strict;\n"; +print FH "use $package qw(@names_only);\n"; +print FH <<"EOT"; + +use utf8; + +print "1..1\n"; +if (open OUTPUT, ">$output") { + print "ok 1\n"; + select OUTPUT; +} else { + print "not ok 1 # Failed to open '$output': $!\n"; + exit 1; +} +EOT + +print FH << 'EOT'; + +# What follows goes to the temporary file. +# IV +my $five = FIVE; +if ($five == 5) { + print "ok 5\n"; +} else { + print "not ok 5 # $five\n"; +} + +# PV +print OK6; + +# PVN containing embedded \0s +$_ = OK7; +s/.*\0//s; +print; + +# NV +my $farthing = FARTHING; +if ($farthing == 0.25) { + print "ok 8\n"; +} else { + print "not ok 8 # $farthing\n"; +} + +# UV +my $not_zero = NOT_ZERO; +if ($not_zero > 0 && $not_zero == ~0) { + print "ok 9\n"; +} else { + print "not ok 9 # \$not_zero=$not_zero ~0=" . (~0) . "\n"; +} + +# 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"; +} else { + print "not ok 10 # \$close='$close'\n"; +} + +# Default values if macro not defined. +my $answer = ANSWER; +if ($answer == 42) { + print "ok 11\n"; +} else { + print "not ok 11 # What do you get if you multiply six by nine? '$answer'\n"; +} + +# not defined macro +my $notdef = eval { NOTDEF; }; +if (defined $notdef) { + print "not ok 12 # \$notdef='$notdef'\n"; +} elsif ($@ !~ /Your vendor has not defined ExtTest macro NOTDEF/) { + print "not ok 12 # \$@='$@'\n"; +} else { + print "ok 12\n"; +} + +# not a macro +my $notthere = eval { &ExtTest::NOTTHERE; }; +if (defined $notthere) { + print "not ok 13 # \$notthere='$notthere'\n"; +} elsif ($@ !~ /NOTTHERE is not a valid ExtTest macro/) { + chomp $@; + print "not ok 13 # \$@='$@'\n"; +} else { + print "ok 13\n"; +} + +# Truth +my $yes = Yes; +if ($yes) { + print "ok 14\n"; +} else { + print "not ok 14 # $yes='\$yes'\n"; +} + +# Falsehood +my $no = No; +if (defined $no and !$no) { + print "ok 15\n"; +} else { + print "not ok 15 # \$no=" . defined ($no) ? "'$no'\n" : "undef\n"; +} + +# Undef +my $undef = Undef; +unless (defined $undef) { + print "ok 16\n"; +} else { + print "not ok 16 # \$undef='$undef'\n"; +} + + +# 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"; +} elsif ($@ !~ /^So is not a valid ExtTest macro/) { + print "not ok 17 # \$@='$@'\n"; +} else { + print "ok 17\n"; +} + +# invalid defined macro +$notdef = eval { &ExtTest::EW }; +if (defined $notdef) { + print "not ok 18 # \$notdef='$notdef'\n"; +} elsif ($@ !~ /^EW is not a valid ExtTest macro/) { + print "not ok 18 # \$@='$@'\n"; +} else { + print "ok 18\n"; +} + +my %compass = ( +EOT + +while (my ($point, $bearing) = each %compass) { + print FH "'$point' => $bearing, " +} + +print FH <<'EOT'; + +); + +my $fail; +while (my ($point, $bearing) = each %compass) { + my $val = eval $point; + if ($@) { + print "# $point: \$@='$@'\n"; + $fail = 1; + } elsif (!defined $bearing) { + print "# $point: \$val=undef\n"; + $fail = 1; + } elsif ($val != $bearing) { + print "# $point: \$val=$val, not $bearing\n"; + $fail = 1; + } +} +if ($fail) { + print "not ok 19\n"; +} else { + print "ok 19\n"; +} + +EOT + +print FH <<"EOT"; +my \$rfc1149 = RFC1149; +if (\$rfc1149 ne "$parent_rfc1149") { + print "not ok 20 # '\$rfc1149' ne '$parent_rfc1149'\n"; +} else { + print "ok 20\n"; +} + +if (\$rfc1149 != 1149) { + printf "not ok 21 # %d != 1149\n", \$rfc1149; +} else { + print "ok 21\n"; +} + +EOT + +print FH <<'EOT'; +# test macro=>1 +my $open = OPEN; +if ($open eq '/*') { + print "ok 22\n"; +} else { + print "not ok 22 # \$open='$open'\n"; +} +EOT + +# Do this in 7 bit in case someone is testing with some settings that cause +# 8 bit files incapable of storing this character. +my @values + = map {"'" . join (",", unpack "U*", $_) . "'"} + ($pound, $inf, $pound_bytes, $pound_utf8); +# Values is a list of strings, such as ('194,163,49', '163,49') + +print FH <<'EOT'; + +# I can see that this child test program might be about to use parts of +# Test::Builder + +my $test = 23; +my ($pound, $inf, $pound_bytes, $pound_utf8) = map {eval "pack 'U*', $_"} +EOT + +print FH join ",", @values; + +print FH << 'EOT'; +; + +foreach (["perl", "rules", "rules"], + ["/*", "OPEN", "OPEN"], + ["*/", "CLOSE", "CLOSE"], + [$pound, 'Sterling', []], + [$inf, 'Infinity', []], + [$pound_utf8, '1 Pound', '1 Pound (as bytes)'], + [$pound_bytes, '1 Pound (as bytes)', []], + ) { + # 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; + print "# \"$name\" => \'$expect\'\n"; + # Try to force this to be bytes if possible. + utf8::downgrade ($string, 1); +EOT + +print FH "my (\$error, \$got) = ${package}::constant (\$string);\n"; + +print FH <<'EOT'; + if ($error or $got ne $expect) { + print "not ok $test # error '$error', got '$got'\n"; + } else { + print "ok $test\n"; + } + $test++; + print "# Now upgrade '$name' to utf8\n"; + utf8::upgrade ($string); +EOT + +print FH "my (\$error, \$got) = ${package}::constant (\$string);\n"; + +print FH <<'EOT'; + if ($error or $got ne $expect) { + print "not ok $test # error '$error', got '$got'\n"; + } else { + print "ok $test\n"; + } + $test++; + if (defined $expect_bytes) { + print "# And now with the utf8 byte sequence for name\n"; + # Try the encoded bytes. + utf8::encode ($string); +EOT + +print FH "my (\$error, \$got) = ${package}::constant (\$string);\n"; + +print FH <<'EOT'; + if (ref $expect_bytes) { + # Error expected. + if ($error) { + print "ok $test # error='$error' (as expected)\n"; + } else { + print "not ok $test # expected error, got no error and '$got'\n"; + } + } elsif ($got ne $expect_bytes) { + print "not ok $test # error '$error', expect '$expect_bytes', got '$got'\n"; + } else { + print "ok $test\n"; + } + $test++; + } +} +EOT + +close FH or die "close $testpl: $!\n"; + +# This is where the test numbers carry on after the test number above are +# relayed +my $test = 44; + +################ Makefile.PL +# We really need a Makefile.PL because make test for a no dynamic linking perl +# will run Makefile.PL again as part of the "make perl" target. +my $makefilePL = catfile($dir, "Makefile.PL"); +push @files, "Makefile.PL"; +open FH, ">$makefilePL" or die "open >$makefilePL: $!\n"; +print FH <<"EOT"; +#!$perl -w +use ExtUtils::MakeMaker; +WriteMakefile( + 'NAME' => "$package", + 'VERSION_FROM' => "$package.pm", # finds \$VERSION + (\$] >= 5.005 ? + (#ABSTRACT_FROM => "$package.pm", # XXX add this + AUTHOR => "$0") : ()) + ); +EOT + +close FH or die "close $makefilePL: $!\n"; + +################ MANIFEST +# We really need a MANIFEST because make distclean checks it. +my $manifest = catfile($dir, "MANIFEST"); +push @files, "MANIFEST"; +open FH, ">$manifest" or die "open >$manifest: $!\n"; +print FH "$_\n" foreach @files; +close FH or die "close $manifest: $!\n"; + +chdir $dir or die $!; push @INC, '../../lib'; +END {chdir ".." or warn $!}; + +my @perlout = `$runperl Makefile.PL PERL_CORE=1`; +if ($?) { + print "not ok 1 # $runperl Makefile.PL failed: $?\n"; + print "# $_" foreach @perlout; + exit($?); +} else { + print "ok 1\n"; +} + + +my $makefile = ($^O eq 'VMS' ? 'descrip' : 'Makefile'); +my $makefile_ext = ($^O eq 'VMS' ? '.mms' : ''); +if (-f "$makefile$makefile_ext") { + print "ok 2\n"; +} else { + print "not ok 2\n"; +} + +# Renamed by make clean +my $makefile_rename = $makefile . ($^O eq 'VMS' ? '.mms' : '.old'); + +my $make = $Config{make}; + +$make = $ENV{MAKE} if exists $ENV{MAKE}; + +if ($^O eq 'MSWin32' && $make eq 'nmake') { $make .= " -nologo"; } + +my @makeout; + +if ($^O eq 'VMS') { $make .= ' all'; } +print "# make = '$make'\n"; +@makeout = `$make`; +if ($?) { + print "not ok 3 # $make failed: $?\n"; + print "# $_" foreach @makeout; + exit($?); +} else { + print "ok 3\n"; +} + +if ($^O eq 'VMS') { $make =~ s{ all}{}; } + +if ($Config{usedl}) { + print "ok 4\n"; +} else { + my $makeperl = "$make perl"; + print "# make = '$makeperl'\n"; + @makeout = `$makeperl`; + if ($?) { + print "not ok 4 # $makeperl failed: $?\n"; + print "# $_" foreach @makeout; + exit($?); + } else { + print "ok 4\n"; + } +} + +my $maketest = "$make test"; +print "# make = '$maketest'\n"; + +@makeout = `$maketest`; + +if (open OUTPUT, "<$output") { + print while <OUTPUT>; + close OUTPUT or print "# Close $output failed: $!\n"; +} else { + # Harness will report missing test results at this point. + print "# Open <$output failed: $!\n"; +} + +if ($?) { + print "not ok $test # $maketest failed: $?\n"; + print "# $_" foreach @makeout; +} else { + print "ok $test - maketest\n"; +} +$test++; + + +# -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 $test # $runperl -x $package.xs failed: $?\n"; +} else { + print "ok $test - regen\n"; +} +$test++; + +my $expect = $constant_types . $C_constant . + "\n#### XS Section:\n" . $XS_constant; + +if ($expect eq $regen) { + print "ok $test - regen worked\n"; +} else { + print "not ok $test - regen worked\n"; + # open FOO, ">expect"; print FOO $expect; + # open FOO, ">regen"; print FOO $regen; close FOO; +} +$test++; + +my $makeclean = "$make clean"; +print "# make = '$makeclean'\n"; +@makeout = `$makeclean`; +if ($?) { + print "not ok $test # $make failed: $?\n"; + print "# $_" foreach @makeout; +} else { + print "ok $test\n"; +} +$test++; + +sub check_for_bonus_files { + my $dir = shift; + my %expect = map {($^O eq 'VMS' ? lc($_) : $_), 1} @_; + + my $fail; + opendir DIR, $dir or die "opendir '$dir': $!"; + while (defined (my $entry = readdir DIR)) { + $entry =~ s/\.$// if $^O eq 'VMS'; # delete trailing dot that indicates no extension + next if $expect{$entry}; + print "# Extra file '$entry'\n"; + $fail = 1; + } + + closedir DIR or warn "closedir '.': $!"; + if ($fail) { + print "not ok $test\n"; + } else { + print "ok $test\n"; + } + $test++; +} + +check_for_bonus_files ('.', @files, $output, $makefile_rename, '.', '..'); + +rename $makefile_rename, $makefile + or die "Can't rename '$makefile_rename' to '$makefile': $!"; + +unlink $output or warn "Can't unlink '$output': $!"; + +# Need to make distclean to remove ../../lib/ExtTest.pm +my $makedistclean = "$make distclean"; +print "# make = '$makedistclean'\n"; +@makeout = `$makedistclean`; +if ($?) { + print "not ok $test # $make failed: $?\n"; + print "# $_" foreach @makeout; +} else { + print "ok $test\n"; +} +$test++; + +check_for_bonus_files ('.', @files, '.', '..'); + +unless ($keep_files) { + foreach (@files) { + unlink $_ or warn "unlink $_: $!"; + } +} + +check_for_bonus_files ('.', '.', '..'); diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Embed.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Embed.t new file mode 100644 index 00000000000..5460a254bd6 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Embed.t @@ -0,0 +1,185 @@ +#!/usr/bin/perl + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } +} +chdir 't'; + +use Config; +use ExtUtils::Embed; +use File::Spec; + +open(my $fh,">embed_test.c") || die "Cannot open embed_test.c:$!"; +print $fh <DATA>; +close($fh); + +$| = 1; +print "1..9\n"; +my $cc = $Config{'cc'}; +my $cl = ($^O eq 'MSWin32' && $cc eq 'cl'); +my $borl = ($^O eq 'MSWin32' && $cc eq 'bcc32'); +my $skip_exe = $^O eq 'os2' && $Config{ldflags} =~ /(?<!\S)-Zexe\b/; +my $exe = 'embed_test'; +$exe .= $Config{'exe_ext'} unless $skip_exe; # Linker will auto-append it +my $obj = 'embed_test' . $Config{'obj_ext'}; +my $inc = File::Spec->updir; +my $lib = File::Spec->updir; +my $libperl_copied; +my $testlib; +my @cmd; +my (@cmd2) if $^O eq 'VMS'; + +if ($^O eq 'VMS') { + push(@cmd,$cc,"/Obj=$obj"); + my (@incs) = ($inc); + my $crazy = ccopts(); + if ($crazy =~ s#/inc[^=/]*=([\w\$\_\-\.\[\]\:]+)##i) { + push(@incs,$1); + } + if ($crazy =~ s/-I([a-zA-Z0-9\$\_\-\.\[\]\:]*)//) { + push(@incs,$1); + } + $crazy =~ s#/Obj[^=/]*=[\w\$\_\-\.\[\]\:]+##i; + push(@cmd,"/Include=(".join(',',@incs).")"); + push(@cmd,$crazy); + push(@cmd,"embed_test.c"); + + push(@cmd2,$Config{'ld'}, $Config{'ldflags'}, "/exe=$exe"); + push(@cmd2,"$obj,[-]perlshr.opt/opt,[-]perlshr_attr.opt/opt"); + +} else { + if ($cl) { + push(@cmd,$cc,"-Fe$exe"); + } + elsif ($borl) { + push(@cmd,$cc,"-o$exe"); + } + else { + push(@cmd,$cc,'-o' => $exe); + } + push(@cmd,"-I$inc",ccopts(),'embed_test.c'); + if ($^O eq 'MSWin32') { + $inc = File::Spec->catdir($inc,'win32'); + push(@cmd,"-I$inc"); + $inc = File::Spec->catdir($inc,'include'); + push(@cmd,"-I$inc"); + if ($cc eq 'cl') { + push(@cmd,'-link',"-libpath:$lib",$Config{'libperl'},$Config{'libs'}); + } + else { + push(@cmd,"-L$lib",File::Spec->catfile($lib,$Config{'libperl'}),$Config{'libc'}); + } + } + else { # Not MSWin32. + push(@cmd,"-L$lib",'-lperl'); + local $SIG{__WARN__} = sub { + warn $_[0] unless $_[0] =~ /No library found for .*perl/ + }; + push(@cmd, '-Zlinker', '/PM:VIO') # Otherwise puts a warning to STDOUT! + if $^O eq 'os2' and $Config{ldflags} =~ /(?<!\S)-Zomf\b/; + push(@cmd,ldopts()); + } + if ($borl) { + @cmd = ($cmd[0],(grep{/^-[LI]/}@cmd[1..$#cmd]),(grep{!/^-[LI]/}@cmd[1..$#cmd])); + } + + if ($^O eq 'aix') { # AIX needs an explicit symbol export list. + my ($perl_exp) = grep { -f } qw(perl.exp ../perl.exp); + die "where is perl.exp?\n" unless defined $perl_exp; + for (@cmd) { + s!-bE:(\S+)!-bE:$perl_exp!; + } + } + elsif ($^O eq 'cygwin') { # Cygwin needs the shared libperl copied + my $v_e_r_s = $Config{version}; + $v_e_r_s =~ tr/./_/; + system("cp ../cygperl$v_e_r_s.dll ./"); # for test 1 + } + elsif ($Config{'libperl'} !~ /\Alibperl\./) { + # Everyone needs libperl copied if it's not found by '-lperl'. + $testlib = $Config{'libperl'}; + my $srclib = $testlib; + $testlib =~ s/^[^.]+/libperl/; + $testlib = File::Spec::->catfile($lib, $testlib); + $srclib = File::Spec::->catfile($lib, $srclib); + if (-f $srclib) { + unlink $testlib if -f $testlib; + my $ln_or_cp = $Config{'ln'} || $Config{'cp'}; + my $lncmd = "$ln_or_cp $srclib $testlib"; + #print "# $lncmd\n"; + $libperl_copied = 1 unless system($lncmd); + } + } +} +my $status; +# On OS/2 the linker will always emit an empty line to STDOUT; filter these +my $cmd = join ' ', @cmd; +chomp($cmd); # where is the newline coming from? ldopts()? +print "# $cmd\n"; +my @out = `$cmd`; +$status = $?; +print "# $_\n" foreach @out; + +if ($^O eq 'VMS' && !$status) { + print "# @cmd2\n"; + $status = system(join(' ',@cmd2)); +} +print (($status? 'not ': '')."ok 1\n"); + +my $embed_test = File::Spec->catfile(File::Spec->curdir, $exe); +$embed_test = "run/nodebug $exe" if $^O eq 'VMS'; +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$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` + +__END__ + +/* perl_test.c */ + +#include <EXTERN.h> +#include <perl.h> + +#define my_puts(a) if(puts(a) < 0) exit(666) + +static char *cmds[] = { "perl","-e", "print qq[ok 5\\n]", NULL }; + +int main(int argc, char **argv, char **env) +{ + PerlInterpreter *my_perl = perl_alloc(); + + my_puts("ok 2"); + + perl_construct(my_perl); + + my_puts("ok 3"); + + perl_parse(my_perl, NULL, (sizeof(cmds)/sizeof(char *))-1, cmds, env); + + my_puts("ok 4"); + + fflush(stdout); + + perl_run(my_perl); + + my_puts("ok 6"); + + perl_destruct(my_perl); + + my_puts("ok 7"); + + perl_free(my_perl); + + my_puts("ok 8"); + + return 0; +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/INST.t b/gnu/usr.bin/perl/lib/ExtUtils/t/INST.t new file mode 100644 index 00000000000..d6780ac6744 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/INST.t @@ -0,0 +1,141 @@ +#!/usr/bin/perl -w + +# Wherein we ensure the INST_* and INSTALL* variables are set correctly +# in a default Makefile.PL run +# +# Essentially, this test is a Makefile.PL. + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} + +use strict; +use Test::More tests => 23; +use MakeMaker::Test::Utils; +use ExtUtils::MakeMaker; +use File::Spec; +use TieOut; +use Config; + +chdir 't'; + +perl_lib; + +$| = 1; + +my $Makefile = makefile_name; +my $Curdir = File::Spec->curdir; +my $Updir = File::Spec->updir; + +ok( chdir 'Big-Dummy', "chdir'd to Big-Dummy" ) || + diag("chdir failed: $!"); + +my $stdout = tie *STDOUT, 'TieOut' or die; +my $mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + PREREQ_PM => {}, + PERL_CORE => $ENV{PERL_CORE}, +); +like( $stdout->read, qr{ + Writing\ $Makefile\ for\ Big::Liar\n + Big::Liar's\ vars\n + INST_LIB\ =\ \S+\n + INST_ARCHLIB\ =\ \S+\n + Writing\ $Makefile\ for\ Big::Dummy\n +}x ); +undef $stdout; +untie *STDOUT; + +isa_ok( $mm, 'ExtUtils::MakeMaker' ); + +is( $mm->{NAME}, 'Big::Dummy', 'NAME' ); +is( $mm->{VERSION}, 0.01, 'VERSION' ); + +my $config_prefix = $Config{installprefixexp} || $Config{installprefix} || + $Config{prefixexp} || $Config{prefix}; +is( $mm->{PREFIX}, $config_prefix, 'PREFIX' ); + +is( !!$mm->{PERL_CORE}, !!$ENV{PERL_CORE}, 'PERL_CORE' ); + +my($perl_src, $mm_perl_src); +if( $ENV{PERL_CORE} ) { + $perl_src = File::Spec->catdir($Updir, $Updir); + $perl_src = File::Spec->canonpath($perl_src); + $mm_perl_src = File::Spec->canonpath($mm->{PERL_SRC}); +} +else { + $mm_perl_src = $mm->{PERL_SRC}; +} + +is( $mm_perl_src, $perl_src, 'PERL_SRC' ); + + +# PERM_* +is( $mm->{PERM_RW}, 644, 'PERM_RW' ); +is( $mm->{PERM_RWX}, 755, 'PERM_RWX' ); + + +# INST_* +is( $mm->{INST_ARCHLIB}, + $mm->{PERL_CORE} ? $mm->{PERL_ARCHLIB} + : File::Spec->catdir($Curdir, 'blib', 'arch'), + 'INST_ARCHLIB'); +is( $mm->{INST_BIN}, File::Spec->catdir($Curdir, 'blib', 'bin'), + 'INST_BIN' ); + +is( keys %{$mm->{CHILDREN}}, 1 ); +my($child_pack) = keys %{$mm->{CHILDREN}}; +my $c_mm = $mm->{CHILDREN}{$child_pack}; +is( $c_mm->{INST_ARCHLIB}, + $c_mm->{PERL_CORE} ? $c_mm->{PERL_ARCHLIB} + : File::Spec->catdir($Updir, 'blib', 'arch'), + 'CHILD INST_ARCHLIB'); +is( $c_mm->{INST_BIN}, File::Spec->catdir($Updir, 'blib', 'bin'), + 'CHILD INST_BIN' ); + + +my $inst_lib = File::Spec->catdir($Curdir, 'blib', 'lib'); +is( $mm->{INST_LIB}, + $mm->{PERL_CORE} ? $mm->{PERL_LIB} : $inst_lib, 'INST_LIB' ); + + +# INSTALL* +is( $mm->{INSTALLDIRS}, 'site', 'INSTALLDIRS' ); + + + +# Make sure the INSTALL*MAN*DIR variables work. We forgot them +# at one point. +$stdout = tie *STDOUT, 'TieOut' or die; +$mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + PERL_CORE => $ENV{PERL_CORE}, + INSTALLMAN1DIR => 'none', + INSTALLSITEMAN3DIR => 'none', + INSTALLVENDORMAN1DIR => 'none', + INST_MAN1DIR => 'none', +); +like( $stdout->read, qr{ + Writing\ $Makefile\ for\ Big::Liar\n + Big::Liar's\ vars\n + INST_LIB\ =\ \S+\n + INST_ARCHLIB\ =\ \S+\n + Writing\ $Makefile\ for\ Big::Dummy\n +}x ); +undef $stdout; +untie *STDOUT; + +isa_ok( $mm, 'ExtUtils::MakeMaker' ); + +is ( $mm->{INSTALLMAN1DIR}, 'none' ); +is ( $mm->{INSTALLSITEMAN3DIR}, 'none' ); +is ( $mm->{INSTALLVENDORMAN1DIR}, 'none' ); +is ( $mm->{INST_MAN1DIR}, 'none' ); diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/INST_PREFIX.t b/gnu/usr.bin/perl/lib/ExtUtils/t/INST_PREFIX.t new file mode 100644 index 00000000000..8af8c307fa8 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/INST_PREFIX.t @@ -0,0 +1,134 @@ +#!/usr/bin/perl -w + +# Wherein we ensure the INST_* and INSTALL* variables are set correctly +# when various PREFIX variables are set. +# +# Essentially, this test is a Makefile.PL. + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} + +use strict; +use Test::More tests => 26; +use MakeMaker::Test::Utils; +use ExtUtils::MakeMaker; +use File::Spec; +use TieOut; +use Config; + +my $Is_VMS = $^O eq 'VMS'; + +chdir 't'; + +perl_lib; + +$| = 1; + +my $Makefile = makefile_name; +my $Curdir = File::Spec->curdir; +my $Updir = File::Spec->updir; + +ok( chdir 'Big-Dummy', "chdir'd to Big-Dummy" ) || + diag("chdir failed: $!"); + +my $PREFIX = File::Spec->catdir('foo', 'bar'); +my $stdout = tie *STDOUT, 'TieOut' or die; +my $mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + PREREQ_PM => {}, + PERL_CORE => $ENV{PERL_CORE}, + PREFIX => $PREFIX, +); +like( $stdout->read, qr{ + Writing\ $Makefile\ for\ Big::Liar\n + Big::Liar's\ vars\n + INST_LIB\ =\ \S+\n + INST_ARCHLIB\ =\ \S+\n + Writing\ $Makefile\ for\ Big::Dummy\n +}x ); +undef $stdout; +untie *STDOUT; + +isa_ok( $mm, 'ExtUtils::MakeMaker' ); + +is( $mm->{NAME}, 'Big::Dummy', 'NAME' ); +is( $mm->{VERSION}, 0.01, 'VERSION' ); + +is( $mm->{PREFIX}, $PREFIX, 'PREFIX' ); + +is( !!$mm->{PERL_CORE}, !!$ENV{PERL_CORE}, 'PERL_CORE' ); + +my($perl_src, $mm_perl_src); +if( $ENV{PERL_CORE} ) { + $perl_src = File::Spec->catdir($Updir, $Updir); + $perl_src = File::Spec->canonpath($perl_src); + $mm_perl_src = File::Spec->canonpath($mm->{PERL_SRC}); +} +else { + $mm_perl_src = $mm->{PERL_SRC}; +} + +is( $mm_perl_src, $perl_src, 'PERL_SRC' ); + + +# Every INSTALL* variable must start with some PREFIX. +my @Perl_Install = qw(archlib privlib bin script + man1dir man3dir); +my @Site_Install = qw(sitearch sitelib sitebin + siteman1dir siteman3dir); +my @Vend_Install = qw(vendorarch vendorlib vendorbin + vendorman1dir vendorman3dir); + +foreach my $var (@Perl_Install) { + my $prefix = $Is_VMS ? '[.foo.bar' : File::Spec->catdir(qw(foo bar)); + + # support for man page skipping + $prefix = 'none' if $var =~ /man/ && !$Config{"install$var"}; + like( $mm->{uc "install$var"}, qr/^\Q$prefix\E/, "PREFIX + $var" ); +} + +foreach my $var (@Site_Install) { + my $prefix = $Is_VMS ? '[.foo.bar' : File::Spec->catdir(qw(foo bar)); + + like( $mm->{uc "install$var"}, qr/^\Q$prefix\E/, + "SITEPREFIX + $var" ); +} + +foreach my $var (@Vend_Install) { + my $prefix = $Is_VMS ? '[.foo.bar' : File::Spec->catdir(qw(foo bar)); + + like( $mm->{uc "install$var"}, qr/^\Q$prefix\E/, + "VENDORPREFIX + $var" ); +} + + +# Check that when installman*dir isn't set in Config no man pages +# are generated. +{ + undef *ExtUtils::MM_Unix::Config; + %ExtUtils::MM_Unix::Config = %Config; + $ExtUtils::MM_Unix::Config{installman1dir} = ''; + $ExtUtils::MM_Unix::Config{installman3dir} = ''; + + my $wibble = File::Spec->catdir(qw(wibble and such)); + my $stdout = tie *STDOUT, 'TieOut' or die; + my $mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + PREREQ_PM => {}, + PERL_CORE => $ENV{PERL_CORE}, + PREFIX => $PREFIX, + INSTALLMAN1DIR=> $wibble, + ); + + is( $mm->{INSTALLMAN1DIR}, $wibble ); + is( $mm->{INSTALLMAN3DIR}, 'none' ); +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Installed.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Installed.t new file mode 100644 index 00000000000..d62afba4348 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Installed.t @@ -0,0 +1,251 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } + else { + unshift @INC, 't/lib/'; + } +} +chdir 't'; + + +use strict; + +use Config; +use Cwd; +use File::Path; +use File::Basename; +use File::Spec; + +use Test::More tests => 46; + +BEGIN { use_ok( 'ExtUtils::Installed' ) } + +my $mandirs = !!$Config{man1direxp} + !!$Config{man3direxp}; + +# saves having to qualify package name for class methods +my $ei = bless( {}, 'ExtUtils::Installed' ); + +# _is_prefix +ok( $ei->_is_prefix('foo/bar', 'foo'), + '_is_prefix() should match valid path prefix' ); +ok( !$ei->_is_prefix('\foo\bar', '\bar'), + '... should not match wrong prefix' ); + +# _is_type +ok( $ei->_is_type(0, 'all'), '_is_type() should be true for type of "all"' ); + +foreach my $path (qw( man1dir man3dir )) { +SKIP: { + my $dir = $Config{$path.'exp'}; + skip("no man directory $path on this system", 2 ) unless $dir; + + my $file = $dir . '/foo'; + ok( $ei->_is_type($file, 'doc'), "... should find doc file in $path" ); + ok( !$ei->_is_type($file, 'prog'), "... but not prog file in $path" ); + } +} + +# 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 +# directory +$prefix = VMS::Filespec::unixify($prefix) if $^O eq 'VMS'; + +# ActivePerl 5.6.1/631 has $Config{prefixexp} as 'p:' for some reason +$prefix = $Config{prefix} if $prefix eq 'p:' && $^O eq 'MSWin32'; + +ok( $ei->_is_type( File::Spec->catfile($prefix, 'bar'), 'prog'), + "... should find prog file under $prefix" ); + +SKIP: { + skip('no man directories on this system', 1) unless $mandirs; + is( $ei->_is_type('bar', 'doc'), 0, + '... should not find doc file outside path' ); +} + +ok( !$ei->_is_type('bar', 'prog'), + '... nor prog file outside path' ); +ok( !$ei->_is_type('whocares', 'someother'), '... nor other type anywhere' ); + +# _is_under +ok( $ei->_is_under('foo'), '_is_under() should return true with no dirs' ); + +my @under = qw( boo bar baz ); +ok( !$ei->_is_under('foo', @under), '... should find no file not under dirs'); +ok( $ei->_is_under('baz', @under), '... should find file under dir' ); + + +my $wrotelist; + +rmtree 'auto/FakeMod'; +ok( mkpath('auto/FakeMod') ); +END { rmtree 'auto/FakeMod' } + +ok(open(PACKLIST, '>auto/FakeMod/.packlist')); +print PACKLIST 'list'; +close PACKLIST; + +ok(open(FAKEMOD, '>auto/FakeMod/FakeMod.pm')); + +print FAKEMOD <<'FAKE'; +package FakeMod; +use vars qw( $VERSION ); +$VERSION = '1.1.1'; +1; +FAKE + +close 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(), + sitearchexp => $fake_mod_dir, + ); + + # necessary to fool new() + push @INC, $fake_mod_dir; + + 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'); + 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', + '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) : + ()), + ($Config{man3direxp} ? + (File::Spec->catdir($Config{man3direxp}, 'bar') => 1) : + ()), + File::Spec->catdir($prefix, 'foobar') => 1, + foobaz => 1, + }, +}; + +eval { $ei->files('badmod') }; +like( $@, qr/badmod is not installed/,'files() should croak given bad modname'); +eval { $ei->files('goodmod', 'badtype' ) }; +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}; + @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' ); +} +SKIP: { + skip('no man directories on this system', 1) unless $mandirs; + @files = $ei->files('goodmod', 'doc'); + is( scalar @files, $mandirs, '... should find all doc files with no dir' ); +} + +@files = $ei->files('goodmod', 'prog', 'fake', 'fake2'); +is( scalar @files, 0, '... should find no doc files given wrong dirs' ); +@files = $ei->files('goodmod', 'prog'); +is( scalar @files, 1, '... should find doc file in correct dir' ); +like( $files[0], qr/foobar[>\]]?$/, '... checking file name' ); +@files = $ei->files('goodmod'); +is( scalar @files, 2 + $mandirs, '... should find all files with no type specified' ); +my %dirnames = map { lc($_) => dirname($_) } @files; + +# directories +my @dirs = $ei->directories('goodmod', 'prog', 'fake'); +is( scalar @dirs, 0, 'directories() should return no dirs if no files found' ); + +SKIP: { + skip('no man directories on this system', 1) unless $mandirs; + @dirs = $ei->directories('goodmod', 'doc'); + is( scalar @dirs, $mandirs, '... should find all files files() would' ); +} +@dirs = $ei->directories('goodmod'); +is( scalar @dirs, 2 + $mandirs, '... should find all files files() would, again' ); +@files = sort map { exists $dirnames{lc($_)} ? $dirnames{lc($_)} : '' } @files; +is( join(' ', @files), join(' ', @dirs), '... should sort output' ); + +# directory_tree +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, + 'directory_tree() should report intermediate dirs to those requested' ); +} + +my $fakepak = Fakepak->new(102); + +$ei->{yesmod} = { + version => 101, + packlist => $fakepak, +}; + +# these should all croak +foreach my $sub (qw( validate packlist version )) { + eval { $ei->$sub('nomod') }; + like( $@, qr/nomod is not installed/, + "$sub() should croak when asked about uninstalled module" ); +} + +# validate +is( $ei->validate('yesmod'), 'validated', + 'validate() should return results of packlist validate() call' ); + +# packlist +is( ${ $ei->packlist('yesmod') }, 102, + 'packlist() should report installed mod packlist' ); + +# version +is( $ei->version('yesmod'), 101, + 'version() should report installed mod version' ); + +END { + if ($wrotelist) { + for my $file (qw( .packlist FakePak.pm )) { + 1 while unlink $file; + } + File::Path::rmtree('auto') or warn "Couldn't rmtree auto: $!"; + } +} + +package Fakepak; + +sub new { + my $class = shift; + bless(\(my $scalar = shift), $class); +} + +sub validate { + 'validated' +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_BeOS.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_BeOS.t new file mode 100644 index 00000000000..870e8d47fe7 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_BeOS.t @@ -0,0 +1,48 @@ +#!/usr/bin/perl + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use Test::More; + +BEGIN { + if ($^O =~ /beos/i) { + plan tests => 2; + } else { + plan skip_all => 'This is not BeOS'; + } +} + +use Config; +use File::Spec; +use File::Basename; + +# tels - Taken from MM_Win32.t - I must not understand why this works, right? +# Does this mimic ExtUtils::MakeMaker ok? +{ + @MM::ISA = qw( + ExtUtils::MM_Unix + ExtUtils::Liblist::Kid + ExtUtils::MakeMaker + ); + # MM package faked up by messy MI entanglement + package MM; + sub DESTROY {} +} + +require_ok( 'ExtUtils::MM_BeOS' ); + +# perl_archive() +{ + my $libperl = $Config{libperl} || 'libperl.a'; + is( MM->perl_archive(), File::Spec->catfile('$(PERL_INC)', $libperl ), + 'perl_archive() should respect libperl setting' ); +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Cygwin.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Cygwin.t new file mode 100644 index 00000000000..03641d33f22 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Cygwin.t @@ -0,0 +1,124 @@ +#!/usr/bin/perl + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use Test::More; + +BEGIN { + if ($^O =~ /cygwin/i) { + plan tests => 13; + } else { + plan skip_all => "This is not cygwin"; + } +} + +use Config; +use File::Spec; +use ExtUtils::MM; + +use_ok( 'ExtUtils::MM_Cygwin' ); + +# test canonpath +my $path = File::Spec->canonpath('/a/../../c'); +is( MM->canonpath('/a/../../c'), $path, + 'canonpath() method should work just like the one in File::Spec' ); + +# test cflags, with the fake package below +my $args = bless({ + CFLAGS => 'fakeflags', + CCFLAGS => '', +}, MM); + +# with CFLAGS set, it should be returned +is( $args->cflags(), 'fakeflags', + 'cflags() should return CFLAGS member data, if set' ); + +delete $args->{CFLAGS}; + +# ExtUtils::MM_Cygwin::cflags() calls this, fake the output +{ + local $SIG{__WARN__} = sub { + # no warnings 'redefine'; + warn @_ unless $_[0] =~ /^Subroutine .* redefined/; + }; + sub ExtUtils::MM_Unix::cflags { return $_[1] }; +} + +# respects the config setting, should ignore whitespace around equal sign +my $ccflags = $Config{useshrplib} eq 'true' ? ' -DUSEIMPORTLIB' : ''; +{ + local $args->{NEEDS_LINKING} = 1; + $args->cflags(<<FLAGS); +OPTIMIZE = opt +PERLTYPE =pt +FLAGS +} + +like( $args->{CFLAGS}, qr/OPTIMIZE = opt/, '... should set OPTIMIZE' ); +like( $args->{CFLAGS}, qr/PERLTYPE = pt/, '... should set PERLTYPE' ); +like( $args->{CFLAGS}, qr/CCFLAGS = $ccflags/, '... should set CCFLAGS' ); + +# test manifypods +$args = bless({ + NOECHO => 'noecho', + MAN3PODS => {}, + MAN1PODS => {}, + MAKEFILE => 'Makefile', +}, 'MM'); +like( $args->manifypods(), qr/pure_all\n\tnoecho/, + 'manifypods() should return without PODS values set' ); + +$args->{MAN3PODS} = { foo => 1 }; +my $out = tie *STDOUT, 'FakeOut'; +{ + local $SIG{__WARN__} = sub { + # no warnings 'redefine'; + warn @_ unless $_[0] =~ /used only once/; + }; + no warnings 'once'; + local *MM::perl_script = sub { return }; + my $res = $args->manifypods(); + like( $$out, qr/could not locate your pod2man/, + '... should warn if pod2man cannot be located' ); + like( $res, qr/POD2MAN_EXE = -S pod2man/, + '... should use default pod2man target' ); + like( $res, qr/pure_all.+foo/, '... should add MAN3PODS targets' ); +} + +SKIP: { + skip "Only relevent in the core", 2 unless $ENV{PERL_CORE}; + $args->{PERL_SRC} = File::Spec->updir; + $args->{MAN1PODS} = { bar => 1 }; + $$out = ''; + $res = $args->manifypods(); + is( $$out, '', '... should not warn if PERL_SRC provided' ); + like( $res, qr/bar \\\n\t1 \\\n\tfoo/, + '... should join MAN1PODS and MAN3PODS'); +} + +# test perl_archive +my $libperl = $Config{libperl} || 'libperl.a'; +$libperl =~ s/\.a/.dll.a/; +is( $args->perl_archive(), "\$(PERL_INC)/$libperl", + 'perl_archive() should respect libperl setting' ); + + +package FakeOut; + +sub TIEHANDLE { + bless(\(my $scalar), $_[0]); +} + +sub PRINT { + my $self = shift; + $$self .= shift; +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_NW5.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_NW5.t new file mode 100644 index 00000000000..d2046eeebbf --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_NW5.t @@ -0,0 +1,324 @@ +#!/usr/bin/perl + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + unshift @INC, '../lib'; + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + + +use Test::More; + +BEGIN { + if ($^O =~ /NetWare/i) { + plan tests => 40; + } else { + plan skip_all => 'This is not NW5'; + } +} + +use Config; +use File::Spec; +use File::Basename; +use ExtUtils::MM; + +require_ok( 'ExtUtils::MM_NW5' ); + +# Dummy MM object until we have a real MM init method. +my $MM = bless { + DIR => [], + NOECHO => '@', + XS => {}, + MAKEFILE => 'Makefile', + RM_RF => 'rm -rf', + MV => 'mv', + }, 'MM'; + + +# replace_manpage_separator() => tr|/|.|s ? +{ + my $man = 'a/path/to//something'; + ( my $replaced = $man ) =~ tr|/|.|s; + is( $MM->replace_manpage_separator( $man ), + $replaced, 'replace_manpage_separator()' ); +} + +# maybe_command() +SKIP: { + skip( '$ENV{COMSPEC} not set', 2 ) + unless $ENV{COMSPEC} =~ m!((?:[a-z]:)?[^|<>]+)!i; + my $comspec = $1; + is( $MM->maybe_command( $comspec ), + $comspec, 'COMSPEC is a maybe_command()' ); + ( my $comspec2 = $comspec ) =~ s|\..{3}$||; + like( $MM->maybe_command( $comspec2 ), + qr/\Q$comspec/i, + 'maybe_command() without extension' ); +} + +my $had_pathext = exists $ENV{PATHEXT}; +{ + local $ENV{PATHEXT} = '.exe'; + ok( ! $MM->maybe_command( 'not_a_command.com' ), + 'not a maybe_command()' ); +} +# Bug in Perl. local $ENV{FOO} won't delete the key afterward. +delete $ENV{PATHEXT} unless $had_pathext; + +# file_name_is_absolute() [Does not support UNC-paths] +{ + ok( $MM->file_name_is_absolute( 'SYS:/' ), + 'file_name_is_absolute()' ); + ok( ! $MM->file_name_is_absolute( 'some/path/' ), + 'not file_name_is_absolute()' ); + +} + +# find_perl() +# Should be able to find running perl... $^X is OK on NW5 +{ + my $my_perl = $1 if $^X =~ /(.*)/; # are we in -T or -t? + my( $perl, $path ) = fileparse( $my_perl ); + like( $MM->find_perl( $], [ $perl ], [ $path ] ), + qr/^\Q$my_perl\E$/i, 'find_perl() finds this perl' ); +} + +# catdir() (calls MM_NW5->canonpath) +{ + my @path_eg = qw( SYS trick dir/now_OK ); + + is( $MM->catdir( @path_eg ), + 'SYS\\trick\\dir\\now_OK', 'catdir()' ); + is( $MM->catdir( @path_eg ), + File::Spec->catdir( @path_eg ), + 'catdir() eq File::Spec->catdir()' ); + +# catfile() (calls MM_NW5->catdir) + push @path_eg, 'file.ext'; + + is( $MM->catfile( @path_eg ), + 'SYS\\trick\\dir\\now_OK\\file.ext', 'catfile()' ); + + is( $MM->catfile( @path_eg ), + File::Spec->catfile( @path_eg ), + 'catfile() eq File::Spec->catfile()' ); +} + +# init_others(): check if all keys are created and set? +# qw( TOUCH CHMOD CP RM_F RM_RF MV NOOP TEST_F LD AR LDLOADLIBS DEV_NUL ) +{ + my $mm_w32 = bless( {}, 'MM' ); + $mm_w32->init_others(); + my @keys = qw( TOUCH CHMOD CP RM_F RM_RF MV NOOP + TEST_F LD AR LDLOADLIBS DEV_NULL ); + for my $key ( @keys ) { + ok( $mm_w32->{ $key }, "init_others: $key" ); + } +} + +# constants() +{ + my $mm_w32 = bless { + NAME => 'TestMM_NW5', + VERSION => '1.00', + VERSION_FROM => 'TestMM_NW5', + PM => { 'MM_NW5.pm' => 1 }, + }, 'MM'; + + # XXX Hack until we have a proper init method. + # Flesh out some necessary keys in the MM object. + foreach my $key (qw(XS C O_FILES H HTMLLIBPODS HTMLSCRIPTPODS + MAN1PODS MAN3PODS PARENT_NAME)) { + $mm_w32->{$key} = ''; + } + my $s_PM = join( " \\\n\t", sort keys %{$mm_w32->{PM}} ); + my $k_PM = join( " \\\n\t", %{$mm_w32->{PM}} ); + + like( $mm_w32->constants(), + qr|^NAME\ =\ TestMM_NW5\s+VERSION\ =\ 1\.00.+ + MAKEMAKER\ =\ \Q$INC{'ExtUtils/MakeMaker.pm'}\E\s+ + MM_VERSION\ =\ \Q$ExtUtils::MakeMaker::VERSION\E.+ + VERSION_FROM\ =\ TestMM_NW5.+ + TO_INST_PM\ =\ \Q$s_PM\E\s+ + PM_TO_BLIB\ =\ \Q$k_PM\E + |xs, 'constants()' ); + +} + +# path() +my $had_path = exists $ENV{PATH}; +{ + my @path_eg = ( qw( . .. ), 'SYS:\\Program Files' ); + local $ENV{PATH} = join ';', @path_eg; + ok( eq_array( [ $MM->path() ], [ @path_eg ] ), + 'path() [preset]' ); +} +# Bug in Perl. local $ENV{FOO} will not delete key afterwards. +delete $ENV{PATH} unless $had_path; + +# static_lib() should look into that +# dynamic_bs() should look into that +# dynamic_lib() should look into that + +# clean() +{ + my $clean = $Config{cc} =~ /^gcc/i ? 'dll.base dll.exp' : '*.pdb'; + like( $MM->clean(), qr/^clean ::\s+\Q-$(RM_F) $clean\E\s+$/m, + 'clean() Makefile target' ); +} + +# perl_archive() +{ + my $libperl = $Config{libperl} || 'libperl.a'; + is( $MM->perl_archive(), File::Spec->catfile('$(PERL_INC)', $libperl ), + 'perl_archive() should respect libperl setting' ); +} + +# export_list +{ + my $mm_w32 = bless { BASEEXT => 'someext' }, 'MM'; + is( $mm_w32->export_list(), 'someext.def', 'export_list()' ); +} + +# canonpath() +{ + my $path = 'SYS:/TEMP'; + is( $MM->canonpath( $path ), File::Spec->canonpath( $path ), + 'canonpath() eq File::Spec->canonpath' ); +} + +# perl_script() +my $script_ext = ''; +my $script_name = 'mm_w32tmp'; +SKIP: { + local *SCRIPT; + skip( "Can't create temp file: $!", 4 ) + unless open SCRIPT, "> $script_name"; + print SCRIPT <<'EOSCRIPT'; +#! perl +__END__ +EOSCRIPT + skip( "Can't write to temp file: $!", 4 ) + unless close SCRIPT; + # now start tests: + is( $MM->perl_script( $script_name ), + "${script_name}$script_ext", "perl_script ($script_ext)" ); + + skip( "Can't rename temp file: $!", 3 ) + unless rename $script_name, "${script_name}.pl"; + $script_ext = '.pl'; + is( $MM->perl_script( $script_name ), + "${script_name}$script_ext", "perl_script ($script_ext)" ); + + skip( "Can't rename temp file: $!", 2 ) + unless rename "${script_name}$script_ext", "${script_name}.bat"; + $script_ext = '.bat'; + is( $MM->perl_script( $script_name ), + "${script_name}$script_ext", "perl_script ($script_ext)" ); + + skip( "Can't rename temp file: $!", 1 ) + unless rename "${script_name}$script_ext", "${script_name}.noscript"; + $script_ext = '.noscript'; + + isnt( $MM->perl_script( $script_name ), + "${script_name}$script_ext", + "not a perl_script anymore ($script_ext)" ); + is( $MM->perl_script( $script_name ), undef, + "perl_script ($script_ext) returns empty" ); +} +unlink "${script_name}$script_ext" if -f "${script_name}$script_ext"; + + +# pm_to_blib() +{ + like( $MM->pm_to_blib(), + qr/^pm_to_blib: \Q$(TO_INST_PM)\E.+\Q$(TOUCH) \E\$@\s+$/ms, + 'pm_to_blib' ); +} + +# tool_autosplit() +{ + my %attribs = ( MAXLEN => 255 ); + like( $MM->tool_autosplit( %attribs ), + qr/^\#\ Usage:\ \$\(AUTOSPLITFILE\) + \ FileToSplit\ AutoDirToSplitInto.+ + AUTOSPLITFILE\ =\ \$\(PERLRUN\)\ .+ + \$AutoSplit::Maxlen=$attribs{MAXLEN}; + /xms, + '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 + +# manifypods() +{ + my $mm_w32 = bless { NOECHO => '' }, 'MM'; + like( $mm_w32->manifypods(), + qr/^\nmanifypods :\n\t\$\Q(NOOP)\E\n$/, + 'manifypods() Makefile target' ); +} + +# dist_ci() should look into that +# dist_core() should look into that + +# pasthru() +{ + my $pastru = "PASTHRU = " . ($Config{make} =~ /^nmake/i ? "-nologo" : ""); + is( $MM->pasthru(), $pastru, 'pasthru()' ); +} + +package FakeOut; + +sub TIEHANDLE { + bless(\(my $scalar), $_[0]); +} + +sub PRINT { + my $self = shift; + $$self .= shift; +} + +__END__ + +=head1 NAME + +MM_NW5.t - Tests for ExtUtils::MM_NW5 + +=head1 TODO + + - Methods to still be checked: + # static_lib() should look into that + # dynamic_bs() should look into that + # dynamic_lib() should look into that + # xs_o() should look into that + # top_targets() should look into that + # dist_ci() should look into that + # dist_core() should look into that + +=head1 AUTHOR + +20011228 Abe Timmerman <abe@ztreet.demon.nl> + +=cut diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_OS2.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_OS2.t new file mode 100644 index 00000000000..53b83f3f855 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_OS2.t @@ -0,0 +1,275 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use strict; +use Test::More; +if ($^O =~ /os2/i) { + plan( tests => 32 ); +} else { + plan( skip_all => "This is not OS/2" ); +} + +# for dlsyms, overridden in tests +BEGIN { + package ExtUtils::MM_OS2; + use subs 'system', 'unlink'; +} + +# for maybe_command +use File::Spec; + +use_ok( 'ExtUtils::MM_OS2' ); +ok( grep( 'ExtUtils::MM_OS2', @MM::ISA), + 'ExtUtils::MM_OS2 should be parent of MM' ); + +# dlsyms +my $mm = bless({ + SKIPHASH => { + dynamic => 1 + }, + NAME => 'foo:bar::', +}, 'ExtUtils::MM_OS2'); + +is( $mm->dlsyms(), '', + 'dlsyms() should return nothing with dynamic flag set' ); + +$mm->{BASEEXT} = 'baseext'; +delete $mm->{SKIPHASH}; +my $res = $mm->dlsyms(); +like( $res, qr/baseext\.def: Makefile/, + '... without flag, should return make targets' ); +like( $res, qr/"DL_FUNCS" => { }/, + '... should provide empty hash refs where necessary' ); +like( $res, qr/"DL_VARS" => \[]/, '... and empty array refs too' ); + +$mm->{FUNCLIST} = 'funclist'; +$res = $mm->dlsyms( IMPORTS => 'imports' ); +like( $res, qr/"FUNCLIST" => .+funclist/, + '... should pick up values from object' ); +like( $res, qr/"IMPORTS" => .+imports/, '... and allow parameter options too' ); + +my $can_write; +{ + local *OUT; + $can_write = open(OUT, '>tmp_imp'); +} + +SKIP: { + skip("Cannot write test files: $!", 7) unless $can_write; + + $mm->{IMPORTS} = { foo => 'bar' }; + + local $@; + eval { $mm->dlsyms() }; + like( $@, qr/Can.t mkdir tmp_imp/, + '... should die if directory cannot be made' ); + + unlink('tmp_imp') or skip("Cannot remove test file: $!", 9); + eval { $mm->dlsyms() }; + like( $@, qr/Malformed IMPORT/, 'should die from malformed import symbols'); + + $mm->{IMPORTS} = { foo => 'bar.baz' }; + + my @sysfail = ( 1, 0, 1 ); + my ($sysargs, $unlinked); + + *ExtUtils::MM_OS2::system = sub { + $sysargs = shift; + return shift @sysfail; + }; + + *ExtUtils::MM_OS2::unlink = sub { + $unlinked++; + }; + + eval { $mm->dlsyms() }; + + like( $sysargs, qr/^emximp/, '... should try to call system() though' ); + like( $@, qr/Cannot make import library/, + '... should die if emximp syscall fails' ); + + # sysfail is 0 now, call emximp call should succeed + eval { $mm->dlsyms() }; + is( $unlinked, 1, '... should attempt to unlink temp files' ); + like( $@, qr/Cannot extract import/, + '... should die if other syscall fails' ); + + # make both syscalls succeed + @sysfail = (0, 0); + local $@; + eval { $mm->dlsyms() }; + is( $@, '', '... should not die if both syscalls succeed' ); +} + +# static_lib +{ + my $called = 0; + + # avoid "used only once" + local *ExtUtils::MM_Unix::static_lib; + *ExtUtils::MM_Unix::static_lib = sub { + $called++; + return "\n\ncalled static_lib\n\nline2\nline3\n\nline4"; + }; + + my $args = bless({ IMPORTS => {}, }, 'MM'); + + # without IMPORTS as a populated hash, there will be no extra data + my $ret = ExtUtils::MM_OS2::static_lib( $args ); + is( $called, 1, 'static_lib() should call parent method' ); + like( $ret, qr/^called static_lib/m, + '... should return parent data unless IMPORTS exists' ); + + $args->{IMPORTS} = { foo => 1}; + $ret = ExtUtils::MM_OS2::static_lib( $args ); + is( $called, 2, '... should call parent method if extra imports passed' ); + like( $ret, qr/^called static_lib\n\t\$\(AR\) \$\(AR_STATIC_ARGS\)/m, + '... should append make tags to first line from parent method' ); + like( $ret, qr/\$@\n\n\nline2\nline3\n\nline4/m, + '... should include remaining data from parent method' ); + +} + +# replace_manpage_separator +my $sep = '//a///b//c/de'; +is( ExtUtils::MM_OS2->replace_manpage_separator($sep), '.a.b.c.de', + 'replace_manpage_separator() should turn multiple slashes into periods' ); + +# maybe_command +{ + local *DIR; + my ($dir, $noext, $exe, $cmd); + my $found = 0; + + my ($curdir, $updir) = (File::Spec->curdir, File::Spec->updir); + + # we need: + # 1) a directory + # 2) an executable file with no extension + # 3) an executable file with the .exe extension + # 4) an executable file with the .cmd extension + # we assume there will be one somewhere in the path + # in addition, we need them to be unique enough they do not trip + # an earlier file test in maybe_command(). Portability. + + foreach my $path (split(/:/, $ENV{PATH})) { + opendir(DIR, $path) or next; + while (defined(my $file = readdir(DIR))) { + next if $file eq $curdir or $file eq $updir; + $file = File::Spec->catfile($path, $file); + unless (defined $dir) { + if (-d $file) { + next if ( -x $file . '.exe' or -x $file . '.cmd' ); + + $dir = $file; + $found++; + } + } + if (-x $file) { + my $ext; + if ($file =~ s/\.(exe|cmd)\z//) { + $ext = $1; + + # skip executable files with names too similar + next if -x $file; + $file .= '.' . $ext; + + } else { + unless (defined $noext) { + $noext = $file; + $found++; + } + next; + } + + unless (defined $exe) { + if ($ext eq 'exe') { + $exe = $file; + $found++; + next; + } + } + unless (defined $cmd) { + if ($ext eq 'cmd') { + $cmd = $file; + $found++; + next; + } + } + } + last if $found == 4; + } + last if $found == 4; + } + + SKIP: { + skip('No appropriate directory found', 1) unless defined $dir; + is( ExtUtils::MM_OS2->maybe_command( $dir ), undef, + 'maybe_command() should ignore directories' ); + } + + SKIP: { + skip('No non-exension command found', 1) unless defined $noext; + is( ExtUtils::MM_OS2->maybe_command( $noext ), $noext, + 'maybe_command() should find executable lacking file extension' ); + } + + SKIP: { + skip('No .exe command found', 1) unless defined $exe; + (my $noexe = $exe) =~ s/\.exe\z//; + is( ExtUtils::MM_OS2->maybe_command( $noexe ), $exe, + 'maybe_command() should find .exe file lacking extension' ); + } + + SKIP: { + skip('No .cmd command found', 1) unless defined $cmd; + (my $nocmd = $cmd) =~ s/\.cmd\z//; + is( ExtUtils::MM_OS2->maybe_command( $nocmd ), $cmd, + 'maybe_command() should find .cmd file lacking extension' ); + } +} + +# file_name_is_absolute +ok( ExtUtils::MM_OS2->file_name_is_absolute( 's:/' ), + 'file_name_is_absolute() should be true for paths with volume and slash' ); +ok( ExtUtils::MM_OS2->file_name_is_absolute( '\foo' ), + '... and for paths with leading slash but no volume' ); +ok( ! ExtUtils::MM_OS2->file_name_is_absolute( 'arduk' ), + '... but not for paths with no leading slash or volume' ); + +# perl_archive +is( ExtUtils::MM_OS2->perl_archive(), '$(PERL_INC)/libperl$(LIB_EXT)', + 'perl_archive() should return a static string' ); + +# perl_archive_after +{ + my $aout = 0; + local *OS2::is_aout; + *OS2::is_aout = \$aout; + + isnt( ExtUtils::MM_OS2->perl_archive_after(), '', + 'perl_archive_after() should return string without $is_aout set' ); + $aout = 1; + is( ExtUtils::MM_OS2->perl_archive_after(), '', + '... and blank string if it is set' ); +} + +# export_list +is( ExtUtils::MM_OS2::export_list({ BASEEXT => 'foo' }), 'foo.def', + 'export_list() should add .def to BASEEXT member' ); + +END { + use File::Path; + rmtree('tmp_imp'); + unlink 'tmpimp.imp'; +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Unix.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Unix.t new file mode 100644 index 00000000000..1e47f1bc370 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Unix.t @@ -0,0 +1,252 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +BEGIN { + use Test::More; + + if( $^O =~ /^VMS|os2|MacOS|MSWin32|cygwin|beos|netware$/i ) { + plan skip_all => 'Non-Unix platform'; + } + else { + plan tests => 112; + } +} + +BEGIN { use_ok( 'ExtUtils::MM_Unix' ); } + +use vars qw($VERSION); +$VERSION = '0.02'; +use strict; +use File::Spec; + +my $class = 'ExtUtils::MM_Unix'; + +# only one of the following can be true +# test should be removed if MM_Unix ever stops handling other OS than Unix +my $os = ($ExtUtils::MM_Unix::Is_OS2 || 0) + + ($ExtUtils::MM_Unix::Is_Mac || 0) + + ($ExtUtils::MM_Unix::Is_Win32 || 0) + + ($ExtUtils::MM_Unix::Is_Dos || 0) + + ($ExtUtils::MM_Unix::Is_VMS || 0); +ok ( $os <= 1, 'There can be only one (or none)'); + +cmp_ok ($ExtUtils::MM_Unix::VERSION, '>=', '1.12606', 'Should be at least version 1.12606'); + +# when the following calls like canonpath, catdir etc are replaced by +# File::Spec calls, the test's become a bit pointless + +foreach ( qw( xx/ ./xx/ xx/././xx xx///xx) ) + { + is ($class->canonpath($_), File::Spec->canonpath($_), "canonpath $_"); + } + +is ($class->catdir('xx','xx'), File::Spec->catdir('xx','xx'), + 'catdir(xx, xx) => xx/xx'); +is ($class->catfile('xx','xx','yy'), File::Spec->catfile('xx','xx','yy'), + 'catfile(xx, xx) => xx/xx'); + +is ($class->file_name_is_absolute('Bombdadil'), + File::Spec->file_name_is_absolute('Bombdadil'), + 'file_name_is_absolute()'); + +is ($class->path(), File::Spec->path(), 'path() same as File::Spec->path()'); + +foreach (qw/updir curdir rootdir/) + { + is ($class->$_(), File::Spec->$_(), $_ ); + } + +foreach ( qw / + c_o + clean + const_cccmd + const_config + const_loadlibs + constants + depend + dir_target + dist + dist_basics + dist_ci + dist_core + dist_dir + dist_test + dlsyms + dynamic + dynamic_bs + dynamic_lib + exescan + export_list + extliblist + find_perl + fixin + force + guess_name + init_dirscan + init_main + init_others + install + installbin + linkext + lsdir + macro + makeaperl + makefile + manifypods + maybe_command_in_dirs + needs_linking + pasthru + perldepend + pm_to_blib + ppd + prefixify + processPL + quote_paren + realclean + static + static_lib + staticmake + subdir_x + subdirs + test + test_via_harness + test_via_script + tool_autosplit + tool_xsubpp + tools_other + top_targets + writedoc + xs_c + xs_cpp + xs_o + xsubpp_version + / ) + { + can_ok($class, $_); + } + +############################################################################### +# some more detailed tests for the methods above + +ok ( join (' ', $class->dist_basics()), 'distclean :: realclean distcheck'); + +############################################################################### +# has_link_code tests + +my $t = bless { NAME => "Foo" }, $class; +$t->{HAS_LINK_CODE} = 1; +is ($t->has_link_code(),1,'has_link_code'); is ($t->{HAS_LINK_CODE},1); + +$t->{HAS_LINK_CODE} = 0; +is ($t->has_link_code(),0); is ($t->{HAS_LINK_CODE},0); + +delete $t->{HAS_LINK_CODE}; delete $t->{OBJECT}; +is ($t->has_link_code(),0); is ($t->{HAS_LINK_CODE},0); + +delete $t->{HAS_LINK_CODE}; $t->{OBJECT} = 1; +is ($t->has_link_code(),1); is ($t->{HAS_LINK_CODE},1); + +delete $t->{HAS_LINK_CODE}; delete $t->{OBJECT}; $t->{MYEXTLIB} = 1; +is ($t->has_link_code(),1); is ($t->{HAS_LINK_CODE},1); + +delete $t->{HAS_LINK_CODE}; delete $t->{MYEXTLIB}; $t->{C} = [ 'Gloin' ]; +is ($t->has_link_code(),1); is ($t->{HAS_LINK_CODE},1); + +############################################################################### +# libscan + +is ($t->libscan('RCS'),'','libscan on RCS'); +is ($t->libscan('CVS'),'','libscan on CVS'); +is ($t->libscan('SCCS'),'','libscan on SCCS'); +is ($t->libscan('Fatty'),'Fatty','libscan on something not RCS, CVS or SCCS'); + +############################################################################### +# maybe_command + +is ($t->maybe_command('blargel'),undef,"'blargel' isn't a command"); + +############################################################################### +# nicetext (dummy method) + +is ($t->nicetext('LOTR'),'LOTR','nicetext'); + +############################################################################### +# parse_version + +my $self_name = $ENV{PERL_CORE} ? '../lib/ExtUtils/t/MM_Unix.t' + : 'MM_Unix.t'; + +is( $t->parse_version($self_name), '0.02', 'parse_version on ourself'); + +my %versions = ( + '$VERSION = 0.0' => 0.0, + '$VERSION = -1.0' => -1.0, + '$VERSION = undef' => 'undef', + '$wibble = 1.0' => 'undef', + ); + +while( my($code, $expect) = each %versions ) { + open(FILE, ">VERSION.tmp") || die $!; + print FILE "$code\n"; + close FILE; + + is( $t->parse_version('VERSION.tmp'), $expect, $code ); + + unlink "VERSION.tmp"; +} + + +############################################################################### +# perl_script (on unix any ordinary, readable file) + +is ($t->perl_script($self_name),$self_name, 'we pass as a perl_script()'); + +############################################################################### +# perm_rw perm_rwx + +is ($t->perm_rw(),'644', 'perm_rw() is 644'); +is ($t->perm_rwx(),'755', 'perm_rwx() is 755'); + +############################################################################### +# post_constants, postamble, post_initialize + +foreach (qw/ post_constants postamble post_initialize/) + { + is ($t->$_(),'', "$_() is an empty string"); + } + +############################################################################### +# replace_manpage_separator + +is ($t->replace_manpage_separator('Foo/Bar'),'Foo::Bar','manpage_separator'); + +############################################################################### +# export_list, perl_archive, perl_archive_after + +foreach (qw/ export_list perl_archive perl_archive_after/) + { + is ($t->$_(),'',"$_() is empty string on Unix"); + } + + +{ + $t->{CCFLAGS} = '-DMY_THING'; + $t->{LIBPERL_A} = 'libperl.a'; + $t->{LIB_EXT} = '.a'; + local $t->{NEEDS_LINKING} = 1; + $t->cflags(); + + # Brief bug where CCFLAGS was being blown away + is( $t->{CCFLAGS}, '-DMY_THING', 'cflags retains CCFLAGS' ); +} + diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_VMS.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_VMS.t new file mode 100644 index 00000000000..303a599798d --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_VMS.t @@ -0,0 +1,79 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +BEGIN { + @Methods = (qw(wraplist + rootdir + ext + guess_name + find_perl + path + maybe_command + maybe_command_in_dirs + perl_script + file_name_is_absolute + replace_manpage_separator + init_others + constants + cflags + const_cccmd + pm_to_blib + tool_autosplit + tool_xsubpp + xsubpp_version + tools_other + dist + c_o + xs_c + xs_o + top_targets + dlsyms + dynamic_lib + dynamic_bs + static_lib + manifypods + processPL + installbin + subdir_x + clean + realclean + dist_basics + dist_core + dist_dir + dist_test + install + perldepend + makefile + test + test_via_harness + test_via_script + makeaperl + nicetext + )); +} + +BEGIN { + use Test::More; + if ($^O eq 'VMS') { + plan( tests => @Methods + 1 ); + } + else { + plan( skip_all => "This is not VMS" ); + } +} + +use_ok( 'ExtUtils::MM_VMS' ); + +foreach my $meth (@Methods) { + can_ok( 'ExtUtils::MM_VMS', $meth); +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Win32.t b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Win32.t new file mode 100644 index 00000000000..8e2b52c03c4 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/MM_Win32.t @@ -0,0 +1,324 @@ +#!/usr/bin/perl + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use strict; +use Test::More; + +BEGIN { + if ($^O =~ /MSWin32/i) { + plan tests => 40; + } else { + plan skip_all => 'This is not Win32'; + } +} + +use Config; +use File::Spec; +use File::Basename; +use ExtUtils::MM; + +require_ok( 'ExtUtils::MM_Win32' ); + +# Dummy MM object until we have a real MM init method. +my $MM = bless { + DIR => [], + NOECHO => '@', + XS => {}, + MAKEFILE => 'Makefile', + RM_RF => 'rm -rf', + MV => 'mv', + }, 'MM'; + + +# replace_manpage_separator() => tr|/|.|s ? +{ + my $man = 'a/path/to//something'; + ( my $replaced = $man ) =~ tr|/|.|s; + is( $MM->replace_manpage_separator( $man ), + $replaced, 'replace_manpage_separator()' ); +} + +# maybe_command() +SKIP: { + skip( '$ENV{COMSPEC} not set', 2 ) + unless $ENV{COMSPEC} =~ m!((?:[a-z]:)?[^|<>]+)!i; + my $comspec = $1; + is( $MM->maybe_command( $comspec ), + $comspec, 'COMSPEC is a maybe_command()' ); + ( my $comspec2 = $comspec ) =~ s|\..{3}$||; + like( $MM->maybe_command( $comspec2 ), + qr/\Q$comspec/i, + 'maybe_command() without extension' ); +} + +my $had_pathext = exists $ENV{PATHEXT}; +{ + local $ENV{PATHEXT} = '.exe'; + ok( ! $MM->maybe_command( 'not_a_command.com' ), + 'not a maybe_command()' ); +} +# Bug in Perl. local $ENV{FOO} won't delete the key afterward. +delete $ENV{PATHEXT} unless $had_pathext; + +# file_name_is_absolute() [Does not support UNC-paths] +{ + ok( $MM->file_name_is_absolute( 'C:/' ), + 'file_name_is_absolute()' ); + ok( ! $MM->file_name_is_absolute( 'some/path/' ), + 'not file_name_is_absolute()' ); + +} + +# find_perl() +# Should be able to find running perl... $^X is OK on Win32 +{ + my $my_perl = $1 if $^X =~ /(.*)/; # are we in -T or -t? + my( $perl, $path ) = fileparse( $my_perl ); + like( $MM->find_perl( $], [ $perl ], [ $path ] ), + qr/^\Q$my_perl\E$/i, 'find_perl() finds this perl' ); +} + +# catdir() (calls MM_Win32->canonpath) +{ + my @path_eg = qw( c: trick dir/now_OK ); + + is( $MM->catdir( @path_eg ), + 'C:\\trick\\dir\\now_OK', 'catdir()' ); + is( $MM->catdir( @path_eg ), + File::Spec->catdir( @path_eg ), + 'catdir() eq File::Spec->catdir()' ); + +# catfile() (calls MM_Win32->catdir) + push @path_eg, 'file.ext'; + + is( $MM->catfile( @path_eg ), + 'C:\\trick\\dir\\now_OK\\file.ext', 'catfile()' ); + + is( $MM->catfile( @path_eg ), + File::Spec->catfile( @path_eg ), + 'catfile() eq File::Spec->catfile()' ); +} + +# init_others(): check if all keys are created and set? +# qw( TOUCH CHMOD CP RM_F RM_RF MV NOOP TEST_F LD AR LDLOADLIBS DEV_NUL ) +{ + my $mm_w32 = bless( {}, 'MM' ); + $mm_w32->init_others(); + my @keys = qw( TOUCH CHMOD CP RM_F RM_RF MV NOOP + TEST_F LD AR LDLOADLIBS DEV_NULL ); + for my $key ( @keys ) { + ok( $mm_w32->{ $key }, "init_others: $key" ); + } +} + +# constants() +{ + my $mm_w32 = bless { + NAME => 'TestMM_Win32', + VERSION => '1.00', + VERSION_FROM => 'TestMM_Win32', + PM => { 'MM_Win32.pm' => 1 }, + }, 'MM'; + + # XXX Hack until we have a proper init method. + # Flesh out some necessary keys in the MM object. + foreach my $key (qw(XS C O_FILES H HTMLLIBPODS HTMLSCRIPTPODS + MAN1PODS MAN3PODS PARENT_NAME)) { + $mm_w32->{$key} = ''; + } + my $s_PM = join( " \\\n\t", sort keys %{$mm_w32->{PM}} ); + my $k_PM = join( " \\\n\t", %{$mm_w32->{PM}} ); + + like( $mm_w32->constants(), + qr|^NAME\ =\ TestMM_Win32\s+VERSION\ =\ 1\.00.+ + MAKEMAKER\ =\ \Q$INC{'ExtUtils/MakeMaker.pm'}\E\s+ + MM_VERSION\ =\ \Q$ExtUtils::MakeMaker::VERSION\E.+ + VERSION_FROM\ =\ TestMM_Win32.+ + TO_INST_PM\ =\ \Q$s_PM\E\s+ + PM_TO_BLIB\ =\ \Q$k_PM\E + |xs, 'constants()' ); + +} + +# path() +my $had_path = exists $ENV{PATH}; +{ + my @path_eg = ( qw( . .. ), 'C:\\Program Files' ); + local $ENV{PATH} = join ';', @path_eg; + ok( eq_array( [ $MM->path() ], [ @path_eg ] ), + 'path() [preset]' ); +} +# Bug in Perl. local $ENV{FOO} will not delete key afterwards. +delete $ENV{PATH} unless $had_path; + +# static_lib() should look into that +# dynamic_bs() should look into that +# dynamic_lib() should look into that + +# clean() +{ + my $clean = $Config{cc} =~ /^gcc/i ? 'dll.base dll.exp' : '*.pdb'; + like( $MM->clean(), qr/^clean ::\s+\Q-$(RM_F) $clean\E\s+$/m, + 'clean() Makefile target' ); +} + +# perl_archive() +{ + my $libperl = $Config{libperl} || 'libperl.a'; + is( $MM->perl_archive(), File::Spec->catfile('$(PERL_INC)', $libperl ), + 'perl_archive() should respect libperl setting' ); +} + +# export_list +{ + my $mm_w32 = bless { BASEEXT => 'someext' }, 'MM'; + is( $mm_w32->export_list(), 'someext.def', 'export_list()' ); +} + +# canonpath() +{ + my $path = 'c:\\Program Files/SomeApp\\Progje.exe'; + is( $MM->canonpath( $path ), File::Spec->canonpath( $path ), + 'canonpath() eq File::Spec->canonpath' ); +} + +# perl_script() +my $script_ext = ''; +my $script_name = 'mm_w32tmp'; +SKIP: { + local *SCRIPT; + skip( "Can't create temp file: $!", 4 ) + unless open SCRIPT, "> $script_name"; + print SCRIPT <<'EOSCRIPT'; +#! perl +__END__ +EOSCRIPT + skip( "Can't write to temp file: $!", 4 ) + unless close SCRIPT; + # now start tests: + is( $MM->perl_script( $script_name ), + "${script_name}$script_ext", "perl_script ($script_ext)" ); + + skip( "Can't rename temp file: $!", 3 ) + unless rename $script_name, "${script_name}.pl"; + $script_ext = '.pl'; + is( $MM->perl_script( $script_name ), + "${script_name}$script_ext", "perl_script ($script_ext)" ); + + skip( "Can't rename temp file: $!", 2 ) + unless rename "${script_name}$script_ext", "${script_name}.bat"; + $script_ext = '.bat'; + is( $MM->perl_script( $script_name ), + "${script_name}$script_ext", "perl_script ($script_ext)" ); + + skip( "Can't rename temp file: $!", 1 ) + unless rename "${script_name}$script_ext", "${script_name}.noscript"; + $script_ext = '.noscript'; + + isnt( $MM->perl_script( $script_name ), + "${script_name}$script_ext", + "not a perl_script anymore ($script_ext)" ); + is( $MM->perl_script( $script_name ), undef, + "perl_script ($script_ext) returns empty" ); +} +unlink "${script_name}$script_ext" if -f "${script_name}$script_ext"; + + +# pm_to_blib() +{ + like( $MM->pm_to_blib(), + qr/^pm_to_blib: \Q$(TO_INST_PM)\E.+\Q$(TOUCH) \E\$@\s+$/ms, + 'pm_to_blib' ); +} + +# tool_autosplit() +{ + my %attribs = ( MAXLEN => 255 ); + like( $MM->tool_autosplit( %attribs ), + qr/^\#\ Usage:\ \$\(AUTOSPLITFILE\) + \ FileToSplit\ AutoDirToSplitInto.+ + AUTOSPLITFILE\ =\ \$\(PERLRUN\)\ .+ + \$AutoSplit::Maxlen=$attribs{MAXLEN}; + /xms, + '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 + +# manifypods() +{ + my $mm_w32 = bless { NOECHO => '' }, 'MM'; + like( $mm_w32->manifypods(), + qr/^\nmanifypods :\n\t\$\Q(NOOP)\E\n$/, + 'manifypods() Makefile target' ); +} + +# dist_ci() should look into that +# dist_core() should look into that + +# pasthru() +{ + my $pastru = "PASTHRU = " . ($Config{make} =~ /^nmake/i ? "-nologo" : ""); + is( $MM->pasthru(), $pastru, 'pasthru()' ); +} + +package FakeOut; + +sub TIEHANDLE { + bless(\(my $scalar), $_[0]); +} + +sub PRINT { + my $self = shift; + $$self .= shift; +} + +__END__ + +=head1 NAME + +MM_Win32.t - Tests for ExtUtils::MM_Win32 + +=head1 TODO + + - Methods to still be checked: + # static_lib() should look into that + # dynamic_bs() should look into that + # dynamic_lib() should look into that + # xs_o() should look into that + # top_targets() should look into that + # dist_ci() should look into that + # dist_core() should look into that + +=head1 AUTHOR + +20011228 Abe Timmerman <abe@ztreet.demon.nl> + +=cut diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Manifest.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Manifest.t new file mode 100644 index 00000000000..7a488be0937 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Manifest.t @@ -0,0 +1,193 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + unshift @INC, '../lib'; + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + +use strict; + +# these files help the test run +use Test::More tests => 33; +use Cwd; + +# these files are needed for the module itself +use File::Spec; +use File::Path; + +# We're going to be chdir'ing and modules are sometimes loaded on the +# fly in this test, so we need an absolute @INC. +@INC = map { File::Spec->rel2abs($_) } @INC; + +# keep track of everything added so it can all be deleted +my %files; +sub add_file { + my ($file, $data) = @_; + $data ||= 'foo'; + unlink $file; # or else we'll get multiple versions on VMS + open( T, '>'.$file) or return; + print T $data; + ++$files{$file}; + close T; +} + +sub read_manifest { + open( M, 'MANIFEST' ) or return; + chomp( my @files = <M> ); + close M; + return @files; +} + +sub catch_warning { + my $warn; + local $SIG{__WARN__} = sub { $warn .= $_[0] }; + return join('', $_[0]->() ), $warn; +} + +sub remove_dir { + ok( rmdir( $_ ), "remove $_ directory" ) for @_; +} + +# use module, import functions +BEGIN { + use_ok( 'ExtUtils::Manifest', + qw( mkmanifest manicheck filecheck fullcheck + maniread manicopy skipcheck ) ); +} + +my $cwd = Cwd::getcwd(); + +# Just in case any old files were lying around. +rmtree('mantest'); + +ok( mkdir( 'mantest', 0777 ), 'make mantest directory' ); +ok( chdir( 'mantest' ), 'chdir() to mantest' ); +ok( add_file('foo'), 'add a temporary file' ); + +# there shouldn't be a MANIFEST there +my ($res, $warn) = catch_warning( \&mkmanifest ); +# Canonize the order. +$warn = join("", map { "$_|" } + sort { lc($a) cmp lc($b) } split /\r?\n/, $warn); +is( $warn, "Added to MANIFEST: foo|Added to MANIFEST: MANIFEST|", + "mkmanifest() displayed its additions" ); + +# and now you see it +ok( -e 'MANIFEST', 'create MANIFEST file' ); + +my @list = read_manifest(); +is( @list, 2, 'check files in MANIFEST' ); +ok( ! ExtUtils::Manifest::filecheck(), 'no additional files in directory' ); + +# after adding bar, the MANIFEST is out of date +ok( add_file( 'bar' ), 'add another file' ); +ok( ! manicheck(), 'MANIFEST now out of sync' ); + +# it reports that bar has been added and throws a warning +($res, $warn) = catch_warning( \&filecheck ); + +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 ) + }; +cmp_ok( $warn, 'eq', '', 'disabled warnings' ); + +# add a skip file with a rule to skip itself (and the nonexistent glob '*baz*') +add_file( 'MANIFEST.SKIP', "baz\n.SKIP" ); + +# this'll skip the new file +($res, $warn) = catch_warning( \&skipcheck ); +like( $warn, qr/^Skipping MANIFEST\.SKIP/i, 'got skipping warning' ); + +my @skipped; +catch_warning( sub { + @skipped = skipcheck() +}); + +is( join( ' ', @skipped ), 'MANIFEST.SKIP', 'listed skipped files' ); + +{ + local $ExtUtils::Manifest::Quiet = 1; + is( join(' ', filecheck() ), 'bar', 'listing skipped with filecheck()' ); +} + +# add a subdirectory and a file there that should be found +ok( mkdir( 'moretest', 0777 ), 'created moretest directory' ); +add_file( File::Spec->catfile('moretest', 'quux'), 'quux' ); +ok( exists( ExtUtils::Manifest::manifind()->{'moretest/quux'} ), + "manifind found moretest/quux" ); + +# only MANIFEST and foo are in the manifest +my $files = maniread(); +is( keys %$files, 2, 'two files found' ); +is( join(' ', sort { lc($a) cmp lc($b) } keys %$files), 'foo MANIFEST', + 'both files found' ); + +# poison the manifest, and add a comment that should be reported +add_file( 'MANIFEST', 'none #none' ); +is( ExtUtils::Manifest::maniread()->{none}, '#none', + 'maniread found comment' ); + +ok( mkdir( 'copy', 0777 ), 'made copy directory' ); + +$files = maniread(); +eval { (undef, $warn) = catch_warning( sub { + manicopy( $files, 'copy', 'cp' ) }) +}; +like( $@, qr/^Can't read none: /, 'croaked about none' ); + +# a newline comes through, so get rid of it +chomp($warn); + +# the copy should have given one warning and one error +like($warn, qr/^Skipping MANIFEST.SKIP/i, 'warned about MANIFEST.SKIP' ); + +# tell ExtUtils::Manifest to use a different file +{ + 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'}++; +} + + +# Make sure MANIFEST.SKIP is using complete relative paths +add_file( 'MANIFEST.SKIP' => "^moretest/q\n" ); + +# This'll skip moretest/quux +($res, $warn) = catch_warning( \&skipcheck ); +like( $warn, qr{^Skipping moretest/quux$}i, 'got skipping warning again' ); + + +# There was a bug where entries in MANIFEST would be blotted out +# by MANIFEST.SKIP rules. +add_file( 'MANIFEST.SKIP' => 'foo' ); +add_file( 'MANIFEST' => 'foobar' ); +add_file( 'foobar' => '123' ); +($res, $warn) = catch_warning( \&manicheck ); +is( $res, '', 'MANIFEST overrides MANIFEST.SKIP' ); +is( $warn, undef, 'MANIFEST overrides MANIFEST.SKIP, no warnings' ); + + +END { + # the args are evaluated in scalar context + is( unlink( keys %files ), keys %files, 'remove all added files' ); + remove_dir( 'moretest', 'copy' ); + + # now get rid of the parent directory + ok( chdir( $cwd ), 'return to parent directory' ); + unlink('mantest/MANIFEST'); + remove_dir( 'mantest' ); +} + diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Mkbootstrap.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Mkbootstrap.t new file mode 100644 index 00000000000..fe07ddfca5e --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Mkbootstrap.t @@ -0,0 +1,155 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't'; + @INC = ('../lib', 'lib/'); + } + else { + unshift @INC, 't/lib/'; + } +} +chdir 't'; + +use vars qw( $required ); +use Test::More tests => 18; + +BEGIN { use_ok( 'ExtUtils::Mkbootstrap' ) } + +# Mkbootstrap makes a backup copy of "$_[0].bs" if it exists and is non-zero +my $file_is_ready; +local *OUT; +if (open(OUT, '>mkboot.bs')) { + $file_is_ready = 1; + print OUT 'meaningless text'; + close OUT; +} + +SKIP: { + skip("could not make dummy .bs file: $!", 2) unless $file_is_ready; + + Mkbootstrap('mkboot'); + ok( -s 'mkboot.bso', 'Mkbootstrap should backup the .bs file' ); + local *IN; + if (open(IN, 'mkboot.bso')) { + chomp ($file_is_ready = <IN>); + close IN; + } + + is( $file_is_ready, 'meaningless text', 'backup should be a perfect copy' ); +} + + +# if it doesn't exist or is zero bytes in size, it won't be backed up +Mkbootstrap('fakeboot'); +ok( !( -f 'fakeboot.bso' ), 'Mkbootstrap should not backup an empty file' ); + +use TieOut; +my $out = tie *STDOUT, 'TieOut'; + +# with $Verbose set, it should print status messages about libraries +$ExtUtils::Mkbootstrap::Verbose = 1; +Mkbootstrap(''); +is( $out->read, "\tbsloadlibs=\n", 'should report libraries in Verbose mode' ); + +Mkbootstrap('', 'foo'); +like( $out->read, qr/bsloadlibs=foo/, 'should still report libraries' ); + + +# if ${_[0]}_BS exists, require it +$file_is_ready = open(OUT, '>boot_BS'); + +SKIP: { + skip("cannot open boot_BS for writing: $!", 1) unless $file_is_ready; + + print OUT '$main::required = 1'; + close OUT; + Mkbootstrap('boot'); + + ok( $required, 'baseext_BS file should be require()d' ); +} + + +# if there are any arguments, open a file named baseext.bs +$file_is_ready = open(OUT, '>dasboot.bs'); + +SKIP: { + skip("cannot make dasboot.bs: $!", 5) unless $file_is_ready; + + # if it can't be opened for writing, we want to prove that it'll die + close OUT; + chmod 0444, 'dasboot.bs'; + + SKIP: { + skip("cannot write readonly files", 1) if -w 'dasboot.bs'; + + eval{ Mkbootstrap('dasboot', 1) }; + like( $@, qr/Unable to open dasboot\.bs/, 'should die given bad filename' ); + } + + # now put it back like it was + chmod 0777, 'dasboot.bs'; + eval{ Mkbootstrap('dasboot', 'myarg') }; + is( $@, '', 'should not die, given good filename' ); + + # red and reed (a visual pun makes tests worth reading) + my $read = $out->read(); + like( $read, qr/Writing dasboot.bs/, 'should print status' ); + like( $read, qr/containing: my/, 'should print verbose status on request' ); + + # now be tricky, and set the status for the next skip block + $file_is_ready = open(IN, 'dasboot.bs'); + ok( $file_is_ready, 'should have written a new .bs file' ); +} + + +SKIP: { + skip("cannot read .bs file: $!", 2) unless $file_is_ready; + + my $file = do { local $/ = <IN> }; + + # filename should be in header + like( $file, qr/# dasboot DynaLoader/, 'file should have boilerplate' ); + + # should print arguments within this array + like( $file, qr/qw\(myarg\);/, 'should have written array to file' ); +} + + +# overwrite this file (may whack portability, but the name's too good to waste) +$file_is_ready = open(OUT, '>dasboot.bs'); + +SKIP: { + skip("cannot make dasboot.bs again: $!", 1) unless $file_is_ready; + close OUT; + + # if $DynaLoader::bscode is set, write its contents to the file + local $DynaLoader::bscode; + $DynaLoader::bscode = 'Wall'; + $ExtUtils::Mkbootstrap::Verbose = 0; + + # if arguments contain '-l' or '-L' or '-R' print dl_findfile message + eval{ Mkbootstrap('dasboot', '-Larry') }; + is( $@, '', 'should be able to open a file again'); + + $file_is_ready = open(IN, 'dasboot.bs'); +} + +SKIP: { + skip("cannot open dasboot.bs for reading: $!", 3) unless $file_is_ready; + + my $file = do { local $/ = <IN> }; + is( $out->read, "Writing dasboot.bs\n", 'should hush without Verbose set' ); + + # and find our hidden tribute to a fine example + like( $file, qr/dl_findfile.+Larry/s, 'should load libraries if needed' ); + like( $file, qr/Wall\n1;\n/ms, 'should write $DynaLoader::bscode if set' ); +} + +close IN; +close OUT; + +END { + # clean things up, even on VMS + 1 while unlink(qw( mkboot.bso boot_BS dasboot.bs .bs )); +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/Packlist.t b/gnu/usr.bin/perl/lib/ExtUtils/t/Packlist.t new file mode 100644 index 00000000000..58eaf8f6795 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/Packlist.t @@ -0,0 +1,174 @@ +#!/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 => 34; + +use_ok( 'ExtUtils::Packlist' ); + +is( ref(ExtUtils::Packlist::mkfh()), 'GLOB', 'mkfh() should return a FH' ); + +# new calls tie() +my $pl = ExtUtils::Packlist->new(); +isa_ok( $pl, 'ExtUtils::Packlist' ); +is( ref tied %$pl, 'ExtUtils::Packlist', 'obj should be tied underneath' ); + + +$pl = ExtUtils::Packlist::TIEHASH( 'tieclass', 'packfile' ); +is( ref($pl), 'tieclass', 'TIEHASH() should bless into class' ); +is( $pl->{packfile}, 'packfile', 'TIEHASH() should store packfile name' ); + + +ExtUtils::Packlist::STORE($pl, 'key', 'value'); +is( $pl->{data}{key}, 'value', 'STORE() should stuff stuff in data member' ); + + +$pl->{data}{foo} = 'bar'; +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) + unless keys %{ $pl->{data} } > 2; + + # get the first and second key + my ($first, $second) = keys %{ $pl->{data} }; + + # now get a couple of extra keys, to mess with the hash iterator + my $i = 0; + for (keys %{ $pl->{data} } ) { + last if $i++; + } + + # finally, see if it really can get the first key again + is( ExtUtils::Packlist::FIRSTKEY($pl), $first, + 'FIRSTKEY() should be consistent' ); + + is( ExtUtils::Packlist::NEXTKEY($pl), $second, + 'and NEXTKEY() should also be consistent' ); +} + + +ok( ExtUtils::Packlist::EXISTS($pl, 'bar'), 'EXISTS() should find keys' ); + + +ExtUtils::Packlist::DELETE($pl, 'bar'); +ok( !(exists $pl->{data}{bar}), 'DELETE() should delete cleanly' ); + + +ExtUtils::Packlist::CLEAR($pl); +is( keys %{ $pl->{data} }, 0, 'CLEAR() should wipe out data' ); + + +# DESTROY does nothing... +can_ok( 'ExtUtils::Packlist', 'DESTROY' ); + + +# write is a little more complicated +eval { ExtUtils::Packlist::write({}) }; +like( $@, qr/No packlist filename/, 'write() should croak without packfile' ); + +eval { ExtUtils::Packlist::write({}, 'eplist') }; +my $file_is_ready = $@ ? 0 : 1; +ok( $file_is_ready, 'write() can write a file' ); + +local *IN; + +SKIP: { + skip('cannot write files, some tests difficult', 3) unless $file_is_ready; + + # set this file to read-only + chmod 0444, 'eplist'; + + SKIP: { + skip("cannot write readonly files", 1) if -w 'eplist'; + + eval { ExtUtils::Packlist::write({}, 'eplist') }; + like( $@, qr/Can't open file/, 'write() should croak on open failure' ); + } + + #'now set it back (tick here fixes vim syntax highlighting ;) + chmod 0777, 'eplist'; + + # and some test data to be read + $pl->{data} = { + single => 1, + hash => { + foo => 'bar', + baz => 'bup', + }, + '/./abc' => '', + }; + eval { ExtUtils::Packlist::write($pl, 'eplist') }; + is( $@, '', 'write() should normally succeed' ); + is( $pl->{packfile}, 'eplist', 'write() should set packfile name' ); + + $file_is_ready = open(IN, 'eplist'); +} + + +eval { ExtUtils::Packlist::read({}) }; +like( $@, qr/^No packlist filename/, 'read() should croak without packfile' ); + + +eval { ExtUtils::Packlist::read({}, 'abadfilename') }; +like( $@, qr/^Can't open file/, 'read() should croak with bad packfile name' ); +#'open packfile for reading + + +# and more read() tests +SKIP: { + skip("cannot open file for reading: $!", 5) unless $file_is_ready; + my $file = do { local $/ = <IN> }; + + like( $file, qr/single\n/, 'key with value should be available' ); + like( $file, qr!/\./abc\n!, 'key with no value should also be present' ); + like( $file, qr/hash.+baz=bup/, 'key with hash value should be present' ); + like( $file, qr/hash.+foo=bar/, 'second embedded hash value should appear'); + close IN; + + eval{ ExtUtils::Packlist::read($pl, 'eplist') }; + is( $@, '', 'read() should normally succeed' ); + is( $pl->{data}{single}, undef, 'single keys should have undef value' ); + is( ref($pl->{data}{hash}), 'HASH', 'multivalue keys should become hashes'); + + is( $pl->{data}{hash}{foo}, 'bar', 'hash values should be set' ); + ok( exists $pl->{data}{'/abc'}, 'read() should resolve /./ to / in keys' ); + + # give validate a valid and an invalid file to find + $pl->{data} = { + eplist => 1, + fake => undef, + }; + + is( ExtUtils::Packlist::validate($pl), 1, + 'validate() should find missing files' ); + ExtUtils::Packlist::validate($pl, 1); + 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'); +} + + +# packlist_file, $pl should be set from write test +is( ExtUtils::Packlist::packlist_file({ packfile => 'pl' }), 'pl', + 'packlist_file() should fetch packlist from passed hash' ); +is( ExtUtils::Packlist::packlist_file($pl), 'eplist', + 'packlist_file() should fetch packlist from ExtUtils::Packlist object' ); + +END { + 1 while unlink qw( eplist ); +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/VERSION_FROM.t b/gnu/usr.bin/perl/lib/ExtUtils/t/VERSION_FROM.t new file mode 100644 index 00000000000..332b7231623 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/VERSION_FROM.t @@ -0,0 +1,39 @@ +#!/usr/bin/perl -w + +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 => 1; +use MakeMaker::Test::Utils; +use ExtUtils::MakeMaker; +use TieOut; +use File::Path; + +perl_lib(); + +mkdir('Odd-Version', 0777); +END { chdir File::Spec->updir; rmtree 'Odd-Version' } +chdir 'Odd-Version'; + +open(MPL, ">Version") || die $!; +print MPL "\$VERSION = 0\n"; +close MPL; +END { unlink 'Version' } + +my $stdout = tie *STDOUT, 'TieOut' or die; +my $mm = WriteMakefile( + NAME => 'Version', + VERSION_FROM => 'Version' +); + +is( $mm->{VERSION}, 0, 'VERSION_FROM when $VERSION = 0' ); diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/backwards.t b/gnu/usr.bin/perl/lib/ExtUtils/t/backwards.t new file mode 100644 index 00000000000..95b1e160e7e --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/backwards.t @@ -0,0 +1,25 @@ +#!/usr/bin/perl -w + +# This is a test for all the odd little backwards compatible things +# MakeMaker has to support. And we do mean backwards. + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} + +use strict; +use Test::More tests => 2; + +require ExtUtils::MakeMaker; + +# CPAN.pm wants MM. +can_ok('MM', 'new'); + +# Pre 5.8 ExtUtils::Embed wants MY. +can_ok('MY', 'catdir'); diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/basic.t b/gnu/usr.bin/perl/lib/ExtUtils/t/basic.t new file mode 100644 index 00000000000..9080434333c --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/basic.t @@ -0,0 +1,131 @@ +#!/usr/bin/perl -w + +# This test puts MakeMaker through the paces of a basic perl module +# build, test and installation of the Big::Fat::Dummy module. + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} + +use strict; +use Test::More tests => 17; +use MakeMaker::Test::Utils; +use File::Spec; +use TieOut; + +my $perl = which_perl(); + +my $root_dir = 't'; + +if( $^O eq 'VMS' ) { + # On older systems we might exceed the 8-level directory depth limit + # imposed by RMS. We get around this with a rooted logical, but we + # can't create logical names with attributes in Perl, so we do it + # in a DCL subprocess and put it in the job table so the parent sees it. + open( BFDTMP, '>bfdtesttmp.com' ) || die "Error creating command file; $!"; + print BFDTMP <<'COMMAND'; +$ IF F$TRNLNM("PERL_CORE") .EQS. "" .AND. F$TYPE(PERL_CORE) .EQS. "" +$ THEN +$! building CPAN version +$ BFD_TEST_ROOT = F$PARSE("SYS$DISK:[]",,,,"NO_CONCEAL")-".][000000"-"]["-"].;"+".]" +$ ELSE +$! we're in the core +$ BFD_TEST_ROOT = F$PARSE("SYS$DISK:[-]",,,,"NO_CONCEAL")-".][000000"-"]["-"].;"+".]" +$ ENDIF +$ DEFINE/JOB/NOLOG/TRANSLATION=CONCEALED BFD_TEST_ROOT 'BFD_TEST_ROOT' +COMMAND + close BFDTMP; + + system '@bfdtesttmp.com'; + END { 1 while unlink 'bfdtesttmp.com' } + $root_dir = 'BFD_TEST_ROOT:[t]'; +} + +chdir $root_dir; + + +perl_lib; + +my $Touch_Time = calibrate_mtime(); + +$| = 1; + +ok( chdir 'Big-Dummy', "chdir'd to Big-Dummy" ) || + diag("chdir failed: $!"); + +my @mpl_out = `$perl Makefile.PL PREFIX=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'); + +ok( grep(/^Current package is: main$/, + @mpl_out) == 1, + 'Makefile.PL run in package main'); + +ok( -e $makefile, 'Makefile exists' ); + +# -M is flakey on VMS +my $mtime = (stat($makefile))[9]; +cmp_ok( $Touch_Time, '<=', $mtime, ' its been touched' ); + +END { unlink makefile_name(), makefile_backup() } + +my $make = make_run(); + +{ + # Supress 'make manifest' noise + local $ENV{PERL_MM_MANIFEST_VERBOSE} = 0; + my $manifest_out = `$make manifest`; + ok( -e 'MANIFEST', 'make manifest created a MANIFEST' ); + ok( -s 'MANIFEST', ' its not empty' ); +} + +END { unlink 'MANIFEST'; } + +my $test_out = `$make test`; +like( $test_out, qr/All tests successful/, 'make test' ); +is( $?, 0 ); + +# Test 'make test TEST_VERBOSE=1' +my $make_test_verbose = make_macro($make, 'test', TEST_VERBOSE => 1); +$test_out = `$make_test_verbose`; +like( $test_out, qr/ok \d+ - TEST_VERBOSE/, 'TEST_VERBOSE' ); +like( $test_out, qr/All tests successful/, ' successful' ); +is( $?, 0 ); + +my $dist_test_out = `$make disttest`; +is( $?, 0, 'disttest' ) || diag($dist_test_out); + + +# Make sure init_dirscan doesn't go into the distdir +@mpl_out = `$perl Makefile.PL "PREFIX=dummy-install"`; + +cmp_ok( $?, '==', 0, 'Makefile.PL exited with zero' ) || + diag(@mpl_out); + +ok( grep(/^Writing $makefile for Big::Dummy/, + @mpl_out) == 1, + 'init_dirscan skipped distdir') || + diag(@mpl_out); + +# I know we'll get ignored errors from make here, that's ok. +# Send STDERR off to oblivion. +open(SAVERR, ">&STDERR") or die $!; +open(STDERR, ">".File::Spec->devnull) or die $!; + +my $realclean_out = `$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/hints.t b/gnu/usr.bin/perl/lib/ExtUtils/t/hints.t new file mode 100644 index 00000000000..62608d7bbb6 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/hints.t @@ -0,0 +1,48 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't'; + @INC = ('../lib', 'lib/'); + } + else { + unshift @INC, 't/lib/'; + } +} +chdir 't'; + +use Test::More tests => 3; + +mkdir('hints', 0777); +my $hint_file = "hints/$^O.pl"; +open(HINT, ">$hint_file") || die "Can't write dummy hints file $hint_file: $!"; +print HINT <<'CLOO'; +$self->{CCFLAGS} = 'basset hounds got long ears'; +CLOO +close HINT; + +use TieOut; +use ExtUtils::MakeMaker; + +my $out = tie *STDERR, 'TieOut'; +my $mm = bless {}, 'ExtUtils::MakeMaker'; +$mm->check_hints; +is( $mm->{CCFLAGS}, 'basset hounds got long ears' ); +is( $out->read, "Processing hints file $hint_file\n" ); + +open(HINT, ">$hint_file") || die "Can't write dummy hints file $hint_file: $!"; +print HINT <<'CLOO'; +die "Argh!\n"; +CLOO +close HINT; + +$mm->check_hints; +is( $out->read, <<OUT, 'hint files produce errors' ); +Processing hints file $hint_file +Argh! +OUT + +END { + use File::Path; + rmtree ['hints']; +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/prefixify.t b/gnu/usr.bin/perl/lib/ExtUtils/t/prefixify.t new file mode 100644 index 00000000000..0f92a4a8b24 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/prefixify.t @@ -0,0 +1,40 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} + +use strict; +use Test::More; + +if( $^O eq 'VMS' ) { + plan skip_all => 'prefixify works differently on VMS'; +} +else { + plan tests => 2; +} +use File::Spec; +use ExtUtils::MM; + +my $mm = bless {}, 'MM'; + +my $default = File::Spec->catdir(qw(this that)); +$mm->prefixify('installbin', 'wibble', 'something', $default); + +is( $mm->{INSTALLBIN}, File::Spec->catdir('something', $default), + 'prefixify w/defaults'); + +{ + undef *ExtUtils::MM_Unix::Config; + $ExtUtils::MM_Unix::Config{wibble} = 'C:\opt\perl\wibble'; + $mm->prefixify('wibble', 'C:\opt\perl', 'C:\yarrow'); + + is( $mm->{WIBBLE}, 'C:\yarrow\wibble', 'prefixify Win32 paths' ); + { package ExtUtils::MM_Unix; Config->import } +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/problems.t b/gnu/usr.bin/perl/lib/ExtUtils/t/problems.t new file mode 100644 index 00000000000..e9162d20325 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/problems.t @@ -0,0 +1,40 @@ +# Test problems in Makefile.PL's and hint files. + +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 => 3; +use ExtUtils::MM; +use TieOut; + +my $MM = bless { DIR => ['subdir'] }, 'MM'; + +ok( chdir 'Problem-Module', "chdir'd to Problem-Module" ) || + diag("chdir failed: $!"); + + +# Make sure when Makefile.PL's break, they issue a warning. +# Also make sure Makefile.PL's in subdirs still have '.' in @INC. +{ + my $stdout = tie *STDOUT, 'TieOut' or die; + + my $warning = ''; + local $SIG{__WARN__} = sub { $warning = join '', @_ }; + eval { $MM->eval_in_subdirs; }; + + is( $stdout->read, qq{\@INC has .\n}, 'cwd in @INC' ); + like( $@, + qr{^ERROR from evaluation of .*subdir.*Makefile.PL: YYYAaaaakkk}, + 'Makefile.PL death in subdir warns' ); + + untie *STDOUT; +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/testlib.t b/gnu/usr.bin/perl/lib/ExtUtils/t/testlib.t new file mode 100644 index 00000000000..6f496a4136d --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/testlib.t @@ -0,0 +1,37 @@ +#!/usr/bin/perl -Tw + +BEGIN { + if( $ENV{PERL_CORE} ) { + chdir 't' if -d 't'; + @INC = '../lib'; + } + else { + # ./lib is there so t/lib can be seen even after we chdir. + unshift @INC, 't/lib', './lib'; + } +} +chdir 't'; + +use Test::More tests => 5; + +BEGIN { + # non-core tests will have blib in their path. We remove it + # and just use the one in lib/. + unless( $ENV{PERL_CORE} ) { + @INC = grep !/blib/, @INC; + unshift @INC, '../lib'; + } +} + +my @blib_paths = grep /blib/, @INC; +is( @blib_paths, 0, 'No blib dirs yet in @INC' ); + +use_ok( 'ExtUtils::testlib' ); + +@blib_paths = grep { /blib/ } @INC; +is( @blib_paths, 2, 'ExtUtils::testlib added two @INC dirs!' ); +ok( !(grep !File::Spec->file_name_is_absolute($_), @blib_paths), + ' and theyre absolute'); + +eval { eval "# @INC"; }; +is( $@, '', '@INC is not tainted' ); diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/writemakefile_args.t b/gnu/usr.bin/perl/lib/ExtUtils/t/writemakefile_args.t new file mode 100644 index 00000000000..f4b4daf6e39 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/writemakefile_args.t @@ -0,0 +1,116 @@ +#!/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 ExtUtils::MakeMaker; + +chdir 't'; + +perl_lib(); + +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 '', @_; + }; + + my $mm; + + eval { + $mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + MAN3PODS => ' ', # common mistake + ); + }; + + is( $warnings, <<VERIFY ); +WARNING: MAN3PODS takes a hash reference not a string/number. + Please inform the author. +VERIFY + + $warnings = ''; + eval { + $mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + AUTHOR => sub {}, + ); + }; + + is( $warnings, <<VERIFY ); +WARNING: AUTHOR takes a string/number not a code reference. + Please inform the author. +VERIFY + + # LIBS accepts *both* a string or an array ref. The first cut of + # our verification did not take this into account. + $warnings = ''; + $mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + LIBS => '-lwibble -lwobble', + ); + + # We'll get warnings about the bogus libs, that's ok. + unlike( $warnings, qr/WARNING: .* takes/ ); + is_deeply( $mm->{LIBS}, ['-lwibble -lwobble'] ); + + $warnings = ''; + $mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + LIBS => ['-lwibble', '-lwobble'], + ); + + # We'll get warnings about the bogus libs, that's ok. + unlike( $warnings, qr/WARNING: .* takes/ ); + is_deeply( $mm->{LIBS}, ['-lwibble', '-lwobble'] ); + + $warnings = ''; + eval { + $mm = WriteMakefile( + NAME => 'Big::Dummy', + VERSION_FROM => 'lib/Big/Dummy.pm', + LIBS => { wibble => "wobble" }, + ); + }; + + # 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 ); + + + $warnings = ''; + $mm = WriteMakefile( + NAME => 'Big::Dummy', + WIBBLE => 'something', + wump => { foo => 42 }, + ); + + like( $warnings, qr{^WARNING: WIBBLE is not a known parameter.\n}m ); + like( $warnings, qr{^WARNING: wump is not a known parameter.\n}m ); + + is( $mm->{WIBBLE}, 'something' ); + is_deeply( $mm->{wump}, { foo => 42 } ); +} diff --git a/gnu/usr.bin/perl/lib/ExtUtils/t/zz_cleanup_dummy.t b/gnu/usr.bin/perl/lib/ExtUtils/t/zz_cleanup_dummy.t new file mode 100644 index 00000000000..69738445966 --- /dev/null +++ b/gnu/usr.bin/perl/lib/ExtUtils/t/zz_cleanup_dummy.t @@ -0,0 +1,21 @@ +#!/usr/bin/perl -w + +BEGIN { + if( $ENV{PERL_CORE} ) { + @INC = ('../lib', 'lib'); + } + else { + unshift @INC, 't/lib'; + } +} +chdir 't'; + + +use strict; +use Test::More tests => 2; +use File::Path; + +rmtree('Big-Dummy'); +ok(!-d 'Big-Dummy', 'Big-Dummy cleaned up'); +rmtree('Problem-Module'); +ok(!-d 'Problem-Module', 'Problem-Module cleaned up'); |