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