Minor Win32 glitch with -S flag
[p5sagit/p5-mst-13.2.git] / av.c
CommitLineData
a0d0e21e 1/* av.c
79072805 2 *
9607fc9c 3 * Copyright (c) 1991-1997, 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 }
29de640a 36 key = AvARRAY(av) - AvALLOC(av);
37 while (key)
38 AvALLOC(av)[--key] = &sv_undef;
a0d0e21e 39 AvREAL_on(av);
40}
41
42void
43av_extend(av,key)
44AV *av;
45I32 key;
46{
47 if (key > AvMAX(av)) {
48 SV** ary;
49 I32 tmp;
50 I32 newmax;
51
52 if (AvALLOC(av) != AvARRAY(av)) {
53 ary = AvALLOC(av) + AvFILL(av) + 1;
54 tmp = AvARRAY(av) - AvALLOC(av);
55 Move(AvARRAY(av), AvALLOC(av), AvFILL(av)+1, SV*);
56 AvMAX(av) += tmp;
57 SvPVX(av) = (char*)AvALLOC(av);
58 if (AvREAL(av)) {
59 while (tmp)
60 ary[--tmp] = &sv_undef;
61 }
62
63 if (key > AvMAX(av) - 10) {
64 newmax = key + AvMAX(av);
65 goto resize;
66 }
67 }
68 else {
69 if (AvALLOC(av)) {
c07a80fd 70#ifndef STRANGE_MALLOC
4633a7c4 71 U32 bytes;
c07a80fd 72#endif
4633a7c4 73
a0d0e21e 74 newmax = key + AvMAX(av) / 5;
75 resize:
4633a7c4 76#ifdef STRANGE_MALLOC
a0d0e21e 77 Renew(AvALLOC(av),newmax+1, SV*);
4633a7c4 78#else
79 bytes = (newmax + 1) * sizeof(SV*);
80#define MALLOC_OVERHEAD 16
81 tmp = MALLOC_OVERHEAD;
82 while (tmp - MALLOC_OVERHEAD < bytes)
83 tmp += tmp;
84 tmp -= MALLOC_OVERHEAD;
85 tmp /= sizeof(SV*);
86 assert(tmp > newmax);
87 newmax = tmp - 1;
88 New(2,ary, newmax+1, SV*);
89 Copy(AvALLOC(av), ary, AvMAX(av)+1, SV*);
c07a80fd 90 if (AvMAX(av) > 64 && !nice_chunk) {
91 nice_chunk = (char*)AvALLOC(av);
92 nice_chunk_size = (AvMAX(av) + 1) * sizeof(SV*);
93 }
4633a7c4 94 else
95 Safefree(AvALLOC(av));
96 AvALLOC(av) = ary;
97#endif
a0d0e21e 98 ary = AvALLOC(av) + AvMAX(av) + 1;
99 tmp = newmax - AvMAX(av);
7d55f622 100 if (av == curstack) { /* Oops, grew stack (via av_store()?) */
a0d0e21e 101 stack_sp = AvALLOC(av) + (stack_sp - stack_base);
102 stack_base = AvALLOC(av);
103 stack_max = stack_base + newmax;
104 }
105 }
106 else {
107 newmax = key < 4 ? 4 : key;
108 New(2,AvALLOC(av), newmax+1, SV*);
109 ary = AvALLOC(av) + 1;
110 tmp = newmax;
111 AvALLOC(av)[0] = &sv_undef; /* For the stacks */
112 }
113 if (AvREAL(av)) {
114 while (tmp)
115 ary[--tmp] = &sv_undef;
116 }
117
118 SvPVX(av) = (char*)AvALLOC(av);
119 AvMAX(av) = newmax;
120 }
121 }
122}
123
79072805 124SV**
463ee0b2 125av_fetch(av,key,lval)
126register AV *av;
79072805 127I32 key;
128I32 lval;
129{
130 SV *sv;
131
a0d0e21e 132 if (!av)
133 return 0;
134
8990e307 135 if (SvRMAGICAL(av)) {
463ee0b2 136 if (mg_find((SV*)av,'P')) {
8990e307 137 sv = sv_newmortal();
463ee0b2 138 mg_copy((SV*)av, sv, 0, key);
463ee0b2 139 Sv = sv;
140 return &Sv;
141 }
142 }
143
a0d0e21e 144 if (key < 0) {
145 key += AvFILL(av) + 1;
146 if (key < 0)
147 return 0;
148 }
149 else if (key > AvFILL(av)) {
150 if (!lval)
151 return 0;
152 if (AvREALISH(av))
153 sv = NEWSV(5,0);
154 else
155 sv = sv_newmortal();
156 return av_store(av,key,sv);
79072805 157 }
a0d0e21e 158 if (AvARRAY(av)[key] == &sv_undef) {
4dbf4341 159 emptyness:
79072805 160 if (lval) {
161 sv = NEWSV(6,0);
463ee0b2 162 return av_store(av,key,sv);
79072805 163 }
164 return 0;
165 }
4dbf4341 166 else if (AvREIFY(av)
167 && (!AvARRAY(av)[key] /* eg. @_ could have freed elts */
168 || SvTYPE(AvARRAY(av)[key]) == SVTYPEMASK)) {
169 AvARRAY(av)[key] = &sv_undef; /* 1/2 reify */
170 goto emptyness;
171 }
463ee0b2 172 return &AvARRAY(av)[key];
79072805 173}
174
175SV**
463ee0b2 176av_store(av,key,val)
177register AV *av;
79072805 178I32 key;
179SV *val;
180{
79072805 181 SV** ary;
182
a0d0e21e 183 if (!av)
184 return 0;
43fcc5d2 185 if (!val)
186 val = &sv_undef;
463ee0b2 187
8990e307 188 if (SvRMAGICAL(av)) {
463ee0b2 189 if (mg_find((SV*)av,'P')) {
43fcc5d2 190 if (val != &sv_undef)
191 mg_copy((SV*)av, val, 0, key);
463ee0b2 192 return 0;
193 }
194 }
195
a0d0e21e 196 if (key < 0) {
197 key += AvFILL(av) + 1;
198 if (key < 0)
199 return 0;
79072805 200 }
43fcc5d2 201 if (SvREADONLY(av) && key >= AvFILL(av))
202 croak(no_modify);
49beac48 203 if (!AvREAL(av) && AvREIFY(av))
a0d0e21e 204 av_reify(av);
29de640a 205 if (key > AvMAX(av))
206 av_extend(av,key);
463ee0b2 207 ary = AvARRAY(av);
a0d0e21e 208 if (AvFILL(av) < key) {
209 if (!AvREAL(av)) {
7d55f622 210 if (av == curstack && key > stack_sp - stack_base)
a0d0e21e 211 stack_sp = stack_base + key; /* XPUSH in disguise */
212 do
213 ary[++AvFILL(av)] = &sv_undef;
214 while (AvFILL(av) < key);
79072805 215 }
a0d0e21e 216 AvFILL(av) = key;
79072805 217 }
a0d0e21e 218 else if (AvREAL(av))
219 SvREFCNT_dec(ary[key]);
79072805 220 ary[key] = val;
8990e307 221 if (SvSMAGICAL(av)) {
a0d0e21e 222 if (val != &sv_undef) {
223 MAGIC* mg = SvMAGIC(av);
224 sv_magic(val, (SV*)av, toLOWER(mg->mg_type), 0, key);
225 }
463ee0b2 226 mg_set((SV*)av);
227 }
79072805 228 return &ary[key];
229}
230
231AV *
232newAV()
233{
463ee0b2 234 register AV *av;
79072805 235
a0d0e21e 236 av = (AV*)NEWSV(3,0);
237 sv_upgrade((SV *)av, SVt_PVAV);
463ee0b2 238 AvREAL_on(av);
239 AvALLOC(av) = 0;
240 SvPVX(av) = 0;
241 AvMAX(av) = AvFILL(av) = -1;
242 return av;
79072805 243}
244
245AV *
246av_make(size,strp)
247register I32 size;
248register SV **strp;
249{
463ee0b2 250 register AV *av;
79072805 251 register I32 i;
252 register SV** ary;
253
a0d0e21e 254 av = (AV*)NEWSV(8,0);
255 sv_upgrade((SV *) av,SVt_PVAV);
a0d0e21e 256 AvFLAGS(av) = AVf_REAL;
573fa4ea 257 if (size) { /* `defined' was returning undef for size==0 anyway. */
258 New(4,ary,size,SV*);
259 AvALLOC(av) = ary;
260 SvPVX(av) = (char*)ary;
261 AvFILL(av) = size - 1;
262 AvMAX(av) = size - 1;
263 for (i = 0; i < size; i++) {
264 assert (*strp);
265 ary[i] = NEWSV(7,0);
266 sv_setsv(ary[i], *strp);
267 strp++;
268 }
79072805 269 }
463ee0b2 270 return av;
79072805 271}
272
273AV *
274av_fake(size,strp)
275register I32 size;
276register SV **strp;
277{
463ee0b2 278 register AV *av;
79072805 279 register SV** ary;
280
a0d0e21e 281 av = (AV*)NEWSV(9,0);
282 sv_upgrade((SV *)av, SVt_PVAV);
79072805 283 New(4,ary,size+1,SV*);
463ee0b2 284 AvALLOC(av) = ary;
79072805 285 Copy(strp,ary,size,SV*);
a0d0e21e 286 AvFLAGS(av) = AVf_REIFY;
463ee0b2 287 SvPVX(av) = (char*)ary;
288 AvFILL(av) = size - 1;
289 AvMAX(av) = size - 1;
79072805 290 while (size--) {
a0d0e21e 291 assert (*strp);
292 SvTEMP_off(*strp);
79072805 293 strp++;
294 }
463ee0b2 295 return av;
79072805 296}
297
298void
463ee0b2 299av_clear(av)
300register AV *av;
79072805 301{
302 register I32 key;
a0d0e21e 303 SV** ary;
79072805 304
7d55f622 305#ifdef DEBUGGING
306 if (SvREFCNT(av) <= 0) {
307 warn("Attempt to clear deleted array");
308 }
309#endif
a0d0e21e 310 if (!av || AvMAX(av) < 0)
79072805 311 return;
312 /*SUPPRESS 560*/
a0d0e21e 313
314 if (AvREAL(av)) {
315 ary = AvARRAY(av);
316 key = AvFILL(av) + 1;
317 while (key) {
318 SvREFCNT_dec(ary[--key]);
319 ary[key] = &sv_undef;
320 }
321 }
463ee0b2 322 if (key = AvARRAY(av) - AvALLOC(av)) {
323 AvMAX(av) += key;
a0d0e21e 324 SvPVX(av) = (char*)AvALLOC(av);
79072805 325 }
463ee0b2 326 AvFILL(av) = -1;
79072805 327}
328
329void
463ee0b2 330av_undef(av)
331register AV *av;
79072805 332{
333 register I32 key;
334
463ee0b2 335 if (!av)
79072805 336 return;
337 /*SUPPRESS 560*/
a0d0e21e 338 if (AvREAL(av)) {
339 key = AvFILL(av) + 1;
340 while (key)
341 SvREFCNT_dec(AvARRAY(av)[--key]);
342 }
463ee0b2 343 Safefree(AvALLOC(av));
344 AvALLOC(av) = 0;
345 SvPVX(av) = 0;
346 AvMAX(av) = AvFILL(av) = -1;
748a9306 347 if (AvARYLEN(av)) {
348 SvREFCNT_dec(AvARYLEN(av));
349 AvARYLEN(av) = 0;
350 }
79072805 351}
352
a0d0e21e 353void
463ee0b2 354av_push(av,val)
355register AV *av;
79072805 356SV *val;
357{
a0d0e21e 358 if (!av)
359 return;
360 av_store(av,AvFILL(av)+1,val);
79072805 361}
362
363SV *
463ee0b2 364av_pop(av)
365register AV *av;
79072805 366{
367 SV *retval;
368
a0d0e21e 369 if (!av || AvFILL(av) < 0)
370 return &sv_undef;
43fcc5d2 371 if (SvREADONLY(av))
372 croak(no_modify);
463ee0b2 373 retval = AvARRAY(av)[AvFILL(av)];
a0d0e21e 374 AvARRAY(av)[AvFILL(av)--] = &sv_undef;
8990e307 375 if (SvSMAGICAL(av))
463ee0b2 376 mg_set((SV*)av);
79072805 377 return retval;
378}
379
380void
463ee0b2 381av_unshift(av,num)
382register AV *av;
79072805 383register I32 num;
384{
385 register I32 i;
386 register SV **sstr,**dstr;
387
a0d0e21e 388 if (!av || num <= 0)
79072805 389 return;
43fcc5d2 390 if (SvREADONLY(av))
391 croak(no_modify);
49beac48 392 if (!AvREAL(av) && AvREIFY(av))
393 av_reify(av);
a0d0e21e 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 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 413 *dstr-- = *sstr--;
414#ifdef BUGGY_MSC5
415 # pragma loop_opt() /* loop-optimization back to command-line setting */
416#endif /* BUGGY_MSC5 */
417 }
a0d0e21e 418 while (num)
419 AvARRAY(av)[--num] = &sv_undef;
79072805 420 }
421}
422
423SV *
463ee0b2 424av_shift(av)
425register AV *av;
79072805 426{
427 SV *retval;
428
a0d0e21e 429 if (!av || AvFILL(av) < 0)
430 return &sv_undef;
43fcc5d2 431 if (SvREADONLY(av))
432 croak(no_modify);
463ee0b2 433 retval = *AvARRAY(av);
a0d0e21e 434 if (AvREAL(av))
435 *AvARRAY(av) = &sv_undef;
463ee0b2 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 441 return retval;
442}
443
444I32
463ee0b2 445av_len(av)
446register AV *av;
79072805 447{
463ee0b2 448 return AvFILL(av);
79072805 449}
450
451void
463ee0b2 452av_fill(av, fill)
453register AV *av;
79072805 454I32 fill;
455{
a0d0e21e 456 if (!av)
457 croak("panic: null array");
79072805 458 if (fill < 0)
459 fill = -1;
463ee0b2 460 if (fill <= AvMAX(av)) {
a0d0e21e 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 477 mg_set((SV*)av);
478 }
a0d0e21e 479 else
480 (void)av_store(av,fill,&sv_undef);
79072805 481}