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