File Coverage

lib/Hash/Util/Pick.xs
Criterion Covered Total %
statement 65 65 100.0
branch 88 134 65.6
condition n/a
subroutine n/a
pod n/a
total 153 199 76.8


line stmt bran cond sub pod time code
1             #ifdef __cplusplus
2             extern "C" {
3             #endif
4              
5             #define PERL_NO_GET_CONTEXT /* we want efficiency */
6             #include
7             #include
8             #include
9              
10             #ifdef __cplusplus
11             } /* extern "C" */
12             #endif
13              
14             #define NEED_newSVpvn_flags
15             #include "ppport.h"
16              
17             MODULE = Hash::Util::Pick PACKAGE = Hash::Util::Pick
18              
19             PROTOTYPES: DISABLED
20              
21             void
22             pick(...)
23             PROTOTYPE: $@
24             PPCODE:
25             {
26 15           SV **args = &PL_stack_base[ax];
27 15           HV *src = SvROK(args[0]) ?
28 15 100         (HV*)SvRV(args[0]) : (HV*)sv_2mortal((SV*)newHV());
29              
30             I32 i;
31 15           HV *dest = (HV*)sv_2mortal((SV*)newHV());
32              
33 30 100         for (i = 1; i < items; ++i) {
34 15 100         if (hv_exists_ent(src, args[i], 0)) {
35 7           HE *he = hv_fetch_ent(src, args[i], 0, 0);
36 7 50         if (he) {
37 7           SV *v = HeVAL(he);
38 7           hv_store_ent(dest, args[i], v, 0);
39             }
40             }
41             }
42              
43 15 50         XPUSHs(newRV_inc((SV*)dest));
44 15           XSRETURN(1);
45             }
46              
47             void
48             pick_by(...)
49             PROTOTYPE: $&
50             PPCODE:
51             {
52             dMULTICALL;
53             GV *gv;
54             HV *stash;
55             I32 gimme = G_SCALAR;
56              
57 18           HV *src = SvROK(ST(0)) ?
58 18 100         (HV*)SvRV(ST(0)) : (HV*)sv_2mortal((SV*)newHV());
59              
60 18 100         if (!SvROK(ST(1)) || SvTYPE((SV*)SvRV(ST(1))) != SVt_PVCV) {
    50          
61 2 50         XPUSHs(newRV_noinc((SV*)newHV()));
62 2           XSRETURN(1);
63             }
64              
65 16           CV *code = sv_2cv(SvRV(ST(1)), &stash, &gv, 0);
66              
67             char *hkey;
68             I32 hkeylen;
69             SV *value;
70 16           HV *dest = (HV*)sv_2mortal((SV*)newHV());
71              
72 16 50         PUSH_MULTICALL(code);
    50          
73 16           SAVESPTR(GvSV(PL_defgv));
74              
75 16           hv_iterinit(src);
76              
77 47 100         while ((value = hv_iternextsv(src, &hkey, &hkeylen)) != NULL) {
78 15           GvSV(PL_defgv) = value;
79 15           MULTICALL;
80 15 50         if (SvTRUE(*PL_stack_sp)) {
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    50          
    50          
    100          
    50          
    0          
    100          
81 31           hv_store(dest, hkey, hkeylen, value, 0);
82             }
83             }
84              
85 16 50         POP_MULTICALL;
    50          
86              
87 16 50         XPUSHs(newRV_inc((SV*)dest));
88 16           XSRETURN(1);
89             }
90              
91             void
92             omit(...)
93             PROTOTYPE: $@
94             PPCODE:
95             {
96 15           SV **args = &PL_stack_base[ax];
97 15           HV *src = SvROK(args[0]) ?
98 15 100         (HV*)SvRV(args[0]) : (HV*)sv_2mortal((SV*)newHV());
99              
100             I32 i;
101 15           HV *dest = (HV*)sv_2mortal((SV*)newHV());
102 15           HV *omit_key_to_exist = (HV*)sv_2mortal((SV*)newHV());
103              
104 30 100         for (i = 1; i < items; ++i) {
105 15           hv_store_ent(omit_key_to_exist, args[i], &PL_sv_yes, 0);
106             }
107              
108             char *hkey;
109             I32 hkeylen;
110             SV *value;
111              
112 15           hv_iterinit(omit_key_to_exist);
113              
114 42 100         while ((value = hv_iternextsv(src, &hkey, &hkeylen)) != NULL) {
115 12 100         if (!hv_exists(omit_key_to_exist, hkey, hkeylen)) {
116 5           SV **svp = hv_fetch(src, hkey, hkeylen, 0);
117 5 50         if (svp) {
118 20           hv_store(dest, hkey, hkeylen, *svp, 0);
119             }
120             }
121             }
122              
123 15 50         XPUSHs(newRV_inc((SV*)dest));
124 15           XSRETURN(1);
125             }
126              
127             void
128             omit_by(...)
129             PROTOTYPE: $&
130             PPCODE:
131             {
132             dMULTICALL;
133             GV *gv;
134             HV *stash;
135             I32 gimme = G_SCALAR;
136              
137 18           HV *src = SvROK(ST(0)) ?
138 18 100         (HV*)SvRV(ST(0)) : (HV*)sv_2mortal((SV*)newHV());
139 18           HV *dest = (HV*)sv_2mortal((SV*)newHV());
140              
141             char *hkey;
142             I32 hkeylen;
143             SV *value;
144              
145 18 100         if (!SvROK(ST(1)) || SvTYPE((SV*)SvRV(ST(1))) != SVt_PVCV) {
    50          
146 3 100         while ((value = hv_iternextsv(src, &hkey, &hkeylen)) != NULL) {
147 1           hv_store(dest, hkey, hkeylen, value, 0);
148             }
149              
150 2 50         XPUSHs(newRV_inc((SV*)dest));
151 2           XSRETURN(1);
152             }
153              
154 16           CV *code = sv_2cv(SvRV(ST(1)), &stash, &gv, 0);
155              
156 16 50         PUSH_MULTICALL(code);
    50          
157 16           SAVESPTR(GvSV(PL_defgv));
158              
159 16           hv_iterinit(src);
160              
161 31 100         while ((value = hv_iternextsv(src, &hkey, &hkeylen)) != NULL) {
162 15           GvSV(PL_defgv) = value;
163 15           MULTICALL;
164 15 50         if (!SvTRUE(*PL_stack_sp)) {
    50          
    0          
    100          
    50          
    50          
    100          
    50          
    50          
    100          
    50          
    100          
    50          
    50          
    100          
    50          
    0          
    100          
    0          
165 15           hv_store(dest, hkey, hkeylen, value, 0);
166             }
167             }
168              
169 16 50         POP_MULTICALL;
    50          
170              
171 16 50         XPUSHs(newRV_inc((SV*)dest));
172 16           XSRETURN(1);
173             }
174