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