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