XS-Parse-Sublike
view release on metacpan or search on metacpan
lib/XS/Parse/Sublike.xs view on Meta::CPAN
static const struct Registration *find_permitted(pTHX_ const char *kw, STRLEN kwlen)
{
const struct Registration *reg;
HV *hints = GvHV(PL_hintgv);
for(reg = registrations; reg; reg = reg->next) {
if(reg->kwlen != kwlen || !strnEQ(reg->kw, kw, kwlen))
continue;
if(reg->hooks->permit_hintkey &&
(!hints || !hv_fetch(hints, reg->hooks->permit_hintkey, reg->permit_hintkey_len, 0)))
continue;
if(reg->hooks->permit &&
!(*reg->hooks->permit)(aTHX_ reg->hookdata))
continue;
return reg;
}
return NULL;
}
static int IMPL_xs_parse_sublike_any_v6(pTHX_ const struct XSParseSublikeHooks *hooksA, void *hookdataA, OP **op_ptr)
{
SV *kwsv = lex_scan_ident();
if(!kwsv || !SvCUR(kwsv))
croak("Expected a keyword to introduce a sub or sub-like construction");
const char *kw = SvPV_nolen(kwsv);
STRLEN kwlen = SvCUR(kwsv);
lex_read_space(0);
const struct Registration *reg = NULL;
/* We permit 'sub' as a NULL set of hooks; anything else should be a registered keyword */
if(kwlen != 3 || !strEQ(kw, "sub")) {
reg = find_permitted(aTHX_ kw, kwlen);
if(!reg)
croak("Expected a keyword to introduce a sub or sub-like construction, found " QUOTED_PVNf,
QUOTED_PVNfARG(kw, kwlen));
}
SvREFCNT_dec(kwsv);
struct HooksAndData hd[] = {
{ .hooks = hooksA, .data = hookdataA },
{ 0 }
};
if(reg) {
hd[1].hooks = reg->hooks;
hd[1].data = reg->hookdata;
}
return parse(aTHX_ hd, 1 + !!reg, op_ptr);
}
static void IMPL_register_xps_signature_attribute(pTHX_ const char *name, const struct XPSSignatureAttributeFuncs *funcs, void *funcdata)
{
if(funcs->ver < 5)
croak("Mismatch in signature param attribute ABI version field: module wants %u; we require >= 5\n",
funcs->ver);
if(funcs->ver > XSPARSESUBLIKE_ABI_VERSION)
croak("Mismatch in signature param attribute ABI version field: module wants %u; we support <= %d\n",
funcs->ver, XSPARSESUBLIKE_ABI_VERSION);
if(!name || !(name[0] >= 'A' && name[0] <= 'Z'))
croak("Signature param attribute names must begin with a capital letter");
if(!funcs->permit_hintkey)
croak("Signature param attributes require a permit hinthash key");
register_subsignature_attribute(name, funcs, funcdata);
}
#ifdef HAVE_FEATURE_CLASS
static bool permit_core_method(pTHX_ void *hookdata)
{
return FEATURE_CLASS_IS_ENABLED;
}
static void pre_subparse_core_method(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata)
{
ctx->actions |= XS_PARSE_SUBLIKE_ACTION_CVf_IsMETHOD;
}
static const struct XSParseSublikeHooks hooks_core_method = {
.ver = XSPARSESUBLIKE_ABI_VERSION,
.permit = &permit_core_method,
.pre_subparse = &pre_subparse_core_method,
.require_parts = XS_PARSE_SUBLIKE_PART_SIGNATURE, /* enable signatures feature */
};
#endif
#ifdef HAVE_LEXICAL_SUB
static void pre_subparse_lexical_sub(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata)
{
ctx->actions &= ~XS_PARSE_SUBLIKE_ACTION_INSTALL_SYMBOL;
ctx->actions |= XS_PARSE_SUBLIKE_ACTION_INSTALL_LEXICAL;
}
static const struct XSParseSublikeHooks hooks_lexical_sub = {
.ver = XSPARSESUBLIKE_ABI_VERSION,
/* no permit needed */
.pre_subparse = &pre_subparse_lexical_sub,
};
#endif
/* Sublike::Extended */
static struct XSParseSublikeHooks hooks_extended = {
.ver = XSPARSESUBLIKE_ABI_VERSION,
.permit_hintkey = "Sublike::Extended/extended",
.flags = XS_PARSE_SUBLIKE_FLAG_PREFIX|
XS_PARSE_SUBLIKE_FLAG_BODY_OPTIONAL|
XS_PARSE_SUBLIKE_FLAG_SIGNATURE_NAMED_PARAMS|
XS_PARSE_SUBLIKE_FLAG_SIGNATURE_PARAM_ATTRIBUTES|
XS_PARSE_SUBLIKE_FLAG_SIGNATURE_REFALIAS,
/* No hooks */
};
static struct XSParseSublikeHooks hooks_extended_sub = {
.ver = XSPARSESUBLIKE_ABI_VERSION,
.permit_hintkey = "Sublike::Extended/extended-sub",
.flags = XS_PARSE_SUBLIKE_FLAG_BODY_OPTIONAL|
XS_PARSE_SUBLIKE_FLAG_SIGNATURE_NAMED_PARAMS|
XS_PARSE_SUBLIKE_FLAG_SIGNATURE_PARAM_ATTRIBUTES|
XS_PARSE_SUBLIKE_FLAG_SIGNATURE_REFALIAS,
/* No hooks */
};
( run in 1.327 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )