[win32] remove __declspec kludge in sdbm.h in favor of setting a
[p5sagit/p5-mst-13.2.git] / av.c
1 /*    av.c
2  *
3  *    Copyright (c) 1991-1997, Larry Wall
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  *
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
13  */
14
15 #include "EXTERN.h"
16 #include "perl.h"
17
18 void
19 av_reify(AV *av)
20 {
21     I32 key;
22     SV* sv;
23
24     if (AvREAL(av))                           
25         return;          
26 #ifdef DEBUGGING
27     if (SvRMAGICAL(av) && mg_find((SV*)av,'P')) 
28         warn("av_reify called on tied array");
29 #endif
30     key = AvMAX(av) + 1;
31     while (key > AvFILLp(av) + 1)
32         AvARRAY(av)[--key] = &sv_undef;
33     while (key) {
34         sv = AvARRAY(av)[--key];
35         assert(sv);
36         if (sv != &sv_undef) {
37             dTHR;
38             (void)SvREFCNT_inc(sv);
39         }
40     }
41     key = AvARRAY(av) - AvALLOC(av);
42     while (key)
43         AvALLOC(av)[--key] = &sv_undef;
44     AvREAL_on(av);
45 }
46
47 void
48 av_extend(AV *av, I32 key)
49 {
50     dTHR;                       /* only necessary if we have to extend stack */
51     MAGIC *mg;
52     if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
53         dSP;
54         ENTER;
55         SAVETMPS;
56         PUSHSTACK(SI_MAGIC);
57         PUSHMARK(SP);
58         EXTEND(SP,2);
59         PUSHs(mg->mg_obj);
60         PUSHs(sv_2mortal(newSViv(key+1)));
61         PUTBACK;
62         perl_call_method("EXTEND", G_SCALAR|G_DISCARD);
63         POPSTACK();
64         FREETMPS;
65         LEAVE;
66         return;
67     }
68     if (key > AvMAX(av)) {
69         SV** ary;
70         I32 tmp;
71         I32 newmax;
72
73         if (AvALLOC(av) != AvARRAY(av)) {
74             ary = AvALLOC(av) + AvFILLp(av) + 1;
75             tmp = AvARRAY(av) - AvALLOC(av);
76             Move(AvARRAY(av), AvALLOC(av), AvFILLp(av)+1, SV*);
77             AvMAX(av) += tmp;
78             SvPVX(av) = (char*)AvALLOC(av);
79             if (AvREAL(av)) {
80                 while (tmp)
81                     ary[--tmp] = &sv_undef;
82             }
83             
84             if (key > AvMAX(av) - 10) {
85                 newmax = key + AvMAX(av);
86                 goto resize;
87             }
88         }
89         else {
90             if (AvALLOC(av)) {
91 #ifndef STRANGE_MALLOC
92                 U32 bytes;
93 #endif
94
95                 newmax = key + AvMAX(av) / 5;
96               resize:
97 #ifdef STRANGE_MALLOC
98                 Renew(AvALLOC(av),newmax+1, SV*);
99 #else
100                 bytes = (newmax + 1) * sizeof(SV*);
101 #define MALLOC_OVERHEAD 16
102                 tmp = MALLOC_OVERHEAD;
103                 while (tmp - MALLOC_OVERHEAD < bytes)
104                     tmp += tmp;
105                 tmp -= MALLOC_OVERHEAD;
106                 tmp /= sizeof(SV*);
107                 assert(tmp > newmax);
108                 newmax = tmp - 1;
109                 New(2,ary, newmax+1, SV*);
110                 Copy(AvALLOC(av), ary, AvMAX(av)+1, SV*);
111                 if (AvMAX(av) > 64)
112                     offer_nice_chunk(AvALLOC(av), (AvMAX(av)+1) * sizeof(SV*));
113                 else
114                     Safefree(AvALLOC(av));
115                 AvALLOC(av) = ary;
116 #endif
117                 ary = AvALLOC(av) + AvMAX(av) + 1;
118                 tmp = newmax - AvMAX(av);
119                 if (av == curstack) {   /* Oops, grew stack (via av_store()?) */
120                     stack_sp = AvALLOC(av) + (stack_sp - stack_base);
121                     stack_base = AvALLOC(av);
122                     stack_max = stack_base + newmax;
123                 }
124             }
125             else {
126                 newmax = key < 4 ? 4 : key;
127                 New(2,AvALLOC(av), newmax+1, SV*);
128                 ary = AvALLOC(av) + 1;
129                 tmp = newmax;
130                 AvALLOC(av)[0] = &sv_undef;     /* For the stacks */
131             }
132             if (AvREAL(av)) {
133                 while (tmp)
134                     ary[--tmp] = &sv_undef;
135             }
136             
137             SvPVX(av) = (char*)AvALLOC(av);
138             AvMAX(av) = newmax;
139         }
140     }
141 }
142
143 SV**
144 av_fetch(register AV *av, I32 key, I32 lval)
145 {
146     SV *sv;
147
148     if (!av)
149         return 0;
150
151     if (key < 0) {
152         key += AvFILL(av) + 1;
153         if (key < 0)
154             return 0;
155     }
156
157     if (SvRMAGICAL(av)) {
158         if (mg_find((SV*)av,'P')) {
159             dTHR;
160             sv = sv_newmortal();
161             mg_copy((SV*)av, sv, 0, key);
162             av_fetch_sv = sv;
163             return &av_fetch_sv;
164         }
165     }
166
167     if (key > AvFILLp(av)) {
168         if (!lval)
169             return 0;
170         if (AvREALISH(av))
171             sv = NEWSV(5,0);
172         else
173             sv = sv_newmortal();
174         return av_store(av,key,sv);
175     }
176     if (AvARRAY(av)[key] == &sv_undef) {
177     emptyness:
178         if (lval) {
179             sv = NEWSV(6,0);
180             return av_store(av,key,sv);
181         }
182         return 0;
183     }
184     else if (AvREIFY(av)
185              && (!AvARRAY(av)[key]      /* eg. @_ could have freed elts */
186                  || SvTYPE(AvARRAY(av)[key]) == SVTYPEMASK)) {
187         AvARRAY(av)[key] = &sv_undef;   /* 1/2 reify */
188         goto emptyness;
189     }
190     return &AvARRAY(av)[key];
191 }
192
193 SV**
194 av_store(register AV *av, I32 key, SV *val)
195 {
196     SV** ary;
197     U32  fill;
198
199
200     if (!av)
201         return 0;
202     if (!val)
203         val = &sv_undef;
204
205     if (key < 0) {
206         key += AvFILL(av) + 1;
207         if (key < 0)
208             return 0;
209     }
210
211     if (SvREADONLY(av) && key >= AvFILL(av))
212         croak(no_modify);
213
214     if (SvRMAGICAL(av)) {
215         if (mg_find((SV*)av,'P')) {
216             if (val != &sv_undef) {
217                 mg_copy((SV*)av, val, 0, key);
218             }
219             return 0;
220         }
221     }
222
223     if (!AvREAL(av) && AvREIFY(av))
224         av_reify(av);
225     if (key > AvMAX(av))
226         av_extend(av,key);
227     ary = AvARRAY(av);
228     if (AvFILLp(av) < key) {
229         if (!AvREAL(av)) {
230             dTHR;
231             if (av == curstack && key > stack_sp - stack_base)
232                 stack_sp = stack_base + key;    /* XPUSH in disguise */
233             do
234                 ary[++AvFILLp(av)] = &sv_undef;
235             while (AvFILLp(av) < key);
236         }
237         AvFILLp(av) = key;
238     }
239     else if (AvREAL(av))
240         SvREFCNT_dec(ary[key]);
241     ary[key] = val;
242     if (SvSMAGICAL(av)) {
243         if (val != &sv_undef) {
244             MAGIC* mg = SvMAGIC(av);
245             sv_magic(val, (SV*)av, toLOWER(mg->mg_type), 0, key);
246         }
247         mg_set((SV*)av);
248     }
249     return &ary[key];
250 }
251
252 AV *
253 newAV(void)
254 {
255     register AV *av;
256
257     av = (AV*)NEWSV(3,0);
258     sv_upgrade((SV *)av, SVt_PVAV);
259     AvREAL_on(av);
260     AvALLOC(av) = 0;
261     SvPVX(av) = 0;
262     AvMAX(av) = AvFILLp(av) = -1;
263     return av;
264 }
265
266 AV *
267 av_make(register I32 size, register SV **strp)
268 {
269     register AV *av;
270     register I32 i;
271     register SV** ary;
272
273     av = (AV*)NEWSV(8,0);
274     sv_upgrade((SV *) av,SVt_PVAV);
275     AvFLAGS(av) = AVf_REAL;
276     if (size) {         /* `defined' was returning undef for size==0 anyway. */
277         New(4,ary,size,SV*);
278         AvALLOC(av) = ary;
279         SvPVX(av) = (char*)ary;
280         AvFILLp(av) = size - 1;
281         AvMAX(av) = size - 1;
282         for (i = 0; i < size; i++) {
283             assert (*strp);
284             ary[i] = NEWSV(7,0);
285             sv_setsv(ary[i], *strp);
286             strp++;
287         }
288     }
289     return av;
290 }
291
292 AV *
293 av_fake(register I32 size, register SV **strp)
294 {
295     register AV *av;
296     register SV** ary;
297
298     av = (AV*)NEWSV(9,0);
299     sv_upgrade((SV *)av, SVt_PVAV);
300     New(4,ary,size+1,SV*);
301     AvALLOC(av) = ary;
302     Copy(strp,ary,size,SV*);
303     AvFLAGS(av) = AVf_REIFY;
304     SvPVX(av) = (char*)ary;
305     AvFILLp(av) = size - 1;
306     AvMAX(av) = size - 1;
307     while (size--) {
308         assert (*strp);
309         SvTEMP_off(*strp);
310         strp++;
311     }
312     return av;
313 }
314
315 void
316 av_clear(register AV *av)
317 {
318     register I32 key;
319     SV** ary;
320
321 #ifdef DEBUGGING
322     if (SvREFCNT(av) <= 0) {
323         warn("Attempt to clear deleted array");
324     }
325 #endif
326     if (!av)
327         return;
328     /*SUPPRESS 560*/
329
330     /* Give any tie a chance to cleanup first */
331     if (SvRMAGICAL(av))
332         mg_clear((SV*)av); 
333
334     if (AvMAX(av) < 0)
335         return;
336
337     if (AvREAL(av)) {
338         ary = AvARRAY(av);
339         key = AvFILLp(av) + 1;
340         while (key) {
341             SvREFCNT_dec(ary[--key]);
342             ary[key] = &sv_undef;
343         }
344     }
345     if (key = AvARRAY(av) - AvALLOC(av)) {
346         AvMAX(av) += key;
347         SvPVX(av) = (char*)AvALLOC(av);
348     }
349     AvFILLp(av) = -1;
350
351 }
352
353 void
354 av_undef(register AV *av)
355 {
356     register I32 key;
357
358     if (!av)
359         return;
360     /*SUPPRESS 560*/
361
362     /* Give any tie a chance to cleanup first */
363     if (SvRMAGICAL(av) && mg_find((SV*)av,'P')) 
364         av_fill(av, -1);   /* mg_clear() ? */
365
366     if (AvREAL(av)) {
367         key = AvFILLp(av) + 1;
368         while (key)
369             SvREFCNT_dec(AvARRAY(av)[--key]);
370     }
371     Safefree(AvALLOC(av));
372     SvPVX(av) = 0;
373     AvALLOC(av) = 0;
374     SvPVX(av) = 0;
375     AvMAX(av) = AvFILLp(av) = -1;
376     if (AvARYLEN(av)) {
377         SvREFCNT_dec(AvARYLEN(av));
378         AvARYLEN(av) = 0;
379     }
380 }
381
382 void
383 av_push(register AV *av, SV *val)
384 {             
385     MAGIC *mg;
386     if (!av)
387         return;
388     if (SvREADONLY(av))
389         croak(no_modify);
390
391     if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
392         dSP;
393         PUSHSTACK(SI_MAGIC);
394         PUSHMARK(SP);
395         EXTEND(SP,2);
396         PUSHs(mg->mg_obj);
397         PUSHs(val);
398         PUTBACK;
399         ENTER;
400         perl_call_method("PUSH", G_SCALAR|G_DISCARD);
401         LEAVE;
402         POPSTACK();
403         return;
404     }
405     av_store(av,AvFILLp(av)+1,val);
406 }
407
408 SV *
409 av_pop(register AV *av)
410 {
411     SV *retval;
412     MAGIC* mg;
413
414     if (!av || AvFILL(av) < 0)
415         return &sv_undef;
416     if (SvREADONLY(av))
417         croak(no_modify);
418     if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
419         dSP;    
420         PUSHSTACK(SI_MAGIC);
421         PUSHMARK(SP);
422         XPUSHs(mg->mg_obj);
423         PUTBACK;
424         ENTER;
425         if (perl_call_method("POP", G_SCALAR)) {
426             retval = newSVsv(*stack_sp--);    
427         } else {    
428             retval = &sv_undef;
429         }
430         LEAVE;
431         POPSTACK();
432         return retval;
433     }
434     retval = AvARRAY(av)[AvFILLp(av)];
435     AvARRAY(av)[AvFILLp(av)--] = &sv_undef;
436     if (SvSMAGICAL(av))
437         mg_set((SV*)av);
438     return retval;
439 }
440
441 void
442 av_unshift(register AV *av, register I32 num)
443 {
444     register I32 i;
445     register SV **ary;
446     MAGIC* mg;
447
448     if (!av || num <= 0)
449         return;
450     if (SvREADONLY(av))
451         croak(no_modify);
452
453     if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
454         dSP;
455         PUSHSTACK(SI_MAGIC);
456         PUSHMARK(SP);
457         EXTEND(SP,1+num);
458         PUSHs(mg->mg_obj);
459         while (num-- > 0) {
460             PUSHs(&sv_undef);
461         }
462         PUTBACK;
463         ENTER;
464         perl_call_method("UNSHIFT", G_SCALAR|G_DISCARD);
465         LEAVE;
466         POPSTACK();
467         return;
468     }
469
470     if (!AvREAL(av) && AvREIFY(av))
471         av_reify(av);
472     i = AvARRAY(av) - AvALLOC(av);
473     if (i) {
474         if (i > num)
475             i = num;
476         num -= i;
477     
478         AvMAX(av) += i;
479         AvFILLp(av) += i;
480         SvPVX(av) = (char*)(AvARRAY(av) - i);
481     }
482     if (num) {     
483         i = AvFILLp(av);
484         av_extend(av, i + num);
485         AvFILLp(av) += num;
486         ary = AvARRAY(av);
487         Move(ary, ary + num, i + 1, SV*);
488         do {
489             ary[--num] = &sv_undef;
490         } while (num);
491     }
492 }
493
494 SV *
495 av_shift(register AV *av)
496 {
497     SV *retval;
498     MAGIC* mg;
499
500     if (!av || AvFILL(av) < 0)
501         return &sv_undef;
502     if (SvREADONLY(av))
503         croak(no_modify);
504     if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
505         dSP;
506         PUSHSTACK(SI_MAGIC);
507         PUSHMARK(SP);
508         XPUSHs(mg->mg_obj);
509         PUTBACK;
510         ENTER;
511         if (perl_call_method("SHIFT", G_SCALAR)) {
512             retval = newSVsv(*stack_sp--);            
513         } else {    
514             retval = &sv_undef;
515         }     
516         LEAVE;
517         POPSTACK();
518         return retval;
519     }
520     retval = *AvARRAY(av);
521     if (AvREAL(av))
522         *AvARRAY(av) = &sv_undef;
523     SvPVX(av) = (char*)(AvARRAY(av) + 1);
524     AvMAX(av)--;
525     AvFILLp(av)--;
526     if (SvSMAGICAL(av))
527         mg_set((SV*)av);
528     return retval;
529 }
530
531 I32
532 av_len(register AV *av)
533 {
534     return AvFILL(av);
535 }
536
537 void
538 av_fill(register AV *av, I32 fill)
539 {
540     MAGIC *mg;
541     if (!av)
542         croak("panic: null array");
543     if (fill < 0)
544         fill = -1;
545     if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
546         dSP;            
547         ENTER;
548         SAVETMPS;
549         PUSHSTACK(SI_MAGIC);
550         PUSHMARK(SP);
551         EXTEND(SP,2);
552         PUSHs(mg->mg_obj);
553         PUSHs(sv_2mortal(newSViv(fill+1)));
554         PUTBACK;
555         perl_call_method("STORESIZE", G_SCALAR|G_DISCARD);
556         POPSTACK();
557         FREETMPS;
558         LEAVE;
559         return;
560     }
561     if (fill <= AvMAX(av)) {
562         I32 key = AvFILLp(av);
563         SV** ary = AvARRAY(av);
564
565         if (AvREAL(av)) {
566             while (key > fill) {
567                 SvREFCNT_dec(ary[key]);
568                 ary[key--] = &sv_undef;
569             }
570         }
571         else {
572             while (key < fill)
573                 ary[++key] = &sv_undef;
574         }
575             
576         AvFILLp(av) = fill;
577         if (SvSMAGICAL(av))
578             mg_set((SV*)av);
579     }
580     else
581         (void)av_store(av,fill,&sv_undef);
582 }
583
584   
585 HV*
586 avhv_keys(AV *av)
587 {
588     SV **keysp;
589     HV *keys = Nullhv;
590
591     keysp = av_fetch(av, 0, FALSE);
592     if (keysp) {
593         SV *sv = *keysp;
594         if (SvGMAGICAL(sv))
595             mg_get(sv);
596         if (SvROK(sv)) {
597             sv = SvRV(sv);
598             if (SvTYPE(sv) == SVt_PVHV)
599                 keys = (HV*)sv;
600         }
601     }
602     if (!keys)
603         croak("Can't coerce array into hash");
604     return keys;
605 }
606
607 SV**
608 avhv_fetch(AV *av, char *key, U32 klen, I32 lval)
609 {
610     SV **indsvp;
611     HV *keys = avhv_keys(av);
612     I32 ind;
613     
614     indsvp = hv_fetch(keys, key, klen, FALSE);
615     if (indsvp) {
616         ind = SvIV(*indsvp);
617         if (ind < 1)
618             croak("Bad index while coercing array into hash");
619     } else {
620         if (!lval)
621             return 0;
622         
623         ind = AvFILL(av) + 1;
624         hv_store(keys, key, klen, newSViv(ind), 0);
625     }
626     return av_fetch(av, ind, lval);
627 }
628
629 SV**
630 avhv_fetch_ent(AV *av, SV *keysv, I32 lval, U32 hash)
631 {
632     SV **indsvp;
633     HV *keys = avhv_keys(av);
634     HE *he;
635     I32 ind;
636     
637     he = hv_fetch_ent(keys, keysv, FALSE, hash);
638     if (he) {
639         ind = SvIV(HeVAL(he));
640         if (ind < 1)
641             croak("Bad index while coercing array into hash");
642     } else {
643         if (!lval)
644             return 0;
645         
646         ind = AvFILL(av) + 1;
647         hv_store_ent(keys, keysv, newSViv(ind), 0);
648     }
649     return av_fetch(av, ind, lval);
650 }
651
652 SV**
653 avhv_store(AV *av, char *key, U32 klen, SV *val, U32 hash)
654 {
655     SV **indsvp;
656     HV *keys = avhv_keys(av);
657     I32 ind;
658     
659     indsvp = hv_fetch(keys, key, klen, FALSE);
660     if (indsvp) {
661         ind = SvIV(*indsvp);
662         if (ind < 1)
663             croak("Bad index while coercing array into hash");
664     } else {
665         ind = AvFILL(av) + 1;
666         hv_store(keys, key, klen, newSViv(ind), hash);
667     }
668     return av_store(av, ind, val);
669 }
670
671 SV**
672 avhv_store_ent(AV *av, SV *keysv, SV *val, U32 hash)
673 {
674     HV *keys = avhv_keys(av);
675     HE *he;
676     I32 ind;
677     
678     he = hv_fetch_ent(keys, keysv, FALSE, hash);
679     if (he) {
680         ind = SvIV(HeVAL(he));
681         if (ind < 1)
682             croak("Bad index while coercing array into hash");
683     } else {
684         ind = AvFILL(av) + 1;
685         hv_store_ent(keys, keysv, newSViv(ind), hash);
686     }
687     return av_store(av, ind, val);
688 }
689
690 bool
691 avhv_exists_ent(AV *av, SV *keysv, U32 hash)
692 {
693     HV *keys = avhv_keys(av);
694     return hv_exists_ent(keys, keysv, hash);
695 }
696
697 bool
698 avhv_exists(AV *av, char *key, U32 klen)
699 {
700     HV *keys = avhv_keys(av);
701     return hv_exists(keys, key, klen);
702 }
703
704 /* avhv_delete leaks. Caller can re-index and compress if so desired. */
705 SV *
706 avhv_delete(AV *av, char *key, U32 klen, I32 flags)
707 {
708     HV *keys = avhv_keys(av);
709     SV *sv;
710     SV **svp;
711     I32 ind;
712     
713     sv = hv_delete(keys, key, klen, 0);
714     if (!sv)
715         return Nullsv;
716     ind = SvIV(sv);
717     if (ind < 1)
718         croak("Bad index while coercing array into hash");
719     svp = av_fetch(av, ind, FALSE);
720     if (!svp)
721         return Nullsv;
722     if (flags & G_DISCARD) {
723         sv = Nullsv;
724         SvREFCNT_dec(*svp);
725     } else {
726         sv = sv_2mortal(*svp);
727     }
728     *svp = &sv_undef;
729     return sv;
730 }
731
732 /* avhv_delete_ent leaks. Caller can re-index and compress if so desired. */
733 SV *
734 avhv_delete_ent(AV *av, SV *keysv, I32 flags, U32 hash)
735 {
736     HV *keys = avhv_keys(av);
737     SV *sv;
738     SV **svp;
739     I32 ind;
740     
741     sv = hv_delete_ent(keys, keysv, 0, hash);
742     if (!sv)
743         return Nullsv;
744     ind = SvIV(sv);
745     if (ind < 1)
746         croak("Bad index while coercing array into hash");
747     svp = av_fetch(av, ind, FALSE);
748     if (!svp)
749         return Nullsv;
750     if (flags & G_DISCARD) {
751         sv = Nullsv;
752         SvREFCNT_dec(*svp);
753     } else {
754         sv = sv_2mortal(*svp);
755     }
756     *svp = &sv_undef;
757     return sv;
758 }
759
760 I32
761 avhv_iterinit(AV *av)
762 {
763     HV *keys = avhv_keys(av);
764     return hv_iterinit(keys);
765 }
766
767 HE *
768 avhv_iternext(AV *av)
769 {
770     HV *keys = avhv_keys(av);
771     return hv_iternext(keys);
772 }
773
774 SV *
775 avhv_iterval(AV *av, register HE *entry)
776 {
777     HV *keys = avhv_keys(av);
778     SV *sv;
779     I32 ind;
780     
781     sv = hv_iterval(keys, entry);
782     ind = SvIV(sv);
783     if (ind < 1)
784         croak("Bad index while coercing array into hash");
785     return *av_fetch(av, ind, TRUE);
786 }
787
788 SV *
789 avhv_iternextsv(AV *av, char **key, I32 *retlen)
790 {
791     HV *keys = avhv_keys(av);
792     HE *he;
793     SV *sv;
794     I32 ind;
795     
796     he = hv_iternext(keys);
797     if (!he)
798         return Nullsv;
799     *key = hv_iterkey(he, retlen);
800     sv = hv_iterval(keys, he);
801     ind = SvIV(sv);
802     if (ind < 1)
803         croak("Bad index while coercing array into hash");
804     return *av_fetch(av, ind, TRUE);
805 }