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 3886           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 3886 50         if (!temple)
10 0           temple = (SV*)newHV();
11             else
12 3886           SvREFCNT_inc(temple);
13 3886 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 3885           ref = newRV_noinc(temple);
19 3885           sv_bless(ref, stash);
20              
21 3885           mgp = &SvMAGIC(temple);
22 3885 50         while ((mg = *mgp))
23 0           mgp = &mg->mg_moremagic;
24              
25 3885           New(0, mg, 1, MAGIC);
26 3885           Zero(mg, 1, MAGIC);
27 3885           mg->mg_type = '~';
28 3885           mg->mg_ptr = (char*) ptr; /* NOT refcnt'd */
29 3885           mg->mg_private = mgcode;
30 3885           *mgp = mg;
31              
32 3885           return ref;
33             }
34              
35 145011           static void* sv_2thing(U16 mgcode, SV *sv) {
36             MAGIC *mg;
37 145011           SV *origsv = sv;
38 145011 50         if (!sv || !SvROK(sv))
    100          
39 1           croak("sv_2thing: not a reference?");
40 145010           sv = SvRV(sv);
41 145010 100         if (SvTYPE(sv) < SVt_PVMG)
42 3           croak("sv_2thing: not a thing");
43 145007 50         if (!SvOBJECT(sv))
44 0           croak("sv_2thing: not an object");
45 145007           mg = mg_find(sv, '~');
46 145007 50         if (mg) {
47 145007 100         if (mg->mg_private != mgcode) {
48 1           croak("Can't find event magic (SV=0x%x)", sv);
49             }
50 145006           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 3885           static SV *wrap_watcher(void *ptr, HV *stash, SV *temple) {
59 3885           return wrap_thing(MG_WATCHER_CODE, ptr, stash, temple);
60             }
61              
62 117883           SV *watcher_2sv(pe_watcher *wa) { /**SLOW IS OKAY**/
63             assert(!WaDESTROYED(wa));
64 117883 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 117883           return SvREFCNT_inc(sv_2mortal(wa->mysv));
73             }
74              
75 145001           void* sv_2watcher(SV *sv) {
76 145001           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 110980           SV *event_2sv(pe_event *ev) { /**MAKE FAST**/
105 110980 100         if (!ev->mysv) {
106 110969           SV *rv = newSV(0);
107 110969           SV *sv = newSVrv(rv,0);
108 110969           sv_bless(rv, ev->vtbl->stash);
109 110969           sv_setiv(sv, PTR2IV(ev));
110 110969           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 110980           return SvREFCNT_inc(sv_2mortal(ev->mysv));
119             }
120              
121 331823           void *sv_2event(SV *sv) {
122             void *ptr;
123             assert(sv);
124             assert(SvROK(sv));
125 331823           sv = SvRV(sv);
126 331823 50         ptr = INT2PTR(void *, SvIV(sv));
127             assert(ptr);
128 331823           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 140           int sv_2interval(char *label, SV *in, NV *out) {
137 140           SV *sv = in;
138 140 50         if (!sv) return 0;
139 140 50         if (SvGMAGICAL(sv))
140 0           mg_get(sv);
141 140 100         if (!SvOK(sv)) return 0;
    50          
    50          
142 124 50         if (SvROK(sv))
143 0           sv = SvRV(sv);
144 124 50         if (!SvOK(sv)) {
    0          
    0          
145 0           warn("Event: %s interval undef", label);
146 0           *out = 0;
147 124 100         } else if (SvNOK(sv)) {
148 122           *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 124 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 124           return 1;
165             }
166              
167 110101           SV* events_mask_2sv(int mask) {
168 110101           SV *ret = newSV(0);
169 110101 50         (void)SvUPGRADE(ret, SVt_PVIV);
170 110101           sv_setpvn(ret, "", 0);
171 110101 100         if (mask & PE_R) sv_catpv(ret, "r");
172 110101 100         if (mask & PE_W) sv_catpv(ret, "w");
173 110101 50         if (mask & PE_E) sv_catpv(ret, "e");
174 110101 100         if (mask & PE_T) sv_catpv(ret, "t");
175 110101           SvIVX(ret) = mask;
176 110101           SvIOK_on(ret);
177 110101           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             }