This is patch.2b1f to perl5.002beta1.
[p5sagit/p5-mst-13.2.git] / av.c
CommitLineData
a0d0e21e 1/* av.c
79072805 2 *
a0d0e21e 3 * Copyright (c) 1991-1994, Larry Wall
79072805 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 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 13 */
14
15#include "EXTERN.h"
16#include "perl.h"
17
a0d0e21e 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)) {
4633a7c4 67 U32 bytes;
68
a0d0e21e 69 newmax = key + AvMAX(av) / 5;
70 resize:
4633a7c4 71#ifdef STRANGE_MALLOC
a0d0e21e 72 Renew(AvALLOC(av),newmax+1, SV*);
4633a7c4 73#else
74 bytes = (newmax + 1) * sizeof(SV*);
75#define MALLOC_OVERHEAD 16
76 tmp = MALLOC_OVERHEAD;
77 while (tmp - MALLOC_OVERHEAD < bytes)
78 tmp += tmp;
79 tmp -= MALLOC_OVERHEAD;
80 tmp /= sizeof(SV*);
81 assert(tmp > newmax);
82 newmax = tmp - 1;
83 New(2,ary, newmax+1, SV*);
84 Copy(AvALLOC(av), ary, AvMAX(av)+1, SV*);
85 if (AvMAX(av) > 64 && !AvREUSED(av))
86 sv_add_arena((char*)AvALLOC(av), AvMAX(av) * sizeof(SV*),0);
87 else
88 Safefree(AvALLOC(av));
89 AvALLOC(av) = ary;
90#endif
a0d0e21e 91 ary = AvALLOC(av) + AvMAX(av) + 1;
92 tmp = newmax - AvMAX(av);
93 if (av == stack) { /* Oops, grew stack (via av_store()?) */
94 stack_sp = AvALLOC(av) + (stack_sp - stack_base);
95 stack_base = AvALLOC(av);
96 stack_max = stack_base + newmax;
97 }
98 }
99 else {
100 newmax = key < 4 ? 4 : key;
101 New(2,AvALLOC(av), newmax+1, SV*);
102 ary = AvALLOC(av) + 1;
103 tmp = newmax;
104 AvALLOC(av)[0] = &sv_undef; /* For the stacks */
105 }
106 if (AvREAL(av)) {
107 while (tmp)
108 ary[--tmp] = &sv_undef;
109 }
110
111 SvPVX(av) = (char*)AvALLOC(av);
112 AvMAX(av) = newmax;
113 }
114 }
115}
116
79072805 117SV**
463ee0b2 118av_fetch(av,key,lval)
119register AV *av;
79072805 120I32 key;
121I32 lval;
122{
123 SV *sv;
124
a0d0e21e 125 if (!av)
126 return 0;
127
8990e307 128 if (SvRMAGICAL(av)) {
463ee0b2 129 if (mg_find((SV*)av,'P')) {
8990e307 130 sv = sv_newmortal();
463ee0b2 131 mg_copy((SV*)av, sv, 0, key);
463ee0b2 132 Sv = sv;
133 return &Sv;
134 }
135 }
136
a0d0e21e 137 if (key < 0) {
138 key += AvFILL(av) + 1;
139 if (key < 0)
140 return 0;
141 }
142 else if (key > AvFILL(av)) {
143 if (!lval)
144 return 0;
145 if (AvREALISH(av))
146 sv = NEWSV(5,0);
147 else
148 sv = sv_newmortal();
149 return av_store(av,key,sv);
79072805 150 }
a0d0e21e 151 if (AvARRAY(av)[key] == &sv_undef) {
79072805 152 if (lval) {
153 sv = NEWSV(6,0);
463ee0b2 154 return av_store(av,key,sv);
79072805 155 }
156 return 0;
157 }
463ee0b2 158 return &AvARRAY(av)[key];
79072805 159}
160
161SV**
463ee0b2 162av_store(av,key,val)
163register AV *av;
79072805 164I32 key;
165SV *val;
166{
79072805 167 SV** ary;
168
a0d0e21e 169 if (!av)
170 return 0;
463ee0b2 171
8990e307 172 if (SvRMAGICAL(av)) {
463ee0b2 173 if (mg_find((SV*)av,'P')) {
174 mg_copy((SV*)av, val, 0, key);
175 return 0;
176 }
177 }
178
a0d0e21e 179 if (key < 0) {
180 key += AvFILL(av) + 1;
181 if (key < 0)
182 return 0;
79072805 183 }
a0d0e21e 184 if (!val)
185 val = &sv_undef;
186
187 if (key > AvMAX(av))
188 av_extend(av,key);
189 if (AvREIFY(av))
190 av_reify(av);
191
463ee0b2 192 ary = AvARRAY(av);
a0d0e21e 193 if (AvFILL(av) < key) {
194 if (!AvREAL(av)) {
195 if (av == stack && key > stack_sp - stack_base)
196 stack_sp = stack_base + key; /* XPUSH in disguise */
197 do
198 ary[++AvFILL(av)] = &sv_undef;
199 while (AvFILL(av) < key);
79072805 200 }
a0d0e21e 201 AvFILL(av) = key;
79072805 202 }
a0d0e21e 203 else if (AvREAL(av))
204 SvREFCNT_dec(ary[key]);
79072805 205 ary[key] = val;
8990e307 206 if (SvSMAGICAL(av)) {
a0d0e21e 207 if (val != &sv_undef) {
208 MAGIC* mg = SvMAGIC(av);
209 sv_magic(val, (SV*)av, toLOWER(mg->mg_type), 0, key);
210 }
463ee0b2 211 mg_set((SV*)av);
212 }
79072805 213 return &ary[key];
214}
215
216AV *
217newAV()
218{
463ee0b2 219 register AV *av;
79072805 220
a0d0e21e 221 av = (AV*)NEWSV(3,0);
222 sv_upgrade((SV *)av, SVt_PVAV);
463ee0b2 223 AvREAL_on(av);
224 AvALLOC(av) = 0;
225 SvPVX(av) = 0;
226 AvMAX(av) = AvFILL(av) = -1;
227 return av;
79072805 228}
229
230AV *
231av_make(size,strp)
232register I32 size;
233register SV **strp;
234{
463ee0b2 235 register AV *av;
79072805 236 register I32 i;
237 register SV** ary;
238
a0d0e21e 239 av = (AV*)NEWSV(8,0);
240 sv_upgrade((SV *) av,SVt_PVAV);
79072805 241 New(4,ary,size+1,SV*);
463ee0b2 242 AvALLOC(av) = ary;
a0d0e21e 243 AvFLAGS(av) = AVf_REAL;
463ee0b2 244 SvPVX(av) = (char*)ary;
245 AvFILL(av) = size - 1;
246 AvMAX(av) = size - 1;
79072805 247 for (i = 0; i < size; i++) {
a0d0e21e 248 assert (*strp);
249 ary[i] = NEWSV(7,0);
250 sv_setsv(ary[i], *strp);
79072805 251 strp++;
252 }
463ee0b2 253 return av;
79072805 254}
255
256AV *
257av_fake(size,strp)
258register I32 size;
259register SV **strp;
260{
463ee0b2 261 register AV *av;
79072805 262 register SV** ary;
263
a0d0e21e 264 av = (AV*)NEWSV(9,0);
265 sv_upgrade((SV *)av, SVt_PVAV);
79072805 266 New(4,ary,size+1,SV*);
463ee0b2 267 AvALLOC(av) = ary;
79072805 268 Copy(strp,ary,size,SV*);
a0d0e21e 269 AvFLAGS(av) = AVf_REIFY;
463ee0b2 270 SvPVX(av) = (char*)ary;
271 AvFILL(av) = size - 1;
272 AvMAX(av) = size - 1;
79072805 273 while (size--) {
a0d0e21e 274 assert (*strp);
275 SvTEMP_off(*strp);
79072805 276 strp++;
277 }
463ee0b2 278 return av;
79072805 279}
280
281void
463ee0b2 282av_clear(av)
283register AV *av;
79072805 284{
285 register I32 key;
a0d0e21e 286 SV** ary;
79072805 287
a0d0e21e 288 if (!av || AvMAX(av) < 0)
79072805 289 return;
290 /*SUPPRESS 560*/
a0d0e21e 291
292 if (AvREAL(av)) {
293 ary = AvARRAY(av);
294 key = AvFILL(av) + 1;
295 while (key) {
296 SvREFCNT_dec(ary[--key]);
297 ary[key] = &sv_undef;
298 }
299 }
463ee0b2 300 if (key = AvARRAY(av) - AvALLOC(av)) {
301 AvMAX(av) += key;
a0d0e21e 302 SvPVX(av) = (char*)AvALLOC(av);
79072805 303 }
463ee0b2 304 AvFILL(av) = -1;
79072805 305}
306
307void
463ee0b2 308av_undef(av)
309register AV *av;
79072805 310{
311 register I32 key;
312
463ee0b2 313 if (!av)
79072805 314 return;
315 /*SUPPRESS 560*/
a0d0e21e 316 if (AvREAL(av)) {
317 key = AvFILL(av) + 1;
318 while (key)
319 SvREFCNT_dec(AvARRAY(av)[--key]);
320 }
463ee0b2 321 if (key = AvARRAY(av) - AvALLOC(av)) {
322 AvMAX(av) += key;
a0d0e21e 323 SvPVX(av) = (char*)AvALLOC(av);
79072805 324 }
463ee0b2 325 Safefree(AvALLOC(av));
326 AvALLOC(av) = 0;
327 SvPVX(av) = 0;
328 AvMAX(av) = AvFILL(av) = -1;
4633a7c4 329 AvREUSED_on(av); /* Avoid leak of making SVs out of old memory again. */
748a9306 330 if (AvARYLEN(av)) {
331 SvREFCNT_dec(AvARYLEN(av));
332 AvARYLEN(av) = 0;
333 }
79072805 334}
335
a0d0e21e 336void
463ee0b2 337av_push(av,val)
338register AV *av;
79072805 339SV *val;
340{
a0d0e21e 341 if (!av)
342 return;
343 av_store(av,AvFILL(av)+1,val);
79072805 344}
345
346SV *
463ee0b2 347av_pop(av)
348register AV *av;
79072805 349{
350 SV *retval;
351
a0d0e21e 352 if (!av || AvFILL(av) < 0)
353 return &sv_undef;
463ee0b2 354 retval = AvARRAY(av)[AvFILL(av)];
a0d0e21e 355 AvARRAY(av)[AvFILL(av)--] = &sv_undef;
8990e307 356 if (SvSMAGICAL(av))
463ee0b2 357 mg_set((SV*)av);
79072805 358 return retval;
359}
360
361void
463ee0b2 362av_unshift(av,num)
363register AV *av;
79072805 364register I32 num;
365{
366 register I32 i;
367 register SV **sstr,**dstr;
368
a0d0e21e 369 if (!av || num <= 0)
79072805 370 return;
a0d0e21e 371 if (!AvREAL(av)) {
372 if (AvREIFY(av))
373 av_reify(av);
374 else
375 croak("Can't unshift");
79072805 376 }
a0d0e21e 377 i = AvARRAY(av) - AvALLOC(av);
378 if (i) {
379 if (i > num)
380 i = num;
381 num -= i;
382
383 AvMAX(av) += i;
384 AvFILL(av) += i;
385 SvPVX(av) = (char*)(AvARRAY(av) - i);
386 }
387 if (num) {
388 av_extend(av,AvFILL(av)+num);
389 AvFILL(av) += num;
463ee0b2 390 dstr = AvARRAY(av) + AvFILL(av);
79072805 391 sstr = dstr - num;
392#ifdef BUGGY_MSC5
393 # pragma loop_opt(off) /* don't loop-optimize the following code */
394#endif /* BUGGY_MSC5 */
a0d0e21e 395 for (i = AvFILL(av) - num; i >= 0; --i) {
79072805 396 *dstr-- = *sstr--;
397#ifdef BUGGY_MSC5
398 # pragma loop_opt() /* loop-optimization back to command-line setting */
399#endif /* BUGGY_MSC5 */
400 }
a0d0e21e 401 while (num)
402 AvARRAY(av)[--num] = &sv_undef;
79072805 403 }
404}
405
406SV *
463ee0b2 407av_shift(av)
408register AV *av;
79072805 409{
410 SV *retval;
411
a0d0e21e 412 if (!av || AvFILL(av) < 0)
413 return &sv_undef;
463ee0b2 414 retval = *AvARRAY(av);
a0d0e21e 415 if (AvREAL(av))
416 *AvARRAY(av) = &sv_undef;
463ee0b2 417 SvPVX(av) = (char*)(AvARRAY(av) + 1);
418 AvMAX(av)--;
419 AvFILL(av)--;
8990e307 420 if (SvSMAGICAL(av))
463ee0b2 421 mg_set((SV*)av);
79072805 422 return retval;
423}
424
425I32
463ee0b2 426av_len(av)
427register AV *av;
79072805 428{
463ee0b2 429 return AvFILL(av);
79072805 430}
431
432void
463ee0b2 433av_fill(av, fill)
434register AV *av;
79072805 435I32 fill;
436{
a0d0e21e 437 if (!av)
438 croak("panic: null array");
79072805 439 if (fill < 0)
440 fill = -1;
463ee0b2 441 if (fill <= AvMAX(av)) {
a0d0e21e 442 I32 key = AvFILL(av);
443 SV** ary = AvARRAY(av);
444
445 if (AvREAL(av)) {
446 while (key > fill) {
447 SvREFCNT_dec(ary[key]);
448 ary[key--] = &sv_undef;
449 }
450 }
451 else {
452 while (key < fill)
453 ary[++key] = &sv_undef;
454 }
455
463ee0b2 456 AvFILL(av) = fill;
8990e307 457 if (SvSMAGICAL(av))
463ee0b2 458 mg_set((SV*)av);
459 }
a0d0e21e 460 else
461 (void)av_store(av,fill,&sv_undef);
79072805 462}