File Coverage

easyxs/easyxs_perlcall.h
Criterion Covered Total %
statement 31 32 96.8
branch 50 130 38.4
condition n/a
subroutine n/a
pod n/a
total 81 162 50.0


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 13           static inline void _EASYXS_SET_ARGS (pTHX_ SV* object, SV** args) {
7 13           dSP;
8              
9 13           unsigned argscount = 0;
10              
11 13 50         if (args) {
12 22 100         while (args[argscount] != NULL) argscount++;
13             }
14              
15 13           ENTER;
16 13           SAVETMPS;
17              
18 13 50         PUSHMARK(SP);
19              
20 13 50         if (object || argscount) {
    100          
21 9 50         EXTEND(SP, (object ? 1 : 0) + argscount);
    50          
    0          
22              
23 9 50         if (object) PUSHs( sv_mortalcopy(object) );
24              
25 9           unsigned a=0;
26 18 100         while (a < argscount) mPUSHs( args[a++] );
27              
28 9           PUTBACK;
29             }
30 13           }
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 12           static inline SV* _easyxs_fetch_scalar_return (pTHX_ int count) {
49 12           dSP;
50              
51 12           SPAGAIN;
52              
53             SV* ret;
54              
55 12 50         if (count == 0) {
56 0           ret = &PL_sv_undef;
57             }
58             else {
59 12           ret = SvREFCNT_inc(POPs);
60              
61 12 50         while (count-- > 1) PERL_UNUSED_VAR(POPs);
62             }
63              
64 12           PUTBACK;
65 12 50         FREETMPS;
66 12           LEAVE;
67              
68 12           return ret;
69             }
70              
71             static inline SV** _easyxs_fetch_list_return (pTHX_ int count) {
72             dSP;
73              
74             SPAGAIN;
75              
76             SV** ret;
77              
78             Newx(ret, 1 + count, SV*);
79             ret[count] = NULL;
80              
81             while (count-- > 0) {
82             ret[count] = SvREFCNT_inc(POPs);
83             }
84              
85             PUTBACK;
86             FREETMPS;
87             LEAVE;
88              
89             SAVEFREEPV(ret);
90              
91             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, err_p) STMT_START { \
128             dSP; \
129             SV* err_tmp = ERRSV; \
130             if (SvTRUE(err_tmp)) { \
131             while (count--) PERL_UNUSED_VAR(POPs); \
132             \
133             *err_p = err_tmp; \
134             \
135             PUTBACK; \
136             FREETMPS; \
137             LEAVE; \
138             } \
139             } STMT_END
140              
141             static inline void _easyxs_call_sv_void_trapped (pTHX_ SV* cb, SV** args, SV** error) {
142             _EASYXS_SET_ARGS(aTHX_ NULL, args);
143              
144             int count = call_sv(cb, G_VOID | G_EVAL);
145              
146             _handle_trapped_error(count, error);
147             }
148              
149             #define exs_call_sv_void_trapped(sv, args, err_p) \
150             _easyxs_call_sv_void_trapped(aTHX_ sv, args, err_p)
151              
152 13           static inline SV* _easyxs_call_sv_scalar_trapped (pTHX_ SV* cb, SV** args, SV** error) {
153 13           _EASYXS_SET_ARGS(aTHX_ NULL, args);
154              
155 13           int count = call_sv(cb, G_SCALAR | G_EVAL);
156              
157 14 50         _handle_trapped_error(count, error);
    50          
    50          
    50          
    0          
    0          
    100          
    50          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    100          
    100          
    50          
158              
159 13 50         if (SvTRUE(ERRSV)) return NULL;
    50          
    50          
    50          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    50          
    100          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    100          
160              
161 12           return _easyxs_fetch_scalar_return(aTHX_ count);
162             }
163              
164             #define exs_call_sv_scalar_trapped(sv, args, err_p) \
165             _easyxs_call_sv_scalar_trapped(aTHX_ sv, args, err_p)
166              
167             static inline SV** _easyxs_call_sv_list_trapped (pTHX_ SV* cb, SV** args, SV** error) {
168             _EASYXS_SET_ARGS(aTHX_ NULL, args);
169              
170             int count = call_sv(cb, G_ARRAY | G_EVAL);
171              
172             _handle_trapped_error(count, error);
173              
174             if (SvTRUE(ERRSV)) return NULL;
175              
176             return _easyxs_fetch_list_return(aTHX_ count);
177             }
178              
179             #define exs_call_sv_list_trapped(sv, args, err_p) \
180             _easyxs_call_sv_list_trapped(aTHX_ sv, args, err_p)
181              
182             #endif