1*0Sstevel@tonic-gate#!./perl 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gate# "This IS structured code. It's just randomly structured." 4*0Sstevel@tonic-gate 5*0Sstevel@tonic-gateBEGIN { 6*0Sstevel@tonic-gate chdir 't' if -d 't'; 7*0Sstevel@tonic-gate @INC = qw(. ../lib); 8*0Sstevel@tonic-gate} 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gateprint "1..32\n"; 11*0Sstevel@tonic-gate 12*0Sstevel@tonic-gaterequire "test.pl"; 13*0Sstevel@tonic-gate 14*0Sstevel@tonic-gatewhile ($?) { 15*0Sstevel@tonic-gate $foo = 1; 16*0Sstevel@tonic-gate label1: 17*0Sstevel@tonic-gate $foo = 2; 18*0Sstevel@tonic-gate goto label2; 19*0Sstevel@tonic-gate} continue { 20*0Sstevel@tonic-gate $foo = 0; 21*0Sstevel@tonic-gate goto label4; 22*0Sstevel@tonic-gate label3: 23*0Sstevel@tonic-gate $foo = 4; 24*0Sstevel@tonic-gate goto label4; 25*0Sstevel@tonic-gate} 26*0Sstevel@tonic-gategoto label1; 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate$foo = 3; 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gatelabel2: 31*0Sstevel@tonic-gateprint "#1\t:$foo: == 2\n"; 32*0Sstevel@tonic-gateif ($foo == 2) {print "ok 1\n";} else {print "not ok 1\n";} 33*0Sstevel@tonic-gategoto label3; 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gatelabel4: 36*0Sstevel@tonic-gateprint "#2\t:$foo: == 4\n"; 37*0Sstevel@tonic-gateif ($foo == 4) {print "ok 2\n";} else {print "not ok 2\n";} 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate$PERL = ($^O eq 'MSWin32') ? '.\perl' : ($^O eq 'MacOS') ? $^X : ($^O eq 'NetWare') ? 'perl' : './perl'; 40*0Sstevel@tonic-gate$CMD = qq[$PERL -e "goto foo;" 2>&1 ]; 41*0Sstevel@tonic-gate$x = `$CMD`; 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gateif ($x =~ /label/) {print "ok 3\n";} else {print "not ok 3\n";} 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gatesub foo { 46*0Sstevel@tonic-gate goto bar; 47*0Sstevel@tonic-gate print "not ok 4\n"; 48*0Sstevel@tonic-gate return; 49*0Sstevel@tonic-gatebar: 50*0Sstevel@tonic-gate print "ok 4\n"; 51*0Sstevel@tonic-gate} 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate&foo; 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gatesub bar { 56*0Sstevel@tonic-gate $x = 'bypass'; 57*0Sstevel@tonic-gate eval "goto $x"; 58*0Sstevel@tonic-gate} 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate&bar; 61*0Sstevel@tonic-gateexit; 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gateFINALE: 64*0Sstevel@tonic-gateprint "ok 13\n"; 65*0Sstevel@tonic-gate 66*0Sstevel@tonic-gate# does goto LABEL handle block contexts correctly? 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gatemy $cond = 1; 69*0Sstevel@tonic-gatefor (1) { 70*0Sstevel@tonic-gate if ($cond == 1) { 71*0Sstevel@tonic-gate $cond = 0; 72*0Sstevel@tonic-gate goto OTHER; 73*0Sstevel@tonic-gate } 74*0Sstevel@tonic-gate elsif ($cond == 0) { 75*0Sstevel@tonic-gate OTHER: 76*0Sstevel@tonic-gate $cond = 2; 77*0Sstevel@tonic-gate print "ok 14\n"; 78*0Sstevel@tonic-gate goto THIRD; 79*0Sstevel@tonic-gate } 80*0Sstevel@tonic-gate else { 81*0Sstevel@tonic-gate THIRD: 82*0Sstevel@tonic-gate print "ok 15\n"; 83*0Sstevel@tonic-gate } 84*0Sstevel@tonic-gate} 85*0Sstevel@tonic-gateprint "ok 16\n"; 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate# Does goto work correctly within a for(;;) loop? 88*0Sstevel@tonic-gate# (BUG ID 20010309.004) 89*0Sstevel@tonic-gate 90*0Sstevel@tonic-gatefor(my $i=0;!$i++;) { 91*0Sstevel@tonic-gate my $x=1; 92*0Sstevel@tonic-gate goto label; 93*0Sstevel@tonic-gate label: print (defined $x?"ok ": "not ok ", "17\n") 94*0Sstevel@tonic-gate} 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate# Does goto work correctly going *to* a for(;;) loop? 97*0Sstevel@tonic-gate# (make sure it doesn't skip the initializer) 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gatemy ($z, $y) = (0); 100*0Sstevel@tonic-gateFORL1: for($y="ok 18\n"; $z;) {print $y; goto TEST19} 101*0Sstevel@tonic-gate($y,$z) = ("not ok 18\n", 1); 102*0Sstevel@tonic-gategoto FORL1; 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate# Even from within the loop? 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gateTEST19: $z = 0; 107*0Sstevel@tonic-gateFORL2: for($y="ok 19\n"; 1;) { 108*0Sstevel@tonic-gate if ($z) { 109*0Sstevel@tonic-gate print $y; 110*0Sstevel@tonic-gate last; 111*0Sstevel@tonic-gate } 112*0Sstevel@tonic-gate ($y, $z) = ("not ok 19\n", 1); 113*0Sstevel@tonic-gate goto FORL2; 114*0Sstevel@tonic-gate} 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate# Does goto work correctly within a try block? 117*0Sstevel@tonic-gate# (BUG ID 20000313.004) 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gatemy $ok = 0; 120*0Sstevel@tonic-gateeval { 121*0Sstevel@tonic-gate my $variable = 1; 122*0Sstevel@tonic-gate goto LABEL20; 123*0Sstevel@tonic-gate LABEL20: $ok = 1 if $variable; 124*0Sstevel@tonic-gate}; 125*0Sstevel@tonic-gateprint ($ok&&!$@ ? "ok 20\n" : "not ok 20\n"); 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate# And within an eval-string? 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gate$ok = 0; 131*0Sstevel@tonic-gateeval q{ 132*0Sstevel@tonic-gate my $variable = 1; 133*0Sstevel@tonic-gate goto LABEL21; 134*0Sstevel@tonic-gate LABEL21: $ok = 1 if $variable; 135*0Sstevel@tonic-gate}; 136*0Sstevel@tonic-gateprint ($ok&&!$@ ? "ok 21\n" : "not ok 21\n"); 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate# Test that goto works in nested eval-string 140*0Sstevel@tonic-gate$ok = 0; 141*0Sstevel@tonic-gate{eval q{ 142*0Sstevel@tonic-gate eval q{ 143*0Sstevel@tonic-gate goto LABEL22; 144*0Sstevel@tonic-gate }; 145*0Sstevel@tonic-gate $ok = 0; 146*0Sstevel@tonic-gate last; 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate LABEL22: $ok = 1; 149*0Sstevel@tonic-gate}; 150*0Sstevel@tonic-gate$ok = 0 if $@; 151*0Sstevel@tonic-gate} 152*0Sstevel@tonic-gateprint ($ok ? "ok 22\n" : "not ok 22\n"); 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate{ 155*0Sstevel@tonic-gate my $false = 0; 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate $ok = 0; 158*0Sstevel@tonic-gate { goto A; A: $ok = 1 } continue { } 159*0Sstevel@tonic-gate print "not " unless $ok; 160*0Sstevel@tonic-gate print "ok 23 - #20357 goto inside /{ } continue { }/ loop\n"; 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate $ok = 0; 163*0Sstevel@tonic-gate { do { goto A; A: $ok = 1 } while $false } 164*0Sstevel@tonic-gate print "not " unless $ok; 165*0Sstevel@tonic-gate print "ok 24 - #20154 goto inside /do { } while ()/ loop\n"; 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gate $ok = 0; 168*0Sstevel@tonic-gate foreach(1) { goto A; A: $ok = 1 } continue { }; 169*0Sstevel@tonic-gate print "not " unless $ok; 170*0Sstevel@tonic-gate print "ok 25 - goto inside /foreach () { } continue { }/ loop\n"; 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate $ok = 0; 173*0Sstevel@tonic-gate sub a { 174*0Sstevel@tonic-gate A: { if ($false) { redo A; B: $ok = 1; redo A; } } 175*0Sstevel@tonic-gate goto B unless $r++ 176*0Sstevel@tonic-gate } 177*0Sstevel@tonic-gate a(); 178*0Sstevel@tonic-gate print "not " unless $ok; 179*0Sstevel@tonic-gate print "ok 26 - #19061 loop label wiped away by goto\n"; 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate $ok = 0; 182*0Sstevel@tonic-gate for ($p=1;$p && goto A;$p=0) { A: $ok = 1 } 183*0Sstevel@tonic-gate print "not " unless $ok; 184*0Sstevel@tonic-gate print "ok 27 - weird case of goto and for(;;) loop\n"; 185*0Sstevel@tonic-gate} 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate# bug #9990 - don't prematurely free the CV we're &going to. 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gatesub f1 { 190*0Sstevel@tonic-gate my $x; 191*0Sstevel@tonic-gate goto sub { $x; print "ok 28 - don't prematurely free CV\n" } 192*0Sstevel@tonic-gate} 193*0Sstevel@tonic-gatef1(); 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate# bug #22181 - this used to coredump or make $x undefined, due to 196*0Sstevel@tonic-gate# erroneous popping of the inner BLOCK context 197*0Sstevel@tonic-gate 198*0Sstevel@tonic-gatefor ($i=0; $i<2; $i++) { 199*0Sstevel@tonic-gate my $x = 1; 200*0Sstevel@tonic-gate goto LABEL29; 201*0Sstevel@tonic-gate LABEL29: 202*0Sstevel@tonic-gate print "not " if !defined $x || $x != 1; 203*0Sstevel@tonic-gate} 204*0Sstevel@tonic-gateprint "ok 29 - goto in for(;;) with continuation\n"; 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate# bug #22299 - goto in require doesn't find label 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gateopen my $f, ">goto01.pm" or die; 209*0Sstevel@tonic-gateprint $f <<'EOT'; 210*0Sstevel@tonic-gatepackage goto01; 211*0Sstevel@tonic-gategoto YYY; 212*0Sstevel@tonic-gatedie; 213*0Sstevel@tonic-gateYYY: print "OK\n"; 214*0Sstevel@tonic-gate1; 215*0Sstevel@tonic-gateEOT 216*0Sstevel@tonic-gateclose $f; 217*0Sstevel@tonic-gate 218*0Sstevel@tonic-gatecurr_test(30); 219*0Sstevel@tonic-gatemy $r = runperl(prog => 'use goto01; print qq[DONE\n]'); 220*0Sstevel@tonic-gateis($r, "OK\nDONE\n", "goto within use-d file"); 221*0Sstevel@tonic-gateunlink "goto01.pm"; 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate# test for [perl #24108] 224*0Sstevel@tonic-gatesub i_return_a_label { 225*0Sstevel@tonic-gate print "ok 31 - i_return_a_label called\n"; 226*0Sstevel@tonic-gate return "returned_label"; 227*0Sstevel@tonic-gate} 228*0Sstevel@tonic-gateeval { goto +i_return_a_label; }; 229*0Sstevel@tonic-gateprint "not "; 230*0Sstevel@tonic-gatereturned_label : print "ok 32 - done to returned_label\n"; 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gateexit; 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gatebypass: 235*0Sstevel@tonic-gateprint "ok 5\n"; 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate# Test autoloading mechanism. 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gatesub two { 240*0Sstevel@tonic-gate ($pack, $file, $line) = caller; # Should indicate original call stats. 241*0Sstevel@tonic-gate print "@_ $pack $file $line" eq "1 2 3 main $FILE $LINE" 242*0Sstevel@tonic-gate ? "ok 7\n" 243*0Sstevel@tonic-gate : "not ok 7\n"; 244*0Sstevel@tonic-gate} 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gatesub one { 247*0Sstevel@tonic-gate eval <<'END'; 248*0Sstevel@tonic-gate sub one { print "ok 6\n"; goto &two; print "not ok 6\n"; } 249*0Sstevel@tonic-gateEND 250*0Sstevel@tonic-gate goto &one; 251*0Sstevel@tonic-gate} 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate$FILE = __FILE__; 254*0Sstevel@tonic-gate$LINE = __LINE__ + 1; 255*0Sstevel@tonic-gate&one(1,2,3); 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate$wherever = NOWHERE; 258*0Sstevel@tonic-gateeval { goto $wherever }; 259*0Sstevel@tonic-gateprint $@ =~ /Can't find label NOWHERE/ ? "ok 8\n" : "not ok 8\n"; 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate# see if a modified @_ propagates 262*0Sstevel@tonic-gate{ 263*0Sstevel@tonic-gate package Foo; 264*0Sstevel@tonic-gate sub DESTROY { my $s = shift; print "ok $s->[0]\n"; } 265*0Sstevel@tonic-gate sub show { print "# @_\nnot ok $_[0][0]\n" if @_ != 5; } 266*0Sstevel@tonic-gate sub start { push @_, 1, "foo", {}; goto &show; } 267*0Sstevel@tonic-gate for (9..11) { start(bless([$_]), 'bar'); } 268*0Sstevel@tonic-gate} 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gatesub auto { 271*0Sstevel@tonic-gate goto &loadit; 272*0Sstevel@tonic-gate} 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gatesub AUTOLOAD { print @_ } 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gateauto("ok 12\n"); 277*0Sstevel@tonic-gate 278*0Sstevel@tonic-gate$wherever = FINALE; 279*0Sstevel@tonic-gategoto $wherever; 280