1*0Sstevel@tonic-gate#!./perl 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gate 4*0Sstevel@tonic-gateBEGIN { 5*0Sstevel@tonic-gate chdir 't' if -d 't'; 6*0Sstevel@tonic-gate @INC = '../lib'; 7*0Sstevel@tonic-gate} 8*0Sstevel@tonic-gate 9*0Sstevel@tonic-gatemy %seen; 10*0Sstevel@tonic-gate 11*0Sstevel@tonic-gatepackage Implement; 12*0Sstevel@tonic-gate 13*0Sstevel@tonic-gatesub TIEARRAY 14*0Sstevel@tonic-gate{ 15*0Sstevel@tonic-gate $seen{'TIEARRAY'}++; 16*0Sstevel@tonic-gate my ($class,@val) = @_; 17*0Sstevel@tonic-gate return bless \@val,$class; 18*0Sstevel@tonic-gate} 19*0Sstevel@tonic-gate 20*0Sstevel@tonic-gatesub STORESIZE 21*0Sstevel@tonic-gate{ 22*0Sstevel@tonic-gate $seen{'STORESIZE'}++; 23*0Sstevel@tonic-gate my ($ob,$sz) = @_; 24*0Sstevel@tonic-gate return $#{$ob} = $sz-1; 25*0Sstevel@tonic-gate} 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gatesub EXTEND 28*0Sstevel@tonic-gate{ 29*0Sstevel@tonic-gate $seen{'EXTEND'}++; 30*0Sstevel@tonic-gate my ($ob,$sz) = @_; 31*0Sstevel@tonic-gate return @$ob = $sz; 32*0Sstevel@tonic-gate} 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gatesub FETCHSIZE 35*0Sstevel@tonic-gate{ 36*0Sstevel@tonic-gate $seen{'FETCHSIZE'}++; 37*0Sstevel@tonic-gate return scalar(@{$_[0]}); 38*0Sstevel@tonic-gate} 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gatesub FETCH 41*0Sstevel@tonic-gate{ 42*0Sstevel@tonic-gate $seen{'FETCH'}++; 43*0Sstevel@tonic-gate my ($ob,$id) = @_; 44*0Sstevel@tonic-gate return $ob->[$id]; 45*0Sstevel@tonic-gate} 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gatesub STORE 48*0Sstevel@tonic-gate{ 49*0Sstevel@tonic-gate $seen{'STORE'}++; 50*0Sstevel@tonic-gate my ($ob,$id,$val) = @_; 51*0Sstevel@tonic-gate $ob->[$id] = $val; 52*0Sstevel@tonic-gate} 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gatesub UNSHIFT 55*0Sstevel@tonic-gate{ 56*0Sstevel@tonic-gate $seen{'UNSHIFT'}++; 57*0Sstevel@tonic-gate my $ob = shift; 58*0Sstevel@tonic-gate unshift(@$ob,@_); 59*0Sstevel@tonic-gate} 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gatesub PUSH 62*0Sstevel@tonic-gate{ 63*0Sstevel@tonic-gate $seen{'PUSH'}++; 64*0Sstevel@tonic-gate my $ob = shift;; 65*0Sstevel@tonic-gate push(@$ob,@_); 66*0Sstevel@tonic-gate} 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gatesub CLEAR 69*0Sstevel@tonic-gate{ 70*0Sstevel@tonic-gate $seen{'CLEAR'}++; 71*0Sstevel@tonic-gate @{$_[0]} = (); 72*0Sstevel@tonic-gate} 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gatesub DESTROY 75*0Sstevel@tonic-gate{ 76*0Sstevel@tonic-gate $seen{'DESTROY'}++; 77*0Sstevel@tonic-gate} 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gatesub POP 80*0Sstevel@tonic-gate{ 81*0Sstevel@tonic-gate $seen{'POP'}++; 82*0Sstevel@tonic-gate my ($ob) = @_; 83*0Sstevel@tonic-gate return pop(@$ob); 84*0Sstevel@tonic-gate} 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gatesub SHIFT 87*0Sstevel@tonic-gate{ 88*0Sstevel@tonic-gate $seen{'SHIFT'}++; 89*0Sstevel@tonic-gate my ($ob) = @_; 90*0Sstevel@tonic-gate return shift(@$ob); 91*0Sstevel@tonic-gate} 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gatesub SPLICE 94*0Sstevel@tonic-gate{ 95*0Sstevel@tonic-gate $seen{'SPLICE'}++; 96*0Sstevel@tonic-gate my $ob = shift; 97*0Sstevel@tonic-gate my $off = @_ ? shift : 0; 98*0Sstevel@tonic-gate my $len = @_ ? shift : @$ob-1; 99*0Sstevel@tonic-gate return splice(@$ob,$off,$len,@_); 100*0Sstevel@tonic-gate} 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gatepackage NegIndex; # 20020220 MJD 103*0Sstevel@tonic-gate@ISA = 'Implement'; 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate# simulate indices -2 .. 2 106*0Sstevel@tonic-gatemy $offset = 2; 107*0Sstevel@tonic-gate$NegIndex::NEGATIVE_INDICES = 1; 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gatesub FETCH { 110*0Sstevel@tonic-gate my ($ob,$id) = @_; 111*0Sstevel@tonic-gate# print "# FETCH @_\n"; 112*0Sstevel@tonic-gate $id += $offset; 113*0Sstevel@tonic-gate $ob->[$id]; 114*0Sstevel@tonic-gate} 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gatesub STORE { 117*0Sstevel@tonic-gate my ($ob,$id,$value) = @_; 118*0Sstevel@tonic-gate# print "# STORE @_\n"; 119*0Sstevel@tonic-gate $id += $offset; 120*0Sstevel@tonic-gate $ob->[$id] = $value; 121*0Sstevel@tonic-gate} 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gatesub DELETE { 124*0Sstevel@tonic-gate my ($ob,$id) = @_; 125*0Sstevel@tonic-gate# print "# DELETE @_\n"; 126*0Sstevel@tonic-gate $id += $offset; 127*0Sstevel@tonic-gate delete $ob->[$id]; 128*0Sstevel@tonic-gate} 129*0Sstevel@tonic-gate 130*0Sstevel@tonic-gatesub EXISTS { 131*0Sstevel@tonic-gate my ($ob,$id) = @_; 132*0Sstevel@tonic-gate# print "# EXISTS @_\n"; 133*0Sstevel@tonic-gate $id += $offset; 134*0Sstevel@tonic-gate exists $ob->[$id]; 135*0Sstevel@tonic-gate} 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gatepackage main; 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gateprint "1..61\n"; 140*0Sstevel@tonic-gatemy $test = 1; 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate{my @ary; 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate{ my $ob = tie @ary,'Implement',3,2,1; 145*0Sstevel@tonic-gate print "not " unless $ob; 146*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 147*0Sstevel@tonic-gate print "not " unless tied(@ary) == $ob; 148*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 149*0Sstevel@tonic-gate} 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gateprint "not " unless @ary == 3; 153*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gateprint "not " unless $#ary == 2; 156*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 157*0Sstevel@tonic-gate 158*0Sstevel@tonic-gateprint "not " unless join(':',@ary) eq '3:2:1'; 159*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gateprint "not " unless $seen{'FETCH'} >= 3; 162*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate@ary = (1,2,3); 165*0Sstevel@tonic-gate 166*0Sstevel@tonic-gateprint "not " unless $seen{'STORE'} >= 3; 167*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 168*0Sstevel@tonic-gateprint "not " unless join(':',@ary) eq '1:2:3'; 169*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate{my @thing = @ary; 172*0Sstevel@tonic-gateprint "not " unless join(':',@thing) eq '1:2:3'; 173*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gatetie @thing,'Implement'; 176*0Sstevel@tonic-gate@thing = @ary; 177*0Sstevel@tonic-gateprint "not " unless join(':',@thing) eq '1:2:3'; 178*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 179*0Sstevel@tonic-gate} 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gateprint "not " unless pop(@ary) == 3; 182*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 183*0Sstevel@tonic-gateprint "not " unless $seen{'POP'} == 1; 184*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 185*0Sstevel@tonic-gateprint "not " unless join(':',@ary) eq '1:2'; 186*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gatepush(@ary,4); 189*0Sstevel@tonic-gateprint "not " unless $seen{'PUSH'} == 1; 190*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 191*0Sstevel@tonic-gateprint "not " unless join(':',@ary) eq '1:2:4'; 192*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gatemy @x = splice(@ary,1,1,7); 195*0Sstevel@tonic-gate 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gateprint "not " unless $seen{'SPLICE'} == 1; 198*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gateprint "not " unless @x == 1; 201*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 202*0Sstevel@tonic-gateprint "not " unless $x[0] == 2; 203*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 204*0Sstevel@tonic-gateprint "not " unless join(':',@ary) eq '1:7:4'; 205*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gateprint "not " unless shift(@ary) == 1; 208*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 209*0Sstevel@tonic-gateprint "not " unless $seen{'SHIFT'} == 1; 210*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 211*0Sstevel@tonic-gateprint "not " unless join(':',@ary) eq '7:4'; 212*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gatemy $n = unshift(@ary,5,6); 215*0Sstevel@tonic-gateprint "not " unless $seen{'UNSHIFT'} == 1; 216*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 217*0Sstevel@tonic-gateprint "not " unless $n == 4; 218*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 219*0Sstevel@tonic-gateprint "not " unless join(':',@ary) eq '5:6:7:4'; 220*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate@ary = split(/:/,'1:2:3'); 223*0Sstevel@tonic-gateprint "not " unless join(':',@ary) eq '1:2:3'; 224*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gatemy $t = 0; 228*0Sstevel@tonic-gateforeach $n (@ary) 229*0Sstevel@tonic-gate { 230*0Sstevel@tonic-gate print "not " unless $n == ++$t; 231*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate# (30-33) 20020303 mjd-perl-patch+@plover.com 235*0Sstevel@tonic-gate@ary = (); 236*0Sstevel@tonic-gate$seen{POP} = 0; 237*0Sstevel@tonic-gatepop @ary; # this didn't used to call POP at all 238*0Sstevel@tonic-gateprint "not " unless $seen{POP} == 1; 239*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 240*0Sstevel@tonic-gate$seen{SHIFT} = 0; 241*0Sstevel@tonic-gateshift @ary; # this didn't used to call SHIFT at all 242*0Sstevel@tonic-gateprint "not " unless $seen{SHIFT} == 1; 243*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 244*0Sstevel@tonic-gate$seen{PUSH} = 0; 245*0Sstevel@tonic-gatepush @ary; # this didn't used to call PUSH at all 246*0Sstevel@tonic-gateprint "not " unless $seen{PUSH} == 1; 247*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 248*0Sstevel@tonic-gate$seen{UNSHIFT} = 0; 249*0Sstevel@tonic-gateunshift @ary; # this didn't used to call UNSHIFT at all 250*0Sstevel@tonic-gateprint "not " unless $seen{UNSHIFT} == 1; 251*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate@ary = qw(3 2 1); 254*0Sstevel@tonic-gateprint "not " unless join(':',@ary) eq '3:2:1'; 255*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gateuntie @ary; 258*0Sstevel@tonic-gate 259*0Sstevel@tonic-gate} 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate# 20020401 mjd-perl-patch+@plover.com 262*0Sstevel@tonic-gate# Thanks to Dave Mitchell for the small test case and the fix 263*0Sstevel@tonic-gate{ 264*0Sstevel@tonic-gate my @a; 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate sub X::TIEARRAY { bless {}, 'X' } 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate sub X::SPLICE { 269*0Sstevel@tonic-gate do '/dev/null'; 270*0Sstevel@tonic-gate die; 271*0Sstevel@tonic-gate } 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate tie @a, 'X'; 274*0Sstevel@tonic-gate eval { splice(@a) }; 275*0Sstevel@tonic-gate # If we survived this far. 276*0Sstevel@tonic-gate print "ok ", $test++, "\n"; 277*0Sstevel@tonic-gate} 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate 280*0Sstevel@tonic-gate{ # 20020220 mjd-perl-patch+@plover.com 281*0Sstevel@tonic-gate my @n; 282*0Sstevel@tonic-gate tie @n => 'NegIndex', ('A' .. 'E'); 283*0Sstevel@tonic-gate 284*0Sstevel@tonic-gate # FETCH 285*0Sstevel@tonic-gate print "not " unless $n[0] eq 'C'; 286*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 287*0Sstevel@tonic-gate print "not " unless $n[1] eq 'D'; 288*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 289*0Sstevel@tonic-gate print "not " unless $n[2] eq 'E'; 290*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 291*0Sstevel@tonic-gate print "not " unless $n[-1] eq 'B'; 292*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 293*0Sstevel@tonic-gate print "not " unless $n[-2] eq 'A'; 294*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 295*0Sstevel@tonic-gate 296*0Sstevel@tonic-gate # STORE 297*0Sstevel@tonic-gate $n[-2] = 'a'; 298*0Sstevel@tonic-gate print "not " unless $n[-2] eq 'a'; 299*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 300*0Sstevel@tonic-gate $n[-1] = 'b'; 301*0Sstevel@tonic-gate print "not " unless $n[-1] eq 'b'; 302*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 303*0Sstevel@tonic-gate $n[0] = 'c'; 304*0Sstevel@tonic-gate print "not " unless $n[0] eq 'c'; 305*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 306*0Sstevel@tonic-gate $n[1] = 'd'; 307*0Sstevel@tonic-gate print "not " unless $n[1] eq 'd'; 308*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 309*0Sstevel@tonic-gate $n[2] = 'e'; 310*0Sstevel@tonic-gate print "not " unless $n[2] eq 'e'; 311*0Sstevel@tonic-gate print "ok ", $test++,"\n"; 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate # DELETE and EXISTS 314*0Sstevel@tonic-gate for (-2 .. 2) { 315*0Sstevel@tonic-gate print exists($n[$_]) ? "ok $test\n" : "not ok $test\n"; 316*0Sstevel@tonic-gate $test++; 317*0Sstevel@tonic-gate delete $n[$_]; 318*0Sstevel@tonic-gate print defined($n[$_]) ? "not ok $test\n" : "ok $test\n"; 319*0Sstevel@tonic-gate $test++; 320*0Sstevel@tonic-gate print exists($n[$_]) ? "not ok $test\n" : "ok $test\n"; 321*0Sstevel@tonic-gate $test++; 322*0Sstevel@tonic-gate } 323*0Sstevel@tonic-gate} 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gateprint "not " unless $seen{'DESTROY'} == 3; 328*0Sstevel@tonic-gateprint "ok ", $test++,"\n"; 329*0Sstevel@tonic-gate 330