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