Install extensions with bootstrap (again) in $archlib
[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
fb73857a 18void
8ac85365 19av_reify(AV *av)
a0d0e21e 20{
21 I32 key;
22 SV* sv;
fb73857a 23
93965878 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
a0d0e21e 30 key = AvMAX(av) + 1;
93965878 31 while (key > AvFILLp(av) + 1)
a0d0e21e 32 AvARRAY(av)[--key] = &sv_undef;
33 while (key) {
34 sv = AvARRAY(av)[--key];
35 assert(sv);
11343788 36 if (sv != &sv_undef) {
37 dTHR;
a0d0e21e 38 (void)SvREFCNT_inc(sv);
11343788 39 }
a0d0e21e 40 }
29de640a 41 key = AvARRAY(av) - AvALLOC(av);
42 while (key)
43 AvALLOC(av)[--key] = &sv_undef;
a0d0e21e 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 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 57 PUSHMARK(SP);
58 EXTEND(SP,2);
93965878 59 PUSHs(mg->mg_obj);
a60c0954 60 PUSHs(sv_2mortal(newSViv(key+1)));
93965878 61 PUTBACK;
62 perl_call_method("EXTEND", G_SCALAR|G_DISCARD);
e336de0d 63 POPSTACK();
93965878 64 FREETMPS;
65 LEAVE;
66 return;
67 }
a0d0e21e 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 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 95 newmax = key + AvMAX(av) / 5;
96 resize:
4633a7c4 97#ifdef STRANGE_MALLOC
a0d0e21e 98 Renew(AvALLOC(av),newmax+1, SV*);
4633a7c4 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 111 if (AvMAX(av) > 64)
112 offer_nice_chunk(AvALLOC(av), (AvMAX(av)+1) * sizeof(SV*));
4633a7c4 113 else
114 Safefree(AvALLOC(av));
115 AvALLOC(av) = ary;
116#endif
a0d0e21e 117 ary = AvALLOC(av) + AvMAX(av) + 1;
118 tmp = newmax - AvMAX(av);
7d55f622 119 if (av == curstack) { /* Oops, grew stack (via av_store()?) */
a0d0e21e 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 145{
146 SV *sv;
147
a0d0e21e 148 if (!av)
149 return 0;
150
93965878 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 162 av_fetch_sv = sv;
163 return &av_fetch_sv;
463ee0b2 164 }
165 }
166
93965878 167 if (key > AvFILLp(av)) {
a0d0e21e 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 178 if (lval) {
179 sv = NEWSV(6,0);
463ee0b2 180 return av_store(av,key,sv);
79072805 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 191}
192
193SV**
8ac85365 194av_store(register AV *av, I32 key, SV *val)
79072805 195{
79072805 196 SV** ary;
93965878 197 U32 fill;
198
79072805 199
a0d0e21e 200 if (!av)
201 return 0;
43fcc5d2 202 if (!val)
203 val = &sv_undef;
463ee0b2 204
a0d0e21e 205 if (key < 0) {
206 key += AvFILL(av) + 1;
207 if (key < 0)
208 return 0;
79072805 209 }
93965878 210
43fcc5d2 211 if (SvREADONLY(av) && key >= AvFILL(av))
212 croak(no_modify);
93965878 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 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 232 stack_sp = stack_base + key; /* XPUSH in disguise */
233 do
93965878 234 ary[++AvFILLp(av)] = &sv_undef;
235 while (AvFILLp(av) < key);
79072805 236 }
93965878 237 AvFILLp(av) = key;
79072805 238 }
a0d0e21e 239 else if (AvREAL(av))
240 SvREFCNT_dec(ary[key]);
79072805 241 ary[key] = val;
8990e307 242 if (SvSMAGICAL(av)) {
a0d0e21e 243 if (val != &sv_undef) {
244 MAGIC* mg = SvMAGIC(av);
245 sv_magic(val, (SV*)av, toLOWER(mg->mg_type), 0, key);
246 }
463ee0b2 247 mg_set((SV*)av);
248 }
79072805 249 return &ary[key];
250}
251
252AV *
8ac85365 253newAV(void)
79072805 254{
463ee0b2 255 register AV *av;
79072805 256
a0d0e21e 257 av = (AV*)NEWSV(3,0);
258 sv_upgrade((SV *)av, SVt_PVAV);
463ee0b2 259 AvREAL_on(av);
260 AvALLOC(av) = 0;
261 SvPVX(av) = 0;
93965878 262 AvMAX(av) = AvFILLp(av) = -1;
463ee0b2 263 return av;
79072805 264}
265
266AV *
8ac85365 267av_make(register I32 size, register SV **strp)
79072805 268{
463ee0b2 269 register AV *av;
79072805 270 register I32 i;
271 register SV** ary;
272
a0d0e21e 273 av = (AV*)NEWSV(8,0);
274 sv_upgrade((SV *) av,SVt_PVAV);
a0d0e21e 275 AvFLAGS(av) = AVf_REAL;
573fa4ea 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 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 290}
291
292AV *
8ac85365 293av_fake(register I32 size, register SV **strp)
79072805 294{
463ee0b2 295 register AV *av;
79072805 296 register SV** ary;
297
a0d0e21e 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 308 assert (*strp);
309 SvTEMP_off(*strp);
79072805 310 strp++;
311 }
463ee0b2 312 return av;
79072805 313}
314
315void
8ac85365 316av_clear(register AV *av)
79072805 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 327 return;
328 /*SUPPRESS 560*/
a0d0e21e 329
93965878 330 /* Give any tie a chance to cleanup first */
331 if (SvRMAGICAL(av))
332 mg_clear((SV*)av);
333
a60c0954 334 if (AvMAX(av) < 0)
335 return;
336
a0d0e21e 337 if (AvREAL(av)) {
338 ary = AvARRAY(av);
93965878 339 key = AvFILLp(av) + 1;
a0d0e21e 340 while (key) {
341 SvREFCNT_dec(ary[--key]);
342 ary[key] = &sv_undef;
343 }
344 }
463ee0b2 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 351}
352
353void
8ac85365 354av_undef(register AV *av)
79072805 355{
356 register I32 key;
357
463ee0b2 358 if (!av)
79072805 359 return;
360 /*SUPPRESS 560*/
93965878 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 368 while (key)
369 SvREFCNT_dec(AvARRAY(av)[--key]);
370 }
463ee0b2 371 Safefree(AvALLOC(av));
e1c148c2 372 SvPVX(av) = 0;
463ee0b2 373 AvALLOC(av) = 0;
374 SvPVX(av) = 0;
93965878 375 AvMAX(av) = AvFILLp(av) = -1;
748a9306 376 if (AvARYLEN(av)) {
377 SvREFCNT_dec(AvARYLEN(av));
378 AvARYLEN(av) = 0;
379 }
79072805 380}
381
a0d0e21e 382void
8ac85365 383av_push(register AV *av, SV *val)
93965878 384{
385 MAGIC *mg;
a0d0e21e 386 if (!av)
387 return;
93965878 388 if (SvREADONLY(av))
389 croak(no_modify);
390
391 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
392 dSP;
e336de0d 393 PUSHSTACK(SI_MAGIC);
924508f0 394 PUSHMARK(SP);
395 EXTEND(SP,2);
93965878 396 PUSHs(mg->mg_obj);
397 PUSHs(val);
a60c0954 398 PUTBACK;
399 ENTER;
93965878 400 perl_call_method("PUSH", G_SCALAR|G_DISCARD);
a60c0954 401 LEAVE;
e336de0d 402 POPSTACK();
93965878 403 return;
404 }
405 av_store(av,AvFILLp(av)+1,val);
79072805 406}
407
408SV *
8ac85365 409av_pop(register AV *av)
79072805 410{
411 SV *retval;
93965878 412 MAGIC* mg;
79072805 413
a0d0e21e 414 if (!av || AvFILL(av) < 0)
415 return &sv_undef;
43fcc5d2 416 if (SvREADONLY(av))
417 croak(no_modify);
93965878 418 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
419 dSP;
e336de0d 420 PUSHSTACK(SI_MAGIC);
924508f0 421 PUSHMARK(SP);
93965878 422 XPUSHs(mg->mg_obj);
a60c0954 423 PUTBACK;
424 ENTER;
93965878 425 if (perl_call_method("POP", G_SCALAR)) {
426 retval = newSVsv(*stack_sp--);
427 } else {
428 retval = &sv_undef;
429 }
a60c0954 430 LEAVE;
e336de0d 431 POPSTACK();
93965878 432 return retval;
433 }
434 retval = AvARRAY(av)[AvFILLp(av)];
435 AvARRAY(av)[AvFILLp(av)--] = &sv_undef;
8990e307 436 if (SvSMAGICAL(av))
463ee0b2 437 mg_set((SV*)av);
79072805 438 return retval;
439}
440
441void
8ac85365 442av_unshift(register AV *av, register I32 num)
79072805 443{
444 register I32 i;
67a38de0 445 register SV **ary;
93965878 446 MAGIC* mg;
79072805 447
a0d0e21e 448 if (!av || num <= 0)
79072805 449 return;
43fcc5d2 450 if (SvREADONLY(av))
451 croak(no_modify);
93965878 452
453 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
454 dSP;
e336de0d 455 PUSHSTACK(SI_MAGIC);
924508f0 456 PUSHMARK(SP);
457 EXTEND(SP,1+num);
93965878 458 PUSHs(mg->mg_obj);
459 while (num-- > 0) {
460 PUSHs(&sv_undef);
461 }
462 PUTBACK;
a60c0954 463 ENTER;
93965878 464 perl_call_method("UNSHIFT", G_SCALAR|G_DISCARD);
a60c0954 465 LEAVE;
e336de0d 466 POPSTACK();
93965878 467 return;
468 }
469
49beac48 470 if (!AvREAL(av) && AvREIFY(av))
471 av_reify(av);
a0d0e21e 472 i = AvARRAY(av) - AvALLOC(av);
473 if (i) {
474 if (i > num)
475 i = num;
476 num -= i;
477
478 AvMAX(av) += i;
93965878 479 AvFILLp(av) += i;
a0d0e21e 480 SvPVX(av) = (char*)(AvARRAY(av) - i);
481 }
67a38de0 482 if (num) {
483 i = AvFILLp(av);
484 av_extend(av, i + num);
93965878 485 AvFILLp(av) += num;
67a38de0 486 ary = AvARRAY(av);
487 Move(ary, ary + num, i + 1, SV*);
488 do {
489 ary[--num] = &sv_undef;
490 } while (num);
79072805 491 }
492}
493
494SV *
8ac85365 495av_shift(register AV *av)
79072805 496{
497 SV *retval;
93965878 498 MAGIC* mg;
79072805 499
a0d0e21e 500 if (!av || AvFILL(av) < 0)
501 return &sv_undef;
43fcc5d2 502 if (SvREADONLY(av))
503 croak(no_modify);
93965878 504 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
505 dSP;
e336de0d 506 PUSHSTACK(SI_MAGIC);
924508f0 507 PUSHMARK(SP);
93965878 508 XPUSHs(mg->mg_obj);
a60c0954 509 PUTBACK;
510 ENTER;
93965878 511 if (perl_call_method("SHIFT", G_SCALAR)) {
512 retval = newSVsv(*stack_sp--);
513 } else {
514 retval = &sv_undef;
a60c0954 515 }
516 LEAVE;
e336de0d 517 POPSTACK();
93965878 518 return retval;
519 }
463ee0b2 520 retval = *AvARRAY(av);
a0d0e21e 521 if (AvREAL(av))
522 *AvARRAY(av) = &sv_undef;
463ee0b2 523 SvPVX(av) = (char*)(AvARRAY(av) + 1);
524 AvMAX(av)--;
93965878 525 AvFILLp(av)--;
8990e307 526 if (SvSMAGICAL(av))
463ee0b2 527 mg_set((SV*)av);
79072805 528 return retval;
529}
530
531I32
8ac85365 532av_len(register AV *av)
79072805 533{
463ee0b2 534 return AvFILL(av);
79072805 535}
536
537void
8ac85365 538av_fill(register AV *av, I32 fill)
79072805 539{
93965878 540 MAGIC *mg;
a0d0e21e 541 if (!av)
542 croak("panic: null array");
79072805 543 if (fill < 0)
544 fill = -1;
93965878 545 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
546 dSP;
547 ENTER;
548 SAVETMPS;
e336de0d 549 PUSHSTACK(SI_MAGIC);
924508f0 550 PUSHMARK(SP);
551 EXTEND(SP,2);
93965878 552 PUSHs(mg->mg_obj);
a60c0954 553 PUSHs(sv_2mortal(newSViv(fill+1)));
93965878 554 PUTBACK;
555 perl_call_method("STORESIZE", G_SCALAR|G_DISCARD);
e336de0d 556 POPSTACK();
93965878 557 FREETMPS;
558 LEAVE;
559 return;
560 }
463ee0b2 561 if (fill <= AvMAX(av)) {
93965878 562 I32 key = AvFILLp(av);
a0d0e21e 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
93965878 576 AvFILLp(av) = fill;
8990e307 577 if (SvSMAGICAL(av))
463ee0b2 578 mg_set((SV*)av);
579 }
a0d0e21e 580 else
581 (void)av_store(av,fill,&sv_undef);
79072805 582}
c750a3ec 583
5d5aaa5e 584
585HV*
586avhv_keys(AV *av)
587{
588 SV **keysp;
589 HV *keys = Nullhv;
590
591 keysp = av_fetch(av, 0, FALSE);
592 if (keysp) {
d627ae4e 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;
5d5aaa5e 600 }
601 }
602 if (!keys)
603 croak("Can't coerce array into hash");
604 return keys;
605}
606
c750a3ec 607SV**
8ac85365 608avhv_fetch(AV *av, char *key, U32 klen, I32 lval)
c750a3ec 609{
5d5aaa5e 610 SV **indsvp;
611 HV *keys = avhv_keys(av);
c750a3ec 612 I32 ind;
613
5d5aaa5e 614 indsvp = hv_fetch(keys, key, klen, FALSE);
c750a3ec 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;
5d5aaa5e 624 hv_store(keys, key, klen, newSViv(ind), 0);
c750a3ec 625 }
626 return av_fetch(av, ind, lval);
627}
628
629SV**
8ac85365 630avhv_fetch_ent(AV *av, SV *keysv, I32 lval, U32 hash)
97fcbf96 631{
5d5aaa5e 632 SV **indsvp;
633 HV *keys = avhv_keys(av);
97fcbf96 634 HE *he;
635 I32 ind;
636
5d5aaa5e 637 he = hv_fetch_ent(keys, keysv, FALSE, hash);
97fcbf96 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;
5d5aaa5e 647 hv_store_ent(keys, keysv, newSViv(ind), 0);
97fcbf96 648 }
649 return av_fetch(av, ind, lval);
650}
651
652SV**
8ac85365 653avhv_store(AV *av, char *key, U32 klen, SV *val, U32 hash)
c750a3ec 654{
5d5aaa5e 655 SV **indsvp;
656 HV *keys = avhv_keys(av);
c750a3ec 657 I32 ind;
658
5d5aaa5e 659 indsvp = hv_fetch(keys, key, klen, FALSE);
c750a3ec 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;
5d5aaa5e 666 hv_store(keys, key, klen, newSViv(ind), hash);
c750a3ec 667 }
668 return av_store(av, ind, val);
669}
670
5bc6513d 671SV**
8ac85365 672avhv_store_ent(AV *av, SV *keysv, SV *val, U32 hash)
5bc6513d 673{
5d5aaa5e 674 HV *keys = avhv_keys(av);
5bc6513d 675 HE *he;
676 I32 ind;
677
5d5aaa5e 678 he = hv_fetch_ent(keys, keysv, FALSE, hash);
5bc6513d 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;
5d5aaa5e 685 hv_store_ent(keys, keysv, newSViv(ind), hash);
5bc6513d 686 }
687 return av_store(av, ind, val);
688}
689
c750a3ec 690bool
8ac85365 691avhv_exists_ent(AV *av, SV *keysv, U32 hash)
97fcbf96 692{
5d5aaa5e 693 HV *keys = avhv_keys(av);
694 return hv_exists_ent(keys, keysv, hash);
97fcbf96 695}
696
697bool
8ac85365 698avhv_exists(AV *av, char *key, U32 klen)
c750a3ec 699{
5d5aaa5e 700 HV *keys = avhv_keys(av);
701 return hv_exists(keys, key, klen);
c750a3ec 702}
703
704/* avhv_delete leaks. Caller can re-index and compress if so desired. */
705SV *
8ac85365 706avhv_delete(AV *av, char *key, U32 klen, I32 flags)
c750a3ec 707{
5d5aaa5e 708 HV *keys = avhv_keys(av);
c750a3ec 709 SV *sv;
710 SV **svp;
711 I32 ind;
712
5d5aaa5e 713 sv = hv_delete(keys, key, klen, 0);
c750a3ec 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
97fcbf96 732/* avhv_delete_ent leaks. Caller can re-index and compress if so desired. */
733SV *
8ac85365 734avhv_delete_ent(AV *av, SV *keysv, I32 flags, U32 hash)
97fcbf96 735{
5d5aaa5e 736 HV *keys = avhv_keys(av);
97fcbf96 737 SV *sv;
738 SV **svp;
739 I32 ind;
740
5d5aaa5e 741 sv = hv_delete_ent(keys, keysv, 0, hash);
97fcbf96 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
c750a3ec 760I32
8ac85365 761avhv_iterinit(AV *av)
c750a3ec 762{
5d5aaa5e 763 HV *keys = avhv_keys(av);
764 return hv_iterinit(keys);
c750a3ec 765}
766
767HE *
8ac85365 768avhv_iternext(AV *av)
c750a3ec 769{
5d5aaa5e 770 HV *keys = avhv_keys(av);
771 return hv_iternext(keys);
c750a3ec 772}
773
774SV *
8ac85365 775avhv_iterval(AV *av, register HE *entry)
c750a3ec 776{
5d5aaa5e 777 HV *keys = avhv_keys(av);
c750a3ec 778 SV *sv;
779 I32 ind;
780
5d5aaa5e 781 sv = hv_iterval(keys, entry);
c750a3ec 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
788SV *
8ac85365 789avhv_iternextsv(AV *av, char **key, I32 *retlen)
c750a3ec 790{
5d5aaa5e 791 HV *keys = avhv_keys(av);
c750a3ec 792 HE *he;
793 SV *sv;
794 I32 ind;
795
5d5aaa5e 796 he = hv_iternext(keys);
797 if (!he)
798 return Nullsv;
c750a3ec 799 *key = hv_iterkey(he, retlen);
5d5aaa5e 800 sv = hv_iterval(keys, he);
c750a3ec 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}