Alias

 view release on metacpan or  search on metacpan

Alias.xs  view on Meta::CPAN

}
#endif

#ifndef PERL_VERSION
#include "patchlevel.h"
#define PERL_REVISION         5
#define PERL_VERSION          PATCHLEVEL
#define PERL_SUBVERSION       SUBVERSION
#endif

#if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75 ))

#define PL_stack_sp	stack_sp

#endif

static void process_flag _((char *varname, SV **svp, char **strp, STRLEN *lenp));

static void
process_flag(varname, svp, strp, lenp)
    char *varname;
    SV **svp;
    char **strp;
    STRLEN *lenp;
{
    GV *vargv = gv_fetchpv(varname, FALSE, SVt_PV);
    SV *sv = Nullsv;
    char *str = Nullch;
    STRLEN len = 0;

    if (vargv && (sv = GvSV(vargv))) {
	if (SvROK(sv)) {
	    if (SvTYPE(SvRV(sv)) != SVt_PVCV)
		croak("$%s not a subroutine reference", varname);
	}
	else if (SvOK(sv))
	    str = SvPV(sv, len);
    }
    *svp = sv;
    *strp = str;
    *lenp = len;
}
		

MODULE = Alias		PACKAGE = Alias		PREFIX = alias_

PROTOTYPES: ENABLE

BOOT:
{
    GV *gv = gv_fetchpv("Alias::attr", FALSE, SVt_PVCV);
    if (gv && GvCV(gv))
	CvNODEBUG_on(GvCV(gv));
}


void
alias_attr(hashref)
	SV *	hashref
	PROTOTYPE: $
     PPCODE:
	{
	    HV *hv;
	    int in_destroy = 0;
	    int deref_call;
	    
	    if (SvREFCNT(hashref) == 0)
		in_destroy = 1;
	    
	    ++SvREFCNT(hashref);	/* in case LEAVE wants to clobber us */

	    if (SvROK(hashref) &&
		(hv = (HV *)SvRV(hashref)) && (SvTYPE(hv) == SVt_PVHV))
	    {
		SV *val, *tmpsv;
		char *key;
		I32 klen;
		SV *keypfx, *attrpfx, *deref;
		char *keypfx_c, *attrpfx_c, *deref_c;
		STRLEN keypfx_l, attrpfx_l, deref_l;

		process_flag("Alias::KeyFilter", &keypfx, &keypfx_c, &keypfx_l);
		process_flag("Alias::AttrPrefix", &attrpfx, &attrpfx_c, &attrpfx_l);
		process_flag("Alias::Deref", &deref, &deref_c, &deref_l);
		deref_call = (deref && !deref_c);
		
		LEAVE;                      /* operate at a higher level */
		
		(void)hv_iterinit(hv);
		while ((val = hv_iternextsv(hv, &key, &klen))) {
		    GV *gv;
		    int stype = SvTYPE(val);
		    int deref_this = 1;
		    int deref_objects = 0;

		    /* check the key for validity by either looking at
		     * its prefix, or by calling &$Alias::KeyFilter */
		    if (keypfx) {
			if (keypfx_c) {
			    if (keypfx_l && klen > keypfx_l
				&& strncmp(key, keypfx_c, keypfx_l))
				continue;
			}
			else {
			    dSP;
			    SV *ret = Nullsv;
			    I32 i;
			    
			    ENTER; SAVETMPS; PUSHMARK(sp);
			    XPUSHs(sv_2mortal(newSVpv(key,klen)));
			    PUTBACK;
			    if (perl_call_sv(keypfx, G_SCALAR))
				ret = *PL_stack_sp--;
			    SPAGAIN;
			    i = SvTRUE(ret);
			    FREETMPS; LEAVE;
			    if (!i)
				continue;
			}
		    }



( run in 1.935 second using v1.01-cache-2.11-cpan-71847e10f99 )