File Coverage

Parser.xs
Criterion Covered Total %
statement 41 98 41.8
branch 35 142 24.6
condition n/a
subroutine n/a
pod n/a
total 76 240 31.6


line stmt bran cond sub pod time code
1             #define __PARSER_XS__
2              
3             /* This has a too cosy relationship with the core, of necessity. Define this
4             * so that the functions it needs are available, while they can still be
5             * restricted from normal XS modules (as long as they don't cheat) */
6             #define PERL_EXT
7              
8             #define PERL_NO_GET_CONTEXT
9             #include "EXTERN.h"
10             #include "perl.h"
11             #include "XSUB.h"
12              
13             #define NEED_PL_parser_GLOBAL
14             #include "ppport.h"
15              
16             #include "hook_parser.h"
17              
18             /* Before perl core changed to give us access to these functions, we used a
19             * stolen (and outdated for many releases) copy */
20             #if ! defined(scan_word) || ! defined(scan_str) || ! defined(skipspace_flags)
21             # include "stolen_chunk_of_toke.c"
22             #endif
23              
24             #define NOT_PARSING (!PL_parser || !PL_bufptr)
25              
26             #if PERL_REVISION == 5 && PERL_VERSION >= 10
27             #define HAS_HINTS_HASH
28             #endif
29              
30             char *
31 0           hook_parser_get_linestr (pTHX) {
32 0 0         if (NOT_PARSING) {
    0          
    0          
33 0           return NULL;
34             }
35              
36 0 0         return SvPVX (PL_linestr);
37             }
38              
39             IV
40 3           hook_parser_get_linestr_offset (pTHX) {
41             char *linestr;
42              
43 3 100         if (NOT_PARSING) {
    50          
    50          
44 1           return -1;
45             }
46              
47 2 50         linestr = SvPVX (PL_linestr);
48 2 50         return PL_bufptr - linestr;
49             }
50              
51             void
52 0           hook_parser_set_linestr (pTHX_ const char *new_value) {
53             STRLEN new_len;
54              
55 0 0         if (NOT_PARSING) {
    0          
    0          
56 0           croak ("trying to alter PL_linestr at runtime");
57             }
58              
59 0           new_len = strlen (new_value);
60              
61 0 0         if (SvLEN (PL_linestr) < new_len+1) {
    0          
62 0           croak ("forced to realloc PL_linestr for line %s,"
63 0 0         " bailing out before we crash harder", SvPVX (PL_linestr));
64             }
65              
66 0 0         Copy (new_value, SvPVX (PL_linestr), new_len + 1, char);
67              
68 0 0         SvCUR_set (PL_linestr, new_len);
69 0 0         PL_bufend = SvPVX(PL_linestr) + new_len;
    0          
70 0           }
71              
72             STATIC I32
73 40           grow_linestr (pTHX_ int idx, SV *sv, int maxlen) {
74 40           const I32 count = FILTER_READ (idx + 1, sv, maxlen);
75 40 50         SvGROW (sv, 8192);
    100          
76 40           return count;
77             }
78              
79             STATIC OP *
80 2           grow_eval_sv (pTHX) {
81 2           dSP;
82             SV *sv, **stack;
83              
84             #ifdef HAS_HINTS_HASH
85 2 50         if (PL_op->op_private & OPpEVAL_HAS_HH) {
86 0           stack = &SP[-1];
87             }
88             else {
89 2           stack = &SP[0];
90             }
91             #else
92             stack = &SP[0];
93             #endif
94              
95 2           sv = *stack;
96              
97 2 50         if (SvPOK (sv)) {
98 2 50         if (SvREADONLY (sv)) {
99 0           sv = sv_2mortal (newSVsv (sv));
100             }
101              
102 2 50         if (!SvLEN (sv) || SvPVX (sv)[SvLEN (sv) - 1] != ';') {
    50          
103 2 50         if (!SvTEMP (sv)) {
104 2           sv = sv_2mortal (newSVsv (sv));
105             }
106              
107 2           sv_catpvs (sv, "\n;");
108             }
109              
110 2 50         SvGROW (sv, 8192);
    50          
111             }
112              
113 2           *stack = sv;
114 2           return PL_ppaddr[OP_ENTEREVAL](aTHX);
115             }
116              
117             STATIC OP *
118 9           check_eval (pTHX_ OP *op, void *user_data) {
119             PERL_UNUSED_VAR(user_data);
120 9 100         if (op->op_ppaddr == PL_ppaddr[OP_ENTEREVAL]) {
121 3           op->op_ppaddr = grow_eval_sv;
122             }
123              
124 9           return op;
125             }
126              
127             hook_op_check_id
128 3           hook_parser_setup (pTHX) {
129 3           filter_add (grow_linestr, NULL);
130 3           return hook_op_check (OP_ENTEREVAL, check_eval, NULL);
131             }
132              
133             void
134 0           hook_parser_teardown (hook_op_check_id id) {
135 0           hook_op_check_remove (OP_ENTEREVAL, id);
136 0           }
137              
138             char *
139 0           hook_parser_get_lex_stuff (pTHX) {
140 0 0         if (NOT_PARSING || !PL_lex_stuff) {
    0          
    0          
    0          
    0          
141 0           return NULL;
142             }
143              
144 0 0         return SvPVX (PL_lex_stuff);
145             }
146              
147             void
148 0           hook_parser_clear_lex_stuff (pTHX) {
149 0 0         if (NOT_PARSING) {
    0          
    0          
150 0           return;
151             }
152              
153 0 0         PL_lex_stuff = (SV *)NULL;
154             }
155              
156             char *
157 0           hook_toke_move_past_token (pTHX_ char *s) {
158             STRLEN tokenbuf_len;
159              
160 0 0         while (s < PL_bufend && isSPACE (*s)) {
    0          
    0          
161 0           s++;
162             }
163              
164 0 0         tokenbuf_len = strlen (PL_tokenbuf);
165 0 0         if (memEQ (s, PL_tokenbuf, tokenbuf_len)) {
    0          
166 0           s += tokenbuf_len;
167             }
168              
169 0           return s;
170             }
171              
172             char *
173 0           hook_toke_scan_word (pTHX_ int offset, int handle_package, char *dest, STRLEN destlen, STRLEN *res_len) {
174 0 0         char *base_s = SvPVX (PL_linestr) + offset;
175 0           return scan_word (base_s, dest, destlen, handle_package, res_len);
176             }
177              
178             char *
179 0           hook_toke_skipspace (pTHX_ char *s) {
180 0           return skipspace_flags (s, 0);
181             }
182              
183             char *
184 0           hook_toke_scan_str (pTHX_ char *s) {
185 0           return scan_str (s, 0, 0, 0, NULL);
186             }
187              
188             MODULE = B::Hooks::Parser PACKAGE = B::Hooks::Parser PREFIX = hook_parser_
189              
190             PROTOTYPES: DISABLE
191              
192             UV
193             hook_parser_setup ()
194             CODE:
195 3           RETVAL = hook_parser_setup (aTHX);
196             OUTPUT:
197             RETVAL
198              
199             void
200             hook_parser_teardown (id)
201             UV id
202              
203             SV *
204             hook_parser_get_linestr ()
205             CODE:
206 6 100         if (NOT_PARSING) {
    50          
    50          
207 1           RETVAL = &PL_sv_undef;
208             } else {
209 5 50         RETVAL = newSVsv (PL_linestr);
210             }
211             OUTPUT:
212             RETVAL
213              
214             IV
215             hook_parser_get_linestr_offset ()
216             C_ARGS:
217             aTHX
218              
219             void
220             hook_parser_set_linestr (SV *new_value)
221             PREINIT:
222             char *new_chars;
223             STRLEN new_len;
224             CODE:
225 3 100         if (NOT_PARSING) {
    50          
    50          
226 1           croak ("trying to alter PL_linestr at runtime");
227             }
228 2 50         new_chars = SvPV(new_value, new_len);
229 2 50         if (SvLEN (PL_linestr) < new_len+1) {
    50          
230 0           croak ("forced to realloc PL_linestr for line %s,"
231 0 0         " bailing out before we crash harder", SvPVX (PL_linestr));
232             }
233 2 50         Copy (new_chars, SvPVX (PL_linestr), new_len + 1, char);
234 2 50         SvCUR_set (PL_linestr, new_len);
235 2 50         PL_bufend = SvPVX(PL_linestr) + new_len;
    50          
236              
237             SV *
238             hook_parser_get_lex_stuff ()
239             CODE:
240 0 0         if (NOT_PARSING || !PL_lex_stuff) {
    0          
    0          
    0          
    0          
241 0           RETVAL = &PL_sv_undef;
242             }
243 0 0         RETVAL = newSVsv (PL_lex_stuff);
244             OUTPUT:
245             RETVAL
246              
247             void
248             hook_parser_clear_lex_stuff ()
249             C_ARGS:
250             aTHX
251              
252             MODULE = B::Hooks::Parser PACKAGE = B::Hooks::Toke PREFIX = hook_toke_
253              
254             int
255             hook_toke_move_past_token (offset)
256             int offset
257             PREINIT:
258             char *base_s, *s;
259             CODE:
260 0 0         base_s = SvPVX (PL_linestr) + offset;
261 0           s = hook_toke_move_past_token (aTHX_ base_s);
262 0           RETVAL = s - base_s;
263             OUTPUT:
264             RETVAL
265              
266             void
267             hook_toke_scan_word (offset, handle_package)
268             int offset
269             int handle_package
270             PREINIT:
271             char tmpbuf[sizeof (PL_tokenbuf)];
272             STRLEN retlen;
273             PPCODE:
274 0           (void)hook_toke_scan_word (aTHX_ offset, handle_package, tmpbuf, sizeof (PL_tokenbuf), &retlen);
275              
276 0 0         EXTEND (SP, 2);
277 0           mPUSHp (tmpbuf, retlen);
278 0           mPUSHi (retlen);
279              
280             int
281             hook_toke_skipspace (offset)
282             int offset
283             PREINIT:
284             char *base_s, *s;
285             CODE:
286 0 0         base_s = SvPVX (PL_linestr) + offset;
287 0           s = hook_toke_skipspace (aTHX_ base_s);
288 0           RETVAL = s - base_s;
289             OUTPUT:
290             RETVAL