This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[differences between cumulative patch application and perl5.003_17]
[perl5.git] / av.c
CommitLineData
a0d0e21e 1/* av.c
79072805 2 *
a0d0e21e 3 * Copyright (c) 1991-1994, Larry Wall
79072805
LW
4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
a0d0e21e
LW
8 */
9
10/*
11 * "...for the Entwives desired order, and plenty, and peace (by which they
12 * meant that things should remain where they had set them)." --Treebeard
79072805
LW
13 */
14
15#include "EXTERN.h"
16#include "perl.h"
17
a0d0e21e
LW
18static void av_reify _((AV* av));
19
20static void
21av_reify(av)
22AV* av;
23{
24 I32 key;
25 SV* sv;
26
27 key = AvMAX(av) + 1;
28 while (key > AvFILL(av) + 1)
29 AvARRAY(av)[--key] = &sv_undef;
30 while (key) {
31 sv = AvARRAY(av)[--key];
32 assert(sv);
33 if (sv != &sv_undef)
34 (void)SvREFCNT_inc(sv);
35 }
36 AvREAL_on(av);
37}
38
39void
40av_extend(av,key)
41AV *av;
42I32 key;
43{
44 if (key > AvMAX(av)) {
45 SV** ary;
46 I32 tmp;
47 I32 newmax;
48
49 if (AvALLOC(av) != AvARRAY(av)) {
50 ary = AvALLOC(av) + AvFILL(av) + 1;
51 tmp = AvARRAY(av) - AvALLOC(av);
52 Move(AvARRAY(av), AvALLOC(av), AvFILL(av)+1, SV*);
53 AvMAX(av) += tmp;
54 SvPVX(av) = (char*)AvALLOC(av);
55 if (AvREAL(av)) {
56 while (tmp)
57 ary[--tmp] = &sv_undef;
58 }
59
60 if (key > AvMAX(av) - 10) {
61 newmax = key + AvMAX(av);
62 goto resize;
63 }
64 }
65 else {
66 if (AvALLOC(av)) {
c07a80fd 67#ifndef STRANGE_MALLOC
4633a7c4 68 U32 bytes;
c07a80fd 69#endif
4633a7c4 70
a0d0e21e
LW
71 newmax = key + AvMAX(av) / 5;
72 resize:
4633a7c4 73#ifdef STRANGE_MALLOC
a0d0e21e 74 Renew(AvALLOC(av),newmax+1, SV*);
4633a7c4
LW
75#else
76 bytes = (newmax + 1) * sizeof(SV*);
77#define MALLOC_OVERHEAD 16
78 tmp = MALLOC_OVERHEAD;
79 while (tmp - MALLOC_OVERHEAD < bytes)
80 tmp += tmp;
81 tmp -= MALLOC_OVERHEAD;
82 tmp /= sizeof(SV*);
83 assert(tmp > newmax);
84 newmax = tmp - 1;
85 New(2,ary, newmax+1, SV*);
86 Copy(AvALLOC(av), ary, AvMAX(av)+1, SV*);
c07a80fd 87 if (AvMAX(av) > 64 && !nice_chunk) {
88 nice_chunk = (char*)AvALLOC(av);
89 nice_chunk_size = (AvMAX(av) + 1) * sizeof(SV*);
90 }
4633a7c4
LW
91 else
92 Safefree(AvALLOC(av));
93 AvALLOC(av) = ary;
94#endif
a0d0e21e
LW
95 ary = AvALLOC(av) + AvMAX(av) + 1;
96 tmp = newmax - AvMAX(av);
7d55f622 97 if (av == curstack) { /* Oops, grew stack (via av_store()?) */
a0d0e21e
LW
98 stack_sp = AvALLOC(av) + (stack_sp - stack_base);
99 stack_base = AvALLOC(av);
100 stack_max = stack_base + newmax;
101 }
102 }
103 else {
104 newmax = key < 4 ? 4 : key;
105 New(2,AvALLOC(av), newmax+1, SV*);
106 ary = AvALLOC(av) + 1;
107 tmp = newmax;
108 AvALLOC(av)[0] = &sv_undef; /* For the stacks */
109 }
110 if (AvREAL(av)) {
111 while (tmp)
112 ary[--tmp] = &sv_undef;
113 }
114
115 SvPVX(av) = (char*)AvALLOC(av);
116 AvMAX(av) = newmax;
117 }
118 }
119}
120
79072805 121SV**
463ee0b2
LW
122av_fetch(av,key,lval)
123register AV *av;
79072805
LW
124I32 key;
125I32 lval;
126{
127 SV *sv;
128
a0d0e21e
LW
129 if (!av)
130 return 0;
131
8990e307 132 if (SvRMAGICAL(av)) {
463ee0b2 133 if (mg_find((SV*)av,'P')) {
8990e307 134 sv = sv_newmortal();
463ee0b2 135 mg_copy((SV*)av, sv, 0, key);
463ee0b2
LW
136 Sv = sv;
137 return &Sv;
138 }
139 }
140
a0d0e21e
LW
141 if (key < 0) {
142 key += AvFILL(av) + 1;
143 if (key < 0)
144 return 0;
145 }
146 else if (key > AvFILL(av)) {
147 if (!lval)
148 return 0;
149 if (AvREALISH(av))
150 sv = NEWSV(5,0);
151 else
152 sv = sv_newmortal();
153 return av_store(av,key,sv);
79072805 154 }
a0d0e21e 155 if (AvARRAY(av)[key] == &sv_undef) {
4dbf4341 156 emptyness:
79072805
LW
157 if (lval) {
158 sv = NEWSV(6,0);
463ee0b2 159 return av_store(av,key,sv);
79072805
LW
160 }
161 return 0;
162 }
4dbf4341 163 else if (AvREIFY(av)
164 && (!AvARRAY(av)[key] /* eg. @_ could have freed elts */
165 || SvTYPE(AvARRAY(av)[key]) == SVTYPEMASK)) {
166 AvARRAY(av)[key] = &sv_undef; /* 1/2 reify */
167 goto emptyness;
168 }
463ee0b2 169 return &AvARRAY(av)[key];
79072805
LW
170}
171
172SV**
463ee0b2
LW
173av_store(av,key,val)
174register AV *av;
79072805
LW
175I32 key;
176SV *val;
177{
79072805
LW
178 SV** ary;
179
a0d0e21e
LW
180 if (!av)
181 return 0;
43fcc5d2
CS
182 if (!val)
183 val = &sv_undef;
463ee0b2 184
8990e307 185 if (SvRMAGICAL(av)) {
463ee0b2 186 if (mg_find((SV*)av,'P')) {
43fcc5d2
CS
187 if (val != &sv_undef)
188 mg_copy((SV*)av, val, 0, key);
463ee0b2
LW
189 return 0;
190 }
191 }
192
a0d0e21e
LW
193 if (key < 0) {
194 key += AvFILL(av) + 1;
195 if (key < 0)
196 return 0;
79072805 197 }
43fcc5d2
CS
198 if (SvREADONLY(av) && key >= AvFILL(av))
199 croak(no_modify);
a0d0e21e
LW
200 if (key > AvMAX(av))
201 av_extend(av,key);
202 if (AvREIFY(av))
203 av_reify(av);
204
463ee0b2 205 ary = AvARRAY(av);
a0d0e21e
LW
206 if (AvFILL(av) < key) {
207 if (!AvREAL(av)) {
7d55f622 208 if (av == curstack && key > stack_sp - stack_base)
a0d0e21e
LW
209 stack_sp = stack_base + key; /* XPUSH in disguise */
210 do
211 ary[++AvFILL(av)] = &sv_undef;
212 while (AvFILL(av) < key);
79072805 213 }
a0d0e21e 214 AvFILL(av) = key;
79072805 215 }
a0d0e21e
LW
216 else if (AvREAL(av))
217 SvREFCNT_dec(ary[key]);
79072805 218 ary[key] = val;
8990e307 219 if (SvSMAGICAL(av)) {
a0d0e21e
LW
220 if (val != &sv_undef) {
221 MAGIC* mg = SvMAGIC(av);
222 sv_magic(val, (SV*)av, toLOWER(mg->mg_type), 0, key);
223 }
463ee0b2
LW
224 mg_set((SV*)av);
225 }
79072805
LW
226 return &ary[key];
227}
228
229AV *
230newAV()
231{
463ee0b2 232 register AV *av;
79072805 233
a0d0e21e
LW
234 av = (AV*)NEWSV(3,0);
235 sv_upgrade((SV *)av, SVt_PVAV);
463ee0b2
LW
236 AvREAL_on(av);
237 AvALLOC(av) = 0;
238 SvPVX(av) = 0;
239 AvMAX(av) = AvFILL(av) = -1;
240 return av;
79072805
LW
241}
242
243AV *
244av_make(size,strp)
245register I32 size;
246register SV **strp;
247{
463ee0b2 248 register AV *av;
79072805
LW
249 register I32 i;
250 register SV** ary;
251
a0d0e21e
LW
252 av = (AV*)NEWSV(8,0);
253 sv_upgrade((SV *) av,SVt_PVAV);
79072805 254 New(4,ary,size+1,SV*);
463ee0b2 255 AvALLOC(av) = ary;
a0d0e21e 256 AvFLAGS(av) = AVf_REAL;
463ee0b2
LW
257 SvPVX(av) = (char*)ary;
258 AvFILL(av) = size - 1;
259 AvMAX(av) = size - 1;
79072805 260 for (i = 0; i < size; i++) {
a0d0e21e
LW
261 assert (*strp);
262 ary[i] = NEWSV(7,0);
263 sv_setsv(ary[i], *strp);
79072805
LW
264 strp++;
265 }
463ee0b2 266 return av;
79072805
LW
267}
268
269AV *
270av_fake(size,strp)
271register I32 size;
272register SV **strp;
273{
463ee0b2 274 register AV *av;
79072805
LW
275 register SV** ary;
276
a0d0e21e
LW
277 av = (AV*)NEWSV(9,0);
278 sv_upgrade((SV *)av, SVt_PVAV);
79072805 279 New(4,ary,size+1,SV*);
463ee0b2 280 AvALLOC(av) = ary;
79072805 281 Copy(strp,ary,size,SV*);
a0d0e21e 282 AvFLAGS(av) = AVf_REIFY;
463ee0b2
LW
283 SvPVX(av) = (char*)ary;
284 AvFILL(av) = size - 1;
285 AvMAX(av) = size - 1;
79072805 286 while (size--) {
a0d0e21e
LW
287 assert (*strp);
288 SvTEMP_off(*strp);
79072805
LW
289 strp++;
290 }
463ee0b2 291 return av;
79072805
LW
292}
293
294void
463ee0b2
LW
295av_clear(av)
296register AV *av;
79072805
LW
297{
298 register I32 key;
a0d0e21e 299 SV** ary;
79072805 300
7d55f622 301#ifdef DEBUGGING
302 if (SvREFCNT(av) <= 0) {
303 warn("Attempt to clear deleted array");
304 }
305#endif
a0d0e21e 306 if (!av || AvMAX(av) < 0)
79072805
LW
307 return;
308 /*SUPPRESS 560*/
a0d0e21e
LW
309
310 if (AvREAL(av)) {
311 ary = AvARRAY(av);
312 key = AvFILL(av) + 1;
313 while (key) {
314 SvREFCNT_dec(ary[--key]);
315 ary[key] = &sv_undef;
316 }
317 }
463ee0b2
LW
318 if (key = AvARRAY(av) - AvALLOC(av)) {
319 AvMAX(av) += key;
a0d0e21e 320 SvPVX(av) = (char*)AvALLOC(av);
79072805 321 }
463ee0b2 322 AvFILL(av) = -1;
79072805
LW
323}
324
325void
463ee0b2
LW
326av_undef(av)
327register AV *av;
79072805
LW
328{
329 register I32 key;
330
463ee0b2 331 if (!av)
79072805
LW
332 return;
333 /*SUPPRESS 560*/
a0d0e21e
LW
334 if (AvREAL(av)) {
335 key = AvFILL(av) + 1;
336 while (key)
337 SvREFCNT_dec(AvARRAY(av)[--key]);
338 }
463ee0b2
LW
339 Safefree(AvALLOC(av));
340 AvALLOC(av) = 0;
341 SvPVX(av) = 0;
342 AvMAX(av) = AvFILL(av) = -1;
748a9306
LW
343 if (AvARYLEN(av)) {
344 SvREFCNT_dec(AvARYLEN(av));
345 AvARYLEN(av) = 0;
346 }
79072805
LW
347}
348
a0d0e21e 349void
463ee0b2
LW
350av_push(av,val)
351register AV *av;
79072805
LW
352SV *val;
353{
a0d0e21e
LW
354 if (!av)
355 return;
356 av_store(av,AvFILL(av)+1,val);
79072805
LW
357}
358
359SV *
463ee0b2
LW
360av_pop(av)
361register AV *av;
79072805
LW
362{
363 SV *retval;
364
a0d0e21e
LW
365 if (!av || AvFILL(av) < 0)
366 return &sv_undef;
43fcc5d2
CS
367 if (SvREADONLY(av))
368 croak(no_modify);
463ee0b2 369 retval = AvARRAY(av)[AvFILL(av)];
a0d0e21e 370 AvARRAY(av)[AvFILL(av)--] = &sv_undef;
8990e307 371 if (SvSMAGICAL(av))
463ee0b2 372 mg_set((SV*)av);
79072805
LW
373 return retval;
374}
375
376void
463ee0b2
LW
377av_unshift(av,num)
378register AV *av;
79072805
LW
379register I32 num;
380{
381 register I32 i;
382 register SV **sstr,**dstr;
383
a0d0e21e 384 if (!av || num <= 0)
79072805 385 return;
43fcc5d2
CS
386 if (SvREADONLY(av))
387 croak(no_modify);
a0d0e21e
LW
388 if (!AvREAL(av)) {
389 if (AvREIFY(av))
390 av_reify(av);
391 else
392 croak("Can't unshift");
79072805 393 }
a0d0e21e
LW
394 i = AvARRAY(av) - AvALLOC(av);
395 if (i) {
396 if (i > num)
397 i = num;
398 num -= i;
399
400 AvMAX(av) += i;
401 AvFILL(av) += i;
402 SvPVX(av) = (char*)(AvARRAY(av) - i);
403 }
404 if (num) {
405 av_extend(av,AvFILL(av)+num);
406 AvFILL(av) += num;
463ee0b2 407 dstr = AvARRAY(av) + AvFILL(av);
79072805
LW
408 sstr = dstr - num;
409#ifdef BUGGY_MSC5
410 # pragma loop_opt(off) /* don't loop-optimize the following code */
411#endif /* BUGGY_MSC5 */
a0d0e21e 412 for (i = AvFILL(av) - num; i >= 0; --i) {
79072805
LW
413 *dstr-- = *sstr--;
414#ifdef BUGGY_MSC5
415 # pragma loop_opt() /* loop-optimization back to command-line setting */
416#endif /* BUGGY_MSC5 */
417 }
a0d0e21e
LW
418 while (num)
419 AvARRAY(av)[--num] = &sv_undef;
79072805
LW
420 }
421}
422
423SV *
463ee0b2
LW
424av_shift(av)
425register AV *av;
79072805
LW
426{
427 SV *retval;
428
a0d0e21e
LW
429 if (!av || AvFILL(av) < 0)
430 return &sv_undef;
43fcc5d2
CS
431 if (SvREADONLY(av))
432 croak(no_modify);
463ee0b2 433 retval = *AvARRAY(av);
a0d0e21e
LW
434 if (AvREAL(av))
435 *AvARRAY(av) = &sv_undef;
463ee0b2
LW
436 SvPVX(av) = (char*)(AvARRAY(av) + 1);
437 AvMAX(av)--;
438 AvFILL(av)--;
8990e307 439 if (SvSMAGICAL(av))
463ee0b2 440 mg_set((SV*)av);
79072805
LW
441 return retval;
442}
443
444I32
463ee0b2
LW
445av_len(av)
446register AV *av;
79072805 447{
463ee0b2 448 return AvFILL(av);
79072805
LW
449}
450
451void
463ee0b2
LW
452av_fill(av, fill)
453register AV *av;
79072805
LW
454I32 fill;
455{
a0d0e21e
LW
456 if (!av)
457 croak("panic: null array");
79072805
LW
458 if (fill < 0)
459 fill = -1;
463ee0b2 460 if (fill <= AvMAX(av)) {
a0d0e21e
LW
461 I32 key = AvFILL(av);
462 SV** ary = AvARRAY(av);
463
464 if (AvREAL(av)) {
465 while (key > fill) {
466 SvREFCNT_dec(ary[key]);
467 ary[key--] = &sv_undef;
468 }
469 }
470 else {
471 while (key < fill)
472 ary[++key] = &sv_undef;
473 }
474
463ee0b2 475 AvFILL(av) = fill;
8990e307 476 if (SvSMAGICAL(av))
463ee0b2
LW
477 mg_set((SV*)av);
478 }
a0d0e21e
LW
479 else
480 (void)av_store(av,fill,&sv_undef);
79072805 481}