test failure: lib/ExtUtils/t/Installed.t
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / t / Constant.t
1 #!/usr/bin/perl -w
2
3 print "1..51\n";
4
5 BEGIN {
6     if( $ENV{PERL_CORE} ) {
7         chdir 't' if -d 't';
8         @INC = '../lib';
9     }
10 }
11
12 # use warnings;
13 use strict;
14 use ExtUtils::MakeMaker;
15 use ExtUtils::Constant qw (constant_types C_constant XS_constant autoload);
16 use Config;
17 use File::Spec::Functions qw(catfile rel2abs);
18 # Because were are going to be changing directory before running Makefile.PL
19 my $perl;
20 $perl = rel2abs( $^X ) unless $] < 5.006; # Hack. Until 5.00503 has rel2abs
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;
26
27 print "# perl=$perl\n";
28 my $runperl = "$perl \"-I../../lib\"";
29
30 $| = 1;
31
32 my $dir = "ext-$$";
33 my @files;
34
35 print "# $dir being created...\n";
36 mkdir $dir, 0777 or die "mkdir: $!\n";
37
38 my $output = "output";
39
40 # For debugging set this to 1.
41 my $keep_files = 0;
42
43 END {
44     use File::Path;
45     print "# $dir being removed...\n";
46     rmtree($dir) unless $keep_files;
47 }
48
49 my $package = "ExtTest";
50
51 # Test the code that generates 1 and 2 letter name comparisons.
52 my %compass = (
53 N => 0, 'NE' => 45, E => 90, SE => 135, S => 180, SW => 225, W => 270, NW => 315
54 );
55
56 my $parent_rfc1149 =
57   'A Standard for the Transmission of IP Datagrams on Avian Carriers';
58 # Check that 8 bit and unicode names don't cause problems.
59 my $pound = chr 163; # A pound sign. (Currency)
60 my $inf = chr 0x221E;
61 # Check that we can distiguish the pathological case of a string, and the
62 # utf8 representation of that string.
63 my $pound_bytes = my $pound_utf8 = $pound . '1';
64 utf8::encode ($pound_bytes);
65
66 my @names = ("FIVE", {name=>"OK6", type=>"PV",},
67              {name=>"OK7", type=>"PVN",
68               value=>['"not ok 7\\n\\0ok 7\\n"', 15]},
69              {name => "FARTHING", type=>"NV"},
70              {name => "NOT_ZERO", type=>"UV", value=>"~(UV)0"},
71              {name => "OPEN", type=>"PV", value=>'"/*"', macro=>1},
72              {name => "CLOSE", type=>"PV", value=>'"*/"',
73               macro=>["#if 1\n", "#endif\n"]},
74              {name => "ANSWER", default=>["UV", 42]}, "NOTDEF",
75              {name => "Yes", type=>"YES"},
76              {name => "No", type=>"NO"},
77              {name => "Undef", type=>"UNDEF"},
78 # OK. It wasn't really designed to allow the creation of dual valued constants.
79 # It was more for INADDR_ANY INADDR_BROADCAST INADDR_LOOPBACK INADDR_NONE
80              {name=>"RFC1149", type=>"SV", value=>"sv_2mortal(temp_sv)",
81               pre=>"SV *temp_sv = newSVpv(RFC1149, 0); "
82                    . "(void) SvUPGRADE(temp_sv,SVt_PVIV); SvIOK_on(temp_sv); "
83                    . "SvIVX(temp_sv) = 1149;"},
84              {name=>"perl", type=>"PV",},
85 );
86
87 push @names, $_ foreach keys %compass;
88
89 # Automatically compile the list of all the macro names, and make them
90 # exported constants.
91 my @names_only = map {(ref $_) ? $_->{name} : $_} @names;
92
93 # Exporter::Heavy (currently) isn't able to export these names:
94 push @names, ({name=>"*/", type=>"PV", value=>'"CLOSE"', macro=>1},
95               {name=>"/*", type=>"PV", value=>'"OPEN"', macro=>1},
96               {name=>$pound, type=>"PV", value=>'"Sterling"', macro=>1},
97               {name=>$inf, type=>"PV", value=>'"Infinity"', macro=>1},
98               {name=>$pound_utf8, type=>"PV", value=>'"1 Pound"', macro=>1},
99               {name=>$pound_bytes, type=>"PV", value=>'"1 Pound (as bytes)"',
100                macro=>1},
101              );
102
103 =pod
104
105 The above set of names seems to produce a suitably bad set of compile
106 problems on a Unicode naive version of ExtUtils::Constant (ie 0.11):
107
108 nick@thinking-cap 15439-32-utf$ PERL_CORE=1 ./perl lib/ExtUtils/t/Constant.t
109 1..33
110 # perl=/stuff/perl5/15439-32-utf/perl
111 # ext-30370 being created...
112 Wide character in print at lib/ExtUtils/t/Constant.t line 140.
113 ok 1
114 ok 2
115 # make = 'make'
116 ExtTest.xs: In function `constant_1':
117 ExtTest.xs:80: warning: multi-character character constant
118 ExtTest.xs:80: warning: case value out of range
119 ok 3
120
121 =cut
122
123 my $types = {};
124 my $constant_types = constant_types(); # macro defs
125 my $C_constant = join "\n",
126   C_constant ($package, undef, "IV", $types, undef, undef, @names);
127 my $XS_constant = XS_constant ($package, $types); # XS for ExtTest::constant
128
129 ################ Header
130 my $header = catfile($dir, "test.h");
131 push @files, "test.h";
132 open FH, ">$header" or die "open >$header: $!\n";
133 print FH <<"EOT";
134 #define FIVE 5
135 #define OK6 "ok 6\\n"
136 #define OK7 1
137 #define FARTHING 0.25
138 #define NOT_ZERO 1
139 #define Yes 0
140 #define No 1
141 #define Undef 1
142 #define RFC1149 "$parent_rfc1149"
143 #undef NOTDEF
144 #define perl "rules"
145 EOT
146
147 while (my ($point, $bearing) = each %compass) {
148   print FH "#define $point $bearing\n"
149 }
150 close FH or die "close $header: $!\n";
151
152 ################ XS
153 my $xs = catfile($dir, "$package.xs");
154 push @files, "$package.xs";
155 open FH, ">$xs" or die "open >$xs: $!\n";
156
157 print FH <<'EOT';
158 #include "EXTERN.h"
159 #include "perl.h"
160 #include "XSUB.h"
161 EOT
162
163 print FH "#include \"test.h\"\n\n";
164 print FH $constant_types;
165 print FH $C_constant, "\n";
166 print FH "MODULE = $package             PACKAGE = $package\n";
167 print FH "PROTOTYPES: ENABLE\n";
168 print FH $XS_constant;
169 close FH or die "close $xs: $!\n";
170
171 ################ PM
172 my $pm = catfile($dir, "$package.pm");
173 push @files, "$package.pm";
174 open FH, ">$pm" or die "open >$pm: $!\n";
175 print FH "package $package;\n";
176 print FH "use $];\n";
177
178 print FH <<'EOT';
179
180 use strict;
181 EOT
182 printf FH "use warnings;\n" unless $] < 5.006;
183 print FH <<'EOT';
184 use Carp;
185
186 require Exporter;
187 require DynaLoader;
188 use vars qw ($VERSION @ISA @EXPORT_OK $AUTOLOAD);
189
190 $VERSION = '0.01';
191 @ISA = qw(Exporter DynaLoader);
192 @EXPORT_OK = qw(
193 EOT
194
195 # Print the names of all our autoloaded constants
196 print FH "\t$_\n" foreach (@names_only);
197 print FH ");\n";
198 # Print the AUTOLOAD subroutine ExtUtils::Constant generated for us
199 print FH autoload ($package, $]);
200 print FH "bootstrap $package \$VERSION;\n1;\n__END__\n";
201 close FH or die "close $pm: $!\n";
202
203 ################ test.pl
204 my $testpl = catfile($dir, "test.pl");
205 push @files, "test.pl";
206 open FH, ">$testpl" or die "open >$testpl: $!\n";
207
208 print FH "use strict;\n";
209 print FH "use $package qw(@names_only);\n";
210 print FH <<"EOT";
211
212 use utf8;
213
214 print "1..1\n";
215 if (open OUTPUT, ">$output") {
216   print "ok 1\n";
217   select OUTPUT;
218 } else {
219   print "not ok 1 # Failed to open '$output': $!\n";
220   exit 1;
221 }
222 EOT
223
224 print FH << 'EOT';
225
226 # What follows goes to the temporary file.
227 # IV
228 my $five = FIVE;
229 if ($five == 5) {
230   print "ok 5\n";
231 } else {
232   print "not ok 5 # $five\n";
233 }
234
235 # PV
236 print OK6;
237
238 # PVN containing embedded \0s
239 $_ = OK7;
240 s/.*\0//s;
241 print;
242
243 # NV
244 my $farthing = FARTHING;
245 if ($farthing == 0.25) {
246   print "ok 8\n";
247 } else {
248   print "not ok 8 # $farthing\n";
249 }
250
251 # UV
252 my $not_zero = NOT_ZERO;
253 if ($not_zero > 0 && $not_zero == ~0) {
254   print "ok 9\n";
255 } else {
256   print "not ok 9 # \$not_zero=$not_zero ~0=" . (~0) . "\n";
257 }
258
259 # Value includes a "*/" in an attempt to bust out of a C comment.
260 # Also tests custom cpp #if clauses
261 my $close = CLOSE;
262 if ($close eq '*/') {
263   print "ok 10\n";
264 } else {
265   print "not ok 10 # \$close='$close'\n";
266 }
267
268 # Default values if macro not defined.
269 my $answer = ANSWER;
270 if ($answer == 42) {
271   print "ok 11\n";
272 } else {
273   print "not ok 11 # What do you get if you multiply six by nine? '$answer'\n";
274 }
275
276 # not defined macro
277 my $notdef = eval { NOTDEF; };
278 if (defined $notdef) {
279   print "not ok 12 # \$notdef='$notdef'\n";
280 } elsif ($@ !~ /Your vendor has not defined ExtTest macro NOTDEF/) {
281   print "not ok 12 # \$@='$@'\n";
282 } else {
283   print "ok 12\n";
284 }
285
286 # not a macro
287 my $notthere = eval { &ExtTest::NOTTHERE; };
288 if (defined $notthere) {
289   print "not ok 13 # \$notthere='$notthere'\n";
290 } elsif ($@ !~ /NOTTHERE is not a valid ExtTest macro/) {
291   chomp $@;
292   print "not ok 13 # \$@='$@'\n";
293 } else {
294   print "ok 13\n";
295 }
296
297 # Truth
298 my $yes = Yes;
299 if ($yes) {
300   print "ok 14\n";
301 } else {
302   print "not ok 14 # $yes='\$yes'\n";
303 }
304
305 # Falsehood
306 my $no = No;
307 if (defined $no and !$no) {
308   print "ok 15\n";
309 } else {
310   print "not ok 15 # \$no=" . defined ($no) ? "'$no'\n" : "undef\n";
311 }
312
313 # Undef
314 my $undef = Undef;
315 unless (defined $undef) {
316   print "ok 16\n";
317 } else {
318   print "not ok 16 # \$undef='$undef'\n";
319 }
320
321
322 # invalid macro (chosen to look like a mix up between No and SW)
323 $notdef = eval { &ExtTest::So };
324 if (defined $notdef) {
325   print "not ok 17 # \$notdef='$notdef'\n";
326 } elsif ($@ !~ /^So is not a valid ExtTest macro/) {
327   print "not ok 17 # \$@='$@'\n";
328 } else {
329   print "ok 17\n";
330 }
331
332 # invalid defined macro
333 $notdef = eval { &ExtTest::EW };
334 if (defined $notdef) {
335   print "not ok 18 # \$notdef='$notdef'\n";
336 } elsif ($@ !~ /^EW is not a valid ExtTest macro/) {
337   print "not ok 18 # \$@='$@'\n";
338 } else {
339   print "ok 18\n";
340 }
341
342 my %compass = (
343 EOT
344
345 while (my ($point, $bearing) = each %compass) {
346   print FH "'$point' => $bearing, "
347 }
348
349 print FH <<'EOT';
350
351 );
352
353 my $fail;
354 while (my ($point, $bearing) = each %compass) {
355   my $val = eval $point;
356   if ($@) {
357     print "# $point: \$@='$@'\n";
358     $fail = 1;
359   } elsif (!defined $bearing) {
360     print "# $point: \$val=undef\n";
361     $fail = 1;
362   } elsif ($val != $bearing) {
363     print "# $point: \$val=$val, not $bearing\n";
364     $fail = 1;
365   }
366 }
367 if ($fail) {
368   print "not ok 19\n";
369 } else {
370   print "ok 19\n";
371 }
372
373 EOT
374
375 print FH <<"EOT";
376 my \$rfc1149 = RFC1149;
377 if (\$rfc1149 ne "$parent_rfc1149") {
378   print "not ok 20 # '\$rfc1149' ne '$parent_rfc1149'\n";
379 } else {
380   print "ok 20\n";
381 }
382
383 if (\$rfc1149 != 1149) {
384   printf "not ok 21 # %d != 1149\n", \$rfc1149;
385 } else {
386   print "ok 21\n";
387 }
388
389 EOT
390
391 print FH <<'EOT';
392 # test macro=>1
393 my $open = OPEN;
394 if ($open eq '/*') {
395   print "ok 22\n";
396 } else {
397   print "not ok 22 # \$open='$open'\n";
398 }
399 EOT
400
401 # Do this in 7 bit in case someone is testing with some settings that cause
402 # 8 bit files incapable of storing this character.
403 my @values
404  = map {"'" . join (",", unpack "U*", $_) . "'"}
405  ($pound, $inf, $pound_bytes, $pound_utf8);
406 # Values is a list of strings, such as ('194,163,49', '163,49')
407
408 print FH <<'EOT';
409
410 # I can see that this child test program might be about to use parts of
411 # Test::Builder
412
413 my $test = 23;
414 my ($pound, $inf, $pound_bytes, $pound_utf8) = map {eval "pack 'U*', $_"}
415 EOT
416
417 print FH join ",", @values;
418
419 print FH << 'EOT';
420 ;
421
422 foreach (["perl", "rules", "rules"],
423          ["/*", "OPEN", "OPEN"],
424          ["*/", "CLOSE", "CLOSE"],
425          [$pound, 'Sterling', []],
426          [$inf, 'Infinity', []],
427          [$pound_utf8, '1 Pound', '1 Pound (as bytes)'],
428          [$pound_bytes, '1 Pound (as bytes)', []],
429         ) {
430   # Flag an expected error with a reference for the expect string.
431   my ($string, $expect, $expect_bytes) = @$_;
432   (my $name = $string) =~ s/([^ -~])/sprintf '\x{%X}', ord $1/ges;
433   print "# \"$name\" => \'$expect\'\n";
434   # Try to force this to be bytes if possible.
435   utf8::downgrade ($string, 1);
436 EOT
437
438 print FH  "my (\$error, \$got) = ${package}::constant (\$string);\n";
439
440 print FH <<'EOT';
441   if ($error or $got ne $expect) {
442     print "not ok $test # error '$error', got '$got'\n";
443   } else {
444     print "ok $test\n";
445   }
446   $test++;
447   print "# Now upgrade '$name' to utf8\n";
448   utf8::upgrade ($string);
449 EOT
450
451 print FH  "my (\$error, \$got) = ${package}::constant (\$string);\n";
452
453 print FH <<'EOT';
454   if ($error or $got ne $expect) {
455     print "not ok $test # error '$error', got '$got'\n";
456   } else {
457     print "ok $test\n";
458   }
459   $test++;
460   if (defined $expect_bytes) {
461     print "# And now with the utf8 byte sequence for name\n";
462     # Try the encoded bytes.
463     utf8::encode ($string);
464 EOT
465
466 print FH "my (\$error, \$got) = ${package}::constant (\$string);\n";
467
468 print FH <<'EOT';
469     if (ref $expect_bytes) {
470       # Error expected.
471       if ($error) {
472         print "ok $test # error='$error' (as expected)\n";
473       } else {
474         print "not ok $test # expected error, got no error and '$got'\n";
475       }
476     } elsif ($got ne $expect_bytes) {
477       print "not ok $test # error '$error', expect '$expect_bytes', got '$got'\n";
478     } else {
479       print "ok $test\n";
480     }
481     $test++;
482   }
483 }
484 EOT
485
486 close FH or die "close $testpl: $!\n";
487
488 # This is where the test numbers carry on after the test number above are
489 # relayed
490 my $test = 44;
491
492 ################ Makefile.PL
493 # We really need a Makefile.PL because make test for a no dynamic linking perl
494 # will run Makefile.PL again as part of the "make perl" target.
495 my $makefilePL = catfile($dir, "Makefile.PL");
496 push @files, "Makefile.PL";
497 open FH, ">$makefilePL" or die "open >$makefilePL: $!\n";
498 print FH <<"EOT";
499 #!$perl -w
500 use ExtUtils::MakeMaker;
501 WriteMakefile(
502               'NAME'            => "$package",
503               'VERSION_FROM'    => "$package.pm", # finds \$VERSION
504               (\$] >= 5.005 ?
505                (#ABSTRACT_FROM => "$package.pm", # XXX add this
506                 AUTHOR     => "$0") : ())
507              );
508 EOT
509
510 close FH or die "close $makefilePL: $!\n";
511
512 ################ MANIFEST
513 # We really need a MANIFEST because make distclean checks it.
514 my $manifest = catfile($dir, "MANIFEST");
515 push @files, "MANIFEST";
516 open FH, ">$manifest" or die "open >$manifest: $!\n";
517 print FH "$_\n" foreach @files;
518 close FH or die "close $manifest: $!\n";
519
520 chdir $dir or die $!; push @INC,  '../../lib';
521 END {chdir ".." or warn $!};
522
523 my @perlout = `$runperl Makefile.PL PERL_CORE=1`;
524 if ($?) {
525   print "not ok 1 # $runperl Makefile.PL failed: $?\n";
526   print "# $_" foreach @perlout;
527   exit($?);
528 } else {
529   print "ok 1\n";
530 }
531
532
533 my $makefile = ($^O eq 'VMS' ? 'descrip' : 'Makefile');
534 my $makefile_ext = ($^O eq 'VMS' ? '.mms' : '');
535 if (-f "$makefile$makefile_ext") {
536   print "ok 2\n";
537 } else {
538   print "not ok 2\n";
539 }
540
541 # Renamed by make clean
542 my $makefile_rename = $makefile . ($^O eq 'VMS' ? '.mms' : '.old');
543
544 my $make = $Config{make};
545
546 $make = $ENV{MAKE} if exists $ENV{MAKE};
547
548 if ($^O eq 'MSWin32' && $make eq 'nmake') { $make .= " -nologo"; }
549
550 my @makeout;
551
552 if ($^O eq 'VMS') { $make .= ' all'; }
553 print "# make = '$make'\n";
554 @makeout = `$make`;
555 if ($?) {
556   print "not ok 3 # $make failed: $?\n";
557   print "# $_" foreach @makeout;
558   exit($?);
559 } else {
560   print "ok 3\n";
561 }
562
563 if ($^O eq 'VMS') { $make =~ s{ all}{}; }
564
565 if ($Config{usedl}) {
566   print "ok 4\n";
567 } else {
568   my $makeperl = "$make perl";
569   print "# make = '$makeperl'\n";
570   @makeout = `$makeperl`;
571   if ($?) {
572     print "not ok 4 # $makeperl failed: $?\n";
573   print "# $_" foreach @makeout;
574     exit($?);
575   } else {
576     print "ok 4\n";
577   }
578 }
579
580 my $maketest = "$make test";
581 print "# make = '$maketest'\n";
582
583 @makeout = `$maketest`;
584
585 if (open OUTPUT, "<$output") {
586   print while <OUTPUT>;
587   close OUTPUT or print "# Close $output failed: $!\n";
588 } else {
589   # Harness will report missing test results at this point.
590   print "# Open <$output failed: $!\n";
591 }
592
593 if ($?) {
594   print "not ok $test # $maketest failed: $?\n";
595   print "# $_" foreach @makeout;
596 } else {
597   print "ok $test - maketest\n";
598 }
599 $test++;
600
601
602 # -x is busted on Win32 < 5.6.1, so we emulate it.
603 my $regen;
604 if( $^O eq 'MSWin32' && $] <= 5.006001 ) {
605     open(REGENTMP, ">regentmp") or die $!;
606     open(XS, "$package.xs")     or die $!;
607     my $saw_shebang;
608     while(<XS>) {
609         $saw_shebang++ if /^#!.*/i ;
610         print REGENTMP $_ if $saw_shebang;
611     }
612     close XS;  close REGENTMP;
613     $regen = `$runperl regentmp`;
614     unlink 'regentmp';
615 }
616 else {
617     $regen = `$runperl -x $package.xs`;
618 }
619 if ($?) {
620   print "not ok $test # $runperl -x $package.xs failed: $?\n";
621 } else {
622   print "ok $test - regen\n";
623 }
624 $test++;
625
626 my $expect = $constant_types . $C_constant .
627   "\n#### XS Section:\n" . $XS_constant;
628
629 if ($expect eq $regen) {
630   print "ok $test - regen worked\n";
631 } else {
632   print "not ok $test - regen worked\n";
633   # open FOO, ">expect"; print FOO $expect;
634   # open FOO, ">regen"; print FOO $regen; close FOO;
635 }
636 $test++;
637
638 my $makeclean = "$make clean";
639 print "# make = '$makeclean'\n";
640 @makeout = `$makeclean`;
641 if ($?) {
642   print "not ok $test # $make failed: $?\n";
643   print "# $_" foreach @makeout;
644 } else {
645   print "ok $test\n";
646 }
647 $test++;
648
649 sub check_for_bonus_files {
650   my $dir = shift;
651   my %expect = map {($^O eq 'VMS' ? lc($_) : $_), 1} @_;
652
653   my $fail;
654   opendir DIR, $dir or die "opendir '$dir': $!";
655   while (defined (my $entry = readdir DIR)) {
656     $entry =~ s/\.$// if $^O eq 'VMS';  # delete trailing dot that indicates no extension
657     next if $expect{$entry};
658     print "# Extra file '$entry'\n";
659     $fail = 1;
660   }
661
662   closedir DIR or warn "closedir '.': $!";
663   if ($fail) {
664     print "not ok $test\n";
665   } else {
666     print "ok $test\n";
667   }
668   $test++;
669 }
670
671 check_for_bonus_files ('.', @files, $output, $makefile_rename, '.', '..');
672
673 rename $makefile_rename, $makefile
674  or die "Can't rename '$makefile_rename' to '$makefile': $!";
675
676 unlink $output or warn "Can't unlink '$output': $!";
677
678 # Need to make distclean to remove ../../lib/ExtTest.pm
679 my $makedistclean = "$make distclean";
680 print "# make = '$makedistclean'\n";
681 @makeout = `$makedistclean`;
682 if ($?) {
683   print "not ok $test # $make failed: $?\n";
684   print "# $_" foreach @makeout;
685 } else {
686   print "ok $test\n";
687 }
688 $test++;
689
690 check_for_bonus_files ('.', @files, '.', '..');
691
692 unless ($keep_files) {
693   foreach (@files) {
694     unlink $_ or warn "unlink $_: $!";
695   }
696 }
697
698 check_for_bonus_files ('.', '.', '..');