X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Magic.xs;h=e0e425cb37d16ec284ad515f80ef0410519a0601;hb=9c3bb4de5a4ce520d4669d5f6ff75bece8458fa5;hp=2cd4e7cdd34a48c41b08491d8e7ed36e8a255002;hpb=91aec4cfae75e61ff8eeb79448501a8739b0d240;p=perl%2Fmodules%2FVariable-Magic.git diff --git a/Magic.xs b/Magic.xs index 2cd4e7c..e0e425c 100644 --- a/Magic.xs +++ b/Magic.xs @@ -18,10 +18,6 @@ #define PERL_VERSION_LE(R, V, S) (PERL_REVISION < (R) || (PERL_REVISION == (R) && (PERL_VERSION < (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION <= (S)))))) -#define PERL_API_VERSION_GE(R, V, S) (PERL_API_REVISION > (R) || (PERL_API_REVISION == (R) && (PERL_API_VERSION > (V) || (PERL_API_VERSION == (V) && (PERL_API_SUBVERSION >= (S)))))) - -#define PERL_API_VERSION_LE(R, V, S) (PERL_API_REVISION < (R) || (PERL_API_REVISION == (R) && (PERL_API_VERSION < (V) || (PERL_API_VERSION == (V) && (PERL_API_SUBVERSION <= (S)))))) - #ifndef VMG_PERL_PATCHLEVEL # ifdef PERL_PATCHNUM # define VMG_PERL_PATCHLEVEL PERL_PATCHNUM @@ -30,6 +26,10 @@ # endif #endif +#define VMG_HAS_PERL_OR(P, R, V, S) ((VMG_PERL_PATCHLEVEL >= (P)) || (!VMG_PERL_PATCHLEVEL && PERL_VERSION_GE((R), (V), (S)))) + +#define VMG_HAS_PERL_AND(P, R, V, S) (PERL_VERSION_GE((R), (V), (S)) && (!VMG_PERL_PATCHLEVEL || (VMG_PERL_PATCHLEVEL >= (P)))) + /* --- Compatibility ------------------------------------------------------- */ #ifndef Newx @@ -40,6 +40,10 @@ # define SvMAGIC_set(sv, val) (SvMAGIC(sv) = (val)) #endif +#ifndef mPUSHi +# define mPUSHi(I) PUSHs(sv_2mortal(newSViv(I))) +#endif + #ifndef dMY_CXT # define MY_CXT vmg_globaldata # define dMY_CXT @@ -63,26 +67,27 @@ # define MGf_LOCAL 0 #endif -#if PERL_API_VERSION_GE(5, 10, 0) +/* uvar magic and Hash::Util::FieldHash were commited with p28419 */ +#if VMG_HAS_PERL_AND(28419, 5, 9, 4) # define VMG_UVAR 1 #else # define VMG_UVAR 0 #endif -#if (VMG_PERL_PATCHLEVEL >= 25854) || (!VMG_PERL_PATCHLEVEL && PERL_VERSION_GE(5, 9, 3)) +#if !defined(VMG_COMPAT_ARRAY_PUSH_NOLEN) && VMG_HAS_PERL_OR(25854, 5, 9, 3) # define VMG_COMPAT_ARRAY_PUSH_NOLEN 1 #else # define VMG_COMPAT_ARRAY_PUSH_NOLEN 0 #endif /* since 5.9.5 - see #43357 */ -#if (VMG_PERL_PATCHLEVEL >= 31473) || (!VMG_PERL_PATCHLEVEL && PERL_VERSION_GE(5, 9, 5)) +#if VMG_HAS_PERL_OR(31473, 5, 9, 5) # define VMG_COMPAT_ARRAY_UNDEF_CLEAR 1 #else # define VMG_COMPAT_ARRAY_UNDEF_CLEAR 0 #endif -#if (VMG_PERL_PATCHLEVEL >= 32969) || (!VMG_PERL_PATCHLEVEL && PERL_VERSION_GE(5, 11, 0)) +#if VMG_HAS_PERL_OR(32969, 5, 11, 0) # define VMG_COMPAT_SCALAR_LENGTH_NOLEN 1 #else # define VMG_COMPAT_SCALAR_LENGTH_NOLEN 0 @@ -90,26 +95,24 @@ #if VMG_UVAR -/* Bug-free mg_magical - see http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2008-01/msg00036.html */ -STATIC void vmg_mg_magical(pTHX_ SV *sv) { -#define vmg_mg_magical(S) vmg_mg_magical(aTHX_ (S)) +/* Bug-free mg_magical - see http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2008-01/msg00036.html - but specialized to our needs. */ +STATIC void vmg_sv_magicuvar(pTHX_ SV *sv, const char *uf, I32 len) { +#define vmg_sv_magicuvar(S, U, L) vmg_sv_magicuvar(aTHX_ (S), (U), (L)) const MAGIC* mg; + sv_magic(sv, NULL, PERL_MAGIC_uvar, uf, len); + /* uvar magic has set and get magic, hence this has set SVs_GMG and SVs_SMG. */ PERL_UNUSED_CONTEXT; if ((mg = SvMAGIC(sv))) { SvRMAGICAL_off(sv); do { const MGVTBL* const vtbl = mg->mg_virtual; if (vtbl) { - if (vtbl->svt_get && !(mg->mg_flags & MGf_GSKIP)) - SvGMAGICAL_on(sv); - if (vtbl->svt_set) - SvSMAGICAL_on(sv); - if (vtbl->svt_clear) + if (vtbl->svt_clear) { SvRMAGICAL_on(sv); + break; + } } } while ((mg = mg->mg_moremagic)); - if (!(SvFLAGS(sv) & (SVs_GMG|SVs_SMG))) - SvRMAGICAL_on(sv); } } @@ -307,8 +310,7 @@ STATIC UV vmg_cast(pTHX_ SV *sv, SV *wiz, AV *args) { } if (add_uvar) { - sv_magic(sv, NULL, PERL_MAGIC_uvar, (const char *) &uf, sizeof(uf)); - vmg_mg_magical(sv); + vmg_sv_magicuvar(sv, (const char *) &uf, sizeof(uf)); } } @@ -418,8 +420,8 @@ STATIC int vmg_cb_call(pTHX_ SV *cb, SV *sv, SV *data, unsigned int args, ...) { PUSHs(data ? data : &PL_sv_undef); va_start(ap, args); for (i = 0; i < args; ++i) { - SV *sv = va_arg(ap, SV *); - PUSHs(sv ? sv : &PL_sv_undef); + SV *sva = va_arg(ap, SV *); + PUSHs(sva ? sva : &PL_sv_undef); } va_end(ap); PUTBACK; @@ -469,8 +471,9 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { PUSHs(mg->mg_obj ? mg->mg_obj : &PL_sv_undef); if (SvTYPE(sv) == SVt_PVAV) { len = av_len((AV *) sv) + 1; - PUSHs(sv_2mortal(newSViv(len))); + mPUSHi(len); } else { + len = 1; PUSHs(&PL_sv_undef); } PUTBACK; @@ -481,8 +484,7 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { if (count != 1) { croak("Callback needs to return 1 scalar\n"); } svr = POPs; - ret = SvOK(svr) ? SvUV(svr) - : ((SvTYPE(sv) == SVt_PVAV) ? len : 1); + ret = SvOK(svr) ? SvUV(svr) : len; PUTBACK; @@ -506,7 +508,7 @@ STATIC int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { #if MGf_COPY STATIC int vmg_svt_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, const char *key, -# if (VMG_PERL_PATCHLEVEL >= 33256) || (!VMG_PERL_PATCHLEVEL && PERL_API_VERSION_GE(5, 11, 0)) +# if VMG_HAS_PERL_AND(33256, 5, 11, 0) I32 keylen # else int keylen @@ -597,7 +599,7 @@ STATIC int vmg_wizard_free(pTHX_ SV *wiz, MAGIC *mg) { w = SV2MGWIZ(wiz); SvREFCNT_inc(wiz); /* Fake survival - it's gonna be deleted anyway */ -#if PERL_API_VERSION_GE(5, 9, 5) +#if PERL_VERSION_GE(5, 9, 5) SvREFCNT_inc(wiz); /* One more push */ #endif if (hv_delete(MY_CXT.wizz, buf, sprintf(buf, "%u", w->sig), 0)) {