cleanup installation of utilities on win32
[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
3c78fafa 24 if (AvREAL(av))
25 return;
93965878 26#ifdef DEBUGGING
3c78fafa 27 if (SvRMAGICAL(av) && mg_find((SV*)av,'P'))
93965878 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
39caa665 330 if (SvREADONLY(av))
331 croak(no_modify);
332
93965878 333 /* Give any tie a chance to cleanup first */
334 if (SvRMAGICAL(av))
335 mg_clear((SV*)av);
336
a60c0954 337 if (AvMAX(av) < 0)
338 return;
339
a0d0e21e 340 if (AvREAL(av)) {
341 ary = AvARRAY(av);
93965878 342 key = AvFILLp(av) + 1;
a0d0e21e 343 while (key) {
344 SvREFCNT_dec(ary[--key]);
345 ary[key] = &sv_undef;
346 }
347 }
463ee0b2 348 if (key = AvARRAY(av) - AvALLOC(av)) {
349 AvMAX(av) += key;
a0d0e21e 350 SvPVX(av) = (char*)AvALLOC(av);
79072805 351 }
93965878 352 AvFILLp(av) = -1;
fb73857a 353
79072805 354}
355
356void
8ac85365 357av_undef(register AV *av)
79072805 358{
359 register I32 key;
360
463ee0b2 361 if (!av)
79072805 362 return;
363 /*SUPPRESS 560*/
93965878 364
365 /* Give any tie a chance to cleanup first */
366 if (SvRMAGICAL(av) && mg_find((SV*)av,'P'))
367 av_fill(av, -1); /* mg_clear() ? */
368
a0d0e21e 369 if (AvREAL(av)) {
93965878 370 key = AvFILLp(av) + 1;
a0d0e21e 371 while (key)
372 SvREFCNT_dec(AvARRAY(av)[--key]);
373 }
463ee0b2 374 Safefree(AvALLOC(av));
375 AvALLOC(av) = 0;
376 SvPVX(av) = 0;
93965878 377 AvMAX(av) = AvFILLp(av) = -1;
748a9306 378 if (AvARYLEN(av)) {
379 SvREFCNT_dec(AvARYLEN(av));
380 AvARYLEN(av) = 0;
381 }
79072805 382}
383
a0d0e21e 384void
8ac85365 385av_push(register AV *av, SV *val)
93965878 386{
387 MAGIC *mg;
a0d0e21e 388 if (!av)
389 return;
93965878 390 if (SvREADONLY(av))
391 croak(no_modify);
392
393 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
394 dSP;
e336de0d 395 PUSHSTACK(SI_MAGIC);
924508f0 396 PUSHMARK(SP);
397 EXTEND(SP,2);
93965878 398 PUSHs(mg->mg_obj);
399 PUSHs(val);
a60c0954 400 PUTBACK;
401 ENTER;
93965878 402 perl_call_method("PUSH", G_SCALAR|G_DISCARD);
a60c0954 403 LEAVE;
e336de0d 404 POPSTACK();
93965878 405 return;
406 }
407 av_store(av,AvFILLp(av)+1,val);
79072805 408}
409
410SV *
8ac85365 411av_pop(register AV *av)
79072805 412{
413 SV *retval;
93965878 414 MAGIC* mg;
79072805 415
a0d0e21e 416 if (!av || AvFILL(av) < 0)
417 return &sv_undef;
43fcc5d2 418 if (SvREADONLY(av))
419 croak(no_modify);
93965878 420 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
421 dSP;
e336de0d 422 PUSHSTACK(SI_MAGIC);
924508f0 423 PUSHMARK(SP);
93965878 424 XPUSHs(mg->mg_obj);
a60c0954 425 PUTBACK;
426 ENTER;
93965878 427 if (perl_call_method("POP", G_SCALAR)) {
428 retval = newSVsv(*stack_sp--);
429 } else {
430 retval = &sv_undef;
431 }
a60c0954 432 LEAVE;
e336de0d 433 POPSTACK();
93965878 434 return retval;
435 }
436 retval = AvARRAY(av)[AvFILLp(av)];
437 AvARRAY(av)[AvFILLp(av)--] = &sv_undef;
8990e307 438 if (SvSMAGICAL(av))
463ee0b2 439 mg_set((SV*)av);
79072805 440 return retval;
441}
442
443void
8ac85365 444av_unshift(register AV *av, register I32 num)
79072805 445{
446 register I32 i;
67a38de0 447 register SV **ary;
93965878 448 MAGIC* mg;
79072805 449
a0d0e21e 450 if (!av || num <= 0)
79072805 451 return;
43fcc5d2 452 if (SvREADONLY(av))
453 croak(no_modify);
93965878 454
455 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
456 dSP;
e336de0d 457 PUSHSTACK(SI_MAGIC);
924508f0 458 PUSHMARK(SP);
459 EXTEND(SP,1+num);
93965878 460 PUSHs(mg->mg_obj);
461 while (num-- > 0) {
462 PUSHs(&sv_undef);
463 }
464 PUTBACK;
a60c0954 465 ENTER;
93965878 466 perl_call_method("UNSHIFT", G_SCALAR|G_DISCARD);
a60c0954 467 LEAVE;
e336de0d 468 POPSTACK();
93965878 469 return;
470 }
471
49beac48 472 if (!AvREAL(av) && AvREIFY(av))
473 av_reify(av);
a0d0e21e 474 i = AvARRAY(av) - AvALLOC(av);
475 if (i) {
476 if (i > num)
477 i = num;
478 num -= i;
479
480 AvMAX(av) += i;
93965878 481 AvFILLp(av) += i;
a0d0e21e 482 SvPVX(av) = (char*)(AvARRAY(av) - i);
483 }
d2719217 484 if (num) {
67a38de0 485 i = AvFILLp(av);
486 av_extend(av, i + num);
93965878 487 AvFILLp(av) += num;
67a38de0 488 ary = AvARRAY(av);
489 Move(ary, ary + num, i + 1, SV*);
490 do {
491 ary[--num] = &sv_undef;
492 } while (num);
79072805 493 }
494}
495
496SV *
8ac85365 497av_shift(register AV *av)
79072805 498{
499 SV *retval;
93965878 500 MAGIC* mg;
79072805 501
a0d0e21e 502 if (!av || AvFILL(av) < 0)
503 return &sv_undef;
43fcc5d2 504 if (SvREADONLY(av))
505 croak(no_modify);
93965878 506 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
507 dSP;
e336de0d 508 PUSHSTACK(SI_MAGIC);
924508f0 509 PUSHMARK(SP);
93965878 510 XPUSHs(mg->mg_obj);
a60c0954 511 PUTBACK;
512 ENTER;
93965878 513 if (perl_call_method("SHIFT", G_SCALAR)) {
514 retval = newSVsv(*stack_sp--);
515 } else {
516 retval = &sv_undef;
a60c0954 517 }
518 LEAVE;
e336de0d 519 POPSTACK();
93965878 520 return retval;
521 }
463ee0b2 522 retval = *AvARRAY(av);
a0d0e21e 523 if (AvREAL(av))
524 *AvARRAY(av) = &sv_undef;
463ee0b2 525 SvPVX(av) = (char*)(AvARRAY(av) + 1);
526 AvMAX(av)--;
93965878 527 AvFILLp(av)--;
8990e307 528 if (SvSMAGICAL(av))
463ee0b2 529 mg_set((SV*)av);
79072805 530 return retval;
531}
532
533I32
8ac85365 534av_len(register AV *av)
79072805 535{
463ee0b2 536 return AvFILL(av);
79072805 537}
538
539void
8ac85365 540av_fill(register AV *av, I32 fill)
79072805 541{
93965878 542 MAGIC *mg;
a0d0e21e 543 if (!av)
544 croak("panic: null array");
79072805 545 if (fill < 0)
546 fill = -1;
93965878 547 if (SvRMAGICAL(av) && (mg = mg_find((SV*)av,'P'))) {
548 dSP;
549 ENTER;
550 SAVETMPS;
e336de0d 551 PUSHSTACK(SI_MAGIC);
924508f0 552 PUSHMARK(SP);
553 EXTEND(SP,2);
93965878 554 PUSHs(mg->mg_obj);
a60c0954 555 PUSHs(sv_2mortal(newSViv(fill+1)));
93965878 556 PUTBACK;
557 perl_call_method("STORESIZE", G_SCALAR|G_DISCARD);
e336de0d 558 POPSTACK();
93965878 559 FREETMPS;
560 LEAVE;
561 return;
562 }
463ee0b2 563 if (fill <= AvMAX(av)) {
93965878 564 I32 key = AvFILLp(av);
a0d0e21e 565 SV** ary = AvARRAY(av);
566
567 if (AvREAL(av)) {
568 while (key > fill) {
569 SvREFCNT_dec(ary[key]);
570 ary[key--] = &sv_undef;
571 }
572 }
573 else {
574 while (key < fill)
575 ary[++key] = &sv_undef;
576 }
577
93965878 578 AvFILLp(av) = fill;
8990e307 579 if (SvSMAGICAL(av))
463ee0b2 580 mg_set((SV*)av);
581 }
a0d0e21e 582 else
583 (void)av_store(av,fill,&sv_undef);
79072805 584}
c750a3ec 585
5d5aaa5e 586
587HV*
588avhv_keys(AV *av)
589{
590 SV **keysp;
591 HV *keys = Nullhv;
592
593 keysp = av_fetch(av, 0, FALSE);
594 if (keysp) {
d627ae4e 595 SV *sv = *keysp;
596 if (SvGMAGICAL(sv))
597 mg_get(sv);
598 if (SvROK(sv)) {
599 sv = SvRV(sv);
600 if (SvTYPE(sv) == SVt_PVHV)
601 keys = (HV*)sv;
5d5aaa5e 602 }
603 }
604 if (!keys)
605 croak("Can't coerce array into hash");
606 return keys;
607}
608
c750a3ec 609SV**
8ac85365 610avhv_fetch(AV *av, char *key, U32 klen, I32 lval)
c750a3ec 611{
5d5aaa5e 612 SV **indsvp;
613 HV *keys = avhv_keys(av);
c750a3ec 614 I32 ind;
615
5d5aaa5e 616 indsvp = hv_fetch(keys, key, klen, FALSE);
c750a3ec 617 if (indsvp) {
618 ind = SvIV(*indsvp);
619 if (ind < 1)
620 croak("Bad index while coercing array into hash");
621 } else {
622 if (!lval)
623 return 0;
624
625 ind = AvFILL(av) + 1;
5d5aaa5e 626 hv_store(keys, key, klen, newSViv(ind), 0);
c750a3ec 627 }
628 return av_fetch(av, ind, lval);
629}
630
631SV**
8ac85365 632avhv_fetch_ent(AV *av, SV *keysv, I32 lval, U32 hash)
97fcbf96 633{
5d5aaa5e 634 SV **indsvp;
635 HV *keys = avhv_keys(av);
97fcbf96 636 HE *he;
637 I32 ind;
638
5d5aaa5e 639 he = hv_fetch_ent(keys, keysv, FALSE, hash);
97fcbf96 640 if (he) {
641 ind = SvIV(HeVAL(he));
642 if (ind < 1)
643 croak("Bad index while coercing array into hash");
644 } else {
645 if (!lval)
646 return 0;
647
648 ind = AvFILL(av) + 1;
5d5aaa5e 649 hv_store_ent(keys, keysv, newSViv(ind), 0);
97fcbf96 650 }
651 return av_fetch(av, ind, lval);
652}
653
654SV**
8ac85365 655avhv_store(AV *av, char *key, U32 klen, SV *val, U32 hash)
c750a3ec 656{
5d5aaa5e 657 SV **indsvp;
658 HV *keys = avhv_keys(av);
c750a3ec 659 I32 ind;
660
5d5aaa5e 661 indsvp = hv_fetch(keys, key, klen, FALSE);
c750a3ec 662 if (indsvp) {
663 ind = SvIV(*indsvp);
664 if (ind < 1)
665 croak("Bad index while coercing array into hash");
666 } else {
667 ind = AvFILL(av) + 1;
5d5aaa5e 668 hv_store(keys, key, klen, newSViv(ind), hash);
c750a3ec 669 }
670 return av_store(av, ind, val);
671}
672
5bc6513d 673SV**
8ac85365 674avhv_store_ent(AV *av, SV *keysv, SV *val, U32 hash)
5bc6513d 675{
5d5aaa5e 676 HV *keys = avhv_keys(av);
5bc6513d 677 HE *he;
678 I32 ind;
679
5d5aaa5e 680 he = hv_fetch_ent(keys, keysv, FALSE, hash);
5bc6513d 681 if (he) {
682 ind = SvIV(HeVAL(he));
683 if (ind < 1)
684 croak("Bad index while coercing array into hash");
685 } else {
686 ind = AvFILL(av) + 1;
5d5aaa5e 687 hv_store_ent(keys, keysv, newSViv(ind), hash);
5bc6513d 688 }
689 return av_store(av, ind, val);
690}
691
c750a3ec 692bool
8ac85365 693avhv_exists_ent(AV *av, SV *keysv, U32 hash)
97fcbf96 694{
5d5aaa5e 695 HV *keys = avhv_keys(av);
696 return hv_exists_ent(keys, keysv, hash);
97fcbf96 697}
698
699bool
8ac85365 700avhv_exists(AV *av, char *key, U32 klen)
c750a3ec 701{
5d5aaa5e 702 HV *keys = avhv_keys(av);
703 return hv_exists(keys, key, klen);
c750a3ec 704}
705
706/* avhv_delete leaks. Caller can re-index and compress if so desired. */
707SV *
8ac85365 708avhv_delete(AV *av, char *key, U32 klen, I32 flags)
c750a3ec 709{
5d5aaa5e 710 HV *keys = avhv_keys(av);
c750a3ec 711 SV *sv;
712 SV **svp;
713 I32 ind;
714
5d5aaa5e 715 sv = hv_delete(keys, key, klen, 0);
c750a3ec 716 if (!sv)
717 return Nullsv;
718 ind = SvIV(sv);
719 if (ind < 1)
720 croak("Bad index while coercing array into hash");
721 svp = av_fetch(av, ind, FALSE);
722 if (!svp)
723 return Nullsv;
724 if (flags & G_DISCARD) {
725 sv = Nullsv;
726 SvREFCNT_dec(*svp);
727 } else {
728 sv = sv_2mortal(*svp);
729 }
730 *svp = &sv_undef;
731 return sv;
732}
733
97fcbf96 734/* avhv_delete_ent leaks. Caller can re-index and compress if so desired. */
735SV *
8ac85365 736avhv_delete_ent(AV *av, SV *keysv, I32 flags, U32 hash)
97fcbf96 737{
5d5aaa5e 738 HV *keys = avhv_keys(av);
97fcbf96 739 SV *sv;
740 SV **svp;
741 I32 ind;
742
5d5aaa5e 743 sv = hv_delete_ent(keys, keysv, 0, hash);
97fcbf96 744 if (!sv)
745 return Nullsv;
746 ind = SvIV(sv);
747 if (ind < 1)
748 croak("Bad index while coercing array into hash");
749 svp = av_fetch(av, ind, FALSE);
750 if (!svp)
751 return Nullsv;
752 if (flags & G_DISCARD) {
753 sv = Nullsv;
754 SvREFCNT_dec(*svp);
755 } else {
756 sv = sv_2mortal(*svp);
757 }
758 *svp = &sv_undef;
759 return sv;
760}
761
c750a3ec 762I32
8ac85365 763avhv_iterinit(AV *av)
c750a3ec 764{
5d5aaa5e 765 HV *keys = avhv_keys(av);
766 return hv_iterinit(keys);
c750a3ec 767}
768
769HE *
8ac85365 770avhv_iternext(AV *av)
c750a3ec 771{
5d5aaa5e 772 HV *keys = avhv_keys(av);
773 return hv_iternext(keys);
c750a3ec 774}
775
776SV *
8ac85365 777avhv_iterval(AV *av, register HE *entry)
c750a3ec 778{
5d5aaa5e 779 HV *keys = avhv_keys(av);
c750a3ec 780 SV *sv;
781 I32 ind;
782
5d5aaa5e 783 sv = hv_iterval(keys, entry);
c750a3ec 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 794 HE *he;
795 SV *sv;
796 I32 ind;
797
5d5aaa5e 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 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}