File Coverage

lib/Devel/CallParser.xs
Criterion Covered Total %
statement 130 151 86.0
branch 68 108 62.9
condition n/a
subroutine n/a
pod n/a
total 198 259 76.4


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT 1
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "callchecker0.h"
5             #include "XSUB.h"
6              
7             #define PERL_VERSION_DECIMAL(r,v,s) (r*1000000 + v*1000 + s)
8             #define PERL_DECIMAL_VERSION \
9             PERL_VERSION_DECIMAL(PERL_REVISION,PERL_VERSION,PERL_SUBVERSION)
10             #ifndef PERL_VERSION_GE
11             # define PERL_VERSION_GE(r,v,s) \
12             (PERL_DECIMAL_VERSION >= PERL_VERSION_DECIMAL(r,v,s))
13             #endif /* !PERL_VERSION_GE */
14              
15             #ifndef op_append_elem
16             # define op_append_elem(t, f, l) THX_op_append_elem(aTHX_ t, f, l)
17             static OP *THX_op_append_elem(pTHX_ I32 type, OP *first, OP *last)
18             {
19             if(!first) return last;
20             if(!last) return first;
21             if(first->op_type != (unsigned)type ||
22             (type == OP_LIST && (first->op_flags & OPf_PARENS)))
23             return newLISTOP(type, 0, first, last);
24             if(first->op_flags & OPf_KIDS) {
25             cLISTOPx(first)->op_last->op_sibling = last;
26             } else {
27             first->op_flags |= OPf_KIDS;
28             cLISTOPx(first)->op_first = last;
29             }
30             cLISTOPx(first)->op_last = last;
31             return first;
32             }
33             #endif /* !op_append_elem */
34              
35             #ifndef qerror
36             /* Perl_qerror is exported (EXp) on all platforms but its declaration
37             * is hidden behind PERL_CORE/PERL_EXT header guards. Declare it
38             * ourselves so we can use it. */
39             EXTERN_C void Perl_qerror(pTHX_ SV *err);
40             # define qerror(m) Perl_qerror(aTHX_ m)
41             #endif /* !qerror */
42              
43             #define QPFX C8K61oRQKxigiqmUlVdk_
44             #define QPFXS STRINGIFY(QPFX)
45             #define QCONCAT0(a,b) a##b
46             #define QCONCAT1(a,b) QCONCAT0(a,b)
47             #define QPFXD(name) QCONCAT1(QPFX, name)
48              
49             #if defined(WIN32) && PERL_VERSION_GE(5,13,6)
50             # define MY_BASE_CALLCONV EXTERN_C
51             # define MY_BASE_CALLCONV_S "EXTERN_C"
52             #else /* !(WIN32 && >= 5.13.6) */
53             # define MY_BASE_CALLCONV PERL_CALLCONV
54             # define MY_BASE_CALLCONV_S "PERL_CALLCONV"
55             #endif /* !(WIN32 && >= 5.13.6) */
56              
57             #define MY_EXPORT_CALLCONV MY_BASE_CALLCONV
58              
59             #if defined(WIN32) || defined(__CYGWIN__)
60             # define MY_IMPORT_CALLCONV_S MY_BASE_CALLCONV_S" __declspec(dllimport)"
61             #else
62             # define MY_IMPORT_CALLCONV_S MY_BASE_CALLCONV_S
63             #endif
64              
65             static MGVTBL mgvtbl_parsecall;
66              
67             typedef OP *(*Perl_call_parser)(pTHX_ GV *, SV *, U32 *);
68              
69             #define CALLPARSER_PARENS 0x00000001
70             #define CALLPARSER_STATEMENT 0x00000002
71              
72             #ifdef parse_fullexpr
73             # define Q_PARSER_AVAILABLE 1
74             #endif /* parse_fullexpr */
75              
76             #if Q_PARSER_AVAILABLE
77              
78             # define Perl_parse_args_parenthesised QPFXD(pac0)
79             # define parse_args_parenthesised(fp) Perl_parse_args_parenthesised(aTHX_ fp)
80 179           MY_EXPORT_CALLCONV OP *QPFXD(pac0)(pTHX_ U32 *flags_p)
81             {
82             OP *argsop;
83 179           lex_read_space(0);
84 179 100         if(lex_peek_unichar(0) != '('/*)*/) {
85 29           qerror(mess("syntax error"));
86 29           return NULL;
87             }
88 150           lex_read_unichar(0);
89 150           argsop = parse_fullexpr(PARSE_OPTIONAL);
90 150           lex_read_space(0);
91 150 50         if(lex_peek_unichar(0) != /*(*/')') {
92 0           qerror(mess("syntax error"));
93 0           return argsop;
94             }
95 150           lex_read_unichar(0);
96 150           *flags_p |= CALLPARSER_PARENS;
97 150           return argsop;
98             }
99              
100             # define Perl_parse_args_nullary QPFXD(paz0)
101             # define parse_args_nullary(fp) Perl_parse_args_nullary(aTHX_ fp)
102 63           MY_EXPORT_CALLCONV OP *QPFXD(paz0)(pTHX_ U32 *flags_p)
103             {
104 63           lex_read_space(0);
105 63 100         if(lex_peek_unichar(0) == '('/*)*/)
106 28           return parse_args_parenthesised(flags_p);
107             return NULL;
108             }
109              
110             # define Perl_parse_args_unary QPFXD(pau0)
111             # define parse_args_unary(fp) Perl_parse_args_unary(aTHX_ fp)
112 95           MY_EXPORT_CALLCONV OP *QPFXD(pau0)(pTHX_ U32 *flags_p)
113             {
114 95           lex_read_space(0);
115 95 100         if(lex_peek_unichar(0) == '('/*)*/)
116 36           return parse_args_parenthesised(flags_p);
117 59           return parse_arithexpr(PARSE_OPTIONAL);
118             }
119              
120             # define Perl_parse_args_list QPFXD(pal0)
121             # define parse_args_list(fp) Perl_parse_args_list(aTHX_ fp)
122 79           MY_EXPORT_CALLCONV OP *QPFXD(pal0)(pTHX_ U32 *flags_p)
123             {
124 79           lex_read_space(0);
125 79 100         if(lex_peek_unichar(0) == '('/*)*/)
126 32           return parse_args_parenthesised(flags_p);
127 47           return parse_listexpr(PARSE_OPTIONAL);
128             }
129              
130             # define Perl_parse_args_block_list QPFXD(pab0)
131             # define parse_args_block_list(fp) Perl_parse_args_block_list(aTHX_ fp)
132 63           MY_EXPORT_CALLCONV OP *QPFXD(pab0)(pTHX_ U32 *flags_p)
133             {
134             OP *blkop, *argsop;
135             I32 c;
136 63           lex_read_space(0);
137 63           c = lex_peek_unichar(0);
138 63 100         if(c == '('/*)*/) return parse_args_parenthesised(flags_p);
139 35 100         if(c == '{'/*}*/) {
140 8           I32 floor = start_subparse(0, CVf_ANON);
141 8           SAVEFREESV(PL_compcv);
142 8           blkop = parse_block(0);
143 8 50         SvREFCNT_inc_simple_void((SV*)PL_compcv);
144 8           blkop = newANONATTRSUB(floor, NULL, NULL, blkop);
145             } else {
146             blkop = NULL;
147             }
148 35           argsop = parse_listexpr(PARSE_OPTIONAL);
149 32           return op_prepend_elem(OP_LIST, blkop, argsop);
150             }
151              
152             # define Perl_parse_args_proto QPFXD(pap0)
153             # define parse_args_proto(gv, sv, fp) Perl_parse_args_proto(aTHX_ gv, sv, fp)
154 80           MY_EXPORT_CALLCONV OP *QPFXD(pap0)(pTHX_ GV *namegv, SV *protosv, U32 *flags_p)
155             {
156             STRLEN proto_len;
157             char const *proto;
158             PERL_UNUSED_ARG(namegv);
159 80 100         if (SvTYPE(protosv) == SVt_PVCV ? !SvPOK(protosv) : !SvOK(protosv))
    100          
160 16           croak("panic: parse_args_proto with no proto");
161             /*
162             * There are variations between Perl versions in the syntactic
163             * interpretation of prototypes, which this code in principle
164             * needs to track. However, from the introduction of the parser
165             * API functions required by this code (5.13.8) to the date
166             * of this note (5.14.0-RC0) there have been no such changes.
167             * With luck there may be no more before this function migrates
168             * into the core.
169             */
170 64           proto = SvPV(protosv, proto_len);
171 64 100         if(!proto_len) return parse_args_nullary(flags_p);
172 72 100         while(*proto == ';') proto++;
173 56 100         if(proto[0] == '&') return parse_args_block_list(flags_p);
174 48 100         if(((proto[0] == '$' || proto[0] == '_' ||
    50          
175 8 50         proto[0] == '*' || proto[0] == '+') &&
176 48 50         !proto[1]) ||
    50          
177 0 0         (proto[0] == '\\' && proto[1] && !proto[2]))
    0          
178 40           return parse_args_unary(flags_p);
179 8 50         if(proto[0] == '\\' && proto[1] == '['/*]*/) {
    0          
180 0           proto += 2;
181 0 0         while(*proto && *proto != /*[*/']') proto++;
182 0 0         if(proto[0] == /*[*/']' && !proto[1])
    0          
183 0           return parse_args_unary(flags_p);
184             }
185 8           return parse_args_list(flags_p);
186             }
187              
188             # define Perl_parse_args_proto_or_list QPFXD(pan0)
189             # define parse_args_proto_or_list(gv, sv, fp) \
190             Perl_parse_args_proto_or_list(aTHX_ gv, sv, fp)
191 32           MY_EXPORT_CALLCONV OP *QPFXD(pan0)(pTHX_ GV *namegv, SV *protosv, U32 *flags_p)
192             {
193 32 100         if(SvTYPE(protosv) == SVt_PVCV ? SvPOK(protosv) : SvOK(protosv))
    100          
194 16           return parse_args_proto(namegv, protosv, flags_p);
195             else
196 16           return parse_args_list(flags_p);
197             }
198              
199             #endif /* Q_PARSER_AVAILABLE */
200              
201             #ifndef mg_findext
202             # define mg_findext(sv, type, vtbl) THX_mg_findext(aTHX_ sv, type, vtbl)
203             static MAGIC *THX_mg_findext(pTHX_ SV *sv, int type, MGVTBL const *vtbl)
204             {
205             MAGIC *mg;
206             if(sv)
207             for(mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic)
208             if(mg->mg_type == type && mg->mg_virtual == vtbl)
209             return mg;
210             return NULL;
211             }
212             #endif /* !mg_findext */
213              
214             #ifndef sv_unmagicext
215             # define sv_unmagicext(sv, type, vtbl) THX_sv_unmagicext(aTHX_ sv, type, vtbl)
216             static int THX_sv_unmagicext(pTHX_ SV *sv, int type, MGVTBL const *vtbl)
217             {
218             MAGIC *mg, **mgp;
219             if((vtbl && vtbl->svt_free) || type == PERL_MAGIC_regex_global)
220             /* exceeded intended usage of this reserve implementation */
221             return 0;
222             if(SvTYPE(sv) < SVt_PVMG || !SvMAGIC(sv)) return 0;
223             mgp = NULL;
224             for(mg = mgp ? *mgp : SvMAGIC(sv); mg; mg = mgp ? *mgp : SvMAGIC(sv)) {
225             if(mg->mg_type == type && mg->mg_virtual == vtbl) {
226             if(mgp)
227             *mgp = mg->mg_moremagic;
228             else
229             SvMAGIC_set(sv, mg->mg_moremagic);
230             if(mg->mg_flags & MGf_REFCOUNTED)
231             SvREFCNT_dec(mg->mg_obj);
232             Safefree(mg);
233             } else {
234             mgp = &mg->mg_moremagic;
235             }
236             }
237             SvMAGICAL_off(sv);
238             mg_magical(sv);
239             return 0;
240             }
241             #endif /* !sv_unmagicext */
242              
243 1817           MY_EXPORT_CALLCONV void QPFXD(gcp0)(pTHX_ CV *cv,
244             Perl_call_parser *psfun_p, SV **psobj_p)
245             {
246 1817           MAGIC *callmg = SvMAGICAL((SV*)cv) ?
247 1817 100         mg_findext((SV*)cv, PERL_MAGIC_ext, &mgvtbl_parsecall) : NULL;
248 415 100         if(callmg) {
249 397           *psfun_p = DPTR2FPTR(Perl_call_parser, callmg->mg_ptr);
250 397           *psobj_p = callmg->mg_obj;
251             } else {
252 1420           *psfun_p = DPTR2FPTR(Perl_call_parser, NULL);
253 1420           *psobj_p = NULL;
254             }
255 1817           }
256              
257 48           MY_EXPORT_CALLCONV void QPFXD(scp0)(pTHX_ CV *cv,
258             Perl_call_parser psfun, SV *psobj)
259             {
260 48           if(
261 48 100         (!psfun && !psobj)
262             #if Q_PARSER_AVAILABLE
263 46 100         || (psfun == Perl_parse_args_proto_or_list && psobj == (SV*)cv)
    100          
264             #endif /* Q_PARSER_AVAILABLE */
265             ) {
266 4 50         if(SvMAGICAL((SV*)cv))
267 4           sv_unmagicext((SV*)cv, PERL_MAGIC_ext,
268             &mgvtbl_parsecall);
269             } else {
270             MAGIC *callmg =
271 44           mg_findext((SV*)cv, PERL_MAGIC_ext, &mgvtbl_parsecall);
272 44 100         if(!callmg)
273 33           callmg = sv_magicext((SV*)cv, &PL_sv_undef,
274             PERL_MAGIC_ext, &mgvtbl_parsecall, NULL, 0);
275 44 50         if(callmg->mg_flags & MGf_REFCOUNTED) {
276 44           SvREFCNT_dec(callmg->mg_obj);
277 44           callmg->mg_flags &= ~MGf_REFCOUNTED;
278             }
279 44           callmg->mg_ptr = FPTR2DPTR(char *, psfun);
280 44           callmg->mg_obj = psobj;
281 44 50         if(psobj != (SV*)cv) {
282             SvREFCNT_inc(psobj);
283 44           callmg->mg_flags |= MGf_REFCOUNTED;
284             }
285             }
286 48           }
287              
288             #if Q_PARSER_AVAILABLE
289              
290 10           MY_EXPORT_CALLCONV void QPFXD(gcp1)(pTHX_ CV *cv,
291             Perl_call_parser *psfun_p, SV **psobj_p)
292             {
293 10           QPFXD(gcp0)(aTHX_ cv, psfun_p, psobj_p);
294 10 100         if(!*psfun_p && !*psobj_p) {
    50          
295 6           *psfun_p = Perl_parse_args_proto_or_list;
296 6           *psobj_p = (SV*)cv;
297             }
298 10           }
299              
300 41           MY_EXPORT_CALLCONV void QPFXD(scp1)(pTHX_ CV *cv,
301             Perl_call_parser psfun, SV *psobj)
302             {
303 41 50         if(!psobj) croak("null object for cv_set_call_parser");
304 41           QPFXD(scp0)(aTHX_ cv, psfun, psobj);
305 41           }
306              
307             #endif /* Q_PARSER_AVAILABLE */
308              
309             /*
310             * Find a CV by name, checking lexical hints first (for Lexical::Sub
311             * and similar modules), then falling back to package lookup.
312             * This is more reliable than rv2cv_op_cv() on threaded/debugging perls.
313             *
314             * Lexical::Sub (via Lexical::Var) stores CVs with the key format:
315             * "Lexical::Var/&subname"
316             */
317 50119           static CV *THX_find_lexical_cv(pTHX_ char *name, STRLEN len)
318             {
319             /* Check %^H hints hash - where Lexical::Sub stores its subs */
320 50119 100         if ((PL_hints & HINT_LOCALIZE_HH) && GvHV(PL_hintgv)) {
    50          
321             SV *keysv;
322             SV **svp;
323             /* Construct the Lexical::Var key format: "Lexical::Var/&name" */
324 927           keysv = newSVpvs("Lexical::Var/&");
325 927           sv_catpvn(keysv, name, len);
326 927           svp = hv_fetch(GvHV(PL_hintgv), SvPVX(keysv), (I32)SvCUR(keysv), 0);
327 927           SvREFCNT_dec(keysv);
328 927 50         if (svp && SvROK(*svp) && SvTYPE(SvRV(*svp)) == SVt_PVCV) {
    0          
    0          
329             return (CV*)SvRV(*svp);
330             }
331             }
332             return NULL;
333             }
334              
335             static int (*next_keyword_plugin)(pTHX_ char *, STRLEN, OP **);
336 50119           static int my_keyword_plugin(pTHX_
337             char *keyword_ptr, STRLEN keyword_len, OP **op_ptr)
338             {
339             OP *nmop, *cvop, *argsop;
340             CV *cv;
341             GV *namegv;
342             Perl_call_parser psfun;
343             SV *psobj;
344             U32 parser_flags;
345             /*
346             * First, check for lexically-scoped CVs directly in %^H.
347             * This handles Lexical::Sub and similar modules reliably
348             * across all Perl configurations (threaded, debugging, etc.).
349             */
350 50119           cv = THX_find_lexical_cv(aTHX_ keyword_ptr, keyword_len);
351 50119 50         if (cv) {
352 0           QPFXD(gcp0)(aTHX_ cv, &psfun, &psobj);
353 0 0         if (psfun || psobj) {
    0          
354             /* Found lexical CV with call parser - use it */
355 0           nmop = newSVOP(OP_CONST, 0,
356             newSVpvn(keyword_ptr, keyword_len));
357 0           nmop->op_private = OPpCONST_BARE;
358 0           cvop = newUNOP(OP_RV2CV, 0,
359             newSVOP(OP_CONST, 0, newRV_inc((SV*)cv)));
360 0           namegv = (GV*)newSVpvn(keyword_ptr, keyword_len);
361 0           parser_flags = 0;
362 0           argsop = psfun(aTHX_ namegv, psobj, &parser_flags);
363 0           SvREFCNT_dec((SV*)namegv);
364 0 0         if(!(parser_flags & CALLPARSER_PARENS))
365 0           cvop->op_private |= OPpENTERSUB_NOPAREN;
366 0           *op_ptr = newUNOP(OP_ENTERSUB, OPf_STACKED,
367             op_append_elem(OP_LIST, argsop, cvop));
368 0           return (parser_flags & CALLPARSER_STATEMENT) ?
369 0 0         KEYWORD_PLUGIN_STMT : KEYWORD_PLUGIN_EXPR;
370             }
371             }
372             /*
373             * Fall back to original op-based lookup for package subs.
374             *
375             * Creation of the rv2cv op below (or more precisely its gv op
376             * child created during checking) uses a pad slot under threads.
377             * Normally this is fine, but early versions of the padrange
378             * mechanism make assumptions about pad slots being contiguous
379             * that this breaks. On the affected perl versions, therefore,
380             * we watch for the pad slot being consumed, and restore the
381             * pad's fill pointer if we throw the op away (upon declining
382             * to handle the keyword).
383             *
384             * The core bug was supposedly fixed in Perl 5.19.4, but actually
385             * that version exhibits a different bug also apparently related
386             * to padrange. Restoring the pad's fill pointer works around
387             * this bug too. So for now this workaround is used with no
388             * upper bound on the Perl version.
389             */
390             #define MUST_RESTORE_PAD_FILL PERL_VERSION_GE(5,17,6)
391             #if MUST_RESTORE_PAD_FILL
392 50119           I32 padfill = av_len(PL_comppad);
393             #endif /* MUST_RESTORE_PAD_FILL */
394             /*
395             * If Devel::Declare happens to be loaded, it triggers magic
396             * upon building of an rv2cv op, assuming that it's being built
397             * by the lexer. Since we're about to build such an op here,
398             * replicating what the lexer will normally do shortly after,
399             * there's a risk that Devel::Declare could fire here, ultimately
400             * firing twice for a single appearance of a name it's interested
401             * in. To suppress Devel::Declare, therefore, we temporarily
402             * set PL_parser to null. The same goes for Data::Alias and
403             * some other modules that use similar techniques.
404             *
405             * Unfortunately Devel::Declare prior to 0.006004 still does some
406             * work at the wrong time if PL_parser is null, and Data::Alias
407             * prior to 1.13 crashes if PL_parser is null. So this module
408             * is not compatible with earlier versions of those modules,
409             * and can't be made compatible.
410             */
411 50119           ENTER;
412 50119           SAVEVPTR(PL_parser);
413 50119           PL_parser = NULL;
414 50119           nmop = newSVOP(OP_CONST, 0, newSVpvn(keyword_ptr, keyword_len));
415 50119           nmop->op_private = OPpCONST_BARE;
416 50119           cvop = newCVREF(0, nmop);
417 50119           LEAVE;
418 50119 100         if(!(cv = rv2cv_op_cv(cvop, 0))) {
419 48322           decline:
420 49730           op_free(cvop);
421             #if MUST_RESTORE_PAD_FILL
422 49730           av_fill(PL_comppad, padfill);
423             #endif /* MUST_RESTORE_PAD_FILL */
424 49730           return next_keyword_plugin(aTHX_
425             keyword_ptr, keyword_len, op_ptr);
426             }
427 1797           QPFXD(gcp0)(aTHX_ cv, &psfun, &psobj);
428 1797 100         if(!psfun && !psobj) goto decline;
    50          
429 389           namegv = (GV*)rv2cv_op_cv(cvop,
430             RV2CVOPCV_MARK_EARLY|RV2CVOPCV_RETURN_NAME_GV);
431 389           parser_flags = 0;
432 389           argsop = psfun(aTHX_ namegv, psobj, &parser_flags);
433 358 100         if(!(parser_flags & CALLPARSER_PARENS))
434 206           cvop->op_private |= OPpENTERSUB_NOPAREN;
435 358           *op_ptr = newUNOP(OP_ENTERSUB, OPf_STACKED,
436             op_append_elem(OP_LIST, argsop, cvop));
437 358           return (parser_flags & CALLPARSER_STATEMENT) ?
438 358 100         KEYWORD_PLUGIN_STMT : KEYWORD_PLUGIN_EXPR;
439             }
440              
441             #define fmt_header(n, content) THX_fmt_header(aTHX_ n, content)
442 6           static SV *THX_fmt_header(pTHX_ char n, char const *content)
443             {
444 6           return newSVpvf(
445             "/* DO NOT EDIT -- generated "
446             "by Devel::CallParser version "XS_VERSION" */\n"
447             "#ifndef "QPFXS"INCLUDED_callparser%c\n"
448             "#define "QPFXS"INCLUDED_callparser%c 1\n"
449             "#ifndef PERL_VERSION\n"
450             " #error you must include perl.h before callparser%c.h\n"
451             "#elif !(PERL_REVISION == "STRINGIFY(PERL_REVISION)
452             " && PERL_VERSION == "STRINGIFY(PERL_VERSION)
453             #if PERL_VERSION & 1
454             " && PERL_SUBVERSION == "STRINGIFY(PERL_SUBVERSION)
455             #endif /* PERL_VERSION & 1 */
456             ")\n"
457             " #error this callparser%c.h is for Perl "
458             STRINGIFY(PERL_REVISION)"."STRINGIFY(PERL_VERSION)
459             #if PERL_VERSION & 1
460             "."STRINGIFY(PERL_SUBVERSION)
461             #endif /* PERL_VERSION & 1 */
462             " only\n"
463             "#endif /* Perl version mismatch */\n"
464             "%s"
465             "#endif /* !"QPFXS"INCLUDED_callparser%c */\n",
466             n, n, n, n, content, n);
467             }
468              
469             #define DEFFN(RETTYPE, PUBNAME, PRIVNAME, ARGTYPES, ARGNAMES) \
470             MY_IMPORT_CALLCONV_S" "RETTYPE" "QPFXS PRIVNAME"(pTHX_ "ARGTYPES");\n" \
471             "#define Perl_"PUBNAME" "QPFXS PRIVNAME"\n" \
472             "#define "PUBNAME"("ARGNAMES") Perl_"PUBNAME"(aTHX_ "ARGNAMES")\n"
473              
474             #define DEFCALLBACK \
475             "typedef OP *(*Perl_call_parser)(pTHX_ GV *, SV *, U32 *);\n" \
476             "#define CALLPARSER_PARENS 0x00000001\n" \
477             "#define CALLPARSER_STATEMENT 0x00000002\n"
478              
479             MODULE = Devel::CallParser PACKAGE = Devel::CallParser
480              
481             PROTOTYPES: DISABLE
482              
483             BOOT:
484 10           next_keyword_plugin = PL_keyword_plugin;
485 10           PL_keyword_plugin = my_keyword_plugin;
486              
487             SV *
488             callparser0_h()
489             CODE:
490 3           RETVAL = fmt_header('0',
491             DEFCALLBACK
492             DEFFN("void", "cv_get_call_parser", "gcp0",
493             "CV *, Perl_call_parser *, SV **", "cv, fp, op")
494             DEFFN("void", "cv_set_call_parser", "scp0",
495             "CV *, Perl_call_parser, SV *", "cv, f, o")
496             );
497             OUTPUT:
498             RETVAL
499              
500             SV *
501             callparser1_h()
502             CODE:
503             #if Q_PARSER_AVAILABLE
504 3           RETVAL = fmt_header('1',
505             DEFFN("OP *", "parse_args_parenthesised", "pac0", "U32 *", "fp")
506             DEFFN("OP *", "parse_args_nullary", "paz0", "U32 *", "fp")
507             DEFFN("OP *", "parse_args_unary", "pau0", "U32 *", "fp")
508             DEFFN("OP *", "parse_args_list", "pal0", "U32 *", "fp")
509             DEFFN("OP *", "parse_args_block_list", "pab0", "U32 *", "fp")
510             DEFFN("OP *", "parse_args_proto", "pap0",
511             "GV *, SV *, U32 *", "gv, sv, fp")
512             DEFFN("OP *", "parse_args_proto_or_list", "pan0",
513             "GV *, SV *, U32 *", "gv, sv, fp")
514             DEFCALLBACK
515             DEFFN("void", "cv_get_call_parser", "gcp1",
516             "CV *, Perl_call_parser *, SV **", "cv, fp, op")
517             DEFFN("void", "cv_set_call_parser", "scp1",
518             "CV *, Perl_call_parser, SV *", "cv, f, o")
519             );
520             #else /* !Q_PARSER_AVAILABLE */
521             croak("callparser1.h not available on this version of Perl");
522             #endif /* !Q_PARSER_AVAILABLE */
523             OUTPUT:
524             RETVAL