File Coverage

easyxs/easyxs_perlcall.h
Criterion Covered Total %
statement 32 32 100.0
branch 29 64 45.3
condition n/a
subroutine n/a
pod n/a
total 61 96 63.5


line stmt bran cond sub pod time code
1             #ifndef EASYXS_PERLCALL_H
2             #define EASYXS_PERLCALL_H 1
3              
4             #include "init.h"
5              
6 6           static inline void _EASYXS_SET_ARGS (pTHX_ SV* object, SV** args) {
7 6           dSP;
8              
9 6           unsigned argscount = 0;
10              
11 6 50         if (args) {
12 22 100         while (args[argscount] != NULL) argscount++;
13             }
14              
15 6           ENTER;
16 6           SAVETMPS;
17              
18 6 50         PUSHMARK(SP);
19              
20 6 50         if (object || argscount) {
    100          
21 5 50         EXTEND(SP, (object ? 1 : 0) + argscount);
    50          
    0          
22              
23 5 50         if (object) PUSHs( sv_mortalcopy(object) );
24              
25 5           unsigned a=0;
26 21 100         while (a < argscount) mPUSHs( args[a++] );
27              
28 5           PUTBACK;
29             }
30 6           }
31              
32             #define exs_call_sv_void(sv, args) STMT_START { \
33             _EASYXS_SET_ARGS(aTHX_ NULL, args); \
34             call_sv(sv, G_DISCARD | G_VOID); \
35             FREETMPS; \
36             LEAVE; \
37             } STMT_END
38              
39             #define exs_call_method_void(object, methname, args) STMT_START { \
40             _EASYXS_SET_ARGS(aTHX_ object, args); \
41             \
42             call_method( methname, G_DISCARD | G_VOID ); \
43             \
44             FREETMPS; \
45             LEAVE; \
46             } STMT_END
47              
48             static inline SV* _easyxs_fetch_scalar_return (pTHX_ int count) {
49             dSP;
50              
51             SPAGAIN;
52              
53             SV* ret;
54              
55             if (count == 0) {
56             ret = &PL_sv_undef;
57             }
58             else {
59             ret = SvREFCNT_inc(POPs);
60              
61             while (count-- > 1) PERL_UNUSED_VAR(POPs);
62             }
63              
64             PUTBACK;
65             FREETMPS;
66             LEAVE;
67              
68             return ret;
69             }
70              
71 5           static inline SV** _easyxs_fetch_list_return (pTHX_ int count) {
72 5           dSP;
73              
74 5           SPAGAIN;
75              
76             SV** ret;
77              
78 5 50         Newx(ret, 1 + count, SV*);
79 5           ret[count] = NULL;
80              
81 12 100         while (count-- > 0) {
82 7           ret[count] = SvREFCNT_inc(POPs);
83             }
84              
85 5           PUTBACK;
86 5 50         FREETMPS;
87 5           LEAVE;
88              
89 5           SAVEFREEPV(ret);
90              
91 5           return ret;
92             }
93              
94             static inline SV* _easyxs_call_method_scalar (pTHX_ SV* object, const char* methname, SV** args) {
95             _EASYXS_SET_ARGS(aTHX_ object, args);
96              
97             int count = call_method(methname, G_SCALAR);
98              
99             return _easyxs_fetch_scalar_return(aTHX_ count);
100             }
101              
102             #define exs_call_method_scalar(object, methname, args) \
103             _easyxs_call_method_scalar(aTHX_ object, methname, args)
104              
105             static inline SV* _easyxs_call_sv_scalar (pTHX_ SV* cb, SV** args) {
106             _EASYXS_SET_ARGS(aTHX_ NULL, args);
107              
108             int count = call_sv(cb, G_SCALAR);
109              
110             return _easyxs_fetch_scalar_return(aTHX_ count);
111             }
112              
113             #define exs_call_sv_scalar(sv, args) \
114             _easyxs_call_sv_scalar(aTHX_ sv, args)
115              
116             static inline SV** _easyxs_call_sv_list (pTHX_ SV* cb, SV** args) {
117             _EASYXS_SET_ARGS(aTHX_ NULL, args);
118              
119             int count = call_sv(cb, G_ARRAY);
120              
121             return _easyxs_fetch_list_return(aTHX_ count);
122             }
123              
124             #define exs_call_sv_list(sv, args) \
125             _easyxs_call_sv_list(aTHX_ sv, args)
126              
127             #define _handle_trapped_error(count) STMT_START { \
128             dSP; \
129             SV* err_tmp = ERRSV; \
130             if (SvTRUE(err_tmp)) { \
131             while (count--) PERL_UNUSED_VAR(POPs); \
132             \
133             *error = err_tmp; \
134             \
135             PUTBACK; \
136             FREETMPS; \
137             LEAVE; \
138             \
139             return NULL; \
140             } \
141             } STMT_END
142              
143             static inline SV* _easyxs_call_sv_scalar_trapped (pTHX_ SV* cb, SV** args, SV** error) {
144             _EASYXS_SET_ARGS(aTHX_ NULL, args);
145              
146             int count = call_sv(cb, G_SCALAR | G_EVAL);
147              
148             _handle_trapped_error(count);
149              
150             return _easyxs_fetch_scalar_return(aTHX_ count);
151             }
152              
153             #define exs_call_sv_scalar_trapped(sv, args, err_p) \
154             _easyxs_call_sv_scalar_trapped(aTHX_ sv, args, err_p)
155              
156 6           static inline SV** _easyxs_call_sv_list_trapped (pTHX_ SV* cb, SV** args, SV** error) {
157 6           _EASYXS_SET_ARGS(aTHX_ NULL, args);
158              
159 6           int count = call_sv(cb, G_ARRAY | G_EVAL);
160              
161 6 50         _handle_trapped_error(count);
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    100          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    50          
162              
163 5           return _easyxs_fetch_list_return(aTHX_ count);
164             }
165              
166             #define exs_call_sv_list_trapped(sv, args, err_p) \
167             _easyxs_call_sv_list_trapped(aTHX_ sv, args, err_p)
168              
169             #endif