]> git.vpit.fr Git - perl/modules/Variable-Magic.git/blobdiff - Magic.xs
Importing Variable-Magic-0.14.tar.gz
[perl/modules/Variable-Magic.git] / Magic.xs
index 2df5bb4c10e58f936cc7445dc1660abe8061650f..b218de98cbc0bee835762d1d6d07b01b37f75971 100644 (file)
--- a/Magic.xs
+++ b/Magic.xs
 
 #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
 # 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);