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 )