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