File Coverage

c/typemap.c
Criterion Covered Total %
statement 92 116 79.3
branch 47 82 57.3
condition n/a
subroutine n/a
pod n/a
total 139 198 70.2


line stmt bran cond sub pod time code
1 3820           static SV *wrap_thing(U16 mgcode, void *ptr, HV *stash, SV *temple) {
2             SV *ref;
3             MAGIC **mgp;
4             MAGIC *mg;
5              
6             assert(ptr);
7             assert(stash);
8              
9 3820 50         if (!temple)
10 0           temple = (SV*)newHV();
11             else
12 3820           SvREFCNT_inc(temple);
13 3820 100         if (SvOBJECT(temple))
14 1           croak("Can't attach to blessed reference");
15             assert(!SvROK(temple));
16             assert(mg_find(temple, '~') == 0); /* multiplicity disallowed! */
17              
18 3819           ref = newRV_noinc(temple);
19 3819           sv_bless(ref, stash);
20              
21 3819           mgp = &SvMAGIC(temple);
22 3819 50         while ((mg = *mgp))
23 0           mgp = &mg->mg_moremagic;
24              
25 3819           New(0, mg, 1, MAGIC);
26 3819           Zero(mg, 1, MAGIC);
27 3819           mg->mg_type = '~';
28 3819           mg->mg_ptr = (char*) ptr; /* NOT refcnt'd */
29 3819           mg->mg_private = mgcode;
30 3819           *mgp = mg;
31              
32 3819           return ref;
33             }
34              
35 128427           static void* sv_2thing(U16 mgcode, SV *sv) {
36             MAGIC *mg;
37 128427           SV *origsv = sv;
38 128427 50         if (!sv || !SvROK(sv))
    100          
39 1           croak("sv_2thing: not a reference?");
40 128426           sv = SvRV(sv);
41 128426 100         if (SvTYPE(sv) < SVt_PVMG)
42 3           croak("sv_2thing: not a thing");
43 128423 50         if (!SvOBJECT(sv))
44 0           croak("sv_2thing: not an object");
45 128423           mg = mg_find(sv, '~');
46 128423 50         if (mg) {
47 128423 100         if (mg->mg_private != mgcode) {
48 1           croak("Can't find event magic (SV=0x%x)", sv);
49             }
50 128422           return (void*) mg->mg_ptr;
51             }
52 0           croak("sv_2thing: can't decode SV=0x%x", origsv);
53 0           return 0;
54             }
55              
56             #define MG_WATCHER_CODE ((((unsigned)'e')<<8) + (unsigned)'v')
57              
58 3819           static SV *wrap_watcher(void *ptr, HV *stash, SV *temple) {
59 3819           return wrap_thing(MG_WATCHER_CODE, ptr, stash, temple);
60             }
61              
62 101761           SV *watcher_2sv(pe_watcher *wa) { /**SLOW IS OKAY**/
63             assert(!WaDESTROYED(wa));
64 101761 50         if (!wa->mysv) {
65 0           wa->mysv = wrap_watcher(wa, wa->vtbl->stash, 0);
66             if (WaDEBUGx(wa) >= 4) {
67             STRLEN n_a;
68             warn("Watcher=0x%x '%s' wrapped with SV=0x%x",
69             wa, SvPV(wa->desc, n_a), SvRV(wa->mysv));
70             }
71             }
72 101761           return SvREFCNT_inc(sv_2mortal(wa->mysv));
73             }
74              
75 128417           void* sv_2watcher(SV *sv) {
76 128417           return sv_2thing(MG_WATCHER_CODE, sv);
77             }
78              
79             #define MG_GENERICSRC_CODE 2422 /* randomly chosen */
80              
81 1           static SV *wrap_genericsrc(void *ptr, HV *stash, SV *temple) {
82 1           return wrap_thing(MG_GENERICSRC_CODE, ptr, stash, temple);
83             }
84              
85             static HV *pe_genericsrc_stash;
86              
87 1           static SV *genericsrc_2sv(pe_genericsrc *src) { /**SLOW IS OKAY**/
88 1 50         if (!src->mysv) {
89 0           src->mysv = wrap_genericsrc(src, pe_genericsrc_stash, 0);
90             }
91 1           return SvREFCNT_inc(sv_2mortal(src->mysv));
92             }
93              
94 10           static void* sv_2genericsrc(SV *sv) {
95 10           return sv_2thing(MG_GENERICSRC_CODE, sv);
96             }
97              
98             /*
99             Events have a short lifetime. mysv is kept alive until the event
100             has been serviced. Once perl finally releases mysv then the event
101             is deallocated (or, more likely, recycled).
102             */
103              
104 94979           SV *event_2sv(pe_event *ev) { /**MAKE FAST**/
105 94979 100         if (!ev->mysv) {
106 94968           SV *rv = newSV(0);
107 94968           SV *sv = newSVrv(rv,0);
108 94968           sv_bless(rv, ev->vtbl->stash);
109 94968           sv_setiv(sv, PTR2IV(ev));
110 94968           ev->mysv = rv;
111              
112             if (WaDEBUGx(ev->up) >= 4) {
113             STRLEN n_a;
114             warn("Event=0x%x '%s' wrapped with SV=0x%x",
115             ev, SvPV(ev->up->desc, n_a), SvRV(ev->mysv));
116             }
117             }
118 94979           return SvREFCNT_inc(sv_2mortal(ev->mysv));
119             }
120              
121 283831           void *sv_2event(SV *sv) {
122             void *ptr;
123             assert(sv);
124             assert(SvROK(sv));
125 283831           sv = SvRV(sv);
126 283831 50         ptr = INT2PTR(void *, SvIV(sv));
127             assert(ptr);
128 283831           return ptr;
129             }
130              
131             /***************************************************************/
132              
133             #define VERIFYINTERVAL(name, f) \
134             STMT_START { NV ign; sv_2interval(name, f, &ign); } STMT_END
135              
136 137           int sv_2interval(char *label, SV *in, NV *out) {
137 137           SV *sv = in;
138 137 50         if (!sv) return 0;
139 137 50         if (SvGMAGICAL(sv))
140 0           mg_get(sv);
141 137 100         if (!SvOK(sv)) return 0;
    50          
    50          
142 122 50         if (SvROK(sv))
143 0           sv = SvRV(sv);
144 122 50         if (!SvOK(sv)) {
    0          
    0          
145 0           warn("Event: %s interval undef", label);
146 0           *out = 0;
147 122 100         } else if (SvNOK(sv)) {
148 120           *out = SvNVX(sv);
149 2 50         } else if (SvIOK(sv)) {
150 2           *out = SvIVX(sv);
151 0 0         } else if (looks_like_number(sv)) {
152 0 0         *out = SvNV(sv);
153             } else {
154 0           sv_dump(in);
155 0           croak("Event: %s interval must be a number or reference to a number",
156             label);
157 0           return 0;
158             }
159 122 50         if (*out < 0) {
160 0           warn("Event: %s has negative timeout %.2f (clipped to zero)",
161             label, *out);
162 0           *out = 0;
163             }
164 122           return 1;
165             }
166              
167 94111           SV* events_mask_2sv(int mask) {
168 94111           SV *ret = newSV(0);
169 94111 50         (void)SvUPGRADE(ret, SVt_PVIV);
170 94111           sv_setpvn(ret, "", 0);
171 94111 100         if (mask & PE_R) sv_catpv(ret, "r");
172 94111 100         if (mask & PE_W) sv_catpv(ret, "w");
173 94111 50         if (mask & PE_E) sv_catpv(ret, "e");
174 94111 100         if (mask & PE_T) sv_catpv(ret, "t");
175 94111           SvIVX(ret) = mask;
176 94111           SvIOK_on(ret);
177 94111           return ret;
178             }
179              
180 8           int sv_2events_mask(SV *sv, int bits) {
181 8 100         if (SvPOK(sv)) {
182 6           UV got=0;
183             int xx;
184             STRLEN el;
185 6 50         char *ep = SvPV(sv,el);
186 12 100         for (xx=0; xx < el; xx++) {
187 6           switch (ep[xx]) {
188 4 50         case 'r': if (bits & PE_R) { got |= PE_R; continue; }
189 2 50         case 'w': if (bits & PE_W) { got |= PE_W; continue; }
190 0 0         case 'e': if (bits & PE_E) { got |= PE_E; continue; }
191 0 0         case 't': if (bits & PE_T) { got |= PE_T; continue; }
192             }
193 0           warn("Ignored '%c' in poll mask", ep[xx]);
194             }
195 6           return got;
196             }
197 2 50         else if (SvIOK(sv)) {
198 2           UV extra = SvIVX(sv) & ~bits;
199 2 50         if (extra) warn("Ignored extra bits (0x%x) in poll mask", extra);
200 2           return SvIVX(sv) & bits;
201             }
202             else {
203 0           sv_dump(sv);
204 0           croak("Must be a string /[rwet]/ or bit mask");
205 0           return 0; /* NOTREACHED */
206             }
207             }