Integrate mainline (Win2k/MinGW all ok except threads/t/end.t)
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / t / Constant.t
CommitLineData
39234879 1#!/usr/bin/perl -w
af6c647e 2
72f7b9a1 3print "1..27\n";
af6c647e 4
5BEGIN {
39234879 6 if( $ENV{PERL_CORE} ) {
7 chdir 't' if -d 't';
8 @INC = '../lib';
9 }
af6c647e 10}
11
d7f97632 12# use warnings;
af6c647e 13use strict;
14use ExtUtils::MakeMaker;
15use ExtUtils::Constant qw (constant_types C_constant XS_constant autoload);
16use Config;
357229c3 17use File::Spec::Functions qw(catfile rel2abs);
835f860c 18# Because were are going to be changing directory before running Makefile.PL
8338e367 19my $perl;
d7f97632 20$perl = rel2abs( $^X ) unless $] < 5.006; # Hack. Until 5.00503 has rel2abs
6d79cad2 21# ExtUtils::Constant::C_constant uses $^X inside a comment, and we want to
22# compare output to ensure that it is the same. We were probably run as ./perl
23# whereas we will run the child with the full path in $perl. So make $^X for
24# us the same as our child will see.
25$^X = $perl;
af6c647e 26
835f860c 27print "# perl=$perl\n";
39234879 28my $runperl = "$perl \"-I../../lib\"";
94b1a389 29
af6c647e 30$| = 1;
31
32my $dir = "ext-$$";
0ddb8edc 33my @files;
94b1a389 34
35print "# $dir being created...\n";
36mkdir $dir, 0777 or die "mkdir: $!\n";
37
535acd0f 38my $output = "output";
af6c647e 39
40END {
94b1a389 41 use File::Path;
42 print "# $dir being removed...\n";
43 rmtree($dir);
af6c647e 44}
45
6d79cad2 46my $package = "ExtTest";
47
8ac27563 48# Test the code that generates 1 and 2 letter name comparisons.
49my %compass = (
d7f97632 50N => 0, 'NE' => 45, E => 90, SE => 135, S => 180, SW => 225, W => 270, NW => 315
8ac27563 51);
52
cea00dc5 53my $parent_rfc1149 =
54 'A Standard for the Transmission of IP Datagrams on Avian Carriers';
55
835f860c 56my @names = ("FIVE", {name=>"OK6", type=>"PV",},
57 {name=>"OK7", type=>"PVN",
58 value=>['"not ok 7\\n\\0ok 7\\n"', 15]},
af6c647e 59 {name => "FARTHING", type=>"NV"},
6d79cad2 60 {name => "NOT_ZERO", type=>"UV", value=>"~(UV)0"},
72f7b9a1 61 {name => "OPEN", type=>"PV", value=>'"/*"', macro=>1},
6d79cad2 62 {name => "CLOSE", type=>"PV", value=>'"*/"',
63 macro=>["#if 1\n", "#endif\n"]},
3414cef0 64 {name => "ANSWER", default=>["UV", 42]}, "NOTDEF",
65 {name => "Yes", type=>"YES"},
66 {name => "No", type=>"NO"},
19d75eda 67 {name => "Undef", type=>"UNDEF"},
cea00dc5 68# OK. It wasn't really designed to allow the creation of dual valued constants.
69# It was more for INADDR_ANY INADDR_BROADCAST INADDR_LOOPBACK INADDR_NONE
70 {name=>"RFC1149", type=>"SV", value=>"sv_2mortal(temp_sv)",
71 pre=>"SV *temp_sv = newSVpv(RFC1149, 0); "
72 . "(void) SvUPGRADE(temp_sv,SVt_PVIV); SvIOK_on(temp_sv); "
73 . "SvIVX(temp_sv) = 1149;"},
3414cef0 74);
af6c647e 75
8ac27563 76push @names, $_ foreach keys %compass;
77
af6c647e 78my @names_only = map {(ref $_) ? $_->{name} : $_} @names;
79
6d79cad2 80my $types = {};
81my $constant_types = constant_types(); # macro defs
82my $C_constant = join "\n",
83 C_constant ($package, undef, "IV", $types, undef, undef, @names);
84my $XS_constant = XS_constant ($package, $types); # XS for ExtTest::constant
85
af6c647e 86################ Header
94b1a389 87my $header = catfile($dir, "test.h");
0ddb8edc 88push @files, "test.h";
94b1a389 89open FH, ">$header" or die "open >$header: $!\n";
cea00dc5 90print FH <<"EOT";
835f860c 91#define FIVE 5
7b6ffde5 92#define OK6 "ok 6\\n"
835f860c 93#define OK7 1
af6c647e 94#define FARTHING 0.25
95#define NOT_ZERO 1
3414cef0 96#define Yes 0
97#define No 1
98#define Undef 1
cea00dc5 99#define RFC1149 "$parent_rfc1149"
6d79cad2 100#undef NOTDEF
8ac27563 101
af6c647e 102EOT
8ac27563 103
104while (my ($point, $bearing) = each %compass) {
105 print FH "#define $point $bearing\n"
106}
94b1a389 107close FH or die "close $header: $!\n";
af6c647e 108
109################ XS
94b1a389 110my $xs = catfile($dir, "$package.xs");
0ddb8edc 111push @files, "$package.xs";
94b1a389 112open FH, ">$xs" or die "open >$xs: $!\n";
af6c647e 113
114print FH <<'EOT';
115#include "EXTERN.h"
116#include "perl.h"
117#include "XSUB.h"
118EOT
119
120print FH "#include \"test.h\"\n\n";
6d79cad2 121print FH $constant_types;
122print FH $C_constant, "\n";
af6c647e 123print FH "MODULE = $package PACKAGE = $package\n";
124print FH "PROTOTYPES: ENABLE\n";
6d79cad2 125print FH $XS_constant;
94b1a389 126close FH or die "close $xs: $!\n";
af6c647e 127
128################ PM
94b1a389 129my $pm = catfile($dir, "$package.pm");
0ddb8edc 130push @files, "$package.pm";
94b1a389 131open FH, ">$pm" or die "open >$pm: $!\n";
af6c647e 132print FH "package $package;\n";
133print FH "use $];\n";
134
135print FH <<'EOT';
136
137use strict;
d7f97632 138EOT
139printf FH "use warnings;\n" unless $] < 5.006;
140print FH <<'EOT';
af6c647e 141use Carp;
142
143require Exporter;
144require DynaLoader;
d7f97632 145use vars qw ($VERSION @ISA @EXPORT_OK $AUTOLOAD);
af6c647e 146
147$VERSION = '0.01';
148@ISA = qw(Exporter DynaLoader);
149@EXPORT_OK = qw(
150EOT
151
152print FH "\t$_\n" foreach (@names_only);
153print FH ");\n";
154print FH autoload ($package, $]);
155print FH "bootstrap $package \$VERSION;\n1;\n__END__\n";
94b1a389 156close FH or die "close $pm: $!\n";
af6c647e 157
158################ test.pl
94b1a389 159my $testpl = catfile($dir, "test.pl");
0ddb8edc 160push @files, "test.pl";
94b1a389 161open FH, ">$testpl" or die "open >$testpl: $!\n";
af6c647e 162
6d79cad2 163print FH "use strict;\n";
af6c647e 164print FH "use $package qw(@names_only);\n";
535acd0f 165print FH <<"EOT";
166
167print "1..1\n";
168if (open OUTPUT, ">$output") {
169 print "ok 1\n";
170 select OUTPUT;
171} else {
172 print "not ok 1 # Failed to open '$output': $!\n";
173 exit 1;
174}
175EOT
af6c647e 176
535acd0f 177print FH << 'EOT';
178
179# What follows goes to the temporary file.
6d79cad2 180# IV
835f860c 181my $five = FIVE;
182if ($five == 5) {
183 print "ok 5\n";
af6c647e 184} else {
835f860c 185 print "not ok 5 # $five\n";
af6c647e 186}
187
6d79cad2 188# PV
835f860c 189print OK6;
af6c647e 190
6d79cad2 191# PVN containing embedded \0s
835f860c 192$_ = OK7;
af6c647e 193s/.*\0//s;
194print;
195
6d79cad2 196# NV
af6c647e 197my $farthing = FARTHING;
198if ($farthing == 0.25) {
835f860c 199 print "ok 8\n";
af6c647e 200} else {
835f860c 201 print "not ok 8 # $farthing\n";
af6c647e 202}
203
6d79cad2 204# UV
af6c647e 205my $not_zero = NOT_ZERO;
206if ($not_zero > 0 && $not_zero == ~0) {
835f860c 207 print "ok 9\n";
af6c647e 208} else {
835f860c 209 print "not ok 9 # \$not_zero=$not_zero ~0=" . (~0) . "\n";
af6c647e 210}
211
6d79cad2 212# Value includes a "*/" in an attempt to bust out of a C comment.
213# Also tests custom cpp #if clauses
214my $close = CLOSE;
215if ($close eq '*/') {
216 print "ok 10\n";
217} else {
218 print "not ok 10 # \$close='$close'\n";
219}
220
221# Default values if macro not defined.
222my $answer = ANSWER;
223if ($answer == 42) {
224 print "ok 11\n";
225} else {
226 print "not ok 11 # What do you get if you multiply six by nine? '$answer'\n";
227}
228
229# not defined macro
230my $notdef = eval { NOTDEF; };
231if (defined $notdef) {
232 print "not ok 12 # \$notdef='$notdef'\n";
233} elsif ($@ !~ /Your vendor has not defined ExtTest macro NOTDEF/) {
234 print "not ok 12 # \$@='$@'\n";
235} else {
236 print "ok 12\n";
237}
238
239# not a macro
240my $notthere = eval { &ExtTest::NOTTHERE; };
241if (defined $notthere) {
242 print "not ok 13 # \$notthere='$notthere'\n";
243} elsif ($@ !~ /NOTTHERE is not a valid ExtTest macro/) {
244 chomp $@;
245 print "not ok 13 # \$@='$@'\n";
246} else {
247 print "ok 13\n";
248}
af6c647e 249
3414cef0 250# Truth
251my $yes = Yes;
252if ($yes) {
253 print "ok 14\n";
254} else {
255 print "not ok 14 # $yes='\$yes'\n";
256}
257
258# Falsehood
259my $no = No;
260if (defined $no and !$no) {
261 print "ok 15\n";
262} else {
263 print "not ok 15 # \$no=" . defined ($no) ? "'$no'\n" : "undef\n";
264}
265
266# Undef
267my $undef = Undef;
268unless (defined $undef) {
269 print "ok 16\n";
270} else {
271 print "not ok 16 # \$undef='$undef'\n";
272}
273
8ac27563 274
275# invalid macro (chosen to look like a mix up between No and SW)
276$notdef = eval { &ExtTest::So };
277if (defined $notdef) {
278 print "not ok 17 # \$notdef='$notdef'\n";
279} elsif ($@ !~ /^So is not a valid ExtTest macro/) {
280 print "not ok 17 # \$@='$@'\n";
281} else {
282 print "ok 17\n";
283}
284
285# invalid defined macro
286$notdef = eval { &ExtTest::EW };
287if (defined $notdef) {
288 print "not ok 18 # \$notdef='$notdef'\n";
289} elsif ($@ !~ /^EW is not a valid ExtTest macro/) {
290 print "not ok 18 # \$@='$@'\n";
291} else {
292 print "ok 18\n";
293}
294
295my %compass = (
296EOT
297
298while (my ($point, $bearing) = each %compass) {
d7f97632 299 print FH "'$point' => $bearing, "
8ac27563 300}
301
302print FH <<'EOT';
303
304);
305
306my $fail;
307while (my ($point, $bearing) = each %compass) {
308 my $val = eval $point;
309 if ($@) {
310 print "# $point: \$@='$@'\n";
311 $fail = 1;
312 } elsif (!defined $bearing) {
313 print "# $point: \$val=undef\n";
314 $fail = 1;
315 } elsif ($val != $bearing) {
316 print "# $point: \$val=$val, not $bearing\n";
317 $fail = 1;
318 }
319}
320if ($fail) {
321 print "not ok 19\n";
322} else {
323 print "ok 19\n";
324}
325
af6c647e 326EOT
327
cea00dc5 328print FH <<"EOT";
329my \$rfc1149 = RFC1149;
330if (\$rfc1149 ne "$parent_rfc1149") {
331 print "not ok 20 # '\$rfc1149' ne '$parent_rfc1149'\n";
332} else {
333 print "ok 20\n";
334}
335
336if (\$rfc1149 != 1149) {
337 printf "not ok 21 # %d != 1149\n", \$rfc1149;
338} else {
339 print "ok 21\n";
340}
72f7b9a1 341
342EOT
343
344print FH <<'EOT';
345# test macro=>1
346my $open = OPEN;
347if ($open eq '/*') {
348 print "ok 22\n";
349} else {
350 print "not ok 22 # \$open='$open'\n";
351}
cea00dc5 352EOT
94b1a389 353close FH or die "close $testpl: $!\n";
af6c647e 354
835f860c 355################ Makefile.PL
6d79cad2 356# We really need a Makefile.PL because make test for a no dynamic linking perl
357# will run Makefile.PL again as part of the "make perl" target.
94b1a389 358my $makefilePL = catfile($dir, "Makefile.PL");
0ddb8edc 359push @files, "Makefile.PL";
94b1a389 360open FH, ">$makefilePL" or die "open >$makefilePL: $!\n";
835f860c 361print FH <<"EOT";
6d79cad2 362#!$perl -w
835f860c 363use ExtUtils::MakeMaker;
364WriteMakefile(
365 'NAME' => "$package",
366 'VERSION_FROM' => "$package.pm", # finds \$VERSION
367 (\$] >= 5.005 ?
368 (#ABSTRACT_FROM => "$package.pm", # XXX add this
369 AUTHOR => "$0") : ())
370 );
371EOT
372
94b1a389 373close FH or die "close $makefilePL: $!\n";
af6c647e 374
375chdir $dir or die $!; push @INC, '../../lib';
376END {chdir ".." or warn $!};
377
4bfb3f62 378my @perlout = `$runperl Makefile.PL PERL_CORE=1`;
835f860c 379if ($?) {
380 print "not ok 1 # $runperl Makefile.PL failed: $?\n";
381 print "# $_" foreach @perlout;
382 exit($?);
383} else {
384 print "ok 1\n";
385}
386
387
24874030 388my $makefile = ($^O eq 'VMS' ? 'descrip' : 'Makefile');
389my $makefile_ext = ($^O eq 'VMS' ? '.mms' : '');
390if (-f "$makefile$makefile_ext") {
835f860c 391 print "ok 2\n";
af6c647e 392} else {
835f860c 393 print "not ok 2\n";
af6c647e 394}
24874030 395my $makefile_rename = ($^O eq 'VMS' ? '.mms' : '.old');
396push @files, "$makefile$makefile_rename"; # Renamed by make clean
af6c647e 397
398my $make = $Config{make};
94b1a389 399
af6c647e 400$make = $ENV{MAKE} if exists $ENV{MAKE};
94b1a389 401
91e5ac1f 402if ($^O eq 'MSWin32' && $make eq 'nmake') { $make .= " -nologo"; }
76f26e35 403
535acd0f 404my @makeout;
94b1a389 405
d6b7ef86 406if ($^O eq 'VMS') { $make .= ' all'; }
af6c647e 407print "# make = '$make'\n";
535acd0f 408@makeout = `$make`;
94b1a389 409if ($?) {
835f860c 410 print "not ok 3 # $make failed: $?\n";
535acd0f 411 print "# $_" foreach @makeout;
94b1a389 412 exit($?);
af6c647e 413} else {
835f860c 414 print "ok 3\n";
415}
416
d6b7ef86 417if ($^O eq 'VMS') { $make =~ s{ all}{}; }
418
835f860c 419if ($Config{usedl}) {
420 print "ok 4\n";
421} else {
835f860c 422 my $makeperl = "$make perl";
423 print "# make = '$makeperl'\n";
535acd0f 424 @makeout = `$makeperl`;
835f860c 425 if ($?) {
426 print "not ok 4 # $makeperl failed: $?\n";
535acd0f 427 print "# $_" foreach @makeout;
835f860c 428 exit($?);
429 } else {
430 print "ok 4\n";
431 }
af6c647e 432}
433
535acd0f 434push @files, $output;
435
0ddb8edc 436my $maketest = "$make test";
437print "# make = '$maketest'\n";
3414cef0 438
535acd0f 439@makeout = `$maketest`;
94b1a389 440
535acd0f 441if (open OUTPUT, "<$output") {
442 print while <OUTPUT>;
443 close OUTPUT or print "# Close $output failed: $!\n";
444} else {
445 # Harness will report missing test results at this point.
446 print "# Open <$output failed: $!\n";
447}
835f860c 448
535acd0f 449my $test = 23;
3414cef0 450
451if ($?) {
452 print "not ok $test # $maketest failed: $?\n";
535acd0f 453 print "# $_" foreach @makeout;
3414cef0 454} else {
39234879 455 print "ok $test - maketest\n";
6d79cad2 456}
457$test++;
458
39234879 459
460# -x is busted on Win32 < 5.6.1, so we emulate it.
461my $regen;
462if( $^O eq 'MSWin32' && $] <= 5.006001 ) {
463 open(REGENTMP, ">regentmp") or die $!;
464 open(XS, "$package.xs") or die $!;
465 my $saw_shebang;
466 while(<XS>) {
467 $saw_shebang++ if /^#!.*/i ;
468 print REGENTMP $_ if $saw_shebang;
469 }
470 close XS; close REGENTMP;
471 $regen = `$runperl regentmp`;
472 unlink 'regentmp';
473}
474else {
475 $regen = `$runperl -x $package.xs`;
476}
6d79cad2 477if ($?) {
39234879 478 print "not ok $test # $runperl -x $package.xs failed: $?\n";
6d79cad2 479} else {
39234879 480 print "ok $test - regen\n";
af6c647e 481}
6d79cad2 482$test++;
483
484my $expect = $constant_types . $C_constant .
485 "\n#### XS Section:\n" . $XS_constant;
486
487if ($expect eq $regen) {
39234879 488 print "ok $test - regen worked\n";
6d79cad2 489} else {
39234879 490 print "not ok $test - regen worked\n";
6d79cad2 491 # open FOO, ">expect"; print FOO $expect;
492 # open FOO, ">regen"; print FOO $regen; close FOO;
493}
494$test++;
0ddb8edc 495
496my $makeclean = "$make clean";
497print "# make = '$makeclean'\n";
535acd0f 498@makeout = `$makeclean`;
0ddb8edc 499if ($?) {
6d79cad2 500 print "not ok $test # $make failed: $?\n";
535acd0f 501 print "# $_" foreach @makeout;
0ddb8edc 502} else {
6d79cad2 503 print "ok $test\n";
0ddb8edc 504}
6d79cad2 505$test++;
0ddb8edc 506
507foreach (@files) {
508 unlink $_ or warn "unlink $_: $!";
509}
510
511my $fail;
512opendir DIR, "." or die "opendir '.': $!";
513while (defined (my $entry = readdir DIR)) {
514 next if $entry =~ /^\.\.?$/;
515 print "# Extra file '$entry'\n";
516 $fail = 1;
517}
518closedir DIR or warn "closedir '.': $!";
519if ($fail) {
6d79cad2 520 print "not ok $test\n";
0ddb8edc 521} else {
6d79cad2 522 print "ok $test\n";
0ddb8edc 523}