#!./perl -w
-print "1..8\n";
+print "1..18\n";
BEGIN {
chdir 't' if -d 't';
use ExtUtils::MakeMaker;
use ExtUtils::Constant qw (constant_types C_constant XS_constant autoload);
use Config;
+use File::Spec::Functions;
+use File::Spec;
+# Because were are going to be changing directory before running Makefile.PL
+my $perl = File::Spec->rel2abs( $^X );
+# 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 -x \"-I../../lib\"";
-my $runperl = $^X;
-my $tobitbucket = ">/dev/null";
-# my @cleanup;
$| = 1;
my $dir = "ext-$$";
-mkdir $dir, 0777 or die $!;
+my @files;
+
+print "# $dir being created...\n";
+mkdir $dir, 0777 or die "mkdir: $!\n";
+
END {
- system "$Config{rm} -rf $dir";
+ use File::Path;
+ print "# $dir being removed...\n";
+ rmtree($dir);
}
-# push @cleanup, $dir;
+my $package = "ExtTest";
-my @names = ("THREE", {name=>"OK4", type=>"PV",},
- {name=>"OK5", type=>"PVN",
- value=>['"not ok 5\\n\\0ok 5\\n"', 15]},
+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=>~0 . "u"});
+ {name => "NOT_ZERO", type=>"UV", value=>"~(UV)0"},
+ {name => "CLOSE", type=>"PV", value=>'"*/"',
+ macro=>["#if 1\n", "#endif\n"]},
+ {name => "ANSWER", default=>["UV", 42]}, "NOTDEF");
my @names_only = map {(ref $_) ? $_->{name} : $_} @names;
-my $package = "ExtTest";
+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 = "$dir/test.h";
-open FH, ">$header" or die $!;
+my $header = catfile($dir, "test.h");
+push @files, "test.h";
+open FH, ">$header" or die "open >$header: $!\n";
print FH <<'EOT';
-#define THREE 3
-#define OK4 "ok 4\n"
-#define OK5 1
+#define FIVE 5
+#define OK6 "ok 6\n"
+#define OK7 1
#define FARTHING 0.25
#define NOT_ZERO 1
+#undef NOTDEF
EOT
-close FH or die $!;
-# push @cleanup, $header;
+close FH or die "close $header: $!\n";
################ XS
-my $xs = "$dir/$package.xs";
-open FH, ">$xs" or die $!;
+my $xs = catfile($dir, "$package.xs");
+push @files, "$package.xs";
+open FH, ">$xs" or die "open >$xs: $!\n";
print FH <<'EOT';
#include "EXTERN.h"
EOT
print FH "#include \"test.h\"\n\n";
-print FH constant_types(); # macro defs
-my $types = {};
-foreach (C_constant (undef, "IV", $types, undef, undef, @names) ) {
- print FH $_, "\n"; # C constant subs
-}
+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 ($package, $types); # XS for ExtTest::constant
-close FH or die $!;
-# push @cleanup, $xs;
+print FH $XS_constant;
+close FH or die "close $xs: $!\n";
################ PM
-my $pm = "$dir/$package.pm";
-open FH, ">$pm" or die $!;
+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";
require Exporter;
require DynaLoader;
-use AutoLoader;
use vars qw ($VERSION @ISA @EXPORT_OK);
$VERSION = '0.01';
print FH ");\n";
print FH autoload ($package, $]);
print FH "bootstrap $package \$VERSION;\n1;\n__END__\n";
-close FH or die $!;
-# push @cleanup, $pm;
+close FH or die "close $pm: $!\n";
################ test.pl
-my $testpl = "$dir/test.pl";
-open FH, ">$testpl" or die $!;
+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';
-my $three = THREE;
-if ($three == 3) {
- print "ok 3\n";
+# IV
+my $five = FIVE;
+if ($five == 5) {
+ print "ok 5\n";
} else {
- print "not ok 3 # $three\n";
+ print "not ok 5 # $five\n";
}
-print OK4;
+# PV
+print OK6;
-$_ = OK5;
+# PVN containing embedded \0s
+$_ = OK7;
s/.*\0//s;
print;
+# NV
my $farthing = FARTHING;
if ($farthing == 0.25) {
- print "ok 6\n";
+ print "ok 8\n";
} else {
- print "not ok 6 # $farthing\n";
+ print "not ok 8 # $farthing\n";
}
+# UV
my $not_zero = NOT_ZERO;
if ($not_zero > 0 && $not_zero == ~0) {
- print "ok 7\n";
+ 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 7 # \$not_zero=$not_zero ~0=" . (~0) . "\n";
+ 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";
+}
-EOT
+# 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";
+}
-close FH or die $!;
-# push @cleanup, $testpl;
+# 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";
+}
-################ dummy Makefile.PL
-# Keep the dependancy in the Makefile happy
-my $makefilePL = "$dir/Makefile.PL";
-open FH, ">$makefilePL" or die $!;
-close FH or die $!;
-# push @cleanup, $makefilePL;
+EOT
-chdir $dir or die $!; push @INC, '../../lib';
-END {chdir ".." or warn $!};
+close FH or die "close $testpl: $!\n";
-print "# "; # Grr. MakeMaker hardwired to write its message to STDOUT
+################ 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 ?
+ 'NAME' => "$package",
+ 'VERSION_FROM' => "$package.pm", # finds \$VERSION
+ (\$] >= 5.005 ?
(#ABSTRACT_FROM => "$package.pm", # XXX add this
- AUTHOR => $0) : ())
+ AUTHOR => "$0") : ())
);
-if (-f "Makefile") {
+EOT
+
+close FH or die "close $makefilePL: $!\n";
+
+chdir $dir or die $!; push @INC, '../../lib';
+END {chdir ".." or warn $!};
+
+my @perlout = `$runperl Makefile.PL`;
+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 1\n";
+ print "not ok 2\n";
}
+my $makefile_rename = ($^O eq 'VMS' ? '.mms' : '.old');
+push @files, "$makefile$makefile_rename"; # Renamed by make clean
my $make = $Config{make};
+
$make = $ENV{MAKE} if exists $ENV{MAKE};
+
+my $makeout;
+
print "# make = '$make'\n";
-if (system "$make $tobitbucket") {
- print "not ok 2 # $make failed\n";
- # Bail out?
+$makeout = `$make`;
+if ($?) {
+ print "not ok 3 # $make failed: $?\n";
+ exit($?);
} else {
- print "ok 2\n";
+ print "ok 3\n";
}
-$make .= ' test';
-# This hack to get a # in front of "PERL_DL_NONLAZY=1 ..." isn't going to work
-# on VMS mailboxes.
-print "# make = '$make'\n# ";
-if (system $make) {
- print "not ok 8 # $make failed\n";
+if ($Config{usedl}) {
+ print "ok 4\n";
} else {
- print "ok 8\n";
+ push @files, "perl$Config{exe_ext}";
+ my $makeperl = "$make perl";
+ print "# make = '$makeperl'\n";
+ $makeout = `$makeperl`;
+ if ($?) {
+ print "not ok 4 # $makeperl failed: $?\n";
+ exit($?);
+ } else {
+ print "ok 4\n";
+ }
+}
+
+my $test = 14;
+my $maketest = "$make test";
+print "# make = '$maketest'\n";
+$makeout = `$maketest`;
+if ($?) {
+ print "not ok $test # $maketest failed: $?\n";
+} else {
+ # echo of running the test script
+ $makeout =~ s/^\s*PERL_DL_NONLAZY=.+?\n//m;
+ $makeout =~ s/^MCR.+test.pl\n//mig if $^O eq 'VMS';
+
+ # GNU make babblings
+ $makeout =~ s/^\w*?make.+?(?:entering|leaving) directory.+?\n//mig;
+
+ # Hopefully gets most make's babblings
+ # make -f Makefile.aperl perl
+ $makeout =~ s/^\w*?make.+\sperl[^A-Za-z0-9]*\n//mig;
+ # make[1]: `perl' is up to date.
+ $makeout =~ s/^\w*?make.+perl.+?is up to date.*?\n//mig;
+
+ print $makeout;
+ print "ok $test\n";
+}
+$test++;
+
+my $regen = `$runperl $package.xs`;
+if ($?) {
+ print "not ok $test # $runperl $package.xs failed: $?\n";
+} else {
+ print "ok $test\n";
+}
+$test++;
+
+my $expect = $constant_types . $C_constant .
+ "\n#### XS Section:\n" . $XS_constant;
+
+if ($expect eq $regen) {
+ print "ok $test\n";
+} else {
+ print "not ok $test\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";
+} else {
+ print "ok $test\n";
+}
+$test++;
+
+foreach (@files) {
+ unlink $_ or warn "unlink $_: $!";
+}
+
+my $fail;
+opendir DIR, "." or die "opendir '.': $!";
+while (defined (my $entry = readdir DIR)) {
+ next if $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";
}