diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2000-04-06 16:11:09 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2000-04-06 16:11:09 +0000 |
commit | e852ed17d905386f3bbad057fda2f07926227f89 (patch) | |
tree | 9c602984a369e27373c3cd3b71bd8c8e791393f2 /gnu/usr.bin/perl/xsutils.c | |
parent | 9cfdf10e50d1f9e72606c75c7b7a0e18940c80aa (diff) |
virgin perl 5.6.0
Diffstat (limited to 'gnu/usr.bin/perl/xsutils.c')
-rw-r--r-- | gnu/usr.bin/perl/xsutils.c | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/gnu/usr.bin/perl/xsutils.c b/gnu/usr.bin/perl/xsutils.c new file mode 100644 index 00000000000..0f5989b3dd5 --- /dev/null +++ b/gnu/usr.bin/perl/xsutils.c @@ -0,0 +1,290 @@ +#include "EXTERN.h" +#define PERL_IN_XSUTILS_C +#include "perl.h" + +/* + * Contributed by Spider Boardman (spider.boardman@orb.nashua.nh.us). + */ + +/* package attributes; */ +void XS_attributes__warn_reserved(pTHXo_ CV *cv); +void XS_attributes_reftype(pTHXo_ CV *cv); +void XS_attributes__modify_attrs(pTHXo_ CV *cv); +void XS_attributes__guess_stash(pTHXo_ CV *cv); +void XS_attributes__fetch_attrs(pTHXo_ CV *cv); +void XS_attributes_bootstrap(pTHXo_ CV *cv); + + +/* + * Note that only ${pkg}::bootstrap definitions should go here. + * This helps keep down the start-up time, which is especially + * relevant for users who don't invoke any features which are + * (partially) implemented here. + * + * The various bootstrap definitions can take care of doing + * package-specific newXS() calls. Since the layout of the + * bundled *.pm files is in a version-specific directory, + * version checks in these bootstrap calls are optional. + */ + +void +Perl_boot_core_xsutils(pTHX) +{ + char *file = __FILE__; + + newXS("attributes::bootstrap", XS_attributes_bootstrap, file); +} + +#include "XSUB.h" + +static int +modify_SV_attributes(pTHXo_ SV *sv, SV **retlist, SV **attrlist, int numattrs) +{ + SV *attr; + char *name; + STRLEN len; + bool negated; + int nret; + + for (nret = 0 ; numattrs && (attr = *attrlist++); numattrs--) { + name = SvPV(attr, len); + if ((negated = (*name == '-'))) { + name++; + len--; + } + switch (SvTYPE(sv)) { + case SVt_PVCV: + switch ((int)len) { + case 6: + switch (*name) { + case 'l': +#ifdef CVf_LVALUE + if (strEQ(name, "lvalue")) { + if (negated) + CvFLAGS((CV*)sv) &= ~CVf_LVALUE; + else + CvFLAGS((CV*)sv) |= CVf_LVALUE; + continue; + } +#endif /* defined CVf_LVALUE */ + if (strEQ(name, "locked")) { + if (negated) + CvFLAGS((CV*)sv) &= ~CVf_LOCKED; + else + CvFLAGS((CV*)sv) |= CVf_LOCKED; + continue; + } + break; + case 'm': + if (strEQ(name, "method")) { + if (negated) + CvFLAGS((CV*)sv) &= ~CVf_METHOD; + else + CvFLAGS((CV*)sv) |= CVf_METHOD; + continue; + } + break; + } + break; + } + break; + default: + /* nothing, yet */ + break; + } + /* anything recognized had a 'continue' above */ + *retlist++ = attr; + nret++; + } + + return nret; +} + + + +/* package attributes; */ + +XS(XS_attributes_bootstrap) +{ + dXSARGS; + char *file = __FILE__; + + newXSproto("attributes::_warn_reserved", XS_attributes__warn_reserved, file, ""); + newXS("attributes::_modify_attrs", XS_attributes__modify_attrs, file); + newXSproto("attributes::_guess_stash", XS_attributes__guess_stash, file, "$"); + newXSproto("attributes::_fetch_attrs", XS_attributes__fetch_attrs, file, "$"); + newXSproto("attributes::reftype", XS_attributes_reftype, file, "$"); + + XSRETURN(0); +} + +XS(XS_attributes__modify_attrs) +{ + dXSARGS; + SV *rv, *sv; + + if (items < 1) { +usage: + Perl_croak(aTHX_ + "Usage: attributes::_modify_attrs $reference, @attributes"); + } + + rv = ST(0); + if (!(SvOK(rv) && SvROK(rv))) + goto usage; + sv = SvRV(rv); + if (items > 1) + XSRETURN(modify_SV_attributes(aTHXo_ sv, &ST(0), &ST(1), items-1)); + + XSRETURN(0); +} + +XS(XS_attributes__fetch_attrs) +{ + dXSARGS; + SV *rv, *sv; + cv_flags_t cvflags; + + if (items != 1) { +usage: + Perl_croak(aTHX_ + "Usage: attributes::_fetch_attrs $reference"); + } + + rv = ST(0); + SP -= items; + if (!(SvOK(rv) && SvROK(rv))) + goto usage; + sv = SvRV(rv); + + switch (SvTYPE(sv)) { + case SVt_PVCV: + cvflags = CvFLAGS((CV*)sv); + if (cvflags & CVf_LOCKED) + XPUSHs(sv_2mortal(newSVpvn("locked", 6))); +#ifdef CVf_LVALUE + if (cvflags & CVf_LVALUE) + XPUSHs(sv_2mortal(newSVpvn("lvalue", 6))); +#endif + if (cvflags & CVf_METHOD) + XPUSHs(sv_2mortal(newSVpvn("method", 6))); + break; + default: + break; + } + + PUTBACK; +} + +XS(XS_attributes__guess_stash) +{ + dXSARGS; + SV *rv, *sv; +#ifdef dXSTARGET + dXSTARGET; +#else + SV * TARG = sv_newmortal(); +#endif + + if (items != 1) { +usage: + Perl_croak(aTHX_ + "Usage: attributes::_guess_stash $reference"); + } + + rv = ST(0); + ST(0) = TARG; + if (!(SvOK(rv) && SvROK(rv))) + goto usage; + sv = SvRV(rv); + + if (SvOBJECT(sv)) + sv_setpv(TARG, HvNAME(SvSTASH(sv))); +#if 0 /* this was probably a bad idea */ + else if (SvPADMY(sv)) + sv_setsv(TARG, &PL_sv_no); /* unblessed lexical */ +#endif + else { + HV *stash = Nullhv; + switch (SvTYPE(sv)) { + case SVt_PVCV: + if (CvGV(sv) && isGV(CvGV(sv)) && GvSTASH(CvGV(sv)) && + HvNAME(GvSTASH(CvGV(sv)))) + stash = GvSTASH(CvGV(sv)); + else if (/* !CvANON(sv) && */ CvSTASH(sv) && HvNAME(CvSTASH(sv))) + stash = CvSTASH(sv); + break; + case SVt_PVMG: + if (!(SvFAKE(sv) && SvTIED_mg(sv, '*'))) + break; + /*FALLTHROUGH*/ + case SVt_PVGV: + if (GvGP(sv) && GvESTASH((GV*)sv) && HvNAME(GvESTASH((GV*)sv))) + stash = GvESTASH((GV*)sv); + break; + default: + break; + } + if (stash) + sv_setpv(TARG, HvNAME(stash)); + } + +#ifdef dXSTARGET + SvSETMAGIC(TARG); +#endif + XSRETURN(1); +} + +XS(XS_attributes_reftype) +{ + dXSARGS; + SV *rv, *sv; +#ifdef dXSTARGET + dXSTARGET; +#else + SV * TARG = sv_newmortal(); +#endif + + if (items != 1) { +usage: + Perl_croak(aTHX_ + "Usage: attributes::reftype $reference"); + } + + rv = ST(0); + ST(0) = TARG; + if (!(SvOK(rv) && SvROK(rv))) + goto usage; + sv = SvRV(rv); + sv_setpv(TARG, sv_reftype(sv, 0)); +#ifdef dXSTARGET + SvSETMAGIC(TARG); +#endif + + XSRETURN(1); +} + +XS(XS_attributes__warn_reserved) +{ + dXSARGS; +#ifdef dXSTARGET + dXSTARGET; +#else + SV * TARG = sv_newmortal(); +#endif + + if (items != 0) { + Perl_croak(aTHX_ + "Usage: attributes::_warn_reserved ()"); + } + + EXTEND(SP,1); + ST(0) = TARG; + sv_setiv(TARG, ckWARN(WARN_RESERVED) != 0); +#ifdef dXSTARGET + SvSETMAGIC(TARG); +#endif + + XSRETURN(1); +} + |