Alt-Devel-CallParser-ButWorking
view release on metacpan or search on metacpan
lib/Devel/CallParser.xs view on Meta::CPAN
if (SvTYPE(protosv) == SVt_PVCV ? !SvPOK(protosv) : !SvOK(protosv))
croak("panic: parse_args_proto with no proto");
/*
* There are variations between Perl versions in the syntactic
* interpretation of prototypes, which this code in principle
* needs to track. However, from the introduction of the parser
* API functions required by this code (5.13.8) to the date
* of this note (5.14.0-RC0) there have been no such changes.
* With luck there may be no more before this function migrates
* into the core.
*/
proto = SvPV(protosv, proto_len);
if(!proto_len) return parse_args_nullary(flags_p);
while(*proto == ';') proto++;
if(proto[0] == '&') return parse_args_block_list(flags_p);
if(((proto[0] == '$' || proto[0] == '_' ||
proto[0] == '*' || proto[0] == '+') &&
!proto[1]) ||
(proto[0] == '\\' && proto[1] && !proto[2]))
return parse_args_unary(flags_p);
if(proto[0] == '\\' && proto[1] == '['/*]*/) {
proto += 2;
while(*proto && *proto != /*[*/']') proto++;
if(proto[0] == /*[*/']' && !proto[1])
return parse_args_unary(flags_p);
}
return parse_args_list(flags_p);
}
# define Perl_parse_args_proto_or_list QPFXD(pan0)
# define parse_args_proto_or_list(gv, sv, fp) \
Perl_parse_args_proto_or_list(aTHX_ gv, sv, fp)
MY_EXPORT_CALLCONV OP *QPFXD(pan0)(pTHX_ GV *namegv, SV *protosv, U32 *flags_p)
{
if(SvTYPE(protosv) == SVt_PVCV ? SvPOK(protosv) : SvOK(protosv))
return parse_args_proto(namegv, protosv, flags_p);
else
return parse_args_list(flags_p);
}
#endif /* Q_PARSER_AVAILABLE */
#ifndef mg_findext
# define mg_findext(sv, type, vtbl) THX_mg_findext(aTHX_ sv, type, vtbl)
static MAGIC *THX_mg_findext(pTHX_ SV *sv, int type, MGVTBL const *vtbl)
{
MAGIC *mg;
if(sv)
for(mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic)
if(mg->mg_type == type && mg->mg_virtual == vtbl)
return mg;
return NULL;
}
#endif /* !mg_findext */
#ifndef sv_unmagicext
# define sv_unmagicext(sv, type, vtbl) THX_sv_unmagicext(aTHX_ sv, type, vtbl)
static int THX_sv_unmagicext(pTHX_ SV *sv, int type, MGVTBL const *vtbl)
{
MAGIC *mg, **mgp;
if((vtbl && vtbl->svt_free) || type == PERL_MAGIC_regex_global)
/* exceeded intended usage of this reserve implementation */
return 0;
if(SvTYPE(sv) < SVt_PVMG || !SvMAGIC(sv)) return 0;
mgp = NULL;
for(mg = mgp ? *mgp : SvMAGIC(sv); mg; mg = mgp ? *mgp : SvMAGIC(sv)) {
if(mg->mg_type == type && mg->mg_virtual == vtbl) {
if(mgp)
*mgp = mg->mg_moremagic;
else
SvMAGIC_set(sv, mg->mg_moremagic);
if(mg->mg_flags & MGf_REFCOUNTED)
SvREFCNT_dec(mg->mg_obj);
Safefree(mg);
} else {
mgp = &mg->mg_moremagic;
}
}
SvMAGICAL_off(sv);
mg_magical(sv);
return 0;
}
#endif /* !sv_unmagicext */
MY_EXPORT_CALLCONV void QPFXD(gcp0)(pTHX_ CV *cv,
Perl_call_parser *psfun_p, SV **psobj_p)
{
MAGIC *callmg = SvMAGICAL((SV*)cv) ?
mg_findext((SV*)cv, PERL_MAGIC_ext, &mgvtbl_parsecall) : NULL;
if(callmg) {
*psfun_p = DPTR2FPTR(Perl_call_parser, callmg->mg_ptr);
*psobj_p = callmg->mg_obj;
} else {
*psfun_p = DPTR2FPTR(Perl_call_parser, NULL);
*psobj_p = NULL;
}
}
MY_EXPORT_CALLCONV void QPFXD(scp0)(pTHX_ CV *cv,
Perl_call_parser psfun, SV *psobj)
{
if(
(!psfun && !psobj)
#if Q_PARSER_AVAILABLE
|| (psfun == Perl_parse_args_proto_or_list && psobj == (SV*)cv)
#endif /* Q_PARSER_AVAILABLE */
) {
if(SvMAGICAL((SV*)cv))
sv_unmagicext((SV*)cv, PERL_MAGIC_ext,
&mgvtbl_parsecall);
} else {
MAGIC *callmg =
mg_findext((SV*)cv, PERL_MAGIC_ext, &mgvtbl_parsecall);
if(!callmg)
callmg = sv_magicext((SV*)cv, &PL_sv_undef,
PERL_MAGIC_ext, &mgvtbl_parsecall, NULL, 0);
if(callmg->mg_flags & MGf_REFCOUNTED) {
SvREFCNT_dec(callmg->mg_obj);
callmg->mg_flags &= ~MGf_REFCOUNTED;
}
callmg->mg_ptr = FPTR2DPTR(char *, psfun);
( run in 1.242 second using v1.01-cache-2.11-cpan-39bf76dae61 )