File Coverage

ListUtil.xs
Criterion Covered Total %
statement 0 815 0.0
branch 0 964 0.0
condition n/a
subroutine n/a
pod n/a
total 0 1779 0.0


line stmt bran cond sub pod time code
1             /* Copyright (c) 1997-2000 Graham Barr . All rights reserved.
2             * This program is free software; you can redistribute it and/or
3             * modify it under the same terms as Perl itself.
4             */
5              
6             #define PERL_NO_GET_CONTEXT /* we want efficiency */
7             #include
8             #include
9             #include
10              
11             #ifdef USE_PPPORT_H
12             # define NEED_sv_2pv_flags 1
13             # define NEED_newSVpvn_flags 1
14             # define NEED_sv_catpvn_flags
15             # include "ppport.h"
16             #endif
17              
18             /* For uniqnum, define ACTUAL_NVSIZE to be the number *
19             * of bytes that are actually used to store the NV */
20              
21             #if defined(USE_LONG_DOUBLE) && LDBL_MANT_DIG == 64
22             # define ACTUAL_NVSIZE 10
23             #else
24             # define ACTUAL_NVSIZE NVSIZE
25             #endif
26              
27             /* Detect "DoubleDouble" nvtype */
28              
29             #if defined(USE_LONG_DOUBLE) && LDBL_MANT_DIG == 106
30             # define NV_IS_DOUBLEDOUBLE
31             #endif
32              
33             #ifndef PERL_VERSION_DECIMAL
34             # define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
35             #endif
36             #ifndef PERL_DECIMAL_VERSION
37             # define PERL_DECIMAL_VERSION \
38             PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
39             #endif
40             #ifndef PERL_VERSION_GE
41             # define PERL_VERSION_GE(r,v,s) \
42             (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
43             #endif
44             #ifndef PERL_VERSION_LE
45             # define PERL_VERSION_LE(r,v,s) \
46             (PERL_DECIMAL_VERSION <= PERL_VERSION_DECIMAL(r,v,s))
47             #endif
48              
49             #if PERL_VERSION_GE(5,6,0)
50             # include "multicall.h"
51             #endif
52              
53             #if !PERL_VERSION_GE(5,23,8)
54             # define UNUSED_VAR_newsp PERL_UNUSED_VAR(newsp)
55             #else
56             # define UNUSED_VAR_newsp NOOP
57             #endif
58              
59             #ifndef CvISXSUB
60             # define CvISXSUB(cv) CvXSUB(cv)
61             #endif
62              
63             #ifndef HvNAMELEN_get
64             #define HvNAMELEN_get(stash) strlen(HvNAME(stash))
65             #endif
66              
67             #ifndef HvNAMEUTF8
68             #define HvNAMEUTF8(stash) 0
69             #endif
70              
71             #ifndef GvNAMEUTF8
72             #ifdef GvNAME_HEK
73             #define GvNAMEUTF8(gv) HEK_UTF8(GvNAME_HEK(gv))
74             #else
75             #define GvNAMEUTF8(gv) 0
76             #endif
77             #endif
78              
79             #ifndef SV_CATUTF8
80             #define SV_CATUTF8 0
81             #endif
82              
83             #ifndef SV_CATBYTES
84             #define SV_CATBYTES 0
85             #endif
86              
87             #ifndef sv_catpvn_flags
88             #define sv_catpvn_flags(b,n,l,f) sv_catpvn(b,n,l)
89             #endif
90              
91             #if !PERL_VERSION_GE(5,8,3)
92             static NV Perl_ceil(NV nv) {
93             return -Perl_floor(-nv);
94             }
95             #endif
96              
97             /* Some platforms have strict exports. And before 5.7.3 cxinc (or Perl_cxinc)
98             was not exported. Therefore platforms like win32, VMS etc have problems
99             so we redefine it here -- GMB
100             */
101             #if !PERL_VERSION_GE(5,7,0)
102             /* Not in 5.6.1. */
103             # ifdef cxinc
104             # undef cxinc
105             # endif
106             # define cxinc() my_cxinc(aTHX)
107             static I32
108             my_cxinc(pTHX)
109             {
110             cxstack_max = cxstack_max * 3 / 2;
111             Renew(cxstack, cxstack_max + 1, struct context); /* fencepost bug in older CXINC macros requires +1 here */
112             return cxstack_ix + 1;
113             }
114             #endif
115              
116             #ifndef sv_copypv
117             #define sv_copypv(a, b) my_sv_copypv(aTHX_ a, b)
118             static void
119             my_sv_copypv(pTHX_ SV *const dsv, SV *const ssv)
120             {
121             STRLEN len;
122             const char * const s = SvPV_const(ssv,len);
123             sv_setpvn(dsv,s,len);
124             if(SvUTF8(ssv))
125             SvUTF8_on(dsv);
126             else
127             SvUTF8_off(dsv);
128             }
129             #endif
130              
131             #ifdef SVf_IVisUV
132             # define slu_sv_value(sv) (SvIOK(sv)) ? (SvIOK_UV(sv)) ? (NV)(SvUVX(sv)) : (NV)(SvIVX(sv)) : (SvNV(sv))
133             #else
134             # define slu_sv_value(sv) (SvIOK(sv)) ? (NV)(SvIVX(sv)) : (SvNV(sv))
135             #endif
136              
137             #if PERL_VERSION < 13 || (PERL_VERSION == 13 && PERL_SUBVERSION < 9)
138             # define PERL_HAS_BAD_MULTICALL_REFCOUNT
139             #endif
140              
141             #ifndef SvNV_nomg
142             # define SvNV_nomg SvNV
143             #endif
144              
145             #if PERL_VERSION_GE(5,16,0)
146             # define HAVE_UNICODE_PACKAGE_NAMES
147              
148             # ifndef sv_sethek
149             # define sv_sethek(a, b) Perl_sv_sethek(aTHX_ a, b)
150             # endif
151              
152             # ifndef sv_ref
153             # define sv_ref(dst, sv, ob) my_sv_ref(aTHX_ dst, sv, ob)
154             static SV *
155             my_sv_ref(pTHX_ SV *dst, const SV *sv, int ob)
156             {
157             /* cargoculted from perl 5.22's sv.c */
158             if(!dst)
159             dst = sv_newmortal();
160              
161             if(ob && SvOBJECT(sv)) {
162             if(HvNAME_get(SvSTASH(sv)))
163             sv_sethek(dst, HvNAME_HEK(SvSTASH(sv)));
164             else
165             sv_setpvs(dst, "__ANON__");
166             }
167             else {
168             const char *reftype = sv_reftype(sv, 0);
169             sv_setpv(dst, reftype);
170             }
171              
172             return dst;
173             }
174             # endif
175             #endif /* HAVE_UNICODE_PACKAGE_NAMES */
176              
177             enum slu_accum {
178             ACC_IV,
179             ACC_NV,
180             ACC_SV,
181             };
182              
183 0           static enum slu_accum accum_type(SV *sv) {
184 0 0         if(SvAMAGIC(sv))
    0          
    0          
185 0           return ACC_SV;
186              
187 0 0         if(SvIOK(sv) && !SvNOK(sv) && !SvUOK(sv))
    0          
    0          
188 0           return ACC_IV;
189              
190 0           return ACC_NV;
191             }
192              
193             /* Magic for set_subname */
194             static MGVTBL subname_vtbl;
195              
196 0           static void MY_initrand(pTHX)
197             {
198             #if (PERL_VERSION < 9)
199             struct op dmy_op;
200             struct op *old_op = PL_op;
201              
202             /* We call pp_rand here so that Drand01 get initialized if rand()
203             or srand() has not already been called
204             */
205             memzero((char*)(&dmy_op), sizeof(struct op));
206             /* we let pp_rand() borrow the TARG allocated for this XS sub */
207             dmy_op.op_targ = PL_op->op_targ;
208             PL_op = &dmy_op;
209             (void)*(PL_ppaddr[OP_RAND])(aTHX);
210             PL_op = old_op;
211             #else
212             /* Initialize Drand01 if rand() or srand() has
213             not already been called
214             */
215 0 0         if(!PL_srand_called) {
216 0           (void)seedDrand01((Rand_seed_t)Perl_seed(aTHX));
217 0           PL_srand_called = TRUE;
218             }
219             #endif
220 0           }
221              
222 0           static double MY_callrand(pTHX_ CV *randcv)
223             {
224 0           dSP;
225             double ret, dummy;
226              
227 0           ENTER;
228 0 0         PUSHMARK(SP);
229 0           PUTBACK;
230              
231 0           call_sv((SV *)randcv, G_SCALAR);
232              
233 0           SPAGAIN;
234              
235 0           ret = modf(POPn, &dummy); /* bound to < 1 */
236 0 0         if(ret < 0) ret += 1.0; /* bound to 0 <= ret < 1 */
237              
238 0           LEAVE;
239              
240 0           return ret;
241             }
242              
243             #define sv_to_cv(sv, subname) MY_sv_to_cv(aTHX_ sv, subname);
244 0           static CV* MY_sv_to_cv(pTHX_ SV* sv, const char * const subname)
245             {
246             GV *gv;
247             HV *stash;
248 0           CV *cv = sv_2cv(sv, &stash, &gv, 0);
249              
250 0 0         if(cv == Nullcv)
251 0           croak("Not a subroutine reference");
252              
253 0 0         if(!CvROOT(cv) && !CvXSUB(cv))
    0          
254 0           croak("Undefined subroutine in %s", subname);
255              
256 0           return cv;
257             }
258              
259             enum {
260             ZIP_SHORTEST = 1,
261             ZIP_LONGEST = 2,
262              
263             ZIP_MESH = 4,
264             ZIP_MESH_LONGEST = ZIP_MESH|ZIP_LONGEST,
265             ZIP_MESH_SHORTEST = ZIP_MESH|ZIP_SHORTEST,
266             };
267              
268             MODULE=List::Util PACKAGE=List::Util
269              
270             void
271             min(...)
272             PROTOTYPE: @
273             ALIAS:
274             min = 0
275             max = 1
276             CODE:
277             {
278             int index;
279 0           NV retval = 0.0; /* avoid 'uninit var' warning */
280             SV *retsv;
281             int magic;
282              
283 0 0         if(!items)
284 0           XSRETURN_UNDEF;
285              
286 0           retsv = ST(0);
287 0 0         SvGETMAGIC(retsv);
    0          
288 0 0         magic = SvAMAGIC(retsv);
    0          
    0          
289 0 0         if(!magic)
290 0 0         retval = slu_sv_value(retsv);
    0          
291              
292 0 0         for(index = 1 ; index < items ; index++) {
293 0           SV *stacksv = ST(index);
294             SV *tmpsv;
295 0 0         SvGETMAGIC(stacksv);
    0          
296 0 0         if((magic || SvAMAGIC(stacksv)) && (tmpsv = amagic_call(retsv, stacksv, gt_amg, 0))) {
    0          
    0          
    0          
    0          
297 0 0         if(SvTRUE(tmpsv) ? !ix : ix) {
    0          
298 0           retsv = stacksv;
299 0 0         magic = SvAMAGIC(retsv);
    0          
    0          
300 0 0         if(!magic) {
301 0 0         retval = slu_sv_value(retsv);
    0          
302             }
303             }
304             }
305             else {
306 0 0         NV val = slu_sv_value(stacksv);
    0          
307 0 0         if(magic) {
308 0 0         retval = slu_sv_value(retsv);
    0          
309 0           magic = 0;
310             }
311 0 0         if(val < retval ? !ix : ix) {
    0          
312 0           retsv = stacksv;
313 0           retval = val;
314             }
315             }
316             }
317 0           ST(0) = retsv;
318 0           XSRETURN(1);
319             }
320              
321              
322             void
323             sum(...)
324             PROTOTYPE: @
325             ALIAS:
326             sum = 0
327             sum0 = 1
328             product = 2
329             CODE:
330             {
331 0 0         dXSTARG;
332             SV *sv;
333 0           IV retiv = 0;
334 0           NV retnv = 0.0;
335 0           SV *retsv = NULL;
336             int index;
337             enum slu_accum accum;
338 0           int is_product = (ix == 2);
339             SV *tmpsv;
340              
341 0 0         if(!items)
342 0           switch(ix) {
343 0           case 0: XSRETURN_UNDEF;
344 0           case 1: ST(0) = sv_2mortal(newSViv(0)); XSRETURN(1);
345 0           case 2: ST(0) = sv_2mortal(newSViv(1)); XSRETURN(1);
346             }
347              
348 0           sv = ST(0);
349 0 0         SvGETMAGIC(sv);
    0          
350 0           switch((accum = accum_type(sv))) {
351 0           case ACC_SV:
352 0           retsv = TARG;
353 0           sv_setsv(retsv, sv);
354 0           break;
355 0           case ACC_IV:
356 0           retiv = SvIV(sv);
357 0           break;
358 0           case ACC_NV:
359 0 0         retnv = slu_sv_value(sv);
    0          
360 0           break;
361             }
362              
363 0 0         for(index = 1 ; index < items ; index++) {
364 0           sv = ST(index);
365 0 0         SvGETMAGIC(sv);
    0          
366 0 0         if(accum < ACC_SV && SvAMAGIC(sv)){
    0          
    0          
    0          
367 0 0         if(!retsv)
368 0           retsv = TARG;
369 0 0         sv_setnv(retsv, accum == ACC_NV ? retnv : retiv);
370 0           accum = ACC_SV;
371             }
372 0           switch(accum) {
373 0           case ACC_SV:
374 0 0         tmpsv = amagic_call(retsv, sv,
    0          
    0          
    0          
375             is_product ? mult_amg : add_amg,
376             SvAMAGIC(retsv) ? AMGf_assign : 0);
377 0 0         if(tmpsv) {
378 0           switch((accum = accum_type(tmpsv))) {
379 0           case ACC_SV:
380 0           retsv = tmpsv;
381 0           break;
382 0           case ACC_IV:
383 0           retiv = SvIV(tmpsv);
384 0           break;
385 0           case ACC_NV:
386 0 0         retnv = slu_sv_value(tmpsv);
    0          
387 0           break;
388             }
389             }
390             else {
391             /* fall back to default */
392 0           accum = ACC_NV;
393 0           is_product ? (retnv = SvNV(retsv) * SvNV(sv))
394 0 0         : (retnv = SvNV(retsv) + SvNV(sv));
395             }
396 0           break;
397 0           case ACC_IV:
398 0 0         if(is_product) {
399             /* TODO: Consider if product() should shortcircuit the moment its
400             * accumulator becomes zero
401             */
402             /* XXX testing flags before running get_magic may
403             * cause some valid tied values to fallback to the NV path
404             * - DAPM */
405 0 0         if(!SvNOK(sv) && SvIOK(sv)) {
    0          
406 0           IV i = SvIV(sv);
407 0 0         if (retiv == 0) /* avoid later division by zero */
408 0           break;
409 0 0         if (retiv < -1) { /* avoid -1 because that causes SIGFPE */
410 0 0         if (i < 0) {
411 0 0         if (i >= IV_MAX / retiv) {
412 0           retiv *= i;
413 0           break;
414             }
415             }
416             else {
417 0 0         if (i <= IV_MIN / retiv) {
418 0           retiv *= i;
419 0           break;
420             }
421             }
422             }
423 0 0         else if (retiv > 0) {
424 0 0         if (i < 0) {
425 0 0         if (i >= IV_MIN / retiv) {
426 0           retiv *= i;
427 0           break;
428             }
429             }
430             else {
431 0 0         if (i <= IV_MAX / retiv) {
432 0           retiv *= i;
433 0           break;
434             }
435             }
436             }
437             }
438             /* else fallthrough */
439             }
440             else {
441             /* XXX testing flags before running get_magic may
442             * cause some valid tied values to fallback to the NV path
443             * - DAPM */
444 0 0         if(!SvNOK(sv) && SvIOK(sv)) {
    0          
445 0           IV i = SvIV(sv);
446 0 0         if (retiv >= 0 && i >= 0) {
    0          
447 0 0         if (retiv <= IV_MAX - i) {
448 0           retiv += i;
449 0           break;
450             }
451             /* else fallthrough */
452             }
453 0 0         else if (retiv < 0 && i < 0) {
    0          
454 0 0         if (retiv >= IV_MIN - i) {
455 0           retiv += i;
456 0           break;
457             }
458             /* else fallthrough */
459             }
460             else {
461             /* mixed signs can't overflow */
462 0           retiv += i;
463 0           break;
464             }
465             }
466             /* else fallthrough */
467             }
468              
469 0           retnv = retiv;
470 0           accum = ACC_NV;
471             /* FALLTHROUGH */
472 0           case ACC_NV:
473 0 0         is_product ? (retnv *= slu_sv_value(sv))
    0          
474 0 0         : (retnv += slu_sv_value(sv));
    0          
    0          
475 0           break;
476             }
477             }
478              
479 0 0         if(!retsv)
480 0           retsv = TARG;
481              
482 0           switch(accum) {
483 0           case ACC_SV: /* nothing to do */
484 0           break;
485 0           case ACC_IV:
486 0           sv_setiv(retsv, retiv);
487 0           break;
488 0           case ACC_NV:
489 0           sv_setnv(retsv, retnv);
490 0           break;
491             }
492              
493 0           ST(0) = retsv;
494 0           XSRETURN(1);
495             }
496              
497             #define SLU_CMP_LARGER 1
498             #define SLU_CMP_SMALLER -1
499              
500             void
501             minstr(...)
502             PROTOTYPE: @
503             ALIAS:
504             minstr = SLU_CMP_LARGER
505             maxstr = SLU_CMP_SMALLER
506             CODE:
507             {
508             SV *left;
509             int index;
510              
511 0 0         if(!items)
512 0           XSRETURN_UNDEF;
513              
514 0           left = ST(0);
515             #ifdef OPpLOCALE
516             if(MAXARG & OPpLOCALE) {
517             for(index = 1 ; index < items ; index++) {
518             SV *right = ST(index);
519             if(sv_cmp_locale(left, right) == ix)
520             left = right;
521             }
522             }
523             else {
524             #endif
525 0 0         for(index = 1 ; index < items ; index++) {
526 0           SV *right = ST(index);
527 0 0         if(sv_cmp(left, right) == ix)
528 0           left = right;
529             }
530             #ifdef OPpLOCALE
531             }
532             #endif
533 0           ST(0) = left;
534 0           XSRETURN(1);
535             }
536              
537              
538              
539              
540             void
541             reduce(block,...)
542             SV *block
543             PROTOTYPE: &@
544             ALIAS:
545             reduce = 0
546             reductions = 1
547             CODE:
548             {
549 0           SV *ret = sv_newmortal();
550             int index;
551 0           AV *retvals = NULL;
552             GV *agv,*bgv;
553 0           SV **args = &PL_stack_base[ax];
554 0 0         CV *cv = sv_to_cv(block, ix ? "reductions" : "reduce");
555              
556 0 0         if(items <= 1) {
557 0 0         if(ix)
558 0           XSRETURN(0);
559             else
560 0           XSRETURN_UNDEF;
561             }
562              
563 0           agv = gv_fetchpv("a", GV_ADD, SVt_PV);
564 0           bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
565 0           SAVESPTR(GvSV(agv));
566 0           SAVESPTR(GvSV(bgv));
567 0           GvSV(agv) = ret;
568 0 0         SvSetMagicSV(ret, args[1]);
    0          
569              
570 0 0         if(ix) {
571             /* Precreate an AV for return values; -1 for cv, -1 for top index */
572 0           retvals = newAV();
573 0           av_extend(retvals, items-1-1);
574              
575             /* so if throw an exception they can be reclaimed */
576 0           SAVEFREESV(retvals);
577              
578 0           av_push(retvals, newSVsv(ret));
579             }
580             #ifdef dMULTICALL
581             assert(cv);
582 0 0         if(!CvISXSUB(cv)) {
583             dMULTICALL;
584 0           I32 gimme = G_SCALAR;
585              
586             UNUSED_VAR_newsp;
587 0 0         PUSH_MULTICALL(cv);
588 0 0         for(index = 2 ; index < items ; index++) {
589 0           GvSV(bgv) = args[index];
590 0           MULTICALL;
591 0 0         SvSetMagicSV(ret, *PL_stack_sp);
    0          
592 0 0         if(ix)
593 0           av_push(retvals, newSVsv(ret));
594             }
595             # ifdef PERL_HAS_BAD_MULTICALL_REFCOUNT
596             if(CvDEPTH(multicall_cv) > 1)
597             SvREFCNT_inc_simple_void_NN(multicall_cv);
598             # endif
599 0 0         POP_MULTICALL;
600             }
601             else
602             #endif
603             {
604 0 0         for(index = 2 ; index < items ; index++) {
605 0           dSP;
606 0           GvSV(bgv) = args[index];
607              
608 0 0         PUSHMARK(SP);
609 0           call_sv((SV*)cv, G_SCALAR);
610              
611 0 0         SvSetMagicSV(ret, *PL_stack_sp);
    0          
612 0 0         if(ix)
613 0           av_push(retvals, newSVsv(ret));
614             }
615             }
616              
617 0 0         if(ix) {
618             int i;
619 0           SV **svs = AvARRAY(retvals);
620             /* steal the SVs from retvals */
621 0 0         for(i = 0; i < items-1; i++) {
622 0           ST(i) = sv_2mortal(svs[i]);
623 0           svs[i] = NULL;
624             }
625              
626 0           XSRETURN(items-1);
627             }
628             else {
629 0           ST(0) = ret;
630 0           XSRETURN(1);
631             }
632             }
633              
634             void
635             first(block,...)
636             SV *block
637             PROTOTYPE: &@
638             CODE:
639             {
640             int index;
641 0           SV **args = &PL_stack_base[ax];
642 0           CV *cv = sv_to_cv(block, "first");
643              
644 0 0         if(items <= 1)
645 0           XSRETURN_UNDEF;
646              
647 0           SAVESPTR(GvSV(PL_defgv));
648             #ifdef dMULTICALL
649             assert(cv);
650 0 0         if(!CvISXSUB(cv)) {
651             dMULTICALL;
652 0           I32 gimme = G_SCALAR;
653              
654             UNUSED_VAR_newsp;
655 0 0         PUSH_MULTICALL(cv);
656              
657 0 0         for(index = 1 ; index < items ; index++) {
658 0           SV *def_sv = GvSV(PL_defgv) = args[index];
659             # ifdef SvTEMP_off
660 0           SvTEMP_off(def_sv);
661             # endif
662 0           MULTICALL;
663 0 0         if(SvTRUEx(*PL_stack_sp)) {
664             # ifdef PERL_HAS_BAD_MULTICALL_REFCOUNT
665             if(CvDEPTH(multicall_cv) > 1)
666             SvREFCNT_inc_simple_void_NN(multicall_cv);
667             # endif
668 0 0         POP_MULTICALL;
669 0           ST(0) = ST(index);
670 0           XSRETURN(1);
671             }
672             }
673             # ifdef PERL_HAS_BAD_MULTICALL_REFCOUNT
674             if(CvDEPTH(multicall_cv) > 1)
675             SvREFCNT_inc_simple_void_NN(multicall_cv);
676             # endif
677 0 0         POP_MULTICALL;
678             }
679             else
680             #endif
681             {
682 0 0         for(index = 1 ; index < items ; index++) {
683 0           dSP;
684 0           GvSV(PL_defgv) = args[index];
685              
686 0 0         PUSHMARK(SP);
687 0           call_sv((SV*)cv, G_SCALAR);
688 0 0         if(SvTRUEx(*PL_stack_sp)) {
689 0           ST(0) = ST(index);
690 0           XSRETURN(1);
691             }
692             }
693             }
694 0           XSRETURN_UNDEF;
695             }
696              
697              
698             void
699             any(block,...)
700             SV *block
701             ALIAS:
702             none = 0
703             all = 1
704             any = 2
705             notall = 3
706             PROTOTYPE: &@
707             PPCODE:
708             {
709 0           int ret_true = !(ix & 2); /* return true at end of loop for none/all; false for any/notall */
710 0           int invert = (ix & 1); /* invert block test for all/notall */
711 0           SV **args = &PL_stack_base[ax];
712 0 0         CV *cv = sv_to_cv(block,
    0          
    0          
    0          
713             ix == 0 ? "none" :
714             ix == 1 ? "all" :
715             ix == 2 ? "any" :
716             ix == 3 ? "notall" :
717             "unknown 'any' alias");
718              
719 0           SAVESPTR(GvSV(PL_defgv));
720             #ifdef dMULTICALL
721             assert(cv);
722 0 0         if(!CvISXSUB(cv)) {
723             dMULTICALL;
724 0           I32 gimme = G_SCALAR;
725             int index;
726              
727             UNUSED_VAR_newsp;
728 0 0         PUSH_MULTICALL(cv);
729 0 0         for(index = 1; index < items; index++) {
730 0           SV *def_sv = GvSV(PL_defgv) = args[index];
731             # ifdef SvTEMP_off
732 0           SvTEMP_off(def_sv);
733             # endif
734              
735 0           MULTICALL;
736 0 0         if(SvTRUEx(*PL_stack_sp) ^ invert) {
737 0 0         POP_MULTICALL;
738 0 0         ST(0) = ret_true ? &PL_sv_no : &PL_sv_yes;
739 0           XSRETURN(1);
740             }
741             }
742 0 0         POP_MULTICALL;
743             }
744             else
745             #endif
746             {
747             int index;
748 0 0         for(index = 1; index < items; index++) {
749 0           dSP;
750 0           GvSV(PL_defgv) = args[index];
751              
752 0 0         PUSHMARK(SP);
753 0           call_sv((SV*)cv, G_SCALAR);
754 0 0         if(SvTRUEx(*PL_stack_sp) ^ invert) {
755 0 0         ST(0) = ret_true ? &PL_sv_no : &PL_sv_yes;
756 0           XSRETURN(1);
757             }
758             }
759             }
760              
761 0 0         ST(0) = ret_true ? &PL_sv_yes : &PL_sv_no;
762 0           XSRETURN(1);
763             }
764              
765             void
766             head(size,...)
767             PROTOTYPE: $@
768             ALIAS:
769             head = 0
770             tail = 1
771             PPCODE:
772             {
773 0           int size = 0;
774 0           int start = 0;
775 0           int end = 0;
776 0           int i = 0;
777              
778 0           size = SvIV( ST(0) );
779              
780 0 0         if ( ix == 0 ) {
781 0           start = 1;
782 0           end = start + size;
783 0 0         if ( size < 0 ) {
784 0           end += items - 1;
785             }
786 0 0         if ( end > items ) {
787 0           end = items;
788             }
789             }
790             else {
791 0           end = items;
792 0 0         if ( size < 0 ) {
793 0           start = -size + 1;
794             }
795             else {
796 0           start = end - size;
797             }
798 0 0         if ( start < 1 ) {
799 0           start = 1;
800             }
801             }
802              
803 0 0         if ( end <= start ) {
804 0           XSRETURN(0);
805             }
806             else {
807 0 0         EXTEND( SP, end - start );
    0          
808 0 0         for ( i = start; i < end; i++ ) {
809 0           PUSHs( sv_2mortal( newSVsv( ST(i) ) ) );
810             }
811 0           XSRETURN( end - start );
812             }
813             }
814              
815             void
816             pairs(...)
817             PROTOTYPE: @
818             PPCODE:
819             {
820 0           int argi = 0;
821 0           int reti = 0;
822 0           HV *pairstash = get_hv("List::Util::_Pair::", GV_ADD);
823              
824 0 0         if(items % 2 && ckWARN(WARN_MISC))
    0          
825 0           warn("Odd number of elements in pairs");
826              
827             {
828 0 0         for(; argi < items; argi += 2) {
829 0           SV *a = ST(argi);
830 0 0         SV *b = argi < items-1 ? ST(argi+1) : &PL_sv_undef;
831              
832 0           AV *av = newAV();
833 0           av_push(av, newSVsv(a));
834 0           av_push(av, newSVsv(b));
835              
836 0           ST(reti) = sv_2mortal(newRV_noinc((SV *)av));
837 0           sv_bless(ST(reti), pairstash);
838 0           reti++;
839             }
840             }
841              
842 0           XSRETURN(reti);
843             }
844              
845             void
846             unpairs(...)
847             PROTOTYPE: @
848             PPCODE:
849             {
850             /* Unlike pairs(), we're going to trash the input values on the stack
851             * almost as soon as we start generating output. So clone them first
852             */
853             int i;
854             SV **args_copy;
855 0           Newx(args_copy, items, SV *);
856 0           SAVEFREEPV(args_copy);
857              
858 0           Copy(&ST(0), args_copy, items, SV *);
859              
860 0 0         for(i = 0; i < items; i++) {
861 0           SV *pair = args_copy[i];
862             AV *pairav;
863              
864 0 0         SvGETMAGIC(pair);
    0          
865              
866 0 0         if(SvTYPE(pair) != SVt_RV)
867 0           croak("Not a reference at List::Util::unpairs() argument %d", i);
868 0 0         if(SvTYPE(SvRV(pair)) != SVt_PVAV)
869 0           croak("Not an ARRAY reference at List::Util::unpairs() argument %d", i);
870              
871             /* TODO: assert pair is an ARRAY ref */
872 0           pairav = (AV *)SvRV(pair);
873              
874 0 0         EXTEND(SP, 2);
875              
876 0 0         if(AvFILL(pairav) >= 0)
    0          
877 0           mPUSHs(newSVsv(AvARRAY(pairav)[0]));
878             else
879 0           PUSHs(&PL_sv_undef);
880              
881 0 0         if(AvFILL(pairav) >= 1)
    0          
882 0           mPUSHs(newSVsv(AvARRAY(pairav)[1]));
883             else
884 0           PUSHs(&PL_sv_undef);
885             }
886              
887 0           XSRETURN(items * 2);
888             }
889              
890             void
891             pairkeys(...)
892             PROTOTYPE: @
893             PPCODE:
894             {
895 0           int argi = 0;
896 0           int reti = 0;
897              
898 0 0         if(items % 2 && ckWARN(WARN_MISC))
    0          
899 0           warn("Odd number of elements in pairkeys");
900              
901             {
902 0 0         for(; argi < items; argi += 2) {
903 0           SV *a = ST(argi);
904              
905 0           ST(reti++) = sv_2mortal(newSVsv(a));
906             }
907             }
908              
909 0           XSRETURN(reti);
910             }
911              
912             void
913             pairvalues(...)
914             PROTOTYPE: @
915             PPCODE:
916             {
917 0           int argi = 0;
918 0           int reti = 0;
919              
920 0 0         if(items % 2 && ckWARN(WARN_MISC))
    0          
921 0           warn("Odd number of elements in pairvalues");
922              
923             {
924 0 0         for(; argi < items; argi += 2) {
925 0 0         SV *b = argi < items-1 ? ST(argi+1) : &PL_sv_undef;
926              
927 0           ST(reti++) = sv_2mortal(newSVsv(b));
928             }
929             }
930              
931 0           XSRETURN(reti);
932             }
933              
934             void
935             pairfirst(block,...)
936             SV *block
937             PROTOTYPE: &@
938             PPCODE:
939             {
940             GV *agv,*bgv;
941 0           CV *cv = sv_to_cv(block, "pairfirst");
942 0           I32 ret_gimme = GIMME_V;
943 0           int argi = 1; /* "shift" the block */
944              
945 0 0         if(!(items % 2) && ckWARN(WARN_MISC))
    0          
946 0           warn("Odd number of elements in pairfirst");
947              
948 0           agv = gv_fetchpv("a", GV_ADD, SVt_PV);
949 0           bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
950 0           SAVESPTR(GvSV(agv));
951 0           SAVESPTR(GvSV(bgv));
952             #ifdef dMULTICALL
953             assert(cv);
954 0 0         if(!CvISXSUB(cv)) {
955             /* Since MULTICALL is about to move it */
956 0           SV **stack = PL_stack_base + ax;
957              
958             dMULTICALL;
959 0           I32 gimme = G_SCALAR;
960              
961             UNUSED_VAR_newsp;
962 0 0         PUSH_MULTICALL(cv);
963 0 0         for(; argi < items; argi += 2) {
964 0           SV *a = GvSV(agv) = stack[argi];
965 0 0         SV *b = GvSV(bgv) = argi < items-1 ? stack[argi+1] : &PL_sv_undef;
966              
967 0           MULTICALL;
968              
969 0 0         if(!SvTRUEx(*PL_stack_sp))
970 0           continue;
971              
972 0 0         POP_MULTICALL;
973 0 0         if(ret_gimme == G_LIST) {
974 0           ST(0) = sv_mortalcopy(a);
975 0           ST(1) = sv_mortalcopy(b);
976 0           XSRETURN(2);
977             }
978             else
979 0           XSRETURN_YES;
980             }
981 0 0         POP_MULTICALL;
982 0           XSRETURN(0);
983             }
984             else
985             #endif
986             {
987 0 0         for(; argi < items; argi += 2) {
988 0           dSP;
989 0           SV *a = GvSV(agv) = ST(argi);
990 0 0         SV *b = GvSV(bgv) = argi < items-1 ? ST(argi+1) : &PL_sv_undef;
991              
992 0 0         PUSHMARK(SP);
993 0           call_sv((SV*)cv, G_SCALAR);
994              
995 0           SPAGAIN;
996              
997 0 0         if(!SvTRUEx(*PL_stack_sp))
998 0           continue;
999              
1000 0 0         if(ret_gimme == G_LIST) {
1001 0           ST(0) = sv_mortalcopy(a);
1002 0           ST(1) = sv_mortalcopy(b);
1003 0           XSRETURN(2);
1004             }
1005             else
1006 0           XSRETURN_YES;
1007             }
1008             }
1009              
1010 0           XSRETURN(0);
1011             }
1012              
1013             void
1014             pairgrep(block,...)
1015             SV *block
1016             PROTOTYPE: &@
1017             PPCODE:
1018             {
1019             GV *agv,*bgv;
1020 0           CV *cv = sv_to_cv(block, "pairgrep");
1021 0           I32 ret_gimme = GIMME_V;
1022              
1023             /* This function never returns more than it consumed in arguments. So we
1024             * can build the results "live", behind the arguments
1025             */
1026 0           int argi = 1; /* "shift" the block */
1027 0           int reti = 0;
1028              
1029 0 0         if(!(items % 2) && ckWARN(WARN_MISC))
    0          
1030 0           warn("Odd number of elements in pairgrep");
1031              
1032 0           agv = gv_fetchpv("a", GV_ADD, SVt_PV);
1033 0           bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
1034 0           SAVESPTR(GvSV(agv));
1035 0           SAVESPTR(GvSV(bgv));
1036             #ifdef dMULTICALL
1037             assert(cv);
1038 0 0         if(!CvISXSUB(cv)) {
1039             /* Since MULTICALL is about to move it */
1040 0           SV **stack = PL_stack_base + ax;
1041             int i;
1042              
1043             dMULTICALL;
1044 0           I32 gimme = G_SCALAR;
1045              
1046             UNUSED_VAR_newsp;
1047 0 0         PUSH_MULTICALL(cv);
1048 0 0         for(; argi < items; argi += 2) {
1049 0           SV *a = GvSV(agv) = stack[argi];
1050 0 0         SV *b = GvSV(bgv) = argi < items-1 ? stack[argi+1] : &PL_sv_undef;
1051              
1052 0           MULTICALL;
1053              
1054 0 0         if(SvTRUEx(*PL_stack_sp)) {
1055 0 0         if(ret_gimme == G_LIST) {
1056             /* We can't mortalise yet or they'd be mortal too early */
1057 0           stack[reti++] = newSVsv(a);
1058 0           stack[reti++] = newSVsv(b);
1059             }
1060 0 0         else if(ret_gimme == G_SCALAR)
1061 0           reti++;
1062             }
1063             }
1064 0 0         POP_MULTICALL;
1065              
1066 0 0         if(ret_gimme == G_LIST)
1067 0 0         for(i = 0; i < reti; i++)
1068 0           sv_2mortal(stack[i]);
1069             }
1070             else
1071             #endif
1072             {
1073 0 0         for(; argi < items; argi += 2) {
1074 0           dSP;
1075 0           SV *a = GvSV(agv) = ST(argi);
1076 0 0         SV *b = GvSV(bgv) = argi < items-1 ? ST(argi+1) : &PL_sv_undef;
1077              
1078 0 0         PUSHMARK(SP);
1079 0           call_sv((SV*)cv, G_SCALAR);
1080              
1081 0           SPAGAIN;
1082              
1083 0 0         if(SvTRUEx(*PL_stack_sp)) {
1084 0 0         if(ret_gimme == G_LIST) {
1085 0           ST(reti++) = sv_mortalcopy(a);
1086 0           ST(reti++) = sv_mortalcopy(b);
1087             }
1088 0 0         else if(ret_gimme == G_SCALAR)
1089 0           reti++;
1090             }
1091             }
1092             }
1093              
1094 0 0         if(ret_gimme == G_LIST)
1095 0           XSRETURN(reti);
1096 0 0         else if(ret_gimme == G_SCALAR) {
1097 0           ST(0) = newSViv(reti);
1098 0           XSRETURN(1);
1099             }
1100             }
1101              
1102             void
1103             pairmap(block,...)
1104             SV *block
1105             PROTOTYPE: &@
1106             PPCODE:
1107             {
1108             GV *agv,*bgv;
1109 0           CV *cv = sv_to_cv(block, "pairmap");
1110 0           SV **args_copy = NULL;
1111 0           I32 ret_gimme = GIMME_V;
1112              
1113 0           int argi = 1; /* "shift" the block */
1114 0           int reti = 0;
1115              
1116 0 0         if(!(items % 2) && ckWARN(WARN_MISC))
    0          
1117 0           warn("Odd number of elements in pairmap");
1118              
1119 0           agv = gv_fetchpv("a", GV_ADD, SVt_PV);
1120 0           bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
1121 0           SAVESPTR(GvSV(agv));
1122 0           SAVESPTR(GvSV(bgv));
1123             /* This MULTICALL-based code appears to fail on perl 5.10.0 and 5.8.9
1124             * Skip it on those versions (RT#87857)
1125             */
1126             #if defined(dMULTICALL) && (PERL_VERSION_GE(5,10,1) || PERL_VERSION_LE(5,8,8))
1127             assert(cv);
1128 0 0         if(!CvISXSUB(cv)) {
1129             /* Since MULTICALL is about to move it */
1130 0           SV **stack = PL_stack_base + ax;
1131 0           I32 ret_gimme = GIMME_V;
1132             int i;
1133 0           AV *spill = NULL; /* accumulates results if too big for stack */
1134              
1135             dMULTICALL;
1136 0           I32 gimme = G_LIST;
1137              
1138             UNUSED_VAR_newsp;
1139 0 0         PUSH_MULTICALL(cv);
1140 0 0         for(; argi < items; argi += 2) {
1141             int count;
1142              
1143 0           GvSV(agv) = stack[argi];
1144 0 0         GvSV(bgv) = argi < items-1 ? stack[argi+1]: &PL_sv_undef;
1145              
1146 0           MULTICALL;
1147 0           count = PL_stack_sp - PL_stack_base;
1148              
1149 0 0         if (count > 2 || spill) {
    0          
1150             /* We can't return more than 2 results for a given input pair
1151             * without trashing the remaining arguments on the stack still
1152             * to be processed, or possibly overrunning the stack end.
1153             * So, we'll accumulate the results in a temporary buffer
1154             * instead.
1155             * We didn't do this initially because in the common case, most
1156             * code blocks will return only 1 or 2 items so it won't be
1157             * necessary
1158             */
1159             int fill;
1160              
1161 0 0         if (!spill) {
1162 0           spill = newAV();
1163 0           AvREAL_off(spill); /* don't ref count its contents */
1164             /* can't mortalize here as every nextstate in the code
1165             * block frees temps */
1166 0           SAVEFREESV(spill);
1167             }
1168              
1169 0 0         fill = (int)AvFILL(spill);
1170 0           av_extend(spill, fill + count);
1171 0 0         for(i = 0; i < count; i++)
1172 0           (void)av_store(spill, ++fill,
1173             newSVsv(PL_stack_base[i + 1]));
1174             }
1175             else
1176 0 0         for(i = 0; i < count; i++)
1177 0           stack[reti++] = newSVsv(PL_stack_base[i + 1]);
1178             }
1179              
1180 0 0         if (spill) {
1181             /* the POP_MULTICALL will trigger the SAVEFREESV above;
1182             * keep it alive it on the temps stack instead */
1183 0           SvREFCNT_inc_simple_void_NN(spill);
1184 0           sv_2mortal((SV*)spill);
1185             }
1186              
1187 0 0         POP_MULTICALL;
1188              
1189 0 0         if (spill) {
1190 0 0         int n = (int)AvFILL(spill) + 1;
1191 0           SP = &ST(reti - 1);
1192 0 0         EXTEND(SP, n);
    0          
1193 0 0         for (i = 0; i < n; i++)
1194 0           *++SP = *av_fetch(spill, i, FALSE);
1195 0           reti += n;
1196 0           av_clear(spill);
1197             }
1198              
1199 0 0         if(ret_gimme == G_LIST)
1200 0 0         for(i = 0; i < reti; i++)
1201 0           sv_2mortal(ST(i));
1202             }
1203             else
1204             #endif
1205             {
1206 0 0         for(; argi < items; argi += 2) {
1207 0           dSP;
1208             int count;
1209             int i;
1210              
1211 0 0         GvSV(agv) = args_copy ? args_copy[argi] : ST(argi);
1212 0           GvSV(bgv) = argi < items-1 ?
1213 0 0         (args_copy ? args_copy[argi+1] : ST(argi+1)) :
    0          
1214             &PL_sv_undef;
1215              
1216 0 0         PUSHMARK(SP);
1217 0           count = call_sv((SV*)cv, G_LIST);
1218              
1219 0           SPAGAIN;
1220              
1221 0 0         if(count > 2 && !args_copy && ret_gimme == G_LIST) {
    0          
    0          
1222 0           int n_args = items - argi;
1223 0           Newx(args_copy, n_args, SV *);
1224 0           SAVEFREEPV(args_copy);
1225              
1226 0           Copy(&ST(argi), args_copy, n_args, SV *);
1227              
1228 0           argi = 0;
1229 0           items = n_args;
1230             }
1231              
1232 0 0         if(ret_gimme == G_LIST)
1233 0 0         for(i = 0; i < count; i++)
1234 0           ST(reti++) = sv_mortalcopy(SP[i - count + 1]);
1235             else
1236 0           reti += count;
1237              
1238 0           PUTBACK;
1239             }
1240             }
1241              
1242 0 0         if(ret_gimme == G_LIST)
1243 0           XSRETURN(reti);
1244              
1245 0           ST(0) = sv_2mortal(newSViv(reti));
1246 0           XSRETURN(1);
1247             }
1248              
1249             void
1250             shuffle(...)
1251             PROTOTYPE: @
1252             CODE:
1253             {
1254             int index;
1255 0           SV *randsv = get_sv("List::Util::RAND", 0);
1256 0 0         CV * const randcv = randsv && SvROK(randsv) && SvTYPE(SvRV(randsv)) == SVt_PVCV ?
    0          
1257 0 0         (CV *)SvRV(randsv) : NULL;
1258              
1259 0 0         if(!randcv)
1260 0           MY_initrand(aTHX);
1261              
1262 0 0         for (index = items ; index > 1 ; ) {
1263 0           int swap = (int)(
1264 0 0         (randcv ? MY_callrand(aTHX_ randcv) : Drand01()) * (double)(index--)
1265             );
1266 0           SV *tmp = ST(swap);
1267 0           ST(swap) = ST(index);
1268 0           ST(index) = tmp;
1269             }
1270              
1271 0           XSRETURN(items);
1272             }
1273              
1274             void
1275             sample(...)
1276             PROTOTYPE: $@
1277             CODE:
1278             {
1279 0 0         IV count = items ? SvUV(ST(0)) : 0;
1280 0           IV reti = 0;
1281 0           SV *randsv = get_sv("List::Util::RAND", 0);
1282 0 0         CV * const randcv = randsv && SvROK(randsv) && SvTYPE(SvRV(randsv)) == SVt_PVCV ?
    0          
1283 0 0         (CV *)SvRV(randsv) : NULL;
1284              
1285 0 0         if(!count)
1286 0           XSRETURN(0);
1287              
1288             /* Now we've extracted count from ST(0) the rest of this logic will be a
1289             * lot neater if we move the topmost item into ST(0) so we can just work
1290             * within 0..items-1 */
1291 0           ST(0) = POPs;
1292 0           items--;
1293              
1294 0 0         if(count > items)
1295 0           count = items;
1296              
1297 0 0         if(!randcv)
1298 0           MY_initrand(aTHX);
1299              
1300             /* Partition the stack into ST(0)..ST(reti-1) containing the sampled results
1301             * and ST(reti)..ST(items-1) containing the remaining pending candidates
1302             */
1303 0 0         while(reti < count) {
1304 0           int index = (int)(
1305 0 0         (randcv ? MY_callrand(aTHX_ randcv) : Drand01()) * (double)(items - reti)
1306             );
1307              
1308 0           SV *selected = ST(reti + index);
1309             /* preserve the element we're about to stomp on by putting it back into
1310             * the pending partition */
1311 0           ST(reti + index) = ST(reti);
1312              
1313 0           ST(reti) = selected;
1314 0           reti++;
1315             }
1316              
1317 0           XSRETURN(reti);
1318             }
1319              
1320              
1321             void
1322             uniq(...)
1323             PROTOTYPE: @
1324             ALIAS:
1325             uniqint = 0
1326             uniqstr = 1
1327             uniq = 2
1328             CODE:
1329             {
1330 0           int retcount = 0;
1331             int index;
1332 0           SV **args = &PL_stack_base[ax];
1333             HV *seen;
1334 0           int seen_undef = 0;
1335              
1336 0 0         if(items == 0 || (items == 1 && !SvGAMAGIC(args[0]) && SvOK(args[0]))) {
    0          
    0          
    0          
    0          
    0          
    0          
1337             /* Optimise for the case of the empty list or a defined nonmagic
1338             * singleton. Leave a singleton magical||undef for the regular case */
1339 0           retcount = items;
1340 0           goto finish;
1341             }
1342              
1343 0           sv_2mortal((SV *)(seen = newHV()));
1344              
1345 0 0         for(index = 0 ; index < items ; index++) {
1346 0           SV *arg = args[index];
1347             #ifdef HV_FETCH_EMPTY_HE
1348             HE *he;
1349             #endif
1350              
1351 0 0         if(SvGAMAGIC(arg))
    0          
    0          
    0          
1352             /* clone the value so we don't invoke magic again */
1353 0           arg = sv_mortalcopy(arg);
1354              
1355 0 0         if(ix == 2 && !SvOK(arg)) {
    0          
1356             /* special handling of undef for uniq() */
1357 0 0         if(seen_undef)
1358 0           continue;
1359              
1360 0           seen_undef++;
1361              
1362 0 0         if(GIMME_V == G_LIST)
1363 0           ST(retcount) = arg;
1364 0           retcount++;
1365 0           continue;
1366             }
1367 0 0         if(ix == 0) {
1368             /* uniqint */
1369             /* coerce to integer */
1370             #if PERL_VERSION >= 8
1371             /* int_amg only appeared in perl 5.8.0 */
1372 0 0         if(SvAMAGIC(arg) && (arg = AMG_CALLun(arg, int)))
    0          
    0          
    0          
1373             ; /* nothing to do */
1374             else
1375             #endif
1376 0 0         if(!SvOK(arg) || SvNOK(arg) || SvPOK(arg))
    0          
    0          
1377             {
1378             /* Convert undef, NVs and PVs into a well-behaved int */
1379 0           NV nv = SvNV(arg);
1380              
1381 0 0         if(nv > (NV)UV_MAX)
1382             /* Too positive for UV - use NV */
1383 0           arg = newSVnv(Perl_floor(nv));
1384 0 0         else if(nv < (NV)IV_MIN)
1385             /* Too negative for IV - use NV */
1386 0           arg = newSVnv(Perl_ceil(nv));
1387 0 0         else if(nv > 0 && (UV)nv > (UV)IV_MAX)
    0          
1388             /* Too positive for IV - use UV */
1389 0           arg = newSVuv(nv);
1390             else
1391             /* Must now fit into IV */
1392 0           arg = newSViv(nv);
1393              
1394 0           sv_2mortal(arg);
1395             }
1396             }
1397             #ifdef HV_FETCH_EMPTY_HE
1398 0           he = (HE*) hv_common(seen, arg, NULL, 0, 0, HV_FETCH_LVALUE | HV_FETCH_EMPTY_HE, NULL, 0);
1399 0 0         if (HeVAL(he))
1400 0           continue;
1401              
1402 0           HeVAL(he) = &PL_sv_undef;
1403             #else
1404             if (hv_exists_ent(seen, arg, 0))
1405             continue;
1406              
1407             hv_store_ent(seen, arg, &PL_sv_yes, 0);
1408             #endif
1409              
1410 0 0         if(GIMME_V == G_LIST)
1411 0 0         ST(retcount) = SvOK(arg) ? arg : sv_2mortal(newSVpvn("", 0));
1412 0           retcount++;
1413             }
1414              
1415 0           finish:
1416 0 0         if(GIMME_V == G_LIST)
1417 0           XSRETURN(retcount);
1418             else
1419 0           ST(0) = sv_2mortal(newSViv(retcount));
1420             }
1421              
1422             void
1423             uniqnum(...)
1424             PROTOTYPE: @
1425             CODE:
1426             {
1427 0           int retcount = 0;
1428             int index;
1429 0           SV **args = &PL_stack_base[ax];
1430             HV *seen;
1431             /* A temporary buffer for number stringification */
1432 0           SV *keysv = sv_newmortal();
1433              
1434 0 0         if(items == 0 || (items == 1 && !SvGAMAGIC(args[0]) && SvOK(args[0]))) {
    0          
    0          
    0          
    0          
    0          
    0          
1435             /* Optimise for the case of the empty list or a defined nonmagic
1436             * singleton. Leave a singleton magical||undef for the regular case */
1437 0           retcount = items;
1438 0           goto finish;
1439             }
1440              
1441 0           sv_2mortal((SV *)(seen = newHV()));
1442              
1443 0 0         for(index = 0 ; index < items ; index++) {
1444 0           SV *arg = args[index];
1445             NV nv_arg;
1446             #ifdef HV_FETCH_EMPTY_HE
1447             HE* he;
1448             #endif
1449              
1450 0 0         if(SvGAMAGIC(arg))
    0          
    0          
    0          
1451             /* clone the value so we don't invoke magic again */
1452 0           arg = sv_mortalcopy(arg);
1453              
1454 0 0         if(SvOK(arg) && !(SvUOK(arg) || SvIOK(arg) || SvNOK(arg))) {
    0          
    0          
    0          
1455             #if PERL_VERSION >= 8
1456 0           SvIV(arg); /* sets SVf_IOK/SVf_IsUV if it's an integer */
1457             #else
1458             SvNV(arg); /* SvIV() sets SVf_IOK even on floats on 5.6 */
1459             #endif
1460             }
1461             #if NVSIZE > IVSIZE /* $Config{nvsize} > $Config{ivsize} */
1462             /* Avoid altering arg's flags */
1463             if(SvUOK(arg)) nv_arg = (NV)SvUV(arg);
1464             else if(SvIOK(arg)) nv_arg = (NV)SvIV(arg);
1465             else nv_arg = SvNV(arg);
1466              
1467             /* use 0 for all zeros */
1468             if(nv_arg == 0) sv_setpvs(keysv, "0");
1469              
1470             /* for NaN, use the platform's normal stringification */
1471             else if (nv_arg != nv_arg) sv_setpvf(keysv, "%" NVgf, nv_arg);
1472             #ifdef NV_IS_DOUBLEDOUBLE
1473             /* If the least significant double is zero, it could be either 0.0 *
1474             * or -0.0. We therefore ignore the least significant double and *
1475             * assign to keysv the bytes of the most significant double only. */
1476             else if(nv_arg == (double)nv_arg) {
1477             double double_arg = (double)nv_arg;
1478             sv_setpvn(keysv, (char *) &double_arg, 8);
1479             }
1480             #endif
1481             else {
1482             /* Use the byte structure of the NV. *
1483             * ACTUAL_NVSIZE == sizeof(NV) minus the number of bytes *
1484             * that are allocated but never used. (It is only the 10-byte *
1485             * extended precision long double that allocates bytes that are *
1486             * never used. For all other NV types ACTUAL_NVSIZE == sizeof(NV). */
1487             sv_setpvn(keysv, (char *) &nv_arg, ACTUAL_NVSIZE);
1488             }
1489             #else /* $Config{nvsize} == $Config{ivsize} == 8 */
1490 0 0         if( SvIOK(arg) || !SvOK(arg) ) {
    0          
1491              
1492             /* It doesn't matter if SvUOK(arg) is TRUE */
1493 0           IV iv = SvIV(arg);
1494              
1495             /* use "0" for all zeros */
1496 0 0         if(iv == 0) sv_setpvs(keysv, "0");
1497              
1498             else {
1499 0           int uok = SvUOK(arg);
1500 0 0         int sign = ( iv > 0 || uok ) ? 1 : -1;
    0          
1501              
1502             /* Set keysv to the bytes of SvNV(arg) if and only if the integer value *
1503             * held by arg can be represented exactly as a double - ie if there are *
1504             * no more than 51 bits between its least significant set bit and its *
1505             * most significant set bit. *
1506             * The neatest approach I could find was provided by roboticus at: *
1507             * https://www.perlmonks.org/?node_id=11113490 *
1508             * First, identify the lowest set bit and assign its value to an IV. *
1509             * Note that this value will always be > 0, and always a power of 2. */
1510 0           IV lowest_set = iv & -iv;
1511              
1512             /* Second, shift it left 53 bits to get location of the first bit *
1513             * beyond arg's highest "allowed" set bit. *
1514             * NOTE: If lowest set bit is initially far enough left, then this left *
1515             * shift operation will result in a value of 0, which is fine. *
1516             * Then subtract 1 so that all of the ("allowed") bits below the set bit *
1517             * are 1 && all other ("disallowed") bits are set to 0. *
1518             * (If the value prior to subtraction was 0, then subtracting 1 will set *
1519             * all bits - which is also fine.) */
1520 0           UV valid_bits = (lowest_set << 53) - 1;
1521              
1522             /* The value of arg can be exactly represented by a double unless one *
1523             * or more of its "disallowed" bits are set - ie if iv & (~valid_bits) *
1524             * is untrue. However, if (iv < 0 && !SvUOK(arg)) we need to multiply iv *
1525             * by -1 prior to performing that '&' operation - so multiply iv by sign.*/
1526 0 0         if( !((iv * sign) & (~valid_bits)) ) {
1527             /* Avoid altering arg's flags */
1528 0 0         nv_arg = uok ? (NV)SvUV(arg) : (NV)SvIV(arg);
1529 0           sv_setpvn(keysv, (char *) &nv_arg, 8);
1530             }
1531             else {
1532             /* Read in the bytes, rather than the numeric value of the IV/UV as *
1533             * this is more efficient, despite having to sv_catpvn an extra byte.*/
1534 0           sv_setpvn(keysv, (char *) &iv, 8);
1535             /* We add an extra byte to distinguish between an IV/UV and an NV. *
1536             * We also use that byte to distinguish between a -ve IV and a UV. */
1537 0 0         if(uok) sv_catpvn(keysv, "U", 1);
1538 0           else sv_catpvn(keysv, "I", 1);
1539             }
1540             }
1541             }
1542             else {
1543 0           nv_arg = SvNV(arg);
1544              
1545             /* for NaN, use the platform's normal stringification */
1546 0 0         if (nv_arg != nv_arg) sv_setpvf(keysv, "%" NVgf, nv_arg);
1547              
1548             /* use "0" for all zeros */
1549 0 0         else if(nv_arg == 0) sv_setpvs(keysv, "0");
1550 0           else sv_setpvn(keysv, (char *) &nv_arg, 8);
1551             }
1552             #endif
1553             #ifdef HV_FETCH_EMPTY_HE
1554 0           he = (HE*) hv_common(seen, NULL, SvPVX(keysv), SvCUR(keysv), 0, HV_FETCH_LVALUE | HV_FETCH_EMPTY_HE, NULL, 0);
1555 0 0         if (HeVAL(he))
1556 0           continue;
1557              
1558 0           HeVAL(he) = &PL_sv_undef;
1559             #else
1560             if(hv_exists(seen, SvPVX(keysv), SvCUR(keysv)))
1561             continue;
1562              
1563             hv_store(seen, SvPVX(keysv), SvCUR(keysv), &PL_sv_yes, 0);
1564             #endif
1565              
1566 0 0         if(GIMME_V == G_LIST)
1567 0 0         ST(retcount) = SvOK(arg) ? arg : sv_2mortal(newSViv(0));
1568 0           retcount++;
1569             }
1570              
1571 0           finish:
1572 0 0         if(GIMME_V == G_LIST)
1573 0           XSRETURN(retcount);
1574             else
1575 0           ST(0) = sv_2mortal(newSViv(retcount));
1576             }
1577              
1578             void
1579             zip(...)
1580             ALIAS:
1581             zip_longest = ZIP_LONGEST
1582             zip_shortest = ZIP_SHORTEST
1583             mesh = ZIP_MESH
1584             mesh_longest = ZIP_MESH_LONGEST
1585             mesh_shortest = ZIP_MESH_SHORTEST
1586             PPCODE:
1587 0           Size_t nlists = items; /* number of lists */
1588             AV **lists; /* inbound lists */
1589 0           Size_t len = 0; /* length of longest inbound list = length of result */
1590             Size_t i;
1591 0           bool is_mesh = (ix & ZIP_MESH);
1592 0           ix &= ~ZIP_MESH;
1593              
1594 0 0         if(!nlists)
1595 0           XSRETURN(0);
1596              
1597 0 0         Newx(lists, nlists, AV *);
1598 0           SAVEFREEPV(lists);
1599              
1600             /* TODO: This may or maynot work on objects with arrayification overload */
1601             /* Remember to unit test it */
1602              
1603 0 0         for(i = 0; i < nlists; i++) {
1604 0           SV *arg = ST(i);
1605             AV *av;
1606              
1607 0 0         if(!SvROK(arg) || SvTYPE(SvRV(arg)) != SVt_PVAV)
    0          
1608 0 0         croak("Expected an ARRAY reference to %s",
1609             is_mesh ? "mesh" : "zip");
1610 0           av = lists[i] = (AV *)SvRV(arg);
1611              
1612 0 0         if(!i) {
1613 0           len = av_count(av);
1614 0           continue;
1615             }
1616              
1617 0           switch(ix) {
1618 0           case 0: /* zip is alias to zip_longest */
1619             case ZIP_LONGEST:
1620 0 0         if(av_count(av) > len)
1621 0           len = av_count(av);
1622 0           break;
1623              
1624 0           case ZIP_SHORTEST:
1625 0 0         if(av_count(av) < len)
1626 0           len = av_count(av);
1627 0           break;
1628             }
1629             }
1630              
1631 0 0         if(is_mesh) {
1632 0           SSize_t retcount = (SSize_t)(len * nlists);
1633              
1634 0 0         EXTEND(SP, retcount);
    0          
1635              
1636 0 0         for(i = 0; i < len; i++) {
1637             Size_t listi;
1638              
1639 0 0         for(listi = 0; listi < nlists; listi++) {
1640 0           SV *item = (i < av_count(lists[listi])) ?
1641 0 0         AvARRAY(lists[listi])[i] :
1642             &PL_sv_undef;
1643              
1644 0           mPUSHs(newSVsv(item));
1645             }
1646             }
1647              
1648 0           XSRETURN(retcount);
1649             }
1650             else {
1651 0 0         EXTEND(SP, (SSize_t)len);
    0          
1652              
1653 0 0         for(i = 0; i < len; i++) {
1654             Size_t listi;
1655 0           AV *ret = newAV();
1656 0           av_extend(ret, nlists);
1657              
1658 0 0         for(listi = 0; listi < nlists; listi++) {
1659 0           SV *item = (i < av_count(lists[listi])) ?
1660 0 0         AvARRAY(lists[listi])[i] :
1661             &PL_sv_undef;
1662              
1663 0           av_push(ret, newSVsv(item));
1664             }
1665              
1666 0           mPUSHs(newRV_noinc((SV *)ret));
1667             }
1668              
1669 0           XSRETURN(len);
1670             }
1671              
1672             MODULE=List::Util PACKAGE=Scalar::Util
1673              
1674             void
1675             dualvar(num,str)
1676             SV *num
1677             SV *str
1678             PROTOTYPE: $$
1679             CODE:
1680             {
1681 0 0         dXSTARG;
1682              
1683 0 0         (void)SvUPGRADE(TARG, SVt_PVNV);
1684              
1685 0           sv_copypv(TARG,str);
1686              
1687 0 0         if(SvNOK(num) || SvPOK(num) || SvMAGICAL(num)) {
    0          
    0          
1688 0           SvNV_set(TARG, SvNV(num));
1689 0           SvNOK_on(TARG);
1690             }
1691             #ifdef SVf_IVisUV
1692 0 0         else if(SvUOK(num)) {
1693 0           SvUV_set(TARG, SvUV(num));
1694 0           SvIOK_on(TARG);
1695 0           SvIsUV_on(TARG);
1696             }
1697             #endif
1698             else {
1699 0           SvIV_set(TARG, SvIV(num));
1700 0           SvIOK_on(TARG);
1701             }
1702              
1703 0 0         if(PL_tainting && (SvTAINTED(num) || SvTAINTED(str)))
    0          
    0          
    0          
    0          
1704 0 0         SvTAINTED_on(TARG);
1705              
1706 0           ST(0) = TARG;
1707 0           XSRETURN(1);
1708             }
1709              
1710             void
1711             isdual(sv)
1712             SV *sv
1713             PROTOTYPE: $
1714             CODE:
1715 0 0         if(SvMAGICAL(sv))
1716 0           mg_get(sv);
1717              
1718 0 0         ST(0) = boolSV((SvPOK(sv) || SvPOKp(sv)) && (SvNIOK(sv) || SvNIOKp(sv)));
    0          
    0          
    0          
1719 0           XSRETURN(1);
1720              
1721             #if !PERL_VERSION_GE(5, 40, 0)
1722             SV *
1723             blessed(sv)
1724             SV *sv
1725             PROTOTYPE: $
1726             CODE:
1727             {
1728             SvGETMAGIC(sv);
1729              
1730             if(!(SvROK(sv) && SvOBJECT(SvRV(sv))))
1731             XSRETURN_UNDEF;
1732             #ifdef HAVE_UNICODE_PACKAGE_NAMES
1733             RETVAL = newSVsv(sv_ref(NULL, SvRV(sv), TRUE));
1734             #else
1735             RETVAL = newSV(0);
1736             sv_setpv(RETVAL, sv_reftype(SvRV(sv), TRUE));
1737             #endif
1738             }
1739             OUTPUT:
1740             RETVAL
1741              
1742             char *
1743             reftype(sv)
1744             SV *sv
1745             PROTOTYPE: $
1746             CODE:
1747             {
1748             SvGETMAGIC(sv);
1749             if(!SvROK(sv))
1750             XSRETURN_UNDEF;
1751              
1752             RETVAL = (char*)sv_reftype(SvRV(sv),FALSE);
1753             }
1754             OUTPUT:
1755             RETVAL
1756              
1757             UV
1758             refaddr(sv)
1759             SV *sv
1760             PROTOTYPE: $
1761             CODE:
1762             {
1763             SvGETMAGIC(sv);
1764             if(!SvROK(sv))
1765             XSRETURN_UNDEF;
1766              
1767             RETVAL = PTR2UV(SvRV(sv));
1768             }
1769             OUTPUT:
1770             RETVAL
1771              
1772             void
1773             weaken(sv)
1774             SV *sv
1775             PROTOTYPE: $
1776             CODE:
1777             sv_rvweaken(sv);
1778              
1779             void
1780             unweaken(sv)
1781             SV *sv
1782             PROTOTYPE: $
1783             INIT:
1784             SV *tsv;
1785             CODE:
1786             #if defined(sv_rvunweaken)
1787             PERL_UNUSED_VAR(tsv);
1788             sv_rvunweaken(sv);
1789             #else
1790             /* This code stolen from core's sv_rvweaken() and modified */
1791             if (!SvOK(sv))
1792             return;
1793             if (!SvROK(sv))
1794             croak("Can't unweaken a nonreference");
1795             else if (!SvWEAKREF(sv)) {
1796             if(ckWARN(WARN_MISC))
1797             warn("Reference is not weak");
1798             return;
1799             }
1800             else if (SvREADONLY(sv)) croak_no_modify();
1801              
1802             tsv = SvRV(sv);
1803             #if PERL_VERSION >= 14
1804             SvWEAKREF_off(sv); SvROK_on(sv);
1805             SvREFCNT_inc_NN(tsv);
1806             Perl_sv_del_backref(aTHX_ tsv, sv);
1807             #else
1808             /* Lacking sv_del_backref() the best we can do is clear the old (weak) ref
1809             * then set a new strong one
1810             */
1811             sv_setsv(sv, &PL_sv_undef);
1812             SvRV_set(sv, SvREFCNT_inc_NN(tsv));
1813             SvROK_on(sv);
1814             #endif
1815             #endif
1816              
1817             void
1818             isweak(sv)
1819             SV *sv
1820             PROTOTYPE: $
1821             CODE:
1822             ST(0) = boolSV(SvROK(sv) && SvWEAKREF(sv));
1823             XSRETURN(1);
1824              
1825             #endif /* !PERL_VERSION_GE(5, 40, 0) */
1826              
1827             int
1828             readonly(sv)
1829             SV *sv
1830             PROTOTYPE: $
1831             CODE:
1832 0 0         SvGETMAGIC(sv);
    0          
1833 0 0         RETVAL = SvREADONLY(sv);
1834             OUTPUT:
1835             RETVAL
1836              
1837             int
1838             tainted(sv)
1839             SV *sv
1840             PROTOTYPE: $
1841             CODE:
1842 0 0         SvGETMAGIC(sv);
    0          
1843 0 0         RETVAL = SvTAINTED(sv);
    0          
    0          
1844             OUTPUT:
1845             RETVAL
1846              
1847             void
1848             isvstring(sv)
1849             SV *sv
1850             PROTOTYPE: $
1851             CODE:
1852             #ifdef SvVOK
1853 0 0         SvGETMAGIC(sv);
    0          
1854 0 0         ST(0) = boolSV(SvVOK(sv));
    0          
1855             #else
1856             ST(0) = boolSV(0);
1857             #endif
1858 0           XSRETURN(1);
1859              
1860             SV *
1861             looks_like_number(sv)
1862             SV *sv
1863             PROTOTYPE: $
1864             CODE:
1865             SV *tempsv;
1866 0 0         SvGETMAGIC(sv);
    0          
1867 0 0         if(SvAMAGIC(sv) && (tempsv = AMG_CALLun(sv, numer))) {
    0          
    0          
    0          
1868 0           sv = tempsv;
1869             }
1870             #if !PERL_VERSION_GE(5,8,5)
1871             if(SvPOK(sv) || SvPOKp(sv)) {
1872             RETVAL = looks_like_number(sv) ? &PL_sv_yes : &PL_sv_no;
1873             }
1874             else {
1875             RETVAL = (SvFLAGS(sv) & (SVf_NOK|SVp_NOK|SVf_IOK|SVp_IOK)) ? &PL_sv_yes : &PL_sv_no;
1876             }
1877             #else
1878 0 0         RETVAL = looks_like_number(sv) ? &PL_sv_yes : &PL_sv_no;
1879             #endif
1880             OUTPUT:
1881             RETVAL
1882              
1883             void
1884             openhandle(SV *sv)
1885             PROTOTYPE: $
1886             CODE:
1887             {
1888 0           IO *io = NULL;
1889 0 0         SvGETMAGIC(sv);
    0          
1890 0 0         if(SvROK(sv)){
1891             /* deref first */
1892 0           sv = SvRV(sv);
1893             }
1894              
1895             /* must be GLOB or IO */
1896 0 0         if(isGV(sv)){
1897 0 0         io = GvIO((GV*)sv);
    0          
    0          
    0          
1898             }
1899 0 0         else if(SvTYPE(sv) == SVt_PVIO){
1900 0           io = (IO*)sv;
1901             }
1902              
1903 0 0         if(io){
1904             /* real or tied filehandle? */
1905 0 0         if(IoIFP(io) || SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)){
    0          
    0          
1906 0           XSRETURN(1);
1907             }
1908             }
1909 0           XSRETURN_UNDEF;
1910             }
1911              
1912             MODULE=List::Util PACKAGE=Sub::Util
1913              
1914             void
1915             set_prototype(proto, code)
1916             SV *proto
1917             SV *code
1918             PREINIT:
1919             SV *cv; /* not CV * */
1920             PPCODE:
1921 0 0         SvGETMAGIC(code);
    0          
1922 0 0         if(!SvROK(code))
1923 0           croak("set_prototype: not a reference");
1924              
1925 0           cv = SvRV(code);
1926 0 0         if(SvTYPE(cv) != SVt_PVCV)
1927 0           croak("set_prototype: not a subroutine reference");
1928              
1929 0 0         if(SvPOK(proto)) {
1930             /* set the prototype */
1931 0           sv_copypv(cv, proto);
1932             }
1933             else {
1934             /* delete the prototype */
1935 0           SvPOK_off(cv);
1936             }
1937              
1938 0           PUSHs(code);
1939 0           XSRETURN(1);
1940              
1941             void
1942             set_subname(name, sub)
1943             SV *name
1944             SV *sub
1945             PREINIT:
1946 0           CV *cv = NULL;
1947             GV *gv;
1948 0           HV *stash = CopSTASH(PL_curcop);
1949 0           const char *s, *end = NULL, *begin = NULL;
1950             MAGIC *mg;
1951             STRLEN namelen;
1952 0           const char* nameptr = SvPV(name, namelen);
1953 0           int utf8flag = SvUTF8(name);
1954             #if PERL_VERSION_LT(5, 41, 3) || PERL_VERSION_GT(5, 41, 5)
1955 0           int quotes_seen = 0;
1956 0           bool need_subst = FALSE;
1957             #endif
1958             PPCODE:
1959 0 0         if (!SvROK(sub) && SvGMAGICAL(sub))
    0          
1960 0           mg_get(sub);
1961 0 0         if (SvROK(sub))
1962 0           cv = (CV *) SvRV(sub);
1963 0 0         else if (SvTYPE(sub) == SVt_PVGV)
1964 0 0         cv = GvCVu(sub);
1965 0 0         else if (!SvOK(sub))
1966 0           croak(PL_no_usym, "a subroutine");
1967 0 0         else if (PL_op->op_private & HINT_STRICT_REFS)
1968 0           croak("Can't use string (\"%.32s\") as %s ref while \"strict refs\" in use",
1969             SvPV_nolen(sub), "a subroutine");
1970 0 0         else if ((gv = gv_fetchsv(sub, FALSE, SVt_PVCV)))
1971 0 0         cv = GvCVu(gv);
1972 0 0         if (!cv)
1973 0           croak("Undefined subroutine %s", SvPV_nolen(sub));
1974 0 0         if (SvTYPE(cv) != SVt_PVCV && SvTYPE(cv) != SVt_PVFM)
    0          
1975 0           croak("Not a subroutine reference");
1976 0 0         for (s = nameptr; s <= nameptr + namelen; s++) {
1977 0 0         if (s > nameptr && *s == ':' && s[-1] == ':') {
    0          
    0          
1978 0           end = s - 1;
1979 0           begin = ++s;
1980             #if PERL_VERSION_LT(5, 41, 3) || PERL_VERSION_GT(5, 41, 5)
1981 0 0         if (quotes_seen)
1982 0           need_subst = TRUE;
1983             #endif
1984             }
1985             #if PERL_VERSION_LT(5, 41, 3) || PERL_VERSION_GT(5, 41, 5)
1986 0 0         else if (s > nameptr && *s != '\0' && s[-1] == '\'') {
    0          
    0          
1987 0           end = s - 1;
1988 0           begin = s;
1989 0 0         if (quotes_seen++)
1990 0           need_subst = TRUE;
1991             }
1992             #endif
1993             }
1994 0           s--;
1995 0 0         if (end) {
1996             #if PERL_VERSION_LT(5, 41, 3) || PERL_VERSION_GT(5, 41, 5)
1997             SV* tmp;
1998 0 0         if (need_subst) {
1999 0 0         STRLEN length = end - nameptr + quotes_seen - (*end == '\'' ? 1 : 0);
2000             char* left;
2001             int i, j;
2002 0           tmp = sv_2mortal(newSV(length));
2003 0           left = SvPVX(tmp);
2004 0 0         for (i = 0, j = 0; j < end - nameptr; ++i, ++j) {
2005 0 0         if (nameptr[j] == '\'') {
2006 0           left[i] = ':';
2007 0           left[++i] = ':';
2008             }
2009             else {
2010 0           left[i] = nameptr[j];
2011             }
2012             }
2013 0           stash = gv_stashpvn(left, length, GV_ADD | utf8flag);
2014             }
2015             else
2016             #endif
2017 0           stash = gv_stashpvn(nameptr, end - nameptr, GV_ADD | utf8flag);
2018 0           nameptr = begin;
2019 0           namelen -= begin - nameptr;
2020             }
2021              
2022             /* under debugger, provide information about sub location */
2023 0 0         if (PL_DBsub && CvGV(cv)) {
    0          
2024 0           HV* DBsub = GvHV(PL_DBsub);
2025 0           HE* old_data = NULL;
2026              
2027 0           GV* oldgv = CvGV(cv);
2028 0           HV* oldhv = GvSTASH(oldgv);
2029              
2030 0 0         if (oldhv) {
2031 0 0         SV* old_full_name = sv_2mortal(newSVpvn_flags(HvNAME(oldhv), HvNAMELEN_get(oldhv), HvNAMEUTF8(oldhv) ? SVf_UTF8 : 0));
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
2032 0           sv_catpvn(old_full_name, "::", 2);
2033 0 0         sv_catpvn_flags(old_full_name, GvNAME(oldgv), GvNAMELEN(oldgv), GvNAMEUTF8(oldgv) ? SV_CATUTF8 : SV_CATBYTES);
2034              
2035 0           old_data = hv_fetch_ent(DBsub, old_full_name, 0, 0);
2036             }
2037              
2038 0 0         if (old_data && HeVAL(old_data)) {
    0          
2039 0           SV* old_val = HeVAL(old_data);
2040 0 0         SV* new_full_name = sv_2mortal(newSVpvn_flags(HvNAME(stash), HvNAMELEN_get(stash), HvNAMEUTF8(stash) ? SVf_UTF8 : 0));
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
2041 0           sv_catpvn(new_full_name, "::", 2);
2042 0 0         sv_catpvn_flags(new_full_name, nameptr, s - nameptr, utf8flag ? SV_CATUTF8 : SV_CATBYTES);
2043 0           SvREFCNT_inc(old_val);
2044 0 0         if (!hv_store_ent(DBsub, new_full_name, old_val, 0))
2045 0           SvREFCNT_dec(old_val);
2046             }
2047             }
2048              
2049 0           gv = (GV *) newSV(0);
2050 0           gv_init_pvn(gv, stash, nameptr, s - nameptr, GV_ADDMULTI | utf8flag);
2051              
2052             /*
2053             * set_subname needs to create a GV to store the name. The CvGV field of a
2054             * CV is not refcounted, so perl wouldn't know to SvREFCNT_dec() this GV if
2055             * it destroys the containing CV. We use a MAGIC with an empty vtable
2056             * simply for the side-effect of using MGf_REFCOUNTED to store the
2057             * actually-counted reference to the GV.
2058             */
2059 0           mg = SvMAGIC(cv);
2060 0 0         while (mg && mg->mg_virtual != &subname_vtbl)
    0          
2061 0           mg = mg->mg_moremagic;
2062 0 0         if (!mg) {
2063 0           Newxz(mg, 1, MAGIC);
2064 0           mg->mg_moremagic = SvMAGIC(cv);
2065 0           mg->mg_type = PERL_MAGIC_ext;
2066 0           mg->mg_virtual = &subname_vtbl;
2067 0           SvMAGIC_set(cv, mg);
2068             }
2069 0 0         if (mg->mg_flags & MGf_REFCOUNTED)
2070 0           SvREFCNT_dec(mg->mg_obj);
2071 0           mg->mg_flags |= MGf_REFCOUNTED;
2072 0           mg->mg_obj = (SV *) gv;
2073 0           SvRMAGICAL_on(cv);
2074 0           CvANON_off(cv);
2075             #ifndef CvGV_set
2076             CvGV(cv) = gv;
2077             #else
2078 0           CvGV_set(cv, gv);
2079             #endif
2080 0           PUSHs(sub);
2081              
2082             void
2083             subname(code)
2084             SV *code
2085             PREINIT:
2086             CV *cv;
2087             GV *gv;
2088             const char *stashname;
2089             PPCODE:
2090 0 0         if (!SvROK(code) && SvGMAGICAL(code))
    0          
2091 0           mg_get(code);
2092              
2093 0 0         if(!SvROK(code) || SvTYPE(cv = (CV *)SvRV(code)) != SVt_PVCV)
    0          
2094 0           croak("Not a subroutine reference");
2095              
2096 0 0         if(!(gv = CvGV(cv)))
2097 0           XSRETURN(0);
2098              
2099 0 0         if(GvSTASH(gv))
2100 0 0         stashname = HvNAME(GvSTASH(gv));
    0          
    0          
    0          
    0          
    0          
2101             else
2102 0           stashname = "__ANON__";
2103              
2104 0           mPUSHs(newSVpvf("%s::%s", stashname, GvNAME(gv)));
2105 0           XSRETURN(1);
2106              
2107             BOOT:
2108             {
2109 0           HV *lu_stash = gv_stashpvn("List::Util", 10, TRUE);
2110 0           GV *rmcgv = *(GV**)hv_fetch(lu_stash, "REAL_MULTICALL", 14, TRUE);
2111             SV *rmcsv;
2112 0 0         if(SvTYPE(rmcgv) != SVt_PVGV)
2113 0           gv_init(rmcgv, lu_stash, "List::Util", 10, TRUE);
2114 0 0         rmcsv = GvSVn(rmcgv);
2115             #ifdef REAL_MULTICALL
2116 0           sv_setsv(rmcsv, &PL_sv_yes);
2117             #else
2118             sv_setsv(rmcsv, &PL_sv_no);
2119             #endif
2120             }