Mouse

 view release on metacpan or  search on metacpan

xs-src/MouseUtil.xs  view on Meta::CPAN

MODULE = Mouse::Util  PACKAGE = Mouse::Util

PROTOTYPES:   DISABLE
VERSIONCHECK: DISABLE

BOOT:
{
    MY_CXT_INIT;
    MY_CXT.metas = NULL;
}

void
__register_metaclass_storage(HV* metas, bool cloning)
CODE:
{
    if(cloning){
        MY_CXT_CLONE;
        MY_CXT.metas = NULL;
    }
    {
        dMY_CXT;
        if(MY_CXT.metas && ckWARN(WARN_REDEFINE)){
            Perl_warner(aTHX_ packWARN(WARN_REDEFINE), "Metaclass storage more than once");
        }
        MY_CXT.metas = metas;
        SvREFCNT_inc_simple_void_NN(metas);
    }
}

bool
is_valid_class_name(SV* sv)
CODE:
{
    SvGETMAGIC(sv);
    if(SvPOKp(sv) && SvCUR(sv) > 0){
        UV i;
        RETVAL = TRUE;
        for(i = 0; i < SvCUR(sv); i++){
            char const c = SvPVX(sv)[i];
            if(!(isALNUM(c) || c == ':')){
                RETVAL = FALSE;
                break;
            }
        }
    }
    else{
        RETVAL = SvNIOKp(sv) ? TRUE : FALSE;
    }
}
OUTPUT:
    RETVAL

bool
is_class_loaded(SV* sv)

void
get_code_info(CV* code)
PREINIT:
    GV* gv;
    HV* stash;
PPCODE:
    if((gv = CvGV(code)) && isGV(gv) && (stash = GvSTASH(gv))){
        EXTEND(SP, 2);
        mPUSHs(newSVpvn_share(HvNAME_get(stash), HvNAMELEN_get(stash), 0U));
        mPUSHs(newSVpvn_share(GvNAME_get(gv), GvNAMELEN_get(gv), 0U));
    }

SV*
get_code_package(CV* code)
PREINIT:
    HV* stash;
CODE:
    if(CvGV(code) && isGV(CvGV(code)) && (stash = GvSTASH(CvGV(code)))){
        RETVAL = newSVpvn_share(HvNAME_get(stash), HvNAMELEN_get(stash), 0U);
    }
    else{
        RETVAL = &PL_sv_no;
    }
OUTPUT:
    RETVAL

CV*
get_code_ref(SV* package, SV* name)
CODE:
{
    HV* stash;
    STRLEN name_len;
    const char* name_pv;
    GV* gv;

    must_defined(package, "a package name");
    must_defined(name,    "a subroutine name");

    stash = gv_stashsv(package, FALSE);
    if(!stash){
        XSRETURN_UNDEF;
    }

    name_pv = SvPV_const(name, name_len);
    gv = stash_fetch(stash, name_pv, name_len, FALSE);
    RETVAL = gv ? GvCVu(gv) : NULL;

    if(!RETVAL){
        XSRETURN_UNDEF;
    }
}
OUTPUT:
    RETVAL

void
generate_isa_predicate_for(SV* arg, SV* predicate_name = NULL)
ALIAS:
    generate_isa_predicate_for = 0
    generate_can_predicate_for = 1
PPCODE:
{
    const char* name_pv = NULL;
    CV* xsub;

    must_defined(arg, ix == 0 ? "a class_name" : "method names");

    if(predicate_name){
        must_defined(predicate_name, "a predicate name");
        name_pv = SvPV_nolen_const(predicate_name);
    }

    if(ix == 0){
        xsub = mouse_generate_isa_predicate_for(aTHX_ arg, name_pv);
    }
    else{
        xsub = mouse_generate_can_predicate_for(aTHX_ arg, name_pv);
    }

    if(predicate_name == NULL){ /* anonymous predicate */
        mXPUSHs( newRV_inc((SV*)xsub) );
    }
}

# This xsub will redefine &Mouse::Util::install_subroutines()
void
install_subroutines(SV* into, ...)
CODE:
{
    HV* stash;
    I32 i;

    must_defined(into, "a package name");
    stash = gv_stashsv(into, TRUE);

    if( ((items-1) % 2) != 0 ){
        croak_xs_usage(cv, "into, name => coderef [, other_name, other_coderef ...]");
    }

    for(i = 1; i < items; i += 2) {
        SV* const name = ST(i);
        SV* const code = ST(i+1);
        STRLEN len;
        const char* pv;
        GV* gv;

        must_defined(name, "a subroutine name");
        must_ref(code, "a CODE reference", SVt_PVCV);

        pv = SvPV_const(name, len);
        gv = stash_fetch(stash, pv, len, TRUE);

        mouse_install_sub(aTHX_ gv, code);
    }
}



( run in 1.340 second using v1.01-cache-2.11-cpan-5511b514fd6 )