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