1*0Sstevel@tonic-gate#!./perl 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gate## 4*0Sstevel@tonic-gate## Many of these tests are originally from Michael Schroeder 5*0Sstevel@tonic-gate## <Michael.Schroeder@informatik.uni-erlangen.de> 6*0Sstevel@tonic-gate## Adapted and expanded by Gurusamy Sarathy <gsar@activestate.com> 7*0Sstevel@tonic-gate## 8*0Sstevel@tonic-gate 9*0Sstevel@tonic-gatechdir 't' if -d 't'; 10*0Sstevel@tonic-gate@INC = '../lib'; 11*0Sstevel@tonic-gate$Is_VMS = $^O eq 'VMS'; 12*0Sstevel@tonic-gate$Is_MSWin32 = $^O eq 'MSWin32'; 13*0Sstevel@tonic-gate$Is_NetWare = $^O eq 'NetWare'; 14*0Sstevel@tonic-gate$Is_MacOS = $^O eq 'MacOS'; 15*0Sstevel@tonic-gate$ENV{PERL5LIB} = "../lib" unless $Is_VMS; 16*0Sstevel@tonic-gate 17*0Sstevel@tonic-gate$|=1; 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gateundef $/; 20*0Sstevel@tonic-gate@prgs = split "\n########\n", <DATA>; 21*0Sstevel@tonic-gateprint "1..", scalar @prgs, "\n"; 22*0Sstevel@tonic-gate 23*0Sstevel@tonic-gate$tmpfile = "runltmp000"; 24*0Sstevel@tonic-gate1 while -f ++$tmpfile; 25*0Sstevel@tonic-gateEND { if ($tmpfile) { 1 while unlink $tmpfile; } } 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gatefor (@prgs){ 28*0Sstevel@tonic-gate my $switch = ""; 29*0Sstevel@tonic-gate if (s/^\s*(-\w+)//){ 30*0Sstevel@tonic-gate $switch = $1; 31*0Sstevel@tonic-gate } 32*0Sstevel@tonic-gate my($prog,$expected) = split(/\nEXPECT\n/, $_); 33*0Sstevel@tonic-gate open TEST, ">$tmpfile"; 34*0Sstevel@tonic-gate print TEST "$prog\n"; 35*0Sstevel@tonic-gate close TEST or die "Could not close: $!"; 36*0Sstevel@tonic-gate my $results = $Is_VMS ? 37*0Sstevel@tonic-gate `MCR $^X "-I[-.lib]" $switch $tmpfile 2>&1` : 38*0Sstevel@tonic-gate $Is_MSWin32 ? 39*0Sstevel@tonic-gate `.\\perl -I../lib $switch $tmpfile 2>&1` : 40*0Sstevel@tonic-gate $Is_NetWare ? 41*0Sstevel@tonic-gate `perl -I../lib $switch $tmpfile 2>&1` : 42*0Sstevel@tonic-gate $Is_MacOS ? 43*0Sstevel@tonic-gate `$^X -I::lib -MMac::err=unix $switch $tmpfile` : 44*0Sstevel@tonic-gate `./perl $switch $tmpfile 2>&1`; 45*0Sstevel@tonic-gate my $status = $?; 46*0Sstevel@tonic-gate $results =~ s/\n+$//; 47*0Sstevel@tonic-gate # allow expected output to be written as if $prog is on STDIN 48*0Sstevel@tonic-gate $results =~ s/runltmp\d+/-/g; 49*0Sstevel@tonic-gate $results =~ s/\n%[A-Z]+-[SIWEF]-.*$// if $Is_VMS; # clip off DCL status msg 50*0Sstevel@tonic-gate $expected =~ s/\n+$//; 51*0Sstevel@tonic-gate if ($results ne $expected) { 52*0Sstevel@tonic-gate print STDERR "PROG: $switch\n$prog\n"; 53*0Sstevel@tonic-gate print STDERR "EXPECTED:\n$expected\n"; 54*0Sstevel@tonic-gate print STDERR "GOT:\n$results\n"; 55*0Sstevel@tonic-gate print "not "; 56*0Sstevel@tonic-gate } 57*0Sstevel@tonic-gate print "ok ", ++$i, "\n"; 58*0Sstevel@tonic-gate} 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate__END__ 61*0Sstevel@tonic-gate@a = (1, 2, 3); 62*0Sstevel@tonic-gate{ 63*0Sstevel@tonic-gate @a = sort { last ; } @a; 64*0Sstevel@tonic-gate} 65*0Sstevel@tonic-gateEXPECT 66*0Sstevel@tonic-gateCan't "last" outside a loop block at - line 3. 67*0Sstevel@tonic-gate######## 68*0Sstevel@tonic-gatepackage TEST; 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gatesub TIESCALAR { 71*0Sstevel@tonic-gate my $foo; 72*0Sstevel@tonic-gate return bless \$foo; 73*0Sstevel@tonic-gate} 74*0Sstevel@tonic-gatesub FETCH { 75*0Sstevel@tonic-gate eval 'die("test")'; 76*0Sstevel@tonic-gate print "still in fetch\n"; 77*0Sstevel@tonic-gate return ">$@<"; 78*0Sstevel@tonic-gate} 79*0Sstevel@tonic-gatepackage main; 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gatetie $bar, TEST; 82*0Sstevel@tonic-gateprint "- $bar\n"; 83*0Sstevel@tonic-gateEXPECT 84*0Sstevel@tonic-gatestill in fetch 85*0Sstevel@tonic-gate- >test at (eval 1) line 1. 86*0Sstevel@tonic-gate< 87*0Sstevel@tonic-gate######## 88*0Sstevel@tonic-gatepackage TEST; 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gatesub TIESCALAR { 91*0Sstevel@tonic-gate my $foo; 92*0Sstevel@tonic-gate eval('die("foo\n")'); 93*0Sstevel@tonic-gate print "after eval\n"; 94*0Sstevel@tonic-gate return bless \$foo; 95*0Sstevel@tonic-gate} 96*0Sstevel@tonic-gatesub FETCH { 97*0Sstevel@tonic-gate return "ZZZ"; 98*0Sstevel@tonic-gate} 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gatepackage main; 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gatetie $bar, TEST; 103*0Sstevel@tonic-gateprint "- $bar\n"; 104*0Sstevel@tonic-gateprint "OK\n"; 105*0Sstevel@tonic-gateEXPECT 106*0Sstevel@tonic-gateafter eval 107*0Sstevel@tonic-gate- ZZZ 108*0Sstevel@tonic-gateOK 109*0Sstevel@tonic-gate######## 110*0Sstevel@tonic-gatepackage TEST; 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gatesub TIEHANDLE { 113*0Sstevel@tonic-gate my $foo; 114*0Sstevel@tonic-gate return bless \$foo; 115*0Sstevel@tonic-gate} 116*0Sstevel@tonic-gatesub PRINT { 117*0Sstevel@tonic-gateprint STDERR "PRINT CALLED\n"; 118*0Sstevel@tonic-gate(split(/./, 'x'x10000))[0]; 119*0Sstevel@tonic-gateeval('die("test\n")'); 120*0Sstevel@tonic-gate} 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gatepackage main; 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gateopen FH, ">&STDOUT"; 125*0Sstevel@tonic-gatetie *FH, TEST; 126*0Sstevel@tonic-gateprint FH "OK\n"; 127*0Sstevel@tonic-gateprint STDERR "DONE\n"; 128*0Sstevel@tonic-gateEXPECT 129*0Sstevel@tonic-gatePRINT CALLED 130*0Sstevel@tonic-gateDONE 131*0Sstevel@tonic-gate######## 132*0Sstevel@tonic-gatesub warnhook { 133*0Sstevel@tonic-gate print "WARNHOOK\n"; 134*0Sstevel@tonic-gate eval('die("foooo\n")'); 135*0Sstevel@tonic-gate} 136*0Sstevel@tonic-gate$SIG{'__WARN__'} = 'warnhook'; 137*0Sstevel@tonic-gatewarn("dfsds\n"); 138*0Sstevel@tonic-gateprint "END\n"; 139*0Sstevel@tonic-gateEXPECT 140*0Sstevel@tonic-gateWARNHOOK 141*0Sstevel@tonic-gateEND 142*0Sstevel@tonic-gate######## 143*0Sstevel@tonic-gatepackage TEST; 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gateuse overload 146*0Sstevel@tonic-gate "\"\"" => \&str 147*0Sstevel@tonic-gate; 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gatesub str { 150*0Sstevel@tonic-gate eval('die("test\n")'); 151*0Sstevel@tonic-gate return "STR"; 152*0Sstevel@tonic-gate} 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gatepackage main; 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate$bar = bless {}, TEST; 157*0Sstevel@tonic-gateprint "$bar\n"; 158*0Sstevel@tonic-gateprint "OK\n"; 159*0Sstevel@tonic-gateEXPECT 160*0Sstevel@tonic-gateSTR 161*0Sstevel@tonic-gateOK 162*0Sstevel@tonic-gate######## 163*0Sstevel@tonic-gatesub foo { 164*0Sstevel@tonic-gate $a <=> $b unless eval('$a == 0 ? bless undef : ($a <=> $b)'); 165*0Sstevel@tonic-gate} 166*0Sstevel@tonic-gate@a = (3, 2, 0, 1); 167*0Sstevel@tonic-gate@a = sort foo @a; 168*0Sstevel@tonic-gateprint join(', ', @a)."\n"; 169*0Sstevel@tonic-gateEXPECT 170*0Sstevel@tonic-gate0, 1, 2, 3 171*0Sstevel@tonic-gate######## 172*0Sstevel@tonic-gatesub foo { 173*0Sstevel@tonic-gate goto bar if $a == 0 || $b == 0; 174*0Sstevel@tonic-gate $a <=> $b; 175*0Sstevel@tonic-gate} 176*0Sstevel@tonic-gate@a = (3, 2, 0, 1); 177*0Sstevel@tonic-gate@a = sort foo @a; 178*0Sstevel@tonic-gateprint join(', ', @a)."\n"; 179*0Sstevel@tonic-gateexit; 180*0Sstevel@tonic-gatebar: 181*0Sstevel@tonic-gateprint "bar reached\n"; 182*0Sstevel@tonic-gateEXPECT 183*0Sstevel@tonic-gateCan't "goto" out of a pseudo block at - line 2. 184*0Sstevel@tonic-gate######## 185*0Sstevel@tonic-gate%seen = (); 186*0Sstevel@tonic-gatesub sortfn { 187*0Sstevel@tonic-gate (split(/./, 'x'x10000))[0]; 188*0Sstevel@tonic-gate my (@y) = ( 4, 6, 5); 189*0Sstevel@tonic-gate @y = sort { $a <=> $b } @y; 190*0Sstevel@tonic-gate my $t = "sortfn ".join(', ', @y)."\n"; 191*0Sstevel@tonic-gate print $t if ($seen{$t}++ == 0); 192*0Sstevel@tonic-gate return $_[0] <=> $_[1]; 193*0Sstevel@tonic-gate} 194*0Sstevel@tonic-gate@x = ( 3, 2, 1 ); 195*0Sstevel@tonic-gate@x = sort { &sortfn($a, $b) } @x; 196*0Sstevel@tonic-gateprint "---- ".join(', ', @x)."\n"; 197*0Sstevel@tonic-gateEXPECT 198*0Sstevel@tonic-gatesortfn 4, 5, 6 199*0Sstevel@tonic-gate---- 1, 2, 3 200*0Sstevel@tonic-gate######## 201*0Sstevel@tonic-gate@a = (3, 2, 1); 202*0Sstevel@tonic-gate@a = sort { eval('die("no way")') , $a <=> $b} @a; 203*0Sstevel@tonic-gateprint join(", ", @a)."\n"; 204*0Sstevel@tonic-gateEXPECT 205*0Sstevel@tonic-gate1, 2, 3 206*0Sstevel@tonic-gate######## 207*0Sstevel@tonic-gate@a = (1, 2, 3); 208*0Sstevel@tonic-gatefoo: 209*0Sstevel@tonic-gate{ 210*0Sstevel@tonic-gate @a = sort { last foo; } @a; 211*0Sstevel@tonic-gate} 212*0Sstevel@tonic-gateEXPECT 213*0Sstevel@tonic-gateLabel not found for "last foo" at - line 2. 214*0Sstevel@tonic-gate######## 215*0Sstevel@tonic-gatepackage TEST; 216*0Sstevel@tonic-gate 217*0Sstevel@tonic-gatesub TIESCALAR { 218*0Sstevel@tonic-gate my $foo; 219*0Sstevel@tonic-gate return bless \$foo; 220*0Sstevel@tonic-gate} 221*0Sstevel@tonic-gatesub FETCH { 222*0Sstevel@tonic-gate next; 223*0Sstevel@tonic-gate return "ZZZ"; 224*0Sstevel@tonic-gate} 225*0Sstevel@tonic-gatesub STORE { 226*0Sstevel@tonic-gate} 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gatepackage main; 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gatetie $bar, TEST; 231*0Sstevel@tonic-gate{ 232*0Sstevel@tonic-gate print "- $bar\n"; 233*0Sstevel@tonic-gate} 234*0Sstevel@tonic-gateprint "OK\n"; 235*0Sstevel@tonic-gateEXPECT 236*0Sstevel@tonic-gateCan't "next" outside a loop block at - line 8. 237*0Sstevel@tonic-gate######## 238*0Sstevel@tonic-gatepackage TEST; 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gatesub TIESCALAR { 241*0Sstevel@tonic-gate my $foo; 242*0Sstevel@tonic-gate return bless \$foo; 243*0Sstevel@tonic-gate} 244*0Sstevel@tonic-gatesub FETCH { 245*0Sstevel@tonic-gate goto bbb; 246*0Sstevel@tonic-gate return "ZZZ"; 247*0Sstevel@tonic-gate} 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gatepackage main; 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gatetie $bar, TEST; 252*0Sstevel@tonic-gateprint "- $bar\n"; 253*0Sstevel@tonic-gateexit; 254*0Sstevel@tonic-gatebbb: 255*0Sstevel@tonic-gateprint "bbb\n"; 256*0Sstevel@tonic-gateEXPECT 257*0Sstevel@tonic-gateCan't find label bbb at - line 8. 258*0Sstevel@tonic-gate######## 259*0Sstevel@tonic-gatesub foo { 260*0Sstevel@tonic-gate $a <=> $b unless eval('$a == 0 ? die("foo\n") : ($a <=> $b)'); 261*0Sstevel@tonic-gate} 262*0Sstevel@tonic-gate@a = (3, 2, 0, 1); 263*0Sstevel@tonic-gate@a = sort foo @a; 264*0Sstevel@tonic-gateprint join(', ', @a)."\n"; 265*0Sstevel@tonic-gateEXPECT 266*0Sstevel@tonic-gate0, 1, 2, 3 267*0Sstevel@tonic-gate######## 268*0Sstevel@tonic-gatepackage TEST; 269*0Sstevel@tonic-gatesub TIESCALAR { 270*0Sstevel@tonic-gate my $foo; 271*0Sstevel@tonic-gate return bless \$foo; 272*0Sstevel@tonic-gate} 273*0Sstevel@tonic-gatesub FETCH { 274*0Sstevel@tonic-gate return "fetch"; 275*0Sstevel@tonic-gate} 276*0Sstevel@tonic-gatesub STORE { 277*0Sstevel@tonic-gate(split(/./, 'x'x10000))[0]; 278*0Sstevel@tonic-gate} 279*0Sstevel@tonic-gatepackage main; 280*0Sstevel@tonic-gatetie $bar, TEST; 281*0Sstevel@tonic-gate$bar = "x"; 282*0Sstevel@tonic-gate######## 283*0Sstevel@tonic-gatepackage TEST; 284*0Sstevel@tonic-gatesub TIESCALAR { 285*0Sstevel@tonic-gate my $foo; 286*0Sstevel@tonic-gate next; 287*0Sstevel@tonic-gate return bless \$foo; 288*0Sstevel@tonic-gate} 289*0Sstevel@tonic-gatepackage main; 290*0Sstevel@tonic-gate{ 291*0Sstevel@tonic-gatetie $bar, TEST; 292*0Sstevel@tonic-gate} 293*0Sstevel@tonic-gateEXPECT 294*0Sstevel@tonic-gateCan't "next" outside a loop block at - line 4. 295*0Sstevel@tonic-gate######## 296*0Sstevel@tonic-gate@a = (1, 2, 3); 297*0Sstevel@tonic-gatefoo: 298*0Sstevel@tonic-gate{ 299*0Sstevel@tonic-gate @a = sort { exit(0) } @a; 300*0Sstevel@tonic-gate} 301*0Sstevel@tonic-gateEND { print "foobar\n" } 302*0Sstevel@tonic-gateEXPECT 303*0Sstevel@tonic-gatefoobar 304*0Sstevel@tonic-gate######## 305*0Sstevel@tonic-gate$SIG{__DIE__} = sub { 306*0Sstevel@tonic-gate print "In DIE\n"; 307*0Sstevel@tonic-gate $i = 0; 308*0Sstevel@tonic-gate while (($p,$f,$l,$s) = caller(++$i)) { 309*0Sstevel@tonic-gate print "$p|$f|$l|$s\n"; 310*0Sstevel@tonic-gate } 311*0Sstevel@tonic-gate}; 312*0Sstevel@tonic-gateeval { die }; 313*0Sstevel@tonic-gate&{sub { eval 'die' }}(); 314*0Sstevel@tonic-gatesub foo { eval { die } } foo(); 315*0Sstevel@tonic-gate{package rmb; sub{ eval{die} } ->() }; # check __ANON__ knows package 316*0Sstevel@tonic-gateEXPECT 317*0Sstevel@tonic-gateIn DIE 318*0Sstevel@tonic-gatemain|-|8|(eval) 319*0Sstevel@tonic-gateIn DIE 320*0Sstevel@tonic-gatemain|-|9|(eval) 321*0Sstevel@tonic-gatemain|-|9|main::__ANON__ 322*0Sstevel@tonic-gateIn DIE 323*0Sstevel@tonic-gatemain|-|10|(eval) 324*0Sstevel@tonic-gatemain|-|10|main::foo 325*0Sstevel@tonic-gateIn DIE 326*0Sstevel@tonic-gatermb|-|11|(eval) 327*0Sstevel@tonic-gatermb|-|11|rmb::__ANON__ 328*0Sstevel@tonic-gate######## 329*0Sstevel@tonic-gatepackage TEST; 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gatesub TIEARRAY { 332*0Sstevel@tonic-gate return bless [qw(foo fee fie foe)], $_[0]; 333*0Sstevel@tonic-gate} 334*0Sstevel@tonic-gatesub FETCH { 335*0Sstevel@tonic-gate my ($s,$i) = @_; 336*0Sstevel@tonic-gate if ($i) { 337*0Sstevel@tonic-gate goto bbb; 338*0Sstevel@tonic-gate } 339*0Sstevel@tonic-gatebbb: 340*0Sstevel@tonic-gate return $s->[$i]; 341*0Sstevel@tonic-gate} 342*0Sstevel@tonic-gate 343*0Sstevel@tonic-gatepackage main; 344*0Sstevel@tonic-gatetie my @bar, 'TEST'; 345*0Sstevel@tonic-gateprint join('|', @bar[0..3]), "\n"; 346*0Sstevel@tonic-gateEXPECT 347*0Sstevel@tonic-gatefoo|fee|fie|foe 348*0Sstevel@tonic-gate######## 349*0Sstevel@tonic-gatepackage TH; 350*0Sstevel@tonic-gatesub TIEHASH { bless {}, TH } 351*0Sstevel@tonic-gatesub STORE { eval { print "@_[1,2]\n" }; die "bar\n" } 352*0Sstevel@tonic-gatetie %h, TH; 353*0Sstevel@tonic-gateeval { $h{A} = 1; print "never\n"; }; 354*0Sstevel@tonic-gateprint $@; 355*0Sstevel@tonic-gateeval { $h{B} = 2; }; 356*0Sstevel@tonic-gateprint $@; 357*0Sstevel@tonic-gateEXPECT 358*0Sstevel@tonic-gateA 1 359*0Sstevel@tonic-gatebar 360*0Sstevel@tonic-gateB 2 361*0Sstevel@tonic-gatebar 362*0Sstevel@tonic-gate######## 363*0Sstevel@tonic-gatesub n { 0 } 364*0Sstevel@tonic-gatesub f { my $x = shift; d(); } 365*0Sstevel@tonic-gatef(n()); 366*0Sstevel@tonic-gatef(); 367*0Sstevel@tonic-gate 368*0Sstevel@tonic-gatesub d { 369*0Sstevel@tonic-gate my $i = 0; my @a; 370*0Sstevel@tonic-gate while (do { { package DB; @a = caller($i++) } } ) { 371*0Sstevel@tonic-gate @a = @DB::args; 372*0Sstevel@tonic-gate for (@a) { print "$_\n"; $_ = '' } 373*0Sstevel@tonic-gate } 374*0Sstevel@tonic-gate} 375*0Sstevel@tonic-gateEXPECT 376*0Sstevel@tonic-gate0 377*0Sstevel@tonic-gate######## 378*0Sstevel@tonic-gatesub TIEHANDLE { bless {} } 379*0Sstevel@tonic-gatesub PRINT { next } 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gatetie *STDERR, ''; 382*0Sstevel@tonic-gate{ map ++$_, 1 } 383*0Sstevel@tonic-gate 384*0Sstevel@tonic-gateEXPECT 385*0Sstevel@tonic-gateCan't "next" outside a loop block at - line 2. 386*0Sstevel@tonic-gate######## 387*0Sstevel@tonic-gatesub TIEHANDLE { bless {} } 388*0Sstevel@tonic-gatesub PRINT { print "[TIE] $_[1]" } 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gatetie *STDERR, ''; 391*0Sstevel@tonic-gatedie "DIE\n"; 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gateEXPECT 394*0Sstevel@tonic-gate[TIE] DIE 395*0Sstevel@tonic-gate######## 396*0Sstevel@tonic-gatesub TIEHANDLE { bless {} } 397*0Sstevel@tonic-gatesub PRINT { 398*0Sstevel@tonic-gate (split(/./, 'x'x10000))[0]; 399*0Sstevel@tonic-gate eval('die("test\n")'); 400*0Sstevel@tonic-gate warn "[TIE] $_[1]"; 401*0Sstevel@tonic-gate} 402*0Sstevel@tonic-gateopen OLDERR, '>&STDERR'; 403*0Sstevel@tonic-gatetie *STDERR, ''; 404*0Sstevel@tonic-gate 405*0Sstevel@tonic-gateuse warnings FATAL => qw(uninitialized); 406*0Sstevel@tonic-gateprint undef; 407*0Sstevel@tonic-gate 408*0Sstevel@tonic-gateEXPECT 409*0Sstevel@tonic-gate[TIE] Use of uninitialized value in print at - line 11. 410