File Coverage

ListUtil.xs
Criterion Covered Total %
statement 726 828 87.6
branch 823 1504 54.7
condition n/a
subroutine n/a
pod n/a
total 1549 2332 66.4


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 57           static enum slu_accum accum_type(SV *sv) {
184 57 100         if(SvAMAGIC(sv))
    50          
    50          
185 14           return ACC_SV;
186              
187 43 100         if(SvIOK(sv) && !SvNOK(sv) && !SvUOK(sv))
    50          
    50          
188 40           return ACC_IV;
189              
190 3           return ACC_NV;
191             }
192              
193             /* Magic for set_subname */
194             static MGVTBL subname_vtbl;
195              
196 11           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 11 100         if(!PL_srand_called) {
216 2           (void)seedDrand01((Rand_seed_t)Perl_seed(aTHX));
217 2           PL_srand_called = TRUE;
218             }
219             #endif
220 11           }
221              
222 37           static double MY_callrand(pTHX_ CV *randcv)
223             {
224 37           dSP;
225             double ret, dummy;
226              
227 37           ENTER;
228 37 50         PUSHMARK(SP);
229 37           PUTBACK;
230              
231 37           call_sv((SV *)randcv, G_SCALAR);
232              
233 37           SPAGAIN;
234              
235 37 50         ret = modf(POPn, &dummy); /* bound to < 1 */
236 37 50         if(ret < 0) ret += 1.0; /* bound to 0 <= ret < 1 */
237              
238 37           LEAVE;
239              
240 37           return ret;
241             }
242              
243             #define sv_to_cv(sv, subname) MY_sv_to_cv(aTHX_ sv, subname);
244 113           static CV* MY_sv_to_cv(pTHX_ SV* sv, const char * const subname)
245             {
246             GV *gv;
247             HV *stash;
248 113           CV *cv = sv_2cv(sv, &stash, &gv, 0);
249              
250 108 100         if(cv == Nullcv)
251 16           croak("Not a subroutine reference");
252              
253 92 100         if(!CvROOT(cv) && !CvXSUB(cv))
    50          
254 9           croak("Undefined subroutine in %s", subname);
255              
256 83           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 27           NV retval = 0.0; /* avoid 'uninit var' warning */
280             SV *retsv;
281             int magic;
282              
283 27 50         if(!items)
284 0           XSRETURN_UNDEF;
285              
286 27           retsv = ST(0);
287 27 50         SvGETMAGIC(retsv);
    0          
288 27 100         magic = SvAMAGIC(retsv);
    50          
    50          
289 27 100         if(!magic)
290 19 100         retval = slu_sv_value(retsv);
    50          
    50          
291              
292 125 100         for(index = 1 ; index < items ; index++) {
293 98           SV *stacksv = ST(index);
294             SV *tmpsv;
295 98 100         SvGETMAGIC(stacksv);
    50          
296 98 100         if((magic || SvAMAGIC(stacksv)) && (tmpsv = amagic_call(retsv, stacksv, gt_amg, 0))) {
    100          
    50          
    50          
    100          
297 27 50         if(SvTRUE(tmpsv) ? !ix : ix) {
    50          
    0          
    50          
    0          
    0          
    50          
    50          
    50          
    100          
    50          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
298 8           retsv = stacksv;
299 8 100         magic = SvAMAGIC(retsv);
    50          
    50          
300 8 100         if(!magic) {
301 1 50         retval = slu_sv_value(retsv);
    50          
    0          
302             }
303             }
304             }
305             else {
306 79 100         NV val = slu_sv_value(stacksv);
    50          
    100          
307 79 100         if(magic) {
308 2 50         retval = slu_sv_value(retsv);
    0          
    50          
309 2           magic = 0;
310             }
311 79 100         if(val < retval ? !ix : ix) {
    100          
312 18           retsv = stacksv;
313 18           retval = val;
314             }
315             }
316             }
317 27           ST(0) = retsv;
318 27           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 52 50         dXSTARG;
332             SV *sv;
333 52           IV retiv = 0;
334 52           NV retnv = 0.0;
335 52           SV *retsv = NULL;
336             int index;
337             enum slu_accum accum;
338 52           int is_product = (ix == 2);
339             SV *tmpsv;
340              
341 52 100         if(!items)
342 3           switch(ix) {
343 1           case 0: XSRETURN_UNDEF;
344 1           case 1: ST(0) = sv_2mortal(newSViv(0)); XSRETURN(1);
345 1           case 2: ST(0) = sv_2mortal(newSViv(1)); XSRETURN(1);
346             }
347              
348 49           sv = ST(0);
349 49 50         SvGETMAGIC(sv);
    0          
350 49           switch((accum = accum_type(sv))) {
351             case ACC_SV:
352 6           retsv = TARG;
353 6           sv_setsv(retsv, sv);
354 6           break;
355             case ACC_IV:
356 40 50         retiv = SvIV(sv);
357 40           break;
358             case ACC_NV:
359 3 50         retnv = slu_sv_value(sv);
    0          
    50          
360 3           break;
361             }
362              
363 110 100         for(index = 1 ; index < items ; index++) {
364 61           sv = ST(index);
365 61 100         SvGETMAGIC(sv);
    50          
366 61 100         if(accum < ACC_SV && SvAMAGIC(sv)){
    100          
    50          
    50          
367 10 100         if(!retsv)
368 8           retsv = TARG;
369 10 100         sv_setnv(retsv, accum == ACC_NV ? retnv : retiv);
370 10           accum = ACC_SV;
371             }
372 61           switch(accum) {
373             case ACC_SV:
374 18 100         tmpsv = amagic_call(retsv, sv,
    50          
    50          
    100          
375             is_product ? mult_amg : add_amg,
376             SvAMAGIC(retsv) ? AMGf_assign : 0);
377 18 100         if(tmpsv) {
378 8           switch((accum = accum_type(tmpsv))) {
379             case ACC_SV:
380 8           retsv = tmpsv;
381 8           break;
382             case ACC_IV:
383 0 0         retiv = SvIV(tmpsv);
384 0           break;
385             case ACC_NV:
386 0 0         retnv = slu_sv_value(tmpsv);
    0          
    0          
387 8           break;
388             }
389             }
390             else {
391             /* fall back to default */
392 10           accum = ACC_NV;
393 5 100         is_product ? (retnv = SvNV(retsv) * SvNV(sv))
    50          
394 15 100         : (retnv = SvNV(retsv) + SvNV(sv));
    100          
    50          
395             }
396 18           break;
397             case ACC_IV:
398 36 100         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 19 50         if(!SvNOK(sv) && SvIOK(sv)) {
    50          
406 19 50         IV i = SvIV(sv);
407 19 100         if (retiv == 0) /* avoid later division by zero */
408 4           break;
409 15 100         if (retiv < -1) { /* avoid -1 because that causes SIGFPE */
410 5 100         if (i < 0) {
411 2 100         if (i >= IV_MAX / retiv) {
412 1           retiv *= i;
413 1           break;
414             }
415             }
416             else {
417 3 100         if (i <= IV_MIN / retiv) {
418 2           retiv *= i;
419 2           break;
420             }
421             }
422             }
423 10 100         else if (retiv > 0) {
424 9 100         if (i < 0) {
425 2 100         if (i >= IV_MIN / retiv) {
426 1           retiv *= i;
427 1           break;
428             }
429             }
430             else {
431 7 100         if (i <= IV_MAX / retiv) {
432 6           retiv *= i;
433 11           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 17 100         if(!SvNOK(sv) && SvIOK(sv)) {
    50          
445 16 100         IV i = SvIV(sv);
446 16 100         if (retiv >= 0 && i >= 0) {
    100          
447 13 50         if (retiv <= IV_MAX - i) {
448 13           retiv += i;
449 13           break;
450             }
451             /* else fallthrough */
452             }
453 3 100         else if (retiv < 0 && i < 0) {
    50          
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 3           retiv += i;
463 3           break;
464             }
465             }
466             /* else fallthrough */
467             }
468              
469 6           retnv = retiv;
470 6           accum = ACC_NV;
471             /* FALLTHROUGH */
472             case ACC_NV:
473 9 50         is_product ? (retnv *= slu_sv_value(sv))
    50          
    0          
474 22 100         : (retnv += slu_sv_value(sv));
    100          
    50          
    50          
475 13           break;
476             }
477             }
478              
479 49 100         if(!retsv)
480 35           retsv = TARG;
481              
482 49           switch(accum) {
483             case ACC_SV: /* nothing to do */
484 6           break;
485             case ACC_IV:
486 26           sv_setiv(retsv, retiv);
487 26           break;
488             case ACC_NV:
489 17           sv_setnv(retsv, retnv);
490 17           break;
491             }
492              
493 49           ST(0) = retsv;
494 49           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 8 50         if(!items)
512 0           XSRETURN_UNDEF;
513              
514 8           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 52 100         for(index = 1 ; index < items ; index++) {
526 44           SV *right = ST(index);
527 44 100         if(sv_cmp(left, right) == ix)
528 6           left = right;
529             }
530             #ifdef OPpLOCALE
531             }
532             #endif
533 8           ST(0) = left;
534 8           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 40           SV *ret = sv_newmortal();
550             int index;
551 40           AV *retvals = NULL;
552             GV *agv,*bgv;
553 40           SV **args = &PL_stack_base[ax];
554 40 100         CV *cv = sv_to_cv(block, ix ? "reductions" : "reduce");
555              
556 31 100         if(items <= 1) {
557 2 100         if(ix)
558 1           XSRETURN(0);
559             else
560 1           XSRETURN_UNDEF;
561             }
562              
563 29           agv = gv_fetchpv("a", GV_ADD, SVt_PV);
564 29           bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
565 29           SAVESPTR(GvSV(agv));
566 29           SAVESPTR(GvSV(bgv));
567 29           GvSV(agv) = ret;
568 29 50         SvSetMagicSV(ret, args[1]);
    50          
569              
570 29 100         if(ix) {
571             /* Precreate an AV for return values; -1 for cv, -1 for top index */
572 4           retvals = newAV();
573 4           av_extend(retvals, items-1-1);
574              
575             /* so if throw an exception they can be reclaimed */
576 4           SAVEFREESV(retvals);
577              
578 4           av_push(retvals, newSVsv(ret));
579             }
580             #ifdef dMULTICALL
581             assert(cv);
582 29 100         if(!CvISXSUB(cv)) {
583             dMULTICALL;
584 28           I32 gimme = G_SCALAR;
585              
586             UNUSED_VAR_newsp;
587 28 50         PUSH_MULTICALL(cv);
    100          
588 123 100         for(index = 2 ; index < items ; index++) {
589 100           GvSV(bgv) = args[index];
590 100           MULTICALL;
591 95 100         SvSetMagicSV(ret, *PL_stack_sp);
    100          
592 95 100         if(ix)
593 12           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 23 50         POP_MULTICALL;
    50          
600             }
601             else
602             #endif
603             {
604 3 100         for(index = 2 ; index < items ; index++) {
605 2           dSP;
606 2           GvSV(bgv) = args[index];
607              
608 2 50         PUSHMARK(SP);
609 2           call_sv((SV*)cv, G_SCALAR);
610              
611 2 50         SvSetMagicSV(ret, *PL_stack_sp);
    50          
612 2 50         if(ix)
613 0           av_push(retvals, newSVsv(ret));
614             }
615             }
616              
617 24 100         if(ix) {
618             int i;
619 3           SV **svs = AvARRAY(retvals);
620             /* steal the SVs from retvals */
621 16 100         for(i = 0; i < items-1; i++) {
622 13           ST(i) = sv_2mortal(svs[i]);
623 13           svs[i] = NULL;
624             }
625              
626 3           XSRETURN(items-1);
627             }
628             else {
629 21           ST(0) = ret;
630 21           XSRETURN(1);
631             }
632             }
633              
634             void
635             first(block,...)
636             SV *block
637             PROTOTYPE: &@
638             CODE:
639             {
640             int index;
641 26           SV **args = &PL_stack_base[ax];
642 26           CV *cv = sv_to_cv(block, "first");
643              
644 19 100         if(items <= 1)
645 1           XSRETURN_UNDEF;
646              
647 18           SAVESPTR(GvSV(PL_defgv));
648             #ifdef dMULTICALL
649             assert(cv);
650 18 100         if(!CvISXSUB(cv)) {
651             dMULTICALL;
652 16           I32 gimme = G_SCALAR;
653              
654             UNUSED_VAR_newsp;
655 16 50         PUSH_MULTICALL(cv);
    100          
656              
657 48 100         for(index = 1 ; index < items ; index++) {
658 45           SV *def_sv = GvSV(PL_defgv) = args[index];
659             # ifdef SvTEMP_off
660 45           SvTEMP_off(def_sv);
661             # endif
662 45           MULTICALL;
663 41 50         if(SvTRUEx(*PL_stack_sp)) {
    50          
    0          
    50          
    0          
    0          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    0          
    100          
    0          
    100          
664             # ifdef PERL_HAS_BAD_MULTICALL_REFCOUNT
665             if(CvDEPTH(multicall_cv) > 1)
666             SvREFCNT_inc_simple_void_NN(multicall_cv);
667             # endif
668 9 50         POP_MULTICALL;
    50          
669 9           ST(0) = ST(index);
670 9           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 3 50         POP_MULTICALL;
    50          
678             }
679             else
680             #endif
681             {
682 6 100         for(index = 1 ; index < items ; index++) {
683 5           dSP;
684 5           GvSV(PL_defgv) = args[index];
685              
686 5 50         PUSHMARK(SP);
687 5           call_sv((SV*)cv, G_SCALAR);
688 5 50         if(SvTRUEx(*PL_stack_sp)) {
    50          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    100          
    50          
    0          
    100          
    0          
    100          
689 1           ST(0) = ST(index);
690 1           XSRETURN(1);
691             }
692             }
693             }
694 4           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 21           int ret_true = !(ix & 2); /* return true at end of loop for none/all; false for any/notall */
710 21           int invert = (ix & 1); /* invert block test for all/notall */
711 21           SV **args = &PL_stack_base[ax];
712 21 100         CV *cv = sv_to_cv(block,
    100          
    100          
    50          
713             ix == 0 ? "none" :
714             ix == 1 ? "all" :
715             ix == 2 ? "any" :
716             ix == 3 ? "notall" :
717             "unknown 'any' alias");
718              
719 13           SAVESPTR(GvSV(PL_defgv));
720             #ifdef dMULTICALL
721             assert(cv);
722 13 50         if(!CvISXSUB(cv)) {
723             dMULTICALL;
724 13           I32 gimme = G_SCALAR;
725             int index;
726              
727             UNUSED_VAR_newsp;
728 13 50         PUSH_MULTICALL(cv);
    50          
729 27 100         for(index = 1; index < items; index++) {
730 19           SV *def_sv = GvSV(PL_defgv) = args[index];
731             # ifdef SvTEMP_off
732 19           SvTEMP_off(def_sv);
733             # endif
734              
735 19           MULTICALL;
736 19 50         if(SvTRUEx(*PL_stack_sp) ^ invert) {
    50          
    0          
    50          
    0          
    0          
    50          
    50          
    100          
    100          
    50          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
737 5 50         POP_MULTICALL;
    50          
738 5 100         ST(0) = ret_true ? &PL_sv_no : &PL_sv_yes;
739 5           XSRETURN(1);
740             }
741             }
742 8 50         POP_MULTICALL;
    50          
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) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
755 0 0         ST(0) = ret_true ? &PL_sv_no : &PL_sv_yes;
756 0           XSRETURN(1);
757             }
758             }
759             }
760              
761 8 100         ST(0) = ret_true ? &PL_sv_yes : &PL_sv_no;
762 8           XSRETURN(1);
763             }
764              
765             void
766             head(size,...)
767             PROTOTYPE: $@
768             ALIAS:
769             head = 0
770             tail = 1
771             PPCODE:
772             {
773 20           int size = 0;
774 20           int start = 0;
775 20           int end = 0;
776 20           int i = 0;
777              
778 20 50         size = SvIV( ST(0) );
779              
780 20 100         if ( ix == 0 ) {
781 11           start = 1;
782 11           end = start + size;
783 11 100         if ( size < 0 ) {
784 4           end += items - 1;
785             }
786 11 100         if ( end > items ) {
787 11           end = items;
788             }
789             }
790             else {
791 9           end = items;
792 9 100         if ( size < 0 ) {
793 4           start = -size + 1;
794             }
795             else {
796 5           start = end - size;
797             }
798 9 100         if ( start < 1 ) {
799 1           start = 1;
800             }
801             }
802              
803 20 100         if ( end < start ) {
804 3           XSRETURN(0);
805             }
806             else {
807 17 50         EXTEND( SP, end - start );
    50          
808 52 100         for ( i = start; i <= end; i++ ) {
809 35           PUSHs( sv_2mortal( newSVsv( ST(i) ) ) );
810             }
811 17           XSRETURN( end - start );
812             }
813             }
814              
815             void
816             pairs(...)
817             PROTOTYPE: @
818             PPCODE:
819             {
820 3           int argi = 0;
821 3           int reti = 0;
822 3           HV *pairstash = get_hv("List::Util::_Pair::", GV_ADD);
823              
824 3 100         if(items % 2 && ckWARN(WARN_MISC))
    50          
825 0           warn("Odd number of elements in pairs");
826              
827             {
828 10 100         for(; argi < items; argi += 2) {
829 7           SV *a = ST(argi);
830 7 100         SV *b = argi < items-1 ? ST(argi+1) : &PL_sv_undef;
831              
832 7           AV *av = newAV();
833 7           av_push(av, newSVsv(a));
834 7           av_push(av, newSVsv(b));
835              
836 7           ST(reti) = sv_2mortal(newRV_noinc((SV *)av));
837 7           sv_bless(ST(reti), pairstash);
838 7           reti++;
839             }
840             }
841              
842 3           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 3 50         Newx(args_copy, items, SV *);
856 3           SAVEFREEPV(args_copy);
857              
858 3 50         Copy(&ST(0), args_copy, items, SV *);
859              
860 10 100         for(i = 0; i < items; i++) {
861 7           SV *pair = args_copy[i];
862             AV *pairav;
863              
864 7 50         SvGETMAGIC(pair);
    0          
865              
866 7 50         if(SvTYPE(pair) != SVt_RV)
867 0           croak("Not a reference at List::Util::unpairs() argument %d", i);
868 7 50         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 7           pairav = (AV *)SvRV(pair);
873              
874 7 50         EXTEND(SP, 2);
875              
876 7 50         if(AvFILL(pairav) >= 0)
    50          
877 7           mPUSHs(newSVsv(AvARRAY(pairav)[0]));
878             else
879 0           PUSHs(&PL_sv_undef);
880              
881 7 50         if(AvFILL(pairav) >= 1)
    100          
882 6           mPUSHs(newSVsv(AvARRAY(pairav)[1]));
883             else
884 1           PUSHs(&PL_sv_undef);
885             }
886              
887 3           XSRETURN(items * 2);
888             }
889              
890             void
891             pairkeys(...)
892             PROTOTYPE: @
893             PPCODE:
894             {
895 1           int argi = 0;
896 1           int reti = 0;
897              
898 1 50         if(items % 2 && ckWARN(WARN_MISC))
    0          
899 0           warn("Odd number of elements in pairkeys");
900              
901             {
902 3 100         for(; argi < items; argi += 2) {
903 2           SV *a = ST(argi);
904              
905 2           ST(reti++) = sv_2mortal(newSVsv(a));
906             }
907             }
908              
909 1           XSRETURN(reti);
910             }
911              
912             void
913             pairvalues(...)
914             PROTOTYPE: @
915             PPCODE:
916             {
917 1           int argi = 0;
918 1           int reti = 0;
919              
920 1 50         if(items % 2 && ckWARN(WARN_MISC))
    0          
921 0           warn("Odd number of elements in pairvalues");
922              
923             {
924 3 100         for(; argi < items; argi += 2) {
925 2 50         SV *b = argi < items-1 ? ST(argi+1) : &PL_sv_undef;
926              
927 2           ST(reti++) = sv_2mortal(newSVsv(b));
928             }
929             }
930              
931 1           XSRETURN(reti);
932             }
933              
934             void
935             pairfirst(block,...)
936             SV *block
937             PROTOTYPE: &@
938             PPCODE:
939             {
940             GV *agv,*bgv;
941 6           CV *cv = sv_to_cv(block, "pairfirst");
942 4 50         I32 ret_gimme = GIMME_V;
943 4           int argi = 1; /* "shift" the block */
944              
945 4 50         if(!(items % 2) && ckWARN(WARN_MISC))
    0          
946 0           warn("Odd number of elements in pairfirst");
947              
948 4           agv = gv_fetchpv("a", GV_ADD, SVt_PV);
949 4           bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
950 4           SAVESPTR(GvSV(agv));
951 4           SAVESPTR(GvSV(bgv));
952             #ifdef dMULTICALL
953             assert(cv);
954 4 50         if(!CvISXSUB(cv)) {
955             /* Since MULTICALL is about to move it */
956 4           SV **stack = PL_stack_base + ax;
957              
958             dMULTICALL;
959 4           I32 gimme = G_SCALAR;
960              
961             UNUSED_VAR_newsp;
962 4 50         PUSH_MULTICALL(cv);
    50          
963 14 100         for(; argi < items; argi += 2) {
964 12           SV *a = GvSV(agv) = stack[argi];
965 12 50         SV *b = GvSV(bgv) = argi < items-1 ? stack[argi+1] : &PL_sv_undef;
966              
967 12           MULTICALL;
968              
969 12 50         if(!SvTRUEx(*PL_stack_sp))
    50          
    0          
    50          
    0          
    0          
    50          
    50          
    50          
    100          
    50          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
970 10           continue;
971              
972 2 50         POP_MULTICALL;
    50          
973 2 100         if(ret_gimme == G_LIST) {
974 1           ST(0) = sv_mortalcopy(a);
975 1           ST(1) = sv_mortalcopy(b);
976 1           XSRETURN(2);
977             }
978             else
979 1           XSRETURN_YES;
980             }
981 2 50         POP_MULTICALL;
    50          
982 2           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))
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
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 8           CV *cv = sv_to_cv(block, "pairgrep");
1021 6 50         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 6           int argi = 1; /* "shift" the block */
1027 6           int reti = 0;
1028              
1029 6 100         if(!(items % 2) && ckWARN(WARN_MISC))
    100          
1030 1           warn("Odd number of elements in pairgrep");
1031              
1032 6           agv = gv_fetchpv("a", GV_ADD, SVt_PV);
1033 6           bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
1034 6           SAVESPTR(GvSV(agv));
1035 6           SAVESPTR(GvSV(bgv));
1036             #ifdef dMULTICALL
1037             assert(cv);
1038 6 50         if(!CvISXSUB(cv)) {
1039             /* Since MULTICALL is about to move it */
1040 6           SV **stack = PL_stack_base + ax;
1041             int i;
1042              
1043             dMULTICALL;
1044 6           I32 gimme = G_SCALAR;
1045              
1046             UNUSED_VAR_newsp;
1047 6 50         PUSH_MULTICALL(cv);
    50          
1048 21 100         for(; argi < items; argi += 2) {
1049 15           SV *a = GvSV(agv) = stack[argi];
1050 15 100         SV *b = GvSV(bgv) = argi < items-1 ? stack[argi+1] : &PL_sv_undef;
1051              
1052 15           MULTICALL;
1053              
1054 15 50         if(SvTRUEx(*PL_stack_sp)) {
    50          
    0          
    100          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    100          
    50          
    0          
    100          
    0          
    100          
1055 8 100         if(ret_gimme == G_LIST) {
1056             /* We can't mortalise yet or they'd be mortal too early */
1057 4           stack[reti++] = newSVsv(a);
1058 4           stack[reti++] = newSVsv(b);
1059             }
1060 4 100         else if(ret_gimme == G_SCALAR)
1061 2           reti++;
1062             }
1063             }
1064 6 50         POP_MULTICALL;
    50          
1065              
1066 6 100         if(ret_gimme == G_LIST)
1067 14 100         for(i = 0; i < reti; i++)
1068 8           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)) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
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 6 100         if(ret_gimme == G_LIST)
1095 2           XSRETURN(reti);
1096 4 100         else if(ret_gimme == G_SCALAR) {
1097 1           ST(0) = newSViv(reti);
1098 1           XSRETURN(1);
1099             }
1100             }
1101              
1102             void
1103             pairmap(block,...)
1104             SV *block
1105             PROTOTYPE: &@
1106             PPCODE:
1107             {
1108             GV *agv,*bgv;
1109 12           CV *cv = sv_to_cv(block, "pairmap");
1110 10           SV **args_copy = NULL;
1111 10 100         I32 ret_gimme = GIMME_V;
1112              
1113 10           int argi = 1; /* "shift" the block */
1114 10           int reti = 0;
1115              
1116 10 100         if(!(items % 2) && ckWARN(WARN_MISC))
    50          
1117 0           warn("Odd number of elements in pairmap");
1118              
1119 10           agv = gv_fetchpv("a", GV_ADD, SVt_PV);
1120 10           bgv = gv_fetchpv("b", GV_ADD, SVt_PV);
1121 10           SAVESPTR(GvSV(agv));
1122 10           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 10 50         if(!CvISXSUB(cv)) {
1129             /* Since MULTICALL is about to move it */
1130 10           SV **stack = PL_stack_base + ax;
1131 10 100         I32 ret_gimme = GIMME_V;
1132             int i;
1133 10           AV *spill = NULL; /* accumulates results if too big for stack */
1134              
1135             dMULTICALL;
1136 10           I32 gimme = G_LIST;
1137              
1138             UNUSED_VAR_newsp;
1139 10 50         PUSH_MULTICALL(cv);
    50          
1140 37 100         for(; argi < items; argi += 2) {
1141             int count;
1142              
1143 27           GvSV(agv) = stack[argi];
1144 27 100         GvSV(bgv) = argi < items-1 ? stack[argi+1]: &PL_sv_undef;
1145              
1146 27           MULTICALL;
1147 27           count = PL_stack_sp - PL_stack_base;
1148              
1149 37 100         if (count > 2 || spill) {
    100          
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 10 100         if (!spill) {
1162 3           spill = newAV();
1163 3           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 3           SAVEFREESV(spill);
1167             }
1168              
1169 10 50         fill = (int)AvFILL(spill);
1170 10           av_extend(spill, fill + count);
1171 2028 100         for(i = 0; i < count; i++)
1172 2018           (void)av_store(spill, ++fill,
1173             newSVsv(PL_stack_base[i + 1]));
1174             }
1175             else
1176 39 100         for(i = 0; i < count; i++)
1177 22           stack[reti++] = newSVsv(PL_stack_base[i + 1]);
1178             }
1179              
1180 10 100         if (spill) {
1181             /* the POP_MULTICALL will trigger the SAVEFREESV above;
1182             * keep it alive it on the temps stack instead */
1183 3           SvREFCNT_inc_simple_void_NN(spill);
1184 3           sv_2mortal((SV*)spill);
1185             }
1186              
1187 10 50         POP_MULTICALL;
    50          
1188              
1189 10 100         if (spill) {
1190 3 50         int n = (int)AvFILL(spill) + 1;
1191 3           SP = &ST(reti - 1);
1192 3 50         EXTEND(SP, n);
    100          
1193 2021 100         for (i = 0; i < n; i++)
1194 2018           *++SP = *av_fetch(spill, i, FALSE);
1195 3           reti += n;
1196 3           av_clear(spill);
1197             }
1198              
1199 10 100         if(ret_gimme == G_LIST)
1200 2042 100         for(i = 0; i < reti; i++)
1201 2032           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 0         Newx(args_copy, n_args, SV *);
1224 0           SAVEFREEPV(args_copy);
1225              
1226 0 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 10 100         if(ret_gimme == G_LIST)
1243 8           XSRETURN(reti);
1244              
1245 2           ST(0) = sv_2mortal(newSViv(reti));
1246 2           XSRETURN(1);
1247             }
1248              
1249             void
1250             shuffle(...)
1251             PROTOTYPE: @
1252             CODE:
1253             {
1254             int index;
1255 6           SV *randsv = get_sv("List::Util::RAND", 0);
1256 6 100         CV * const randcv = randsv && SvROK(randsv) && SvTYPE(SvRV(randsv)) == SVt_PVCV ?
    50          
1257 12 50         (CV *)SvRV(randsv) : NULL;
1258              
1259 6 100         if(!randcv)
1260 3           MY_initrand(aTHX);
1261              
1262 132 100         for (index = items ; index > 1 ; ) {
1263 126           int swap = (int)(
1264 126 100         (randcv ? MY_callrand(aTHX_ randcv) : Drand01()) * (double)(index--)
1265             );
1266 126           SV *tmp = ST(swap);
1267 126           ST(swap) = ST(index);
1268 126           ST(index) = tmp;
1269             }
1270              
1271 6           XSRETURN(items);
1272             }
1273              
1274             void
1275             sample(...)
1276             PROTOTYPE: $@
1277             CODE:
1278             {
1279 10 50         IV count = items ? SvUV(ST(0)) : 0;
    50          
1280 10           IV reti = 0;
1281 10           SV *randsv = get_sv("List::Util::RAND", 0);
1282 10 100         CV * const randcv = randsv && SvROK(randsv) && SvTYPE(SvRV(randsv)) == SVt_PVCV ?
    50          
1283 20 50         (CV *)SvRV(randsv) : NULL;
1284              
1285 10 50         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 10           ST(0) = POPs;
1292 10           items--;
1293              
1294 10 100         if(count > items)
1295 1           count = items;
1296              
1297 10 100         if(!randcv)
1298 8           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 62 100         while(reti < count) {
1304 52           int index = (int)(
1305 52 100         (randcv ? MY_callrand(aTHX_ randcv) : Drand01()) * (double)(items - reti)
1306             );
1307              
1308 52           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 52           ST(reti + index) = ST(reti);
1312              
1313 52           ST(reti) = selected;
1314 52           reti++;
1315             }
1316              
1317 10           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 26           int retcount = 0;
1331             int index;
1332 26           SV **args = &PL_stack_base[ax];
1333             HV *seen;
1334 26           int seen_undef = 0;
1335              
1336 26 100         if(items == 0 || (items == 1 && !SvGAMAGIC(args[0]) && SvOK(args[0]))) {
    100          
    50          
    50          
    0          
    0          
    100          
    50          
    50          
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 5           retcount = items;
1340 5           goto finish;
1341             }
1342              
1343 21           sv_2mortal((SV *)(seen = newHV()));
1344              
1345 146 100         for(index = 0 ; index < items ; index++) {
1346 125           SV *arg = args[index];
1347             #ifdef HV_FETCH_EMPTY_HE
1348             HE *he;
1349             #endif
1350              
1351 125 100         if(SvGAMAGIC(arg))
    100          
    50          
    50          
1352             /* clone the value so we don't invoke magic again */
1353 83           arg = sv_mortalcopy(arg);
1354              
1355 125 100         if(ix == 2 && !SvOK(arg)) {
    100          
    50          
    50          
1356             /* special handling of undef for uniq() */
1357 3 100         if(seen_undef)
1358 1           continue;
1359              
1360 2           seen_undef++;
1361              
1362 2 50         if(GIMME_V == G_LIST)
    50          
1363 2           ST(retcount) = arg;
1364 2           retcount++;
1365 2           continue;
1366             }
1367 122 100         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 18 100         if(SvAMAGIC(arg) && (arg = AMG_CALLun(arg, int)))
    50          
    50          
    50          
1373             ; /* nothing to do */
1374             else
1375             #endif
1376 16 100         if(!SvOK(arg) || SvNOK(arg) || SvPOK(arg))
    50          
    50          
    100          
    50          
1377             {
1378             /* Convert undef, NVs and PVs into a well-behaved int */
1379 6 100         NV nv = SvNV(arg);
1380              
1381 6 50         if(nv > (NV)UV_MAX)
1382             /* Too positive for UV - use NV */
1383 0           arg = newSVnv(Perl_floor(nv));
1384 6 50         else if(nv < (NV)IV_MIN)
1385             /* Too negative for IV - use NV */
1386 0           arg = newSVnv(Perl_ceil(nv));
1387 6 100         else if(nv > 0 && (UV)nv > (UV)IV_MAX)
    100          
1388             /* Too positive for IV - use UV */
1389 1           arg = newSVuv(nv);
1390             else
1391             /* Must now fit into IV */
1392 5           arg = newSViv(nv);
1393              
1394 6           sv_2mortal(arg);
1395             }
1396             }
1397             #ifdef HV_FETCH_EMPTY_HE
1398 122           he = (HE*) hv_common(seen, arg, NULL, 0, 0, HV_FETCH_LVALUE | HV_FETCH_EMPTY_HE, NULL, 0);
1399 122 100         if (HeVAL(he))
1400 52           continue;
1401              
1402 70           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 70 50         if(GIMME_V == G_LIST)
    100          
1411 65 100         ST(retcount) = SvOK(arg) ? arg : sv_2mortal(newSVpvn("", 0));
    50          
    50          
1412 70           retcount++;
1413             }
1414              
1415             finish:
1416 26 50         if(GIMME_V == G_LIST)
    100          
1417 25           XSRETURN(retcount);
1418             else
1419 1           ST(0) = sv_2mortal(newSViv(retcount));
1420             }
1421              
1422             void
1423             uniqnum(...)
1424             PROTOTYPE: @
1425             CODE:
1426             {
1427 22           int retcount = 0;
1428             int index;
1429 22           SV **args = &PL_stack_base[ax];
1430             HV *seen;
1431             /* A temporary buffer for number stringification */
1432 22           SV *keysv = sv_newmortal();
1433              
1434 22 50         if(items == 0 || (items == 1 && !SvGAMAGIC(args[0]) && SvOK(args[0]))) {
    100          
    50          
    50          
    0          
    0          
    50          
    50          
    50          
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 22           sv_2mortal((SV *)(seen = newHV()));
1442              
1443 141 100         for(index = 0 ; index < items ; index++) {
1444 119           SV *arg = args[index];
1445             NV nv_arg;
1446             #ifdef HV_FETCH_EMPTY_HE
1447             HE* he;
1448             #endif
1449              
1450 119 100         if(SvGAMAGIC(arg))
    100          
    50          
    50          
1451             /* clone the value so we don't invoke magic again */
1452 6           arg = sv_mortalcopy(arg);
1453              
1454 119 100         if(SvOK(arg) && !(SvUOK(arg) || SvIOK(arg) || SvNOK(arg))) {
    50          
    50          
    100          
    100          
    100          
1455             #if PERL_VERSION >= 8
1456 32 50         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 172 100         if( SvIOK(arg) || !SvOK(arg) ) {
    100          
    50          
    50          
1491              
1492             /* It doesn't matter if SvUOK(arg) is TRUE */
1493 53 100         IV iv = SvIV(arg);
1494              
1495             /* use "0" for all zeros */
1496 53 100         if(iv == 0) sv_setpvs(keysv, "0");
1497              
1498             else {
1499 47           int uok = SvUOK(arg);
1500 47 100         int sign = ( iv > 0 || uok ) ? 1 : -1;
    100          
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 47           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 47           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 47 100         if( !((iv * sign) & (~valid_bits)) ) {
1527             /* Avoid altering arg's flags */
1528 38 100         nv_arg = uok ? (NV)SvUV(arg) : (NV)SvIV(arg);
    50          
    50          
1529 38           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 9           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 9 100         if(uok) sv_catpvn(keysv, "U", 1);
1538 3           else sv_catpvn(keysv, "I", 1);
1539             }
1540             }
1541             }
1542             else {
1543 66 100         nv_arg = SvNV(arg);
1544              
1545             /* for NaN, use the platform's normal stringification */
1546 66 100         if (nv_arg != nv_arg) sv_setpvf(keysv, "%" NVgf, nv_arg);
1547              
1548             /* use "0" for all zeros */
1549 62 100         else if(nv_arg == 0) sv_setpvs(keysv, "0");
1550 61           else sv_setpvn(keysv, (char *) &nv_arg, 8);
1551             }
1552             #endif
1553             #ifdef HV_FETCH_EMPTY_HE
1554 119           he = (HE*) hv_common(seen, NULL, SvPVX(keysv), SvCUR(keysv), 0, HV_FETCH_LVALUE | HV_FETCH_EMPTY_HE, NULL, 0);
1555 119 100         if (HeVAL(he))
1556 34           continue;
1557              
1558 85           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 85 50         if(GIMME_V == G_LIST)
    100          
1567 78 100         ST(retcount) = SvOK(arg) ? arg : sv_2mortal(newSViv(0));
    50          
    50          
1568 85           retcount++;
1569             }
1570              
1571             finish:
1572 22 50         if(GIMME_V == G_LIST)
    100          
1573 19           XSRETURN(retcount);
1574             else
1575 3           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 14           Size_t nlists = items; /* number of lists */
1588             AV **lists; /* inbound lists */
1589 14           Size_t len = 0; /* length of longest inbound list = length of result */
1590             Size_t i;
1591 14           bool is_mesh = (ix & ZIP_MESH);
1592 14           ix &= ~ZIP_MESH;
1593              
1594 14 100         if(!nlists)
1595 2           XSRETURN(0);
1596              
1597 12 50         Newx(lists, nlists, AV *);
1598 12           SAVEFREEPV(lists);
1599              
1600             /* TODO: This may or maynot work on objects with arrayification overload */
1601             /* Remember to unit test it */
1602              
1603 26 100         for(i = 0; i < nlists; i++) {
1604 18           SV *arg = ST(i);
1605             AV *av;
1606              
1607 18 100         if(!SvROK(arg) || SvTYPE(SvRV(arg)) != SVt_PVAV)
    100          
1608 4           croak("Expected an ARRAY reference to zip");
1609 14           av = lists[i] = (AV *)SvRV(arg);
1610              
1611 14 100         if(!i) {
1612 8 50         len = av_count(av);
1613 8           continue;
1614             }
1615              
1616 6           switch(ix) {
1617             case 0: /* zip is alias to zip_longest */
1618             case ZIP_LONGEST:
1619 4 50         if(av_count(av) > len)
    50          
1620 0 0         len = av_count(av);
1621 4           break;
1622              
1623             case ZIP_SHORTEST:
1624 2 50         if(av_count(av) < len)
    50          
1625 2 50         len = av_count(av);
1626 2           break;
1627             }
1628             }
1629              
1630 8 100         if(is_mesh) {
1631 4           SSize_t retcount = (SSize_t)(len * nlists);
1632              
1633 4 50         EXTEND(SP, retcount);
    50          
1634              
1635 14 100         for(i = 0; i < len; i++) {
1636             Size_t listi;
1637              
1638 27 100         for(listi = 0; listi < nlists; listi++) {
1639 17 50         SV *item = (i < av_count(lists[listi])) ?
1640 17 100         AvARRAY(lists[listi])[i] :
1641             &PL_sv_undef;
1642              
1643 17           mPUSHs(SvREFCNT_inc(item));
1644             }
1645             }
1646              
1647 4           XSRETURN(retcount);
1648             }
1649             else {
1650 4 50         EXTEND(SP, (SSize_t)len);
    50          
1651              
1652 14 100         for(i = 0; i < len; i++) {
1653             Size_t listi;
1654 10           AV *ret = newAV();
1655 10           av_extend(ret, nlists);
1656              
1657 27 100         for(listi = 0; listi < nlists; listi++) {
1658 17 50         SV *item = (i < av_count(lists[listi])) ?
1659 17 100         AvARRAY(lists[listi])[i] :
1660             &PL_sv_undef;
1661              
1662 17           av_push(ret, SvREFCNT_inc(item));
1663             }
1664              
1665 10           mPUSHs(newRV_noinc((SV *)ret));
1666             }
1667              
1668 4           XSRETURN(len);
1669             }
1670              
1671             MODULE=List::Util PACKAGE=Scalar::Util
1672              
1673             void
1674             dualvar(num,str)
1675             SV *num
1676             SV *str
1677             PROTOTYPE: $$
1678             CODE:
1679             {
1680 6 50         dXSTARG;
1681              
1682 6 50         (void)SvUPGRADE(TARG, SVt_PVNV);
1683              
1684 6           sv_copypv(TARG,str);
1685              
1686 6 100         if(SvNOK(num) || SvPOK(num) || SvMAGICAL(num)) {
    50          
    100          
1687 3 100         SvNV_set(TARG, SvNV(num));
1688 3           SvNOK_on(TARG);
1689             }
1690             #ifdef SVf_IVisUV
1691 3 100         else if(SvUOK(num)) {
1692 1 50         SvUV_set(TARG, SvUV(num));
1693 1           SvIOK_on(TARG);
1694 1           SvIsUV_on(TARG);
1695             }
1696             #endif
1697             else {
1698 2 50         SvIV_set(TARG, SvIV(num));
1699 2           SvIOK_on(TARG);
1700             }
1701              
1702 6 50         if(PL_tainting && (SvTAINTED(num) || SvTAINTED(str)))
    0          
    0          
    0          
    0          
1703 0 0         SvTAINTED_on(TARG);
1704              
1705 6           ST(0) = TARG;
1706 6           XSRETURN(1);
1707             }
1708              
1709             void
1710             isdual(sv)
1711             SV *sv
1712             PROTOTYPE: $
1713             CODE:
1714 8 50         if(SvMAGICAL(sv))
1715 0           mg_get(sv);
1716              
1717 8 100         ST(0) = boolSV((SvPOK(sv) || SvPOKp(sv)) && (SvNIOK(sv) || SvNIOKp(sv)));
    50          
    100          
    50          
1718 8           XSRETURN(1);
1719              
1720             SV *
1721             blessed(sv)
1722             SV *sv
1723             PROTOTYPE: $
1724             CODE:
1725             {
1726 374 100         SvGETMAGIC(sv);
    50          
1727              
1728 374 100         if(!(SvROK(sv) && SvOBJECT(SvRV(sv))))
    100          
1729 355           XSRETURN_UNDEF;
1730             #ifdef HAVE_UNICODE_PACKAGE_NAMES
1731 19           RETVAL = newSVsv(sv_ref(NULL, SvRV(sv), TRUE));
1732             #else
1733             RETVAL = newSV(0);
1734             sv_setpv(RETVAL, sv_reftype(SvRV(sv), TRUE));
1735             #endif
1736             }
1737             OUTPUT:
1738             RETVAL
1739              
1740             char *
1741             reftype(sv)
1742             SV *sv
1743             PROTOTYPE: $
1744             CODE:
1745             {
1746 109 100         SvGETMAGIC(sv);
    50          
1747 109 100         if(!SvROK(sv))
1748 2           XSRETURN_UNDEF;
1749              
1750 107           RETVAL = (char*)sv_reftype(SvRV(sv),FALSE);
1751             }
1752             OUTPUT:
1753             RETVAL
1754              
1755             UV
1756             refaddr(sv)
1757             SV *sv
1758             PROTOTYPE: $
1759             CODE:
1760             {
1761 36 100         SvGETMAGIC(sv);
    50          
1762 36 100         if(!SvROK(sv))
1763 3           XSRETURN_UNDEF;
1764              
1765 33           RETVAL = PTR2UV(SvRV(sv));
1766             }
1767             OUTPUT:
1768             RETVAL
1769              
1770             void
1771             weaken(sv)
1772             SV *sv
1773             PROTOTYPE: $
1774             CODE:
1775 2252           sv_rvweaken(sv);
1776              
1777             void
1778             unweaken(sv)
1779             SV *sv
1780             PROTOTYPE: $
1781             INIT:
1782             SV *tsv;
1783             CODE:
1784             #if defined(sv_rvunweaken)
1785             PERL_UNUSED_VAR(tsv);
1786             sv_rvunweaken(sv);
1787             #else
1788             /* This code stolen from core's sv_rvweaken() and modified */
1789 1 50         if (!SvOK(sv))
    0          
    0          
1790 0           return;
1791 1 50         if (!SvROK(sv))
1792 0           croak("Can't unweaken a nonreference");
1793 1 50         else if (!SvWEAKREF(sv)) {
1794 0 0         if(ckWARN(WARN_MISC))
1795 0           warn("Reference is not weak");
1796 0           return;
1797             }
1798 1 50         else if (SvREADONLY(sv)) croak_no_modify();
1799              
1800 1           tsv = SvRV(sv);
1801             #if PERL_VERSION >= 14
1802 1           SvWEAKREF_off(sv); SvROK_on(sv);
1803 1           SvREFCNT_inc_NN(tsv);
1804 1           Perl_sv_del_backref(aTHX_ tsv, sv);
1805             #else
1806             /* Lacking sv_del_backref() the best we can do is clear the old (weak) ref
1807             * then set a new strong one
1808             */
1809             sv_setsv(sv, &PL_sv_undef);
1810             SvRV_set(sv, SvREFCNT_inc_NN(tsv));
1811             SvROK_on(sv);
1812             #endif
1813             #endif
1814              
1815             void
1816             isweak(sv)
1817             SV *sv
1818             PROTOTYPE: $
1819             CODE:
1820 9 100         ST(0) = boolSV(SvROK(sv) && SvWEAKREF(sv));
    100          
1821 9           XSRETURN(1);
1822              
1823             int
1824             readonly(sv)
1825             SV *sv
1826             PROTOTYPE: $
1827             CODE:
1828 9 50         SvGETMAGIC(sv);
    0          
1829 9           RETVAL = SvREADONLY(sv);
1830             OUTPUT:
1831             RETVAL
1832              
1833             int
1834             tainted(sv)
1835             SV *sv
1836             PROTOTYPE: $
1837             CODE:
1838 5 100         SvGETMAGIC(sv);
    50          
1839 5 100         RETVAL = SvTAINTED(sv);
    50          
1840             OUTPUT:
1841             RETVAL
1842              
1843             void
1844             isvstring(sv)
1845             SV *sv
1846             PROTOTYPE: $
1847             CODE:
1848             #ifdef SvVOK
1849 2 50         SvGETMAGIC(sv);
    0          
1850 2 100         ST(0) = boolSV(SvVOK(sv));
    50          
1851 2           XSRETURN(1);
1852             #else
1853             croak("vstrings are not implemented in this release of perl");
1854             #endif
1855              
1856             SV *
1857             looks_like_number(sv)
1858             SV *sv
1859             PROTOTYPE: $
1860             CODE:
1861             SV *tempsv;
1862 19 100         SvGETMAGIC(sv);
    50          
1863 19 100         if(SvAMAGIC(sv) && (tempsv = AMG_CALLun(sv, numer))) {
    100          
    50          
    50          
1864 1           sv = tempsv;
1865             }
1866             #if !PERL_VERSION_GE(5,8,5)
1867             if(SvPOK(sv) || SvPOKp(sv)) {
1868             RETVAL = looks_like_number(sv) ? &PL_sv_yes : &PL_sv_no;
1869             }
1870             else {
1871             RETVAL = (SvFLAGS(sv) & (SVf_NOK|SVp_NOK|SVf_IOK|SVp_IOK)) ? &PL_sv_yes : &PL_sv_no;
1872             }
1873             #else
1874 19 100         RETVAL = looks_like_number(sv) ? &PL_sv_yes : &PL_sv_no;
1875             #endif
1876             OUTPUT:
1877             RETVAL
1878              
1879             void
1880             openhandle(SV *sv)
1881             PROTOTYPE: $
1882             CODE:
1883             {
1884 20           IO *io = NULL;
1885 20 50         SvGETMAGIC(sv);
    0          
1886 20 100         if(SvROK(sv)){
1887             /* deref first */
1888 13           sv = SvRV(sv);
1889             }
1890              
1891             /* must be GLOB or IO */
1892 20 100         if(isGV(sv)){
1893 16 50         io = GvIO((GV*)sv);
    50          
    0          
    50          
1894             }
1895 4 100         else if(SvTYPE(sv) == SVt_PVIO){
1896 1           io = (IO*)sv;
1897             }
1898              
1899 20 100         if(io){
1900             /* real or tied filehandle? */
1901 14 100         if(IoIFP(io) || SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)){
    100          
    50          
1902 11           XSRETURN(1);
1903             }
1904             }
1905 9           XSRETURN_UNDEF;
1906             }
1907              
1908             MODULE=List::Util PACKAGE=Sub::Util
1909              
1910             void
1911             set_prototype(proto, code)
1912             SV *proto
1913             SV *code
1914             PREINIT:
1915             SV *cv; /* not CV * */
1916             PPCODE:
1917 15 50         SvGETMAGIC(code);
    0          
1918 15 100         if(!SvROK(code))
1919 1           croak("set_prototype: not a reference");
1920              
1921 14           cv = SvRV(code);
1922 14 100         if(SvTYPE(cv) != SVt_PVCV)
1923 1           croak("set_prototype: not a subroutine reference");
1924              
1925 13 100         if(SvPOK(proto)) {
1926             /* set the prototype */
1927 9           sv_copypv(cv, proto);
1928             }
1929             else {
1930             /* delete the prototype */
1931 4           SvPOK_off(cv);
1932             }
1933              
1934 13           PUSHs(code);
1935 13           XSRETURN(1);
1936              
1937             void
1938             set_subname(name, sub)
1939             SV *name
1940             SV *sub
1941             PREINIT:
1942 271           CV *cv = NULL;
1943             GV *gv;
1944 271           HV *stash = CopSTASH(PL_curcop);
1945 271           const char *s, *end = NULL, *begin = NULL;
1946             MAGIC *mg;
1947             STRLEN namelen;
1948 271 50         const char* nameptr = SvPV(name, namelen);
1949 271           int utf8flag = SvUTF8(name);
1950 271           int quotes_seen = 0;
1951 271           bool need_subst = FALSE;
1952             PPCODE:
1953 271 50         if (!SvROK(sub) && SvGMAGICAL(sub))
    0          
1954 0           mg_get(sub);
1955 271 50         if (SvROK(sub))
1956 271           cv = (CV *) SvRV(sub);
1957 0 0         else if (SvTYPE(sub) == SVt_PVGV)
1958 0 0         cv = GvCVu(sub);
1959 0 0         else if (!SvOK(sub))
    0          
    0          
1960 0           croak(PL_no_usym, "a subroutine");
1961 0 0         else if (PL_op->op_private & HINT_STRICT_REFS)
1962 0 0         croak("Can't use string (\"%.32s\") as %s ref while \"strict refs\" in use",
1963 0           SvPV_nolen(sub), "a subroutine");
1964 0 0         else if ((gv = gv_fetchsv(sub, FALSE, SVt_PVCV)))
1965 0 0         cv = GvCVu(gv);
1966 271 50         if (!cv)
1967 0 0         croak("Undefined subroutine %s", SvPV_nolen(sub));
1968 271 50         if (SvTYPE(cv) != SVt_PVCV && SvTYPE(cv) != SVt_PVFM)
    0          
1969 0           croak("Not a subroutine reference");
1970 10837 100         for (s = nameptr; s <= nameptr + namelen; s++) {
1971 10566 100         if (s > nameptr && *s == ':' && s[-1] == ':') {
    100          
    100          
1972 783           end = s - 1;
1973 783           begin = ++s;
1974 784 100         if (quotes_seen)
1975 1           need_subst = TRUE;
1976             }
1977 9783 100         else if (s > nameptr && *s != '\0' && s[-1] == '\'') {
    100          
    100          
1978 2           end = s - 1;
1979 2           begin = s;
1980 2 100         if (quotes_seen++)
1981 1           need_subst = TRUE;
1982             }
1983             }
1984 271           s--;
1985 271 100         if (end) {
1986             SV* tmp;
1987 262 100         if (need_subst) {
1988 1 50         STRLEN length = end - nameptr + quotes_seen - (*end == '\'' ? 1 : 0);
1989             char* left;
1990             int i, j;
1991 1           tmp = sv_2mortal(newSV(length));
1992 1           left = SvPVX(tmp);
1993 37 100         for (i = 0, j = 0; j < end - nameptr; ++i, ++j) {
1994 36 100         if (nameptr[j] == '\'') {
1995 1           left[i] = ':';
1996 1           left[++i] = ':';
1997             }
1998             else {
1999 35           left[i] = nameptr[j];
2000             }
2001             }
2002 1           stash = gv_stashpvn(left, length, GV_ADD | utf8flag);
2003             }
2004             else
2005 261           stash = gv_stashpvn(nameptr, end - nameptr, GV_ADD | utf8flag);
2006 262           nameptr = begin;
2007 262           namelen -= begin - nameptr;
2008             }
2009              
2010             /* under debugger, provide information about sub location */
2011 271 50         if (PL_DBsub && CvGV(cv)) {
    50          
2012 271           HV* DBsub = GvHV(PL_DBsub);
2013 271           HE* old_data = NULL;
2014              
2015 271           GV* oldgv = CvGV(cv);
2016 271           HV* oldhv = GvSTASH(oldgv);
2017              
2018 271 100         if (oldhv) {
2019 270 50         SV* old_full_name = sv_2mortal(newSVpvn_flags(HvNAME(oldhv), HvNAMELEN_get(oldhv), HvNAMEUTF8(oldhv) ? SVf_UTF8 : 0));
    50          
    50          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    50          
    50          
2020 270           sv_catpvn(old_full_name, "::", 2);
2021 270 50         sv_catpvn_flags(old_full_name, GvNAME(oldgv), GvNAMELEN(oldgv), GvNAMEUTF8(oldgv) ? SV_CATUTF8 : SV_CATBYTES);
2022              
2023 270           old_data = hv_fetch_ent(DBsub, old_full_name, 0, 0);
2024             }
2025              
2026 271 100         if (old_data && HeVAL(old_data)) {
    50          
2027 267           SV* old_val = HeVAL(old_data);
2028 267 50         SV* new_full_name = sv_2mortal(newSVpvn_flags(HvNAME(stash), HvNAMELEN_get(stash), HvNAMEUTF8(stash) ? SVf_UTF8 : 0));
    50          
    50          
    0          
    50          
    50          
    50          
    100          
    50          
    50          
    50          
    0          
    50          
    50          
    50          
    50          
    50          
    0          
    50          
    50          
2029 267           sv_catpvn(new_full_name, "::", 2);
2030 267 100         sv_catpvn_flags(new_full_name, nameptr, s - nameptr, utf8flag ? SV_CATUTF8 : SV_CATBYTES);
2031 267           SvREFCNT_inc(old_val);
2032 267 50         if (!hv_store_ent(DBsub, new_full_name, old_val, 0))
2033 0           SvREFCNT_dec(old_val);
2034             }
2035             }
2036              
2037 271           gv = (GV *) newSV(0);
2038 271           gv_init_pvn(gv, stash, nameptr, s - nameptr, GV_ADDMULTI | utf8flag);
2039              
2040             /*
2041             * set_subname needs to create a GV to store the name. The CvGV field of a
2042             * CV is not refcounted, so perl wouldn't know to SvREFCNT_dec() this GV if
2043             * it destroys the containing CV. We use a MAGIC with an empty vtable
2044             * simply for the side-effect of using MGf_REFCOUNTED to store the
2045             * actually-counted reference to the GV.
2046             */
2047 271           mg = SvMAGIC(cv);
2048 271 100         while (mg && mg->mg_virtual != &subname_vtbl)
    50          
2049 0           mg = mg->mg_moremagic;
2050 271 100         if (!mg) {
2051 265           Newxz(mg, 1, MAGIC);
2052 265           mg->mg_moremagic = SvMAGIC(cv);
2053 265           mg->mg_type = PERL_MAGIC_ext;
2054 265           mg->mg_virtual = &subname_vtbl;
2055 265           SvMAGIC_set(cv, mg);
2056             }
2057 271 100         if (mg->mg_flags & MGf_REFCOUNTED)
2058 6           SvREFCNT_dec(mg->mg_obj);
2059 271           mg->mg_flags |= MGf_REFCOUNTED;
2060 271           mg->mg_obj = (SV *) gv;
2061 271           SvRMAGICAL_on(cv);
2062 271           CvANON_off(cv);
2063             #ifndef CvGV_set
2064             CvGV(cv) = gv;
2065             #else
2066 271           CvGV_set(cv, gv);
2067             #endif
2068 271           PUSHs(sub);
2069              
2070             void
2071             subname(code)
2072             SV *code
2073             PREINIT:
2074             CV *cv;
2075             GV *gv;
2076             const char *stashname;
2077             PPCODE:
2078 8 50         if (!SvROK(code) && SvGMAGICAL(code))
    0          
2079 0           mg_get(code);
2080              
2081 8 50         if(!SvROK(code) || SvTYPE(cv = (CV *)SvRV(code)) != SVt_PVCV)
    100          
2082 1           croak("Not a subroutine reference");
2083              
2084 7 50         if(!(gv = CvGV(cv)))
2085 0           XSRETURN(0);
2086              
2087 7 100         if(GvSTASH(gv))
2088 6 50         stashname = HvNAME(GvSTASH(gv));
    50          
    50          
    0          
    50          
    50          
2089             else
2090 1           stashname = "__ANON__";
2091              
2092 7           mPUSHs(newSVpvf("%s::%s", stashname, GvNAME(gv)));
2093 7           XSRETURN(1);
2094              
2095             BOOT:
2096             {
2097 38           HV *lu_stash = gv_stashpvn("List::Util", 10, TRUE);
2098 38           GV *rmcgv = *(GV**)hv_fetch(lu_stash, "REAL_MULTICALL", 14, TRUE);
2099             SV *rmcsv;
2100             #if !defined(SvVOK)
2101             HV *su_stash = gv_stashpvn("Scalar::Util", 12, TRUE);
2102             GV *vargv = *(GV**)hv_fetch(su_stash, "EXPORT_FAIL", 11, TRUE);
2103             AV *varav;
2104             if(SvTYPE(vargv) != SVt_PVGV)
2105             gv_init(vargv, su_stash, "Scalar::Util", 12, TRUE);
2106             varav = GvAVn(vargv);
2107             #endif
2108 38 50         if(SvTYPE(rmcgv) != SVt_PVGV)
2109 38           gv_init(rmcgv, lu_stash, "List::Util", 10, TRUE);
2110 38 50         rmcsv = GvSVn(rmcgv);
2111             #ifndef SvVOK
2112             av_push(varav, newSVpv("isvstring",9));
2113             #endif
2114             #ifdef REAL_MULTICALL
2115 38           sv_setsv(rmcsv, &PL_sv_yes);
2116             #else
2117             sv_setsv(rmcsv, &PL_sv_no);
2118             #endif
2119             }