source: trunk/third/perl/av.c @ 20075

Revision 20075, 21.9 KB checked in by zacheiss, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20074, which included commits to RCS files with non-trunk default branches.
Line 
1/*    av.c
2 *
3 *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 *    2000, 2001, 2002, 2003, by Larry Wall and others
5 *
6 *    You may distribute under the terms of either the GNU General Public
7 *    License or the Artistic License, as specified in the README file.
8 *
9 */
10
11/*
12 * "...for the Entwives desired order, and plenty, and peace (by which they
13 * meant that things should remain where they had set them)." --Treebeard
14 */
15
16/*
17=head1 Array Manipulation Functions
18*/
19
20#include "EXTERN.h"
21#define PERL_IN_AV_C
22#include "perl.h"
23
24void
25Perl_av_reify(pTHX_ AV *av)
26{
27    I32 key;
28    SV* sv;
29
30    if (AvREAL(av))
31        return;
32#ifdef DEBUGGING
33    if (SvTIED_mg((SV*)av, PERL_MAGIC_tied) && ckWARN_d(WARN_DEBUGGING))
34        Perl_warner(aTHX_ packWARN(WARN_DEBUGGING), "av_reify called on tied array");
35#endif
36    key = AvMAX(av) + 1;
37    while (key > AvFILLp(av) + 1)
38        AvARRAY(av)[--key] = &PL_sv_undef;
39    while (key) {
40        sv = AvARRAY(av)[--key];
41        assert(sv);
42        if (sv != &PL_sv_undef)
43            (void)SvREFCNT_inc(sv);
44    }
45    key = AvARRAY(av) - AvALLOC(av);
46    while (key)
47        AvALLOC(av)[--key] = &PL_sv_undef;
48    AvREIFY_off(av);
49    AvREAL_on(av);
50}
51
52/*
53=for apidoc av_extend
54
55Pre-extend an array.  The C<key> is the index to which the array should be
56extended.
57
58=cut
59*/
60
61void
62Perl_av_extend(pTHX_ AV *av, I32 key)
63{
64    MAGIC *mg;
65    if ((mg = SvTIED_mg((SV*)av, PERL_MAGIC_tied))) {
66        dSP;
67        ENTER;
68        SAVETMPS;
69        PUSHSTACKi(PERLSI_MAGIC);
70        PUSHMARK(SP);
71        EXTEND(SP,2);
72        PUSHs(SvTIED_obj((SV*)av, mg));
73        PUSHs(sv_2mortal(newSViv(key+1)));
74        PUTBACK;
75        call_method("EXTEND", G_SCALAR|G_DISCARD);
76        POPSTACK;
77        FREETMPS;
78        LEAVE;
79        return;
80    }
81    if (key > AvMAX(av)) {
82        SV** ary;
83        I32 tmp;
84        I32 newmax;
85
86        if (AvALLOC(av) != AvARRAY(av)) {
87            ary = AvALLOC(av) + AvFILLp(av) + 1;
88            tmp = AvARRAY(av) - AvALLOC(av);
89            Move(AvARRAY(av), AvALLOC(av), AvFILLp(av)+1, SV*);
90            AvMAX(av) += tmp;
91            SvPVX(av) = (char*)AvALLOC(av);
92            if (AvREAL(av)) {
93                while (tmp)
94                    ary[--tmp] = &PL_sv_undef;
95            }
96           
97            if (key > AvMAX(av) - 10) {
98                newmax = key + AvMAX(av);
99                goto resize;
100            }
101        }
102        else {
103            if (AvALLOC(av)) {
104#if !defined(STRANGE_MALLOC) && !defined(MYMALLOC)
105                MEM_SIZE bytes;
106                IV itmp;
107#endif
108
109#ifdef MYMALLOC
110                newmax = malloced_size((void*)AvALLOC(av))/sizeof(SV*) - 1;
111
112                if (key <= newmax)
113                    goto resized;
114#endif
115                newmax = key + AvMAX(av) / 5;
116              resize:
117#if defined(STRANGE_MALLOC) || defined(MYMALLOC)
118                Renew(AvALLOC(av),newmax+1, SV*);
119#else
120                bytes = (newmax + 1) * sizeof(SV*);
121#define MALLOC_OVERHEAD 16
122                itmp = MALLOC_OVERHEAD;
123                while ((MEM_SIZE)(itmp - MALLOC_OVERHEAD) < bytes)
124                    itmp += itmp;
125                itmp -= MALLOC_OVERHEAD;
126                itmp /= sizeof(SV*);
127                assert(itmp > newmax);
128                newmax = itmp - 1;
129                assert(newmax >= AvMAX(av));
130                New(2,ary, newmax+1, SV*);
131                Copy(AvALLOC(av), ary, AvMAX(av)+1, SV*);
132                if (AvMAX(av) > 64)
133                    offer_nice_chunk(AvALLOC(av), (AvMAX(av)+1) * sizeof(SV*));
134                else
135                    Safefree(AvALLOC(av));
136                AvALLOC(av) = ary;
137#endif
138#ifdef MYMALLOC
139              resized:
140#endif
141                ary = AvALLOC(av) + AvMAX(av) + 1;
142                tmp = newmax - AvMAX(av);
143                if (av == PL_curstack) {        /* Oops, grew stack (via av_store()?) */
144                    PL_stack_sp = AvALLOC(av) + (PL_stack_sp - PL_stack_base);
145                    PL_stack_base = AvALLOC(av);
146                    PL_stack_max = PL_stack_base + newmax;
147                }
148            }
149            else {
150                newmax = key < 3 ? 3 : key;
151                New(2,AvALLOC(av), newmax+1, SV*);
152                ary = AvALLOC(av) + 1;
153                tmp = newmax;
154                AvALLOC(av)[0] = &PL_sv_undef;  /* For the stacks */
155            }
156            if (AvREAL(av)) {
157                while (tmp)
158                    ary[--tmp] = &PL_sv_undef;
159            }
160           
161            SvPVX(av) = (char*)AvALLOC(av);
162            AvMAX(av) = newmax;
163        }
164    }
165}
166
167/*
168=for apidoc av_fetch
169
170Returns the SV at the specified index in the array.  The C<key> is the
171index.  If C<lval> is set then the fetch will be part of a store.  Check
172that the return value is non-null before dereferencing it to a C<SV*>.
173
174See L<perlguts/"Understanding the Magic of Tied Hashes and Arrays"> for
175more information on how to use this function on tied arrays.
176
177=cut
178*/
179
180SV**
181Perl_av_fetch(pTHX_ register AV *av, I32 key, I32 lval)
182{
183    SV *sv;
184
185    if (!av)
186        return 0;
187
188    if (SvRMAGICAL(av)) {
189        MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
190        if (tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata)) {
191            U32 adjust_index = 1;
192
193            if (tied_magic && key < 0) {
194                /* Handle negative array indices 20020222 MJD */
195                SV **negative_indices_glob =
196                    hv_fetch(SvSTASH(SvRV(SvTIED_obj((SV *)av,
197                                                     tied_magic))),
198                             NEGATIVE_INDICES_VAR, 16, 0);
199
200                if (negative_indices_glob
201                    && SvTRUE(GvSV(*negative_indices_glob)))
202                    adjust_index = 0;
203            }
204
205            if (key < 0 && adjust_index) {
206                key += AvFILL(av) + 1;
207                if (key < 0)
208                    return 0;
209            }
210
211            sv = sv_newmortal();
212            sv_upgrade(sv, SVt_PVLV);
213            mg_copy((SV*)av, sv, 0, key);
214            LvTYPE(sv) = 't';
215            LvTARG(sv) = sv; /* fake (SV**) */
216            return &(LvTARG(sv));
217        }
218    }
219
220    if (key < 0) {
221        key += AvFILL(av) + 1;
222        if (key < 0)
223            return 0;
224    }
225
226    if (key > AvFILLp(av)) {
227        if (!lval)
228            return 0;
229        sv = NEWSV(5,0);
230        return av_store(av,key,sv);
231    }
232    if (AvARRAY(av)[key] == &PL_sv_undef) {
233    emptyness:
234        if (lval) {
235            sv = NEWSV(6,0);
236            return av_store(av,key,sv);
237        }
238        return 0;
239    }
240    else if (AvREIFY(av)
241             && (!AvARRAY(av)[key]      /* eg. @_ could have freed elts */
242                 || SvTYPE(AvARRAY(av)[key]) == SVTYPEMASK)) {
243        AvARRAY(av)[key] = &PL_sv_undef;        /* 1/2 reify */
244        goto emptyness;
245    }
246    return &AvARRAY(av)[key];
247}
248
249/*
250=for apidoc av_store
251
252Stores an SV in an array.  The array index is specified as C<key>.  The
253return value will be NULL if the operation failed or if the value did not
254need to be actually stored within the array (as in the case of tied
255arrays). Otherwise it can be dereferenced to get the original C<SV*>.  Note
256that the caller is responsible for suitably incrementing the reference
257count of C<val> before the call, and decrementing it if the function
258returned NULL.
259
260See L<perlguts/"Understanding the Magic of Tied Hashes and Arrays"> for
261more information on how to use this function on tied arrays.
262
263=cut
264*/
265
266SV**
267Perl_av_store(pTHX_ register AV *av, I32 key, SV *val)
268{
269    SV** ary;
270
271    if (!av)
272        return 0;
273    if (!val)
274        val = &PL_sv_undef;
275
276    if (SvRMAGICAL(av)) {
277        MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
278        if (tied_magic) {
279            /* Handle negative array indices 20020222 MJD */
280            if (key < 0) {
281                unsigned adjust_index = 1;
282                SV **negative_indices_glob =
283                    hv_fetch(SvSTASH(SvRV(SvTIED_obj((SV *)av,
284                                                     tied_magic))),
285                             NEGATIVE_INDICES_VAR, 16, 0);
286                if (negative_indices_glob
287                    && SvTRUE(GvSV(*negative_indices_glob)))
288                    adjust_index = 0;
289                if (adjust_index) {
290                    key += AvFILL(av) + 1;
291                    if (key < 0)
292                        return 0;
293                }
294            }
295            if (val != &PL_sv_undef) {
296                mg_copy((SV*)av, val, 0, key);
297            }
298            return 0;
299        }
300    }
301
302
303    if (key < 0) {
304        key += AvFILL(av) + 1;
305        if (key < 0)
306            return 0;
307    }
308
309    if (SvREADONLY(av) && key >= AvFILL(av))
310        Perl_croak(aTHX_ PL_no_modify);
311
312    if (!AvREAL(av) && AvREIFY(av))
313        av_reify(av);
314    if (key > AvMAX(av))
315        av_extend(av,key);
316    ary = AvARRAY(av);
317    if (AvFILLp(av) < key) {
318        if (!AvREAL(av)) {
319            if (av == PL_curstack && key > PL_stack_sp - PL_stack_base)
320                PL_stack_sp = PL_stack_base + key;      /* XPUSH in disguise */
321            do
322                ary[++AvFILLp(av)] = &PL_sv_undef;
323            while (AvFILLp(av) < key);
324        }
325        AvFILLp(av) = key;
326    }
327    else if (AvREAL(av))
328        SvREFCNT_dec(ary[key]);
329    ary[key] = val;
330    if (SvSMAGICAL(av)) {
331        if (val != &PL_sv_undef) {
332            MAGIC* mg = SvMAGIC(av);
333            sv_magic(val, (SV*)av, toLOWER(mg->mg_type), 0, key);
334        }
335        mg_set((SV*)av);
336    }
337    return &ary[key];
338}
339
340/*
341=for apidoc newAV
342
343Creates a new AV.  The reference count is set to 1.
344
345=cut
346*/
347
348AV *
349Perl_newAV(pTHX)
350{
351    register AV *av;
352
353    av = (AV*)NEWSV(3,0);
354    sv_upgrade((SV *)av, SVt_PVAV);
355    AvREAL_on(av);
356    AvALLOC(av) = 0;
357    SvPVX(av) = 0;
358    AvMAX(av) = AvFILLp(av) = -1;
359    return av;
360}
361
362/*
363=for apidoc av_make
364
365Creates a new AV and populates it with a list of SVs.  The SVs are copied
366into the array, so they may be freed after the call to av_make.  The new AV
367will have a reference count of 1.
368
369=cut
370*/
371
372AV *
373Perl_av_make(pTHX_ register I32 size, register SV **strp)
374{
375    register AV *av;
376    register I32 i;
377    register SV** ary;
378
379    av = (AV*)NEWSV(8,0);
380    sv_upgrade((SV *) av,SVt_PVAV);
381    AvFLAGS(av) = AVf_REAL;
382    if (size) {         /* `defined' was returning undef for size==0 anyway. */
383        New(4,ary,size,SV*);
384        AvALLOC(av) = ary;
385        SvPVX(av) = (char*)ary;
386        AvFILLp(av) = size - 1;
387        AvMAX(av) = size - 1;
388        for (i = 0; i < size; i++) {
389            assert (*strp);
390            ary[i] = NEWSV(7,0);
391            sv_setsv(ary[i], *strp);
392            strp++;
393        }
394    }
395    return av;
396}
397
398AV *
399Perl_av_fake(pTHX_ register I32 size, register SV **strp)
400{
401    register AV *av;
402    register SV** ary;
403
404    av = (AV*)NEWSV(9,0);
405    sv_upgrade((SV *)av, SVt_PVAV);
406    New(4,ary,size+1,SV*);
407    AvALLOC(av) = ary;
408    Copy(strp,ary,size,SV*);
409    AvFLAGS(av) = AVf_REIFY;
410    SvPVX(av) = (char*)ary;
411    AvFILLp(av) = size - 1;
412    AvMAX(av) = size - 1;
413    while (size--) {
414        assert (*strp);
415        SvTEMP_off(*strp);
416        strp++;
417    }
418    return av;
419}
420
421/*
422=for apidoc av_clear
423
424Clears an array, making it empty.  Does not free the memory used by the
425array itself.
426
427=cut
428*/
429
430void
431Perl_av_clear(pTHX_ register AV *av)
432{
433    register I32 key;
434    SV** ary;
435
436#ifdef DEBUGGING
437    if (SvREFCNT(av) == 0 && ckWARN_d(WARN_DEBUGGING)) {
438        Perl_warner(aTHX_ packWARN(WARN_DEBUGGING), "Attempt to clear deleted array");
439    }
440#endif
441    if (!av)
442        return;
443    /*SUPPRESS 560*/
444
445    if (SvREADONLY(av))
446        Perl_croak(aTHX_ PL_no_modify);
447
448    /* Give any tie a chance to cleanup first */
449    if (SvRMAGICAL(av))
450        mg_clear((SV*)av);
451
452    if (AvMAX(av) < 0)
453        return;
454
455    if (AvREAL(av)) {
456        ary = AvARRAY(av);
457        key = AvFILLp(av) + 1;
458        while (key) {
459            SV * sv = ary[--key];
460            /* undef the slot before freeing the value, because a
461             * destructor might try to modify this arrray */
462            ary[key] = &PL_sv_undef;
463            SvREFCNT_dec(sv);
464        }
465    }
466    if ((key = AvARRAY(av) - AvALLOC(av))) {
467        AvMAX(av) += key;
468        SvPVX(av) = (char*)AvALLOC(av);
469    }
470    AvFILLp(av) = -1;
471
472}
473
474/*
475=for apidoc av_undef
476
477Undefines the array.  Frees the memory used by the array itself.
478
479=cut
480*/
481
482void
483Perl_av_undef(pTHX_ register AV *av)
484{
485    register I32 key;
486
487    if (!av)
488        return;
489    /*SUPPRESS 560*/
490
491    /* Give any tie a chance to cleanup first */
492    if (SvTIED_mg((SV*)av, PERL_MAGIC_tied))
493        av_fill(av, -1);   /* mg_clear() ? */
494
495    if (AvREAL(av)) {
496        key = AvFILLp(av) + 1;
497        while (key)
498            SvREFCNT_dec(AvARRAY(av)[--key]);
499    }
500    Safefree(AvALLOC(av));
501    AvALLOC(av) = 0;
502    SvPVX(av) = 0;
503    AvMAX(av) = AvFILLp(av) = -1;
504    if (AvARYLEN(av)) {
505        SvREFCNT_dec(AvARYLEN(av));
506        AvARYLEN(av) = 0;
507    }
508}
509
510/*
511=for apidoc av_push
512
513Pushes an SV onto the end of the array.  The array will grow automatically
514to accommodate the addition.
515
516=cut
517*/
518
519void
520Perl_av_push(pTHX_ register AV *av, SV *val)
521{             
522    MAGIC *mg;
523    if (!av)
524        return;
525    if (SvREADONLY(av))
526        Perl_croak(aTHX_ PL_no_modify);
527
528    if ((mg = SvTIED_mg((SV*)av, PERL_MAGIC_tied))) {
529        dSP;
530        PUSHSTACKi(PERLSI_MAGIC);
531        PUSHMARK(SP);
532        EXTEND(SP,2);
533        PUSHs(SvTIED_obj((SV*)av, mg));
534        PUSHs(val);
535        PUTBACK;
536        ENTER;
537        call_method("PUSH", G_SCALAR|G_DISCARD);
538        LEAVE;
539        POPSTACK;
540        return;
541    }
542    av_store(av,AvFILLp(av)+1,val);
543}
544
545/*
546=for apidoc av_pop
547
548Pops an SV off the end of the array.  Returns C<&PL_sv_undef> if the array
549is empty.
550
551=cut
552*/
553
554SV *
555Perl_av_pop(pTHX_ register AV *av)
556{
557    SV *retval;
558    MAGIC* mg;
559
560    if (!av)
561      return &PL_sv_undef;
562    if (SvREADONLY(av))
563        Perl_croak(aTHX_ PL_no_modify);
564    if ((mg = SvTIED_mg((SV*)av, PERL_MAGIC_tied))) {
565        dSP;   
566        PUSHSTACKi(PERLSI_MAGIC);
567        PUSHMARK(SP);
568        XPUSHs(SvTIED_obj((SV*)av, mg));
569        PUTBACK;
570        ENTER;
571        if (call_method("POP", G_SCALAR)) {
572            retval = newSVsv(*PL_stack_sp--);   
573        } else {   
574            retval = &PL_sv_undef;
575        }
576        LEAVE;
577        POPSTACK;
578        return retval;
579    }
580    if (AvFILL(av) < 0)
581        return &PL_sv_undef;
582    retval = AvARRAY(av)[AvFILLp(av)];
583    AvARRAY(av)[AvFILLp(av)--] = &PL_sv_undef;
584    if (SvSMAGICAL(av))
585        mg_set((SV*)av);
586    return retval;
587}
588
589/*
590=for apidoc av_unshift
591
592Unshift the given number of C<undef> values onto the beginning of the
593array.  The array will grow automatically to accommodate the addition.  You
594must then use C<av_store> to assign values to these new elements.
595
596=cut
597*/
598
599void
600Perl_av_unshift(pTHX_ register AV *av, register I32 num)
601{
602    register I32 i;
603    register SV **ary;
604    MAGIC* mg;
605    I32 slide;
606
607    if (!av)
608        return;
609    if (SvREADONLY(av))
610        Perl_croak(aTHX_ PL_no_modify);
611
612    if ((mg = SvTIED_mg((SV*)av, PERL_MAGIC_tied))) {
613        dSP;
614        PUSHSTACKi(PERLSI_MAGIC);
615        PUSHMARK(SP);
616        EXTEND(SP,1+num);
617        PUSHs(SvTIED_obj((SV*)av, mg));
618        while (num-- > 0) {
619            PUSHs(&PL_sv_undef);
620        }
621        PUTBACK;
622        ENTER;
623        call_method("UNSHIFT", G_SCALAR|G_DISCARD);
624        LEAVE;
625        POPSTACK;
626        return;
627    }
628
629    if (num <= 0)
630      return;
631    if (!AvREAL(av) && AvREIFY(av))
632        av_reify(av);
633    i = AvARRAY(av) - AvALLOC(av);
634    if (i) {
635        if (i > num)
636            i = num;
637        num -= i;
638   
639        AvMAX(av) += i;
640        AvFILLp(av) += i;
641        SvPVX(av) = (char*)(AvARRAY(av) - i);
642    }
643    if (num) {
644        i = AvFILLp(av);
645        /* Create extra elements */
646        slide = i > 0 ? i : 0;
647        num += slide;
648        av_extend(av, i + num);
649        AvFILLp(av) += num;
650        ary = AvARRAY(av);
651        Move(ary, ary + num, i + 1, SV*);
652        do {
653            ary[--num] = &PL_sv_undef;
654        } while (num);
655        /* Make extra elements into a buffer */
656        AvMAX(av) -= slide;
657        AvFILLp(av) -= slide;
658        SvPVX(av) = (char*)(AvARRAY(av) + slide);
659    }
660}
661
662/*
663=for apidoc av_shift
664
665Shifts an SV off the beginning of the array.
666
667=cut
668*/
669
670SV *
671Perl_av_shift(pTHX_ register AV *av)
672{
673    SV *retval;
674    MAGIC* mg;
675
676    if (!av)
677        return &PL_sv_undef;
678    if (SvREADONLY(av))
679        Perl_croak(aTHX_ PL_no_modify);
680    if ((mg = SvTIED_mg((SV*)av, PERL_MAGIC_tied))) {
681        dSP;
682        PUSHSTACKi(PERLSI_MAGIC);
683        PUSHMARK(SP);
684        XPUSHs(SvTIED_obj((SV*)av, mg));
685        PUTBACK;
686        ENTER;
687        if (call_method("SHIFT", G_SCALAR)) {
688            retval = newSVsv(*PL_stack_sp--);           
689        } else {   
690            retval = &PL_sv_undef;
691        }     
692        LEAVE;
693        POPSTACK;
694        return retval;
695    }
696    if (AvFILL(av) < 0)
697      return &PL_sv_undef;
698    retval = *AvARRAY(av);
699    if (AvREAL(av))
700        *AvARRAY(av) = &PL_sv_undef;
701    SvPVX(av) = (char*)(AvARRAY(av) + 1);
702    AvMAX(av)--;
703    AvFILLp(av)--;
704    if (SvSMAGICAL(av))
705        mg_set((SV*)av);
706    return retval;
707}
708
709/*
710=for apidoc av_len
711
712Returns the highest index in the array.  Returns -1 if the array is
713empty.
714
715=cut
716*/
717
718I32
719Perl_av_len(pTHX_ register AV *av)
720{
721    return AvFILL(av);
722}
723
724/*
725=for apidoc av_fill
726
727Ensure than an array has a given number of elements, equivalent to
728Perl's C<$#array = $fill;>.
729
730=cut
731*/
732void
733Perl_av_fill(pTHX_ register AV *av, I32 fill)
734{
735    MAGIC *mg;
736    if (!av)
737        Perl_croak(aTHX_ "panic: null array");
738    if (fill < 0)
739        fill = -1;
740    if ((mg = SvTIED_mg((SV*)av, PERL_MAGIC_tied))) {
741        dSP;           
742        ENTER;
743        SAVETMPS;
744        PUSHSTACKi(PERLSI_MAGIC);
745        PUSHMARK(SP);
746        EXTEND(SP,2);
747        PUSHs(SvTIED_obj((SV*)av, mg));
748        PUSHs(sv_2mortal(newSViv(fill+1)));
749        PUTBACK;
750        call_method("STORESIZE", G_SCALAR|G_DISCARD);
751        POPSTACK;
752        FREETMPS;
753        LEAVE;
754        return;
755    }
756    if (fill <= AvMAX(av)) {
757        I32 key = AvFILLp(av);
758        SV** ary = AvARRAY(av);
759
760        if (AvREAL(av)) {
761            while (key > fill) {
762                SvREFCNT_dec(ary[key]);
763                ary[key--] = &PL_sv_undef;
764            }
765        }
766        else {
767            while (key < fill)
768                ary[++key] = &PL_sv_undef;
769        }
770           
771        AvFILLp(av) = fill;
772        if (SvSMAGICAL(av))
773            mg_set((SV*)av);
774    }
775    else
776        (void)av_store(av,fill,&PL_sv_undef);
777}
778
779/*
780=for apidoc av_delete
781
782Deletes the element indexed by C<key> from the array.  Returns the
783deleted element. C<flags> is currently ignored.
784
785=cut
786*/
787SV *
788Perl_av_delete(pTHX_ AV *av, I32 key, I32 flags)
789{
790    SV *sv;
791
792    if (!av)
793        return Nullsv;
794    if (SvREADONLY(av))
795        Perl_croak(aTHX_ PL_no_modify);
796
797    if (SvRMAGICAL(av)) {
798        MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
799        SV **svp;
800        if ((tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata))) {
801            /* Handle negative array indices 20020222 MJD */
802            if (key < 0) {
803                unsigned adjust_index = 1;
804                if (tied_magic) {
805                    SV **negative_indices_glob =
806                        hv_fetch(SvSTASH(SvRV(SvTIED_obj((SV *)av,
807                                                         tied_magic))),
808                                 NEGATIVE_INDICES_VAR, 16, 0);
809                    if (negative_indices_glob
810                        && SvTRUE(GvSV(*negative_indices_glob)))
811                        adjust_index = 0;
812                }
813                if (adjust_index) {
814                    key += AvFILL(av) + 1;
815                    if (key < 0)
816                        return Nullsv;
817                }
818            }
819            svp = av_fetch(av, key, TRUE);
820            if (svp) {
821                sv = *svp;
822                mg_clear(sv);
823                if (mg_find(sv, PERL_MAGIC_tiedelem)) {
824                    sv_unmagic(sv, PERL_MAGIC_tiedelem); /* No longer an element */
825                    return sv;
826                }
827                return Nullsv;     
828            }
829        }
830    }
831
832    if (key < 0) {
833        key += AvFILL(av) + 1;
834        if (key < 0)
835            return Nullsv;
836    }
837
838    if (key > AvFILLp(av))
839        return Nullsv;
840    else {
841        sv = AvARRAY(av)[key];
842        if (key == AvFILLp(av)) {
843            AvARRAY(av)[key] = &PL_sv_undef;
844            do {
845                AvFILLp(av)--;
846            } while (--key >= 0 && AvARRAY(av)[key] == &PL_sv_undef);
847        }
848        else
849            AvARRAY(av)[key] = &PL_sv_undef;
850        if (SvSMAGICAL(av))
851            mg_set((SV*)av);
852    }
853    if (flags & G_DISCARD) {
854        SvREFCNT_dec(sv);
855        sv = Nullsv;
856    }
857    return sv;
858}
859
860/*
861=for apidoc av_exists
862
863Returns true if the element indexed by C<key> has been initialized.
864
865This relies on the fact that uninitialized array elements are set to
866C<&PL_sv_undef>.
867
868=cut
869*/
870bool
871Perl_av_exists(pTHX_ AV *av, I32 key)
872{
873    if (!av)
874        return FALSE;
875
876
877    if (SvRMAGICAL(av)) {
878        MAGIC *tied_magic = mg_find((SV*)av, PERL_MAGIC_tied);
879        if (tied_magic || mg_find((SV*)av, PERL_MAGIC_regdata)) {
880            SV *sv = sv_newmortal();
881            MAGIC *mg;
882            /* Handle negative array indices 20020222 MJD */
883            if (key < 0) {
884                unsigned adjust_index = 1;
885                if (tied_magic) {
886                    SV **negative_indices_glob =
887                        hv_fetch(SvSTASH(SvRV(SvTIED_obj((SV *)av,
888                                                         tied_magic))),
889                                 NEGATIVE_INDICES_VAR, 16, 0);
890                    if (negative_indices_glob
891                        && SvTRUE(GvSV(*negative_indices_glob)))
892                        adjust_index = 0;
893                }
894                if (adjust_index) {
895                    key += AvFILL(av) + 1;
896                    if (key < 0)
897                        return FALSE;
898                }
899            }
900
901            mg_copy((SV*)av, sv, 0, key);
902            mg = mg_find(sv, PERL_MAGIC_tiedelem);
903            if (mg) {
904                magic_existspack(sv, mg);
905                return (bool)SvTRUE(sv);
906            }
907
908        }
909    }
910
911    if (key < 0) {
912        key += AvFILL(av) + 1;
913        if (key < 0)
914            return FALSE;
915    }
916
917    if (key <= AvFILLp(av) && AvARRAY(av)[key] != &PL_sv_undef
918        && AvARRAY(av)[key])
919    {
920        return TRUE;
921    }
922    else
923        return FALSE;
924}
925
926/* AVHV: Support for treating arrays as if they were hashes.  The
927 * first element of the array should be a hash reference that maps
928 * hash keys to array indices.
929 */
930
931STATIC I32
932S_avhv_index_sv(pTHX_ SV* sv)
933{
934    I32 index = SvIV(sv);
935    if (index < 1)
936        Perl_croak(aTHX_ "Bad index while coercing array into hash");
937    return index;   
938}
939
940STATIC I32
941S_avhv_index(pTHX_ AV *av, SV *keysv, U32 hash)
942{
943    HV *keys;
944    HE *he;
945    STRLEN n_a;
946
947    keys = avhv_keys(av);
948    he = hv_fetch_ent(keys, keysv, FALSE, hash);
949    if (!he)
950        Perl_croak(aTHX_ "No such pseudo-hash field \"%s\"", SvPV(keysv,n_a));
951    return avhv_index_sv(HeVAL(he));
952}
953
954HV*
955Perl_avhv_keys(pTHX_ AV *av)
956{
957    SV **keysp = av_fetch(av, 0, FALSE);
958    if (keysp) {
959        SV *sv = *keysp;
960        if (SvGMAGICAL(sv))
961            mg_get(sv);
962        if (SvROK(sv)) {
963            if (ckWARN(WARN_DEPRECATED) && !sv_isa(sv, "pseudohash"))
964                Perl_warner(aTHX_ packWARN(WARN_DEPRECATED),
965                            "Pseudo-hashes are deprecated");
966            sv = SvRV(sv);
967            if (SvTYPE(sv) == SVt_PVHV)
968                return (HV*)sv;
969        }
970    }
971    Perl_croak(aTHX_ "Can't coerce array into hash");
972    return Nullhv;
973}
974
975SV**
976Perl_avhv_store_ent(pTHX_ AV *av, SV *keysv, SV *val, U32 hash)
977{
978    return av_store(av, avhv_index(av, keysv, hash), val);
979}
980
981SV**
982Perl_avhv_fetch_ent(pTHX_ AV *av, SV *keysv, I32 lval, U32 hash)
983{
984    return av_fetch(av, avhv_index(av, keysv, hash), lval);
985}
986
987SV *
988Perl_avhv_delete_ent(pTHX_ AV *av, SV *keysv, I32 flags, U32 hash)
989{
990    HV *keys = avhv_keys(av);
991    HE *he;
992       
993    he = hv_fetch_ent(keys, keysv, FALSE, hash);
994    if (!he || !SvOK(HeVAL(he)))
995        return Nullsv;
996
997    return av_delete(av, avhv_index_sv(HeVAL(he)), flags);
998}
999
1000/* Check for the existence of an element named by a given key.
1001 *
1002 */
1003bool
1004Perl_avhv_exists_ent(pTHX_ AV *av, SV *keysv, U32 hash)
1005{
1006    HV *keys = avhv_keys(av);
1007    HE *he;
1008       
1009    he = hv_fetch_ent(keys, keysv, FALSE, hash);
1010    if (!he || !SvOK(HeVAL(he)))
1011        return FALSE;
1012
1013    return av_exists(av, avhv_index_sv(HeVAL(he)));
1014}
1015
1016HE *
1017Perl_avhv_iternext(pTHX_ AV *av)
1018{
1019    HV *keys = avhv_keys(av);
1020    return hv_iternext(keys);
1021}
1022
1023SV *
1024Perl_avhv_iterval(pTHX_ AV *av, register HE *entry)
1025{
1026    SV *sv = hv_iterval(avhv_keys(av), entry);
1027    return *av_fetch(av, avhv_index_sv(sv), TRUE);
1028}
Note: See TracBrowser for help on using the repository browser.