X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Magic.xs;h=b218de98cbc0bee835762d1d6d07b01b37f75971;hb=refs%2Ftags%2Fv0.14;hp=2df5bb4c10e58f936cc7445dc1660abe8061650f;hpb=fee1a480bc5d827590dc7394e0a77741bad86dc3;p=perl%2Fmodules%2FVariable-Magic.git diff --git a/Magic.xs b/Magic.xs index 2df5bb4..b218de9 100644 --- a/Magic.xs +++ b/Magic.xs @@ -20,6 +20,14 @@ #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 +# else +# define VMG_PERL_PATCHLEVEL 0 +# endif +#endif + /* --- Compatibility ------------------------------------------------------- */ #ifndef Newx @@ -45,7 +53,6 @@ # define MGf_COPY 0 #endif -#undef MGf_DUP /* Disable it for now. */ #ifndef MGf_DUP # define MGf_DUP 0 #endif @@ -60,25 +67,19 @@ # define VMG_UVAR 0 #endif -#if PERL_VERSION_GE(5, 9, 3) +#if (VMG_PERL_PATCHLEVEL >= 25854) || PERL_VERSION_GE(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 PERL_VERSION_GE(5, 9, 5) +#if (VMG_PERL_PATCHLEVEL >= 31473) || PERL_VERSION_GE(5, 9, 5) # define VMG_COMPAT_ARRAY_UNDEF_CLEAR 1 #else # define VMG_COMPAT_ARRAY_UNDEF_CLEAR 0 #endif -#if MGf_COPY && PERL_VERSION_GE(5, 9, 4) -# define VMG_COMPAT_HASH_LISTASSIGN_COPY 1 -#else -# define VMG_COMPAT_HASH_LISTASSIGN_COPY 0 -#endif - #if VMG_UVAR /* Bug-free mg_magical - see http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2008-01/msg00036.html */ @@ -220,6 +221,7 @@ STATIC SV *vmg_data_get(SV *sv, U16 sig) { /* ... Magic cast/dispell .................................................. */ +#if VMG_UVAR STATIC I32 vmg_svt_val(pTHX_ IV, SV *); STATIC void vmg_uvar_del(SV *sv, MAGIC *prevmagic, MAGIC *mg, MAGIC *moremagic) { @@ -232,6 +234,7 @@ STATIC void vmg_uvar_del(SV *sv, MAGIC *prevmagic, MAGIC *mg, MAGIC *moremagic) Safefree(mg->mg_ptr); Safefree(mg); } +#endif /* VMG_UVAR */ STATIC UV vmg_cast(pTHX_ SV *sv, SV *wiz, AV *args) { #define vmg_cast(S, W, A) vmg_cast(aTHX_ (S), (W), (A)) @@ -374,6 +377,7 @@ STATIC UV vmg_dispell(pTHX_ SV *sv, U16 sig) { /* Revert the original uvar magic. */ uf[0] = uf[1]; Renew(uf, 1, struct ufuncs); + mg->mg_ptr = (char *) uf; mg->mg_len = sizeof(struct ufuncs); } else { /* Remove the uvar magic. */ @@ -420,7 +424,7 @@ STATIC int vmg_cb_call(pTHX_ SV *cb, SV *sv, SV *data) { return ret; } -#if MGf_COPY || VMG_UVAR +#if VMG_UVAR STATIC int vmg_cb_call2(pTHX_ SV *cb, SV *sv, SV *data, SV *sv2) { #define vmg_cb_call2(I, S, D, S2) vmg_cb_call2(aTHX_ (I), (S), (D), (S2)) SV *svr; @@ -453,7 +457,43 @@ STATIC int vmg_cb_call2(pTHX_ SV *cb, SV *sv, SV *data, SV *sv2) { return ret; } -#endif /* MGf_COPY || VMG_UVAR */ +#endif /* VMG_UVAR */ + +#if MGf_COPY +STATIC int vmg_cb_call3(pTHX_ SV *cb, SV *sv, SV *data, SV *sv2, SV *sv3) { +#define vmg_cb_call3(I, S, D, S2, S3) vmg_cb_call3(aTHX_ (I), (S), (D), (S2), (S3)) + SV *svr; + int ret; + + dSP; + int count; + + ENTER; + SAVETMPS; + + PUSHMARK(SP); + XPUSHs(sv_2mortal(newRV_inc(sv))); + XPUSHs(data ? data : &PL_sv_undef); + XPUSHs(sv2 ? sv2 : &PL_sv_undef); + if (sv3) { XPUSHs(sv3); } + PUTBACK; + + count = call_sv(cb, G_SCALAR); + + SPAGAIN; + + if (count != 1) { croak("Callback needs to return 1 scalar\n"); } + svr = POPs; + ret = SvOK(svr) ? SvIV(svr) : 0; + + PUTBACK; + + FREETMPS; + LEAVE; + + return ret; +} +#endif /* MGf_COPY */ STATIC int vmg_svt_get(pTHX_ SV *sv, MAGIC *mg) { return vmg_cb_call(SV2MGWIZ(mg->mg_ptr)->cb_get, sv, mg->mg_obj); @@ -513,12 +553,33 @@ 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 *name, int namelen) { - return vmg_cb_call2(SV2MGWIZ(mg->mg_ptr)->cb_copy, sv, mg->mg_obj, nsv); +STATIC int vmg_svt_copy(pTHX_ SV *sv, MAGIC *mg, SV *nsv, const char *key, +# if PERL_API_VERSION_GE(5, 11, 0) + I32 keylen +# else + int keylen +# endif + ) { + SV *keysv; + int ret; + + if (keylen == HEf_SVKEY) { + keysv = (SV *) key; + } else { + keysv = newSVpvn(key, keylen); + } + + ret = vmg_cb_call3(SV2MGWIZ(mg->mg_ptr)->cb_copy, sv, mg->mg_obj, keysv, nsv); + + if (keylen != HEf_SVKEY) { + SvREFCNT_dec(keysv); + } + + return ret; } #endif /* MGf_COPY */ -#if MGf_DUP +#if 0 /* MGf_DUP */ STATIC int vmg_svt_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param) { return 0; } @@ -700,8 +761,6 @@ BOOT: newSVuv(VMG_COMPAT_ARRAY_PUSH_NOLEN)); newCONSTSUB(stash, "VMG_COMPAT_ARRAY_UNDEF_CLEAR", newSVuv(VMG_COMPAT_ARRAY_UNDEF_CLEAR)); - newCONSTSUB(stash, "VMG_COMPAT_HASH_LISTASSIGN_COPY", - newSVuv(VMG_COMPAT_HASH_LISTASSIGN_COPY)); } SV *_wizard(...) @@ -760,7 +819,10 @@ CODE: VMG_SET_SVT_CB(ST(i++), copy); #endif /* MGf_COPY */ #if MGf_DUP - VMG_SET_SVT_CB(ST(i++), dup); + /* VMG_SET_SVT_CB(ST(i++), dup); */ + i++; + t->svt_dup = NULL; + w->cb_dup = NULL; #endif /* MGf_DUP */ #if MGf_LOCAL VMG_SET_SVT_CB(ST(i++), local);