xref: /openbsd-src/gnu/usr.bin/perl/cpan/ExtUtils-Constant/t/Constant.t (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1#!/usr/bin/perl -w
2
3use Config;
4unless ($Config{usedl}) {
5    print "1..0 # no usedl, skipping\n";
6    exit 0;
7}
8
9# use warnings;
10use strict;
11use ExtUtils::MakeMaker;
12use ExtUtils::Constant qw (C_constant autoload);
13use File::Spec;
14use Cwd;
15
16my $do_utf_tests = $] > 5.006;
17my $better_than_56 = $] > 5.007;
18# For debugging set this to 1.
19my $keep_files = 0;
20$| = 1;
21
22# Because were are going to be changing directory before running Makefile.PL
23# 5.005 doesn't have new enough File::Spec to have rel2abs. But actually we
24# only need it when $^X isn't absolute, which is going to be 5.8.0 or later
25# (where ExtUtils::Constant is in the core, and tests against the uninstalled
26# perl)
27my $perl = $] < 5.006 ? $^X : File::Spec->rel2abs($^X);
28# ExtUtils::Constant::C_constant uses $^X inside a comment, and we want to
29# compare output to ensure that it is the same. We were probably run as ./perl
30# whereas we will run the child with the full path in $perl. So make $^X for
31# us the same as our child will see.
32$^X = $perl;
33# 5.005 doesn't have rel2abs, but also doesn't need to load an uninstalled
34# module from blib
35@INC = map {File::Spec->rel2abs($_)} @INC if $] < 5.007 && $] >= 5.006;
36
37my $make = $Config{make};
38$make = $ENV{MAKE} if exists $ENV{MAKE};
39if ($^O eq 'MSWin32' && $make eq 'nmake') { $make .= " -nologo"; }
40
41# VMS may be using something other than MMS/MMK
42my $mms_or_mmk = 0;
43my $vms_lc = 0;
44my $vms_nodot = 0;
45if ($^O eq 'VMS') {
46    $mms_or_mmk = 1 if (($make eq 'MMK') || ($make eq 'MMS'));
47    $vms_lc = 1;
48    $vms_nodot = 1;
49    my $vms_unix_rpt = 0;
50    my $vms_efs = 0;
51    my $vms_efs_case = 0;
52    if (eval 'require VMS::Feature') {
53        $vms_unix_rpt = VMS::Feature::current("filename_unix_report");
54        $vms_efs = VMS::Feature::current("efs_case_preserve");
55        $vms_efs_case = VMS::Feature::current("efs_charset");
56    } else {
57        my $unix_rpt = $ENV{'DECC$FILENAME_UNIX_REPORT'} || '';
58        my $efs_charset = $ENV{'DECC$EFS_CHARSET'} || '';
59        my $efs_case = $ENV{'DECC$EFS_CASE_PRESERVE'} || '';
60        $vms_unix_rpt = $unix_rpt =~ /^[ET1]/i;
61        $vms_efs = $efs_charset =~ /^[ET1]/i;
62        $vms_efs_case = $efs_case =~ /^[ET1]/i;
63    }
64    $vms_lc = 0 if $vms_efs_case;
65    $vms_nodot = 0 if $vms_unix_rpt;
66}
67
68# Renamed by make clean
69my $makefile = ($mms_or_mmk ? 'descrip' : 'Makefile');
70my $makefile_ext = ($mms_or_mmk ? '.mms' : '');
71my $makefile_rename = $makefile . ($mms_or_mmk ? '.mms_old' : '.old');
72
73my $output = "output";
74my $package = "ExtTest";
75my $dir = "ext-$$";
76my $subdir = 0;
77# The real test counter.
78my $realtest = 1;
79
80my $orig_cwd = cwd;
81my $updir = File::Spec->updir;
82die "Can't get current directory: $!" unless defined $orig_cwd;
83
84print "# $dir being created...\n";
85mkdir $dir, 0777 or die "mkdir: $!\n";
86
87END {
88  if (defined $orig_cwd and length $orig_cwd) {
89    chdir $orig_cwd or die "Can't chdir back to '$orig_cwd': $!";
90    use File::Path;
91    print "# $dir being removed...\n";
92    rmtree($dir) unless $keep_files;
93  } else {
94    # Can't get here.
95    die "cwd at start was empty, but directory '$dir' was created" if $dir;
96  }
97}
98
99chdir $dir or die $!;
100push @INC, '../../lib', '../../../lib';
101
102package TieOut;
103
104sub TIEHANDLE {
105    my $class = shift;
106    bless(\( my $ref = ''), $class);
107}
108
109sub PRINT {
110    my $self = shift;
111    $$self .= join('', @_);
112}
113
114sub PRINTF {
115    my $self = shift;
116    $$self .= sprintf shift, @_;
117}
118
119sub read {
120    my $self = shift;
121    return substr($$self, 0, length($$self), '');
122}
123
124package main;
125
126sub check_for_bonus_files {
127  my $dir = shift;
128  my %expect = map {($vms_lc ? lc($_) : $_), 1} @_;
129
130  my $fail;
131  opendir DIR, $dir or die "opendir '$dir': $!";
132  while (defined (my $entry = readdir DIR)) {
133    $entry =~ s/\.$// if $vms_nodot;  # delete trailing dot that indicates no extension
134    next if $expect{$entry};
135    print "# Extra file '$entry'\n";
136    $fail = 1;
137  }
138
139  closedir DIR or warn "closedir '.': $!";
140  if ($fail) {
141    print "not ok $realtest\n";
142  } else {
143    print "ok $realtest\n";
144  }
145  $realtest++;
146}
147
148sub build_and_run {
149  my ($tests, $expect, $files) = @_;
150  my $core = $ENV{PERL_CORE} ? ' PERL_CORE=1' : '';
151  my @perlout = `$perl Makefile.PL $core`;
152  if ($?) {
153    print "not ok $realtest # $perl Makefile.PL failed: $?\n";
154    print "# $_" foreach @perlout;
155    exit($?);
156  } else {
157    print "ok $realtest\n";
158  }
159  $realtest++;
160
161  if (-f "$makefile$makefile_ext") {
162    print "ok $realtest\n";
163  } else {
164    print "not ok $realtest\n";
165  }
166  $realtest++;
167
168  my @makeout;
169
170  if ($^O eq 'VMS') { $make .= ' all'; }
171
172  # Sometimes it seems that timestamps can get confused
173
174  # make failed: 256
175  # Makefile out-of-date with respect to Makefile.PL
176  # Cleaning current config before rebuilding Makefile...
177  # make -f Makefile.old clean > /dev/null 2>&1 || /bin/sh -c true
178  # ../../perl "-I../../../lib" "-I../../../lib" Makefile.PL "PERL_CORE=1"
179  # Checking if your kit is complete...
180  # Looks good
181  # Writing Makefile for ExtTest
182  # ==> Your Makefile has been rebuilt. <==
183  # ==> Please rerun the make command.  <==
184  # false
185
186  my $timewarp = (-M "Makefile.PL") - (-M "$makefile$makefile_ext");
187  # Convert from days to seconds
188  $timewarp *= 86400;
189  print "# Makefile.PL is $timewarp second(s) older than $makefile$makefile_ext\n";
190  if ($timewarp < 0) {
191      # Sleep for a while to catch up.
192      $timewarp = -$timewarp;
193      $timewarp+=2;
194      $timewarp = 10 if $timewarp > 10;
195      print "# Sleeping for $timewarp second(s) to try to resolve this\n";
196      sleep $timewarp;
197  }
198
199  print "# make = '$make'\n";
200  @makeout = `$make`;
201  if ($?) {
202    print "not ok $realtest # $make failed: $?\n";
203    print "# $_" foreach @makeout;
204    exit($?);
205  } else {
206    print "ok $realtest\n";
207  }
208  $realtest++;
209
210  if ($^O eq 'VMS') { $make =~ s{ all}{}; }
211
212  if ($Config{usedl}) {
213    print "ok $realtest # This is dynamic linking, so no need to make perl\n";
214  } else {
215    my $makeperl = "$make perl";
216    print "# make = '$makeperl'\n";
217    @makeout = `$makeperl`;
218    if ($?) {
219      print "not ok $realtest # $makeperl failed: $?\n";
220      print "# $_" foreach @makeout;
221      exit($?);
222    } else {
223      print "ok $realtest\n";
224    }
225  }
226  $realtest++;
227
228  my $maketest = "$make test";
229  print "# make = '$maketest'\n";
230
231  @makeout = `$maketest`;
232
233  if (open OUTPUT, "<$output") {
234    local $/; # Slurp it - faster.
235    print <OUTPUT>;
236    close OUTPUT or print "# Close $output failed: $!\n";
237  } else {
238    # Harness will report missing test results at this point.
239    print "# Open <$output failed: $!\n";
240  }
241
242  $realtest += $tests;
243  if ($?) {
244    print "not ok $realtest # $maketest failed: $?\n";
245    print "# $_" foreach @makeout;
246  } else {
247    print "ok $realtest - maketest\n";
248  }
249  $realtest++;
250
251  if (defined $expect) {
252      # -x is busted on Win32 < 5.6.1, so we emulate it.
253      my $regen;
254      if( $^O eq 'MSWin32' && $] <= 5.006001 ) {
255	  open(REGENTMP, ">regentmp") or die $!;
256	  open(XS, "$package.xs")     or die $!;
257	  my $saw_shebang;
258	  while(<XS>) {
259	      $saw_shebang++ if /^#!.*/i ;
260	      print REGENTMP $_ if $saw_shebang;
261	  }
262	  close XS;  close REGENTMP;
263	  $regen = `$perl regentmp`;
264	  unlink 'regentmp';
265      }
266      else {
267	  $regen = `$perl -x $package.xs`;
268      }
269      if ($?) {
270	  print "not ok $realtest # $perl -x $package.xs failed: $?\n";
271	  } else {
272	      print "ok $realtest - regen\n";
273	  }
274      $realtest++;
275
276      if ($expect eq $regen) {
277	  print "ok $realtest - regen worked\n";
278      } else {
279	  print "not ok $realtest - regen worked\n";
280	  # open FOO, ">expect"; print FOO $expect;
281	  # open FOO, ">regen"; print FOO $regen; close FOO;
282      }
283      $realtest++;
284  } else {
285    for (0..1) {
286      print "ok $realtest # skip no regen or expect for this set of tests\n";
287      $realtest++;
288    }
289  }
290
291  my $makeclean = "$make clean";
292  print "# make = '$makeclean'\n";
293  @makeout = `$makeclean`;
294  if ($?) {
295    print "not ok $realtest # $make failed: $?\n";
296    print "# $_" foreach @makeout;
297  } else {
298    print "ok $realtest\n";
299  }
300  $realtest++;
301
302  check_for_bonus_files ('.', @$files, $output, $makefile_rename, '.', '..');
303
304  rename $makefile_rename, $makefile . $makefile_ext
305    or die "Can't rename '$makefile_rename' to '$makefile$makefile_ext': $!";
306
307  unlink $output or warn "Can't unlink '$output': $!";
308
309  # Need to make distclean to remove ../../lib/ExtTest.pm
310  my $makedistclean = "$make distclean";
311  print "# make = '$makedistclean'\n";
312  @makeout = `$makedistclean`;
313  if ($?) {
314    print "not ok $realtest # $make failed: $?\n";
315    print "# $_" foreach @makeout;
316  } else {
317    print "ok $realtest\n";
318  }
319  $realtest++;
320
321  check_for_bonus_files ('.', @$files, '.', '..');
322
323  unless ($keep_files) {
324    foreach (@$files) {
325      unlink $_ or warn "unlink $_: $!";
326    }
327  }
328
329  check_for_bonus_files ('.', '.', '..');
330}
331
332sub Makefile_PL {
333  my $package = shift;
334  ################ Makefile.PL
335  # We really need a Makefile.PL because make test for a no dynamic linking perl
336  # will run Makefile.PL again as part of the "make perl" target.
337  my $makefilePL = "Makefile.PL";
338  open FH, ">$makefilePL" or die "open >$makefilePL: $!\n";
339  print FH <<"EOT";
340#!$perl -w
341use ExtUtils::MakeMaker;
342WriteMakefile(
343              'NAME'		=> "$package",
344              'VERSION_FROM'	=> "$package.pm", # finds \$VERSION
345              (\$] >= 5.005 ?
346               (#ABSTRACT_FROM => "$package.pm", # XXX add this
347                AUTHOR     => "$0") : ())
348             );
349EOT
350
351  close FH or die "close $makefilePL: $!\n";
352  return $makefilePL;
353}
354
355sub MANIFEST {
356  my (@files) = @_;
357  ################ MANIFEST
358  # We really need a MANIFEST because make distclean checks it.
359  my $manifest = "MANIFEST";
360  push @files, $manifest;
361  open FH, ">$manifest" or die "open >$manifest: $!\n";
362  print FH "$_\n" foreach @files;
363  close FH or die "close $manifest: $!\n";
364  return @files;
365}
366
367sub write_and_run_extension {
368  my ($name, $items, $export_names, $package, $header, $testfile, $num_tests,
369      $wc_args) = @_;
370
371  local *C;
372  local *XS;
373
374  my $c = tie *C, 'TieOut';
375  my $xs = tie *XS, 'TieOut';
376
377  ExtUtils::Constant::WriteConstants(C_FH => \*C,
378				     XS_FH => \*XS,
379				     NAME => $package,
380				     NAMES => $items,
381				     @$wc_args,
382				     );
383
384  my $C_code = $c->read();
385  my $XS_code = $xs->read();
386
387  undef $c;
388  undef $xs;
389
390  untie *C;
391  untie *XS;
392
393  # Don't check the regeneration code if we specify extra arguments to
394  # WriteConstants. (Fix this to give finer grained control if needed)
395  my $expect;
396  $expect = $C_code . "\n#### XS Section:\n" . $XS_code unless $wc_args;
397
398  print "# $name\n# $dir/$subdir being created...\n";
399  mkdir $subdir, 0777 or die "mkdir: $!\n";
400  chdir $subdir or die $!;
401
402  my @files;
403
404  ################ Header
405  my $header_name = "test.h";
406  push @files, $header_name;
407  open FH, ">$header_name" or die "open >$header_name: $!\n";
408  print FH $header or die $!;
409  close FH or die "close $header_name: $!\n";
410
411  ################ XS
412  my $xs_name = "$package.xs";
413  push @files, $xs_name;
414  open FH, ">$xs_name" or die "open >$xs_name: $!\n";
415
416  print FH <<"EOT";
417#include "EXTERN.h"
418#include "perl.h"
419#include "XSUB.h"
420#include "$header_name"
421
422
423$C_code
424MODULE = $package		PACKAGE = $package
425PROTOTYPES: ENABLE
426$XS_code;
427EOT
428
429  close FH or die "close $xs: $!\n";
430
431  ################ PM
432  my $pm = "$package.pm";
433  push @files, $pm;
434  open FH, ">$pm" or die "open >$pm: $!\n";
435  print FH "package $package;\n";
436  print FH "use $];\n";
437
438  print FH <<'EOT';
439
440use strict;
441EOT
442  printf FH "use warnings;\n" unless $] < 5.006;
443  print FH <<'EOT';
444use Carp;
445
446require Exporter;
447require DynaLoader;
448use vars qw ($VERSION @ISA @EXPORT_OK $AUTOLOAD);
449
450$VERSION = '0.01';
451@ISA = qw(Exporter DynaLoader);
452EOT
453  # Having this qw( in the here doc confuses cperl mode far too much to be
454  # helpful. And I'm using cperl mode to edit this, even if you're not :-)
455  print FH "\@EXPORT_OK = qw(\n";
456
457  # Print the names of all our autoloaded constants
458  print FH "\t$_\n" foreach (@$export_names);
459  print FH ");\n";
460  # Print the AUTOLOAD subroutine ExtUtils::Constant generated for us
461  print FH autoload ($package, $]);
462  print FH "bootstrap $package \$VERSION;\n1;\n__END__\n";
463  close FH or die "close $pm: $!\n";
464
465  ################ test.pl
466  my $testpl = "test.pl";
467  push @files, $testpl;
468  open FH, ">$testpl" or die "open >$testpl: $!\n";
469  # Standard test header (need an option to suppress this?)
470  print FH <<"EOT" or die $!;
471use strict;
472use $package qw(@$export_names);
473
474print "1..2\n";
475if (open OUTPUT, ">$output") {
476  print "ok 1\n";
477  select OUTPUT;
478} else {
479  print "not ok 1 # Failed to open '$output': \$!\n";
480  exit 1;
481}
482EOT
483  print FH $testfile or die $!;
484  print FH <<"EOT" or die $!;
485select STDOUT;
486if (close OUTPUT) {
487  print "ok 2\n";
488} else {
489  print "not ok 2 # Failed to close '$output': \$!\n";
490}
491EOT
492  close FH or die "close $testpl: $!\n";
493
494  push @files, Makefile_PL($package);
495  @files = MANIFEST (@files);
496
497  build_and_run ($num_tests, $expect, \@files);
498
499  chdir $updir or die "chdir '$updir': $!";
500  ++$subdir;
501}
502
503# Tests are arrayrefs of the form
504# $name, [items], [export_names], $package, $header, $testfile, $num_tests
505my @tests;
506my $before_tests = 4; # Number of "ok"s emitted to build extension
507my $after_tests = 8; # Number of "ok"s emitted after make test run
508my $dummytest = 1;
509
510my $here;
511sub start_tests {
512  $dummytest += $before_tests;
513  $here = $dummytest;
514}
515sub end_tests {
516  my ($name, $items, $export_names, $header, $testfile, $args) = @_;
517  push @tests, [$name, $items, $export_names, $package, $header, $testfile,
518               $dummytest - $here, $args];
519  $dummytest += $after_tests;
520}
521
522my $pound;
523if (ord('A') == 193) {  # EBCDIC platform
524  $pound = chr 177; # A pound sign. (Currency)
525} else { # ASCII platform
526  $pound = chr 163; # A pound sign. (Currency)
527}
528my @common_items = (
529                    {name=>"perl", type=>"PV",},
530                    {name=>"*/", type=>"PV", value=>'"CLOSE"', macro=>1},
531                    {name=>"/*", type=>"PV", value=>'"OPEN"', macro=>1},
532                    {name=>$pound, type=>"PV", value=>'"Sterling"', macro=>1},
533                   );
534
535my @args = undef;
536push @args, [PROXYSUBS => 1] if $] > 5.009002;
537foreach my $args (@args)
538{
539  # Simple tests
540  start_tests();
541  my $parent_rfc1149 =
542    'A Standard for the Transmission of IP Datagrams on Avian Carriers';
543  # Test the code that generates 1 and 2 letter name comparisons.
544  my %compass = (
545                 N => 0, 'NE' => 45, E => 90, SE => 135,
546                 S => 180, SW => 225, W => 270, NW => 315
547                );
548
549  my $header = << "EOT";
550#define FIVE 5
551#define OK6 "ok 6\\n"
552#define OK7 1
553#define FARTHING 0.25
554#define NOT_ZERO 1
555#define Yes 0
556#define No 1
557#define Undef 1
558#define RFC1149 "$parent_rfc1149"
559#undef NOTDEF
560#define perl "rules"
561EOT
562
563  while (my ($point, $bearing) = each %compass) {
564    $header .= "#define $point $bearing\n"
565  }
566
567  my @items = ("FIVE", {name=>"OK6", type=>"PV",},
568               {name=>"OK7", type=>"PVN",
569                value=>['"not ok 7\\n\\0ok 7\\n"', 15]},
570               {name => "FARTHING", type=>"NV"},
571               {name => "NOT_ZERO", type=>"UV", value=>"~(UV)0"},
572               {name => "OPEN", type=>"PV", value=>'"/*"', macro=>1},
573               {name => "CLOSE", type=>"PV", value=>'"*/"',
574                macro=>["#if 1\n", "#endif\n"]},
575               {name => "ANSWER", default=>["UV", 42]}, "NOTDEF",
576               {name => "Yes", type=>"YES"},
577               {name => "No", type=>"NO"},
578               {name => "Undef", type=>"UNDEF"},
579  # OK. It wasn't really designed to allow the creation of dual valued
580  # constants.
581  # It was more for INADDR_ANY INADDR_BROADCAST INADDR_LOOPBACK INADDR_NONE
582               {name=>"RFC1149", type=>"SV", value=>"sv_2mortal(temp_sv)",
583                pre=>"SV *temp_sv = newSVpv(RFC1149, 0); "
584                . "(void) SvUPGRADE(temp_sv,SVt_PVIV); SvIOK_on(temp_sv); "
585                . "SvIV_set(temp_sv, 1149);"},
586              );
587
588  push @items, $_ foreach keys %compass;
589
590  # Automatically compile the list of all the macro names, and make them
591  # exported constants.
592  my @export_names = map {(ref $_) ? $_->{name} : $_} @items;
593
594  # Exporter::Heavy (currently) isn't able to export the last 3 of these:
595  push @items, @common_items;
596
597  my $test_body = <<"EOT";
598
599my \$test = $dummytest;
600
601EOT
602
603  $test_body .= <<'EOT';
604# What follows goes to the temporary file.
605# IV
606my $five = FIVE;
607if ($five == 5) {
608  print "ok $test\n";
609} else {
610  print "not ok $test # \$five\n";
611}
612$test++;
613
614# PV
615if (OK6 eq "ok 6\n") {
616  print "ok $test\n";
617} else {
618  print "not ok $test # \$five\n";
619}
620$test++;
621
622# PVN containing embedded \0s
623$_ = OK7;
624s/.*\0//s;
625s/7/$test/;
626$test++;
627print;
628
629# NV
630my $farthing = FARTHING;
631if ($farthing == 0.25) {
632  print "ok $test\n";
633} else {
634  print "not ok $test # $farthing\n";
635}
636$test++;
637
638EOT
639
640  my $cond;
641  if ($] >= 5.006 || $Config{longsize} < 8) {
642    $cond = '$not_zero > 0 && $not_zero == ~0';
643  } else {
644    $cond = q{pack 'Q', $not_zero eq ~pack 'Q', 0};
645  }
646
647  $test_body .= sprintf <<'EOT', $cond;
648# UV
649my $not_zero = NOT_ZERO;
650if (%s) {
651  print "ok $test\n";
652} else {
653  print "not ok $test # \$not_zero=$not_zero ~0=" . (~0) . "\n";
654}
655$test++;
656
657EOT
658
659  $test_body .= <<'EOT';
660
661# Value includes a "*/" in an attempt to bust out of a C comment.
662# Also tests custom cpp #if clauses
663my $close = CLOSE;
664if ($close eq '*/') {
665  print "ok $test\n";
666} else {
667  print "not ok $test # \$close='$close'\n";
668}
669$test++;
670
671# Default values if macro not defined.
672my $answer = ANSWER;
673if ($answer == 42) {
674  print "ok $test\n";
675} else {
676  print "not ok $test # What do you get if you multiply six by nine? '$answer'\n";
677}
678$test++;
679
680# not defined macro
681my $notdef = eval { NOTDEF; };
682if (defined $notdef) {
683  print "not ok $test # \$notdef='$notdef'\n";
684} elsif ($@ !~ /Your vendor has not defined ExtTest macro NOTDEF/) {
685  print "not ok $test # \$@='$@'\n";
686} else {
687  print "ok $test\n";
688}
689$test++;
690
691# not a macro
692my $notthere = eval { &ExtTest::NOTTHERE; };
693if (defined $notthere) {
694  print "not ok $test # \$notthere='$notthere'\n";
695} elsif ($@ !~ /NOTTHERE is not a valid ExtTest macro/) {
696  chomp $@;
697  print "not ok $test # \$@='$@'\n";
698} else {
699  print "ok $test\n";
700}
701$test++;
702
703# Truth
704my $yes = Yes;
705if ($yes) {
706  print "ok $test\n";
707} else {
708  print "not ok $test # $yes='\$yes'\n";
709}
710$test++;
711
712# Falsehood
713my $no = No;
714if (defined $no and !$no) {
715  print "ok $test\n";
716} else {
717  print "not ok $test # \$no=" . defined ($no) ? "'$no'\n" : "undef\n";
718}
719$test++;
720
721# Undef
722my $undef = Undef;
723unless (defined $undef) {
724  print "ok $test\n";
725} else {
726  print "not ok $test # \$undef='$undef'\n";
727}
728$test++;
729
730# invalid macro (chosen to look like a mix up between No and SW)
731$notdef = eval { &ExtTest::So };
732if (defined $notdef) {
733  print "not ok $test # \$notdef='$notdef'\n";
734} elsif ($@ !~ /^So is not a valid ExtTest macro/) {
735  print "not ok $test # \$@='$@'\n";
736} else {
737  print "ok $test\n";
738}
739$test++;
740
741# invalid defined macro
742$notdef = eval { &ExtTest::EW };
743if (defined $notdef) {
744  print "not ok $test # \$notdef='$notdef'\n";
745} elsif ($@ !~ /^EW is not a valid ExtTest macro/) {
746  print "not ok $test # \$@='$@'\n";
747} else {
748  print "ok $test\n";
749}
750$test++;
751
752my %compass = (
753EOT
754
755while (my ($point, $bearing) = each %compass) {
756  $test_body .= "'$point' => $bearing, "
757}
758
759$test_body .= <<'EOT';
760
761);
762
763my $fail;
764while (my ($point, $bearing) = each %compass) {
765  my $val = eval $point;
766  if ($@) {
767    print "# $point: \$@='$@'\n";
768    $fail = 1;
769  } elsif (!defined $bearing) {
770    print "# $point: \$val=undef\n";
771    $fail = 1;
772  } elsif ($val != $bearing) {
773    print "# $point: \$val=$val, not $bearing\n";
774    $fail = 1;
775  }
776}
777if ($fail) {
778  print "not ok $test\n";
779} else {
780  print "ok $test\n";
781}
782$test++;
783
784EOT
785
786$test_body .= <<"EOT";
787my \$rfc1149 = RFC1149;
788if (\$rfc1149 ne "$parent_rfc1149") {
789  print "not ok \$test # '\$rfc1149' ne '$parent_rfc1149'\n";
790} else {
791  print "ok \$test\n";
792}
793\$test++;
794
795if (\$rfc1149 != 1149) {
796  printf "not ok \$test # %d != 1149\n", \$rfc1149;
797} else {
798  print "ok \$test\n";
799}
800\$test++;
801
802EOT
803
804$test_body .= <<'EOT';
805# test macro=>1
806my $open = OPEN;
807if ($open eq '/*') {
808  print "ok $test\n";
809} else {
810  print "not ok $test # \$open='$open'\n";
811}
812$test++;
813EOT
814$dummytest+=18;
815
816  end_tests("Simple tests", \@items, \@export_names, $header, $test_body,
817	    $args);
818}
819
820if ($do_utf_tests) {
821  # utf8 tests
822  start_tests();
823  my ($inf, $pound_bytes, $pound_utf8);
824
825  $inf = chr 0x221E;
826  # Check that we can distiguish the pathological case of a string, and the
827  # utf8 representation of that string.
828  $pound_utf8 = $pound . '1';
829  if ($better_than_56) {
830    $pound_bytes = $pound_utf8;
831    utf8::encode ($pound_bytes);
832  } else {
833    # Must have that "U*" to generate a zero length UTF string that forces
834    # top bit set chars (such as the pound sign) into UTF8, so that the
835    # unpack 'C*' then gets the byte form of the UTF8.
836    $pound_bytes =  pack 'C*', unpack 'C*', $pound_utf8 . pack "U*";
837  }
838
839  my @items = (@common_items,
840               {name=>$inf, type=>"PV", value=>'"Infinity"', macro=>1},
841               {name=>$pound_utf8, type=>"PV", value=>'"1 Pound"', macro=>1},
842               {name=>$pound_bytes, type=>"PV", value=>'"1 Pound (as bytes)"',
843                macro=>1},
844              );
845
846=pod
847
848The above set of names seems to produce a suitably bad set of compile
849problems on a Unicode naive version of ExtUtils::Constant (ie 0.11):
850
851nick@thinking-cap 15439-32-utf$ PERL_CORE=1 ./perl lib/ExtUtils/t/Constant.t
8521..33
853# perl=/stuff/perl5/15439-32-utf/perl
854# ext-30370 being created...
855Wide character in print at lib/ExtUtils/t/Constant.t line 140.
856ok 1
857ok 2
858# make = 'make'
859ExtTest.xs: In function `constant_1':
860ExtTest.xs:80: warning: multi-character character constant
861ExtTest.xs:80: warning: case value out of range
862ok 3
863
864=cut
865
866# Grr `
867
868  # Do this in 7 bit in case someone is testing with some settings that cause
869  # 8 bit files incapable of storing this character.
870  my @values
871    = map {"'" . join (",", unpack "U*", $_ . pack "U*") . "'"}
872      ($pound, $inf, $pound_bytes, $pound_utf8);
873  # Values is a list of strings, such as ('194,163,49', '163,49')
874
875  my $test_body .= "my \$test = $dummytest;\n";
876  $dummytest += 7 * 3; # 3 tests for each of the 7 things:
877
878  $test_body .= << 'EOT';
879
880use utf8;
881my $better_than_56 = $] > 5.007;
882
883my ($pound, $inf, $pound_bytes, $pound_utf8) = map {eval "pack 'U*', $_"}
884EOT
885
886  $test_body .= join ",", @values;
887
888  $test_body .= << 'EOT';
889;
890
891foreach (["perl", "rules", "rules"],
892	 ["/*", "OPEN", "OPEN"],
893	 ["*/", "CLOSE", "CLOSE"],
894	 [$pound, 'Sterling', []],
895         [$inf, 'Infinity', []],
896	 [$pound_utf8, '1 Pound', '1 Pound (as bytes)'],
897	 [$pound_bytes, '1 Pound (as bytes)', []],
898        ) {
899  # Flag an expected error with a reference for the expect string.
900  my ($string, $expect, $expect_bytes) = @$_;
901  (my $name = $string) =~ s/([^ !"#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~])/sprintf '\x{%X}', ord $1/ges;
902  print "# \"$name\" => \'$expect\'\n";
903  # Try to force this to be bytes if possible.
904  if ($better_than_56) {
905    utf8::downgrade ($string, 1);
906  } else {
907    if ($string =~ tr/0-\377// == length $string) {
908      # No chars outside range 0-255
909      $string = pack 'C*', unpack 'U*', ($string . pack 'U*');
910    }
911  }
912EOT
913
914  $test_body .=  "my (\$error, \$got) = ${package}::constant (\$string);\n";
915
916  $test_body .= <<'EOT';
917  if ($error or $got ne $expect) {
918    print "not ok $test # error '$error', got '$got'\n";
919  } else {
920    print "ok $test\n";
921  }
922  $test++;
923  print "# Now upgrade '$name' to utf8\n";
924  if ($better_than_56) {
925    utf8::upgrade ($string);
926  } else {
927    $string = pack ('U*') . $string;
928  }
929EOT
930
931  $test_body .=  "my (\$error, \$got) = ${package}::constant (\$string);\n";
932
933  $test_body .= <<'EOT';
934  if ($error or $got ne $expect) {
935    print "not ok $test # error '$error', got '$got'\n";
936  } else {
937    print "ok $test\n";
938  }
939  $test++;
940  if (defined $expect_bytes) {
941    print "# And now with the utf8 byte sequence for name\n";
942    # Try the encoded bytes.
943    if ($better_than_56) {
944      utf8::encode ($string);
945    } else {
946      $string = pack 'C*', unpack 'C*', $string . pack "U*";
947    }
948EOT
949
950    $test_body .= "my (\$error, \$got) = ${package}::constant (\$string);\n";
951
952    $test_body .= <<'EOT';
953    if (ref $expect_bytes) {
954      # Error expected.
955      if ($error) {
956        print "ok $test # error='$error' (as expected)\n";
957      } else {
958        print "not ok $test # expected error, got no error and '$got'\n";
959      }
960    } elsif ($got ne $expect_bytes) {
961      print "not ok $test # error '$error', expect '$expect_bytes', got '$got'\n";
962    } else {
963      print "ok $test\n";
964    }
965    $test++;
966  }
967}
968EOT
969
970  end_tests("utf8 tests", \@items, [], "#define perl \"rules\"\n", $test_body);
971}
972
973# XXX I think that I should merge this into the utf8 test above.
974sub explict_call_constant {
975  my ($string, $expect) = @_;
976  # This does assume simple strings suitable for ''
977  my $test_body = <<"EOT";
978{
979  my (\$error, \$got) = ${package}::constant ('$string');\n;
980EOT
981
982  if (defined $expect) {
983    # No error expected
984    $test_body .= <<"EOT";
985  if (\$error or \$got ne "$expect") {
986    print "not ok $dummytest # error '\$error', expect '$expect', got '\$got'\n";
987  } else {
988    print "ok $dummytest\n";
989    }
990  }
991EOT
992  } else {
993    # Error expected.
994    $test_body .= <<"EOT";
995  if (\$error) {
996    print "ok $dummytest # error='\$error' (as expected)\n";
997  } else {
998    print "not ok $dummytest # expected error, got no error and '\$got'\n";
999  }
1000EOT
1001  }
1002  $dummytest++;
1003  return $test_body . <<'EOT';
1004}
1005EOT
1006}
1007
1008# Simple tests to verify bits of the switch generation system work.
1009sub simple {
1010  start_tests();
1011  # Deliberately leave $name in @_, so that it is indexed from 1.
1012  my ($name, @items) = @_;
1013  my $test_header;
1014  my $test_body = "my \$value;\n";
1015  foreach my $counter (1 .. $#_) {
1016    my $thisname = $_[$counter];
1017    $test_header .= "#define $thisname $counter\n";
1018    $test_body .= <<"EOT";
1019\$value = $thisname;
1020if (\$value == $counter) {
1021  print "ok $dummytest\n";
1022} else {
1023  print "not ok $dummytest # $thisname gave \$value\n";
1024}
1025EOT
1026    ++$dummytest;
1027    # Yes, the last time round the loop appends a z to the string.
1028    for my $i (0 .. length $thisname) {
1029      my $copyname = $thisname;
1030      substr ($copyname, $i, 1) = 'z';
1031      $test_body .= explict_call_constant ($copyname,
1032                                           $copyname eq $thisname
1033                                             ? $thisname : undef);
1034    }
1035  }
1036  # Ho. This seems to be buggy in 5.005_03:
1037  # # Now remove $name from @_:
1038  # shift @_;
1039  end_tests($name, \@items, \@items, $test_header, $test_body);
1040}
1041
1042# Check that the memeq clauses work correctly when there isn't a switch
1043# statement to bump off a character
1044simple ("Singletons", "A", "AB", "ABC", "ABCD", "ABCDE");
1045# Check the three code.
1046simple ("Three start", qw(Bea kea Lea lea nea pea rea sea tea Wea yea Zea));
1047# There were 162 2 letter words in /usr/share/dict/words on FreeBSD 4.6, which
1048# I felt was rather too many. So I used words with 2 vowels.
1049simple ("Twos and three middle", qw(aa ae ai ea eu ie io oe era eta));
1050# Given the choice go for the end, else the earliest point
1051simple ("Three end and four symetry", qw(ean ear eat barb marm tart));
1052
1053
1054# Need this if the single test below is rolled into @tests :
1055# --$dummytest;
1056print "1..$dummytest\n";
1057
1058write_and_run_extension @$_ foreach @tests;
1059
1060# This was causing an assertion failure (a C<confess>ion)
1061# Any single byte > 128 should do it.
1062C_constant ($package, undef, undef, undef, undef, undef, chr 255);
1063print "ok $realtest\n"; $realtest++;
1064
1065print STDERR "# You were running with \$keep_files set to $keep_files\n"
1066  if $keep_files;
1067