]> git.vpit.fr Git - perl/modules/Variable-Magic.git/commitdiff
Importing Variable-Magic-0.11.tar.gz v0.11
authorVincent Pit <vince@profvince.com>
Sun, 29 Jun 2008 16:24:44 +0000 (18:24 +0200)
committerVincent Pit <vince@profvince.com>
Sun, 29 Jun 2008 16:24:44 +0000 (18:24 +0200)
Changes
META.yml
Magic.xs
Makefile.PL
README
lib/Variable/Magic.pm
t/01-import.t
t/32-hash.t

diff --git a/Changes b/Changes
index 0d52bc65980136611f3cf262009a5efe5263126d..0d1b8c27271db4614818b4786605f6f18b0fd557 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,15 @@
 Revision history for Variable-Magic
 
+0.11    2008-02-07 17:55 UTC
+        + Add : Copy callbacks now receive the current key/index in $_[2].
+                The current value/element is now in $_[3].
+        + Chg : The trigger of copy magic on list assignment with perls greater
+                than 5.10.0 was caused by uvar magic. Hence,
+                VMG_COMPAT_HASH_LISTASSIGN_COPY was removed. Use VMG_UVAR
+                instead.
+        + Fix : Build failures on patched perls.
+        + Tst : Added missing exported symbols to 01-import.t.
+
 0.10    2008-02-04 11:30 UTC
         + Add : New script : samples/vm_vs_tie.pl, that benchmarks our uvar
                 magic versus tied hashes.
index 799f882e2d629c6d6933d0baac8d2a0e9e3cf355..1312412cbd55e6a6def8f75034fe2330eef1bed9 100644 (file)
--- a/META.yml
+++ b/META.yml
@@ -1,6 +1,6 @@
 --- #YAML:1.0
 name:                Variable-Magic
-version:             0.10
+version:             0.11
 abstract:            Associate user-defined magic to variables from Perl.
 license:             perl
 author:              
index 2df5bb4c10e58f936cc7445dc1660abe8061650f..936e8cd0c5e166cbb16aeab755021498a43c99c1 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
 # 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 */
@@ -420,7 +422,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 +455,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,8 +551,23 @@ 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, int keylen) {
+ 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 */
 
@@ -700,8 +753,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(...)
index f76dda4b2e08f085026b7a324d88e9d0a26d2f70..ebe7a504b3838c71a4574149ea3354408a1feaae 100644 (file)
@@ -4,6 +4,23 @@ use strict;
 use warnings;
 use ExtUtils::MakeMaker;
 
+eval {
+ require Config;
+};
+die "OS unsupported" if $@;
+
+my @DEFINES;
+
+my $pl = $Config::Config{perl_patchlevel};
+print "Checking perl patchlevel... ";
+if (defined $pl && length $pl) {
+ $pl = int $pl;
+ push @DEFINES, DEFINE => '-DVMG_PERL_PATCHLEVEL=' . $pl;
+ print $pl, "\n";
+} else {
+ print "none\n";
+}
+
 WriteMakefile(
     NAME                => 'Variable::Magic',
     AUTHOR              => 'Vincent Pit <perl@profvince.com>',
@@ -11,6 +28,7 @@ WriteMakefile(
     VERSION_FROM        => 'lib/Variable/Magic.pm',
     ABSTRACT_FROM       => 'lib/Variable/Magic.pm',
     PL_FILES            => {},
+    @DEFINES,
     PREREQ_PM => {
         'Carp'       => 0,
         'Exporter'   => 0,
diff --git a/README b/README
index c947b235ad21cea1ec972228c1013849384d4d4f..f31437cd31ddea8004950fa498ea8d0e96a67aa5 100644 (file)
--- a/README
+++ b/README
@@ -2,7 +2,7 @@ NAME
     Variable::Magic - Associate user-defined magic to variables from Perl.
 
 VERSION
-    Version 0.10
+    Version 0.11
 
 SYNOPSIS
         use Variable::Magic qw/wizard cast dispell/;
@@ -95,8 +95,8 @@ PERL MAGIC HISTORY
     *p14416* : 'copy' and 'dup' magic.
 
   5.9.3
-    'len' magic is no longer called when pushing an element into a magic
-    array.
+    *p25854* : 'len' magic is no longer called when pushing an element into
+    a magic array.
     *p26569* : 'local' magic.
 
   5.9.5
@@ -104,6 +104,11 @@ PERL MAGIC HISTORY
     *p31473* : 'clear' magic wasn't invoked when undefining an array. The
     bug is fixed as of this version.
 
+  5.10.0
+    Since "PERL_MAGIC_uvar" is uppercased, "hv_magic_check()" triggers
+    'copy' magic on hash stores for (non-tied) hashes that also have 'uvar'
+    magic.
+
 CONSTANTS
   "SIG_MIN"
     The minimum integer used as a signature for user-defined magic.
@@ -134,10 +139,6 @@ CONSTANTS
   "VMG_COMPAT_ARRAY_UNDEF_CLEAR"
     True for perls that call 'clear' magic when undefining magical arrays.
 
-  "VMG_COMPAT_HASH_LISTASSIGN_COPY"
-    True for perls that call 'copy' magic on list assignments. Implies that
-    "MGf_COPY" is true.
-
 FUNCTIONS
   "wizard"
         wizard sig    => ...,
@@ -147,7 +148,7 @@ FUNCTIONS
                len    => sub { my ($ref, $data, $len) = @_; ... ; return $newlen; },
                clear  => sub { my ($ref, $data) = @_; ... },
                free   => sub { my ($ref, $data) = @_, ... },
-               copy   => sub { my ($ref, $data, $elt) = @_; ... },
+               copy   => sub { my ($ref, $data, $key, $elt) = @_; ... },
                local  => sub { my ($ref, $data) = @_; ... },
                fetch  => sub { my ($ref, $data, $key) = @_; ... },
                store  => sub { my ($ref, $data, $key) = @_; ... },
@@ -178,9 +179,11 @@ FUNCTIONS
         reference to the magic object and $_[1] is always the private data
         (or "undef" when no private data constructor was supplied). In the
         special case of "len" magic and when the variable is an array, $_[2]
-        contains its normal length. "copy" magic receives the current
-        element (i.e. the value) in $_[2]. $_[2] is also the current key in
-        "fetch", "store", "exists" and "delete" callbacks.
+        contains its normal length. $_[2] is the current key in "copy",
+        "fetch", "store", "exists" and "delete" callbacks, although for
+        "copy" it may just be a copy of the actual key so it's useless to
+        (for example) cast magic on it. "copy" magic also receives the
+        current element (i.e. the value) in $_[3].
 
         # A simple scalar tracer
         my $wiz = wizard get  => sub { print STDERR "got ${$_[0]}\n" },
index 8025a408d4e1ed6ed3cb3c01ef27dfd196c17cb3..6e767b969ec530fc01adc280f5cae420ad9ff1e1 100644 (file)
@@ -13,13 +13,13 @@ Variable::Magic - Associate user-defined magic to variables from Perl.
 
 =head1 VERSION
 
-Version 0.10
+Version 0.11
 
 =cut
 
 our $VERSION;
 BEGIN {
- $VERSION = '0.10';
+ $VERSION = '0.11';
 }
 
 =head1 SYNOPSIS
@@ -117,7 +117,7 @@ The places where magic is invoked have changed a bit through perl history. Here'
 
 =over 4
 
-=item 'len' magic is no longer called when pushing an element into a magic array.
+=item I<p25854> : 'len' magic is no longer called when pushing an element into a magic array.
 
 =item I<p26569> : 'local' magic.
 
@@ -133,6 +133,10 @@ The places where magic is invoked have changed a bit through perl history. Here'
 
 =back
 
+=head2 B<5.10.0>
+
+=item Since C<PERL_MAGIC_uvar> is uppercased, C<hv_magic_check()> triggers 'copy' magic on hash stores for (non-tied) hashes that also have 'uvar' magic.
+
 =head1 CONSTANTS
 
 =head2 C<SIG_MIN>
@@ -171,10 +175,6 @@ True for perls that don't call 'len' magic when you push an element in a magical
 
 True for perls that call 'clear' magic when undefining magical arrays.
 
-=head2 C<VMG_COMPAT_HASH_LISTASSIGN_COPY>
-
-True for perls that call 'copy' magic on list assignments. Implies that C<MGf_COPY> is true.
-
 =head1 FUNCTIONS
 
 =cut
@@ -193,7 +193,7 @@ BEGIN {
            len    => sub { my ($ref, $data, $len) = @_; ... ; return $newlen; },
            clear  => sub { my ($ref, $data) = @_; ... },
            free   => sub { my ($ref, $data) = @_, ... },
-           copy   => sub { my ($ref, $data, $elt) = @_; ... },
+           copy   => sub { my ($ref, $data, $key, $elt) = @_; ... },
            local  => sub { my ($ref, $data) = @_; ... },
            fetch  => sub { my ($ref, $data, $key) = @_; ... },
            store  => sub { my ($ref, $data, $key) = @_; ... },
@@ -214,7 +214,7 @@ A code reference to a private data constructor. It is called each time this magi
 
 =item C<get>, C<set>, C<len>, C<clear>, C<free>, C<copy>, C<local>, C<fetch>, C<store>, C<exists> and C<delete>
 
-Code references to corresponding magic callbacks. You don't have to specify all of them : the magic associated with undefined entries simply won't be hooked. In those callbacks, C<$_[0]> is always a reference to the magic object and C<$_[1]> is always the private data (or C<undef> when no private data constructor was supplied). In the special case of C<len> magic and when the variable is an array, C<$_[2]> contains its normal length. C<copy> magic receives the current element (i.e. the value) in C<$_[2]>. C<$_[2]> is also the current key in C<fetch>, C<store>, C<exists> and C<delete> callbacks.
+Code references to corresponding magic callbacks. You don't have to specify all of them : the magic associated with undefined entries simply won't be hooked. In those callbacks, C<$_[0]> is always a reference to the magic object and C<$_[1]> is always the private data (or C<undef> when no private data constructor was supplied). In the special case of C<len> magic and when the variable is an array, C<$_[2]> contains its normal length. C<$_[2]> is the current key in C<copy>, C<fetch>, C<store>, C<exists> and C<delete> callbacks, although for C<copy> it may just be a copy of the actual key so it's useless to (for example) cast magic on it. C<copy> magic also receives the current element (i.e. the value) in C<$_[3]>.
 
 =back
 
@@ -294,7 +294,7 @@ our @EXPORT         = ();
 our %EXPORT_TAGS    = (
  'funcs' =>  [ qw/wizard gensig getsig cast getdata dispell/ ],
  'consts' => [ qw/SIG_MIN SIG_MAX SIG_NBR MGf_COPY MGf_DUP MGf_LOCAL VMG_UVAR/,
-               qw/VMG_COMPAT_ARRAY_PUSH_NOLEN VMG_COMPAT_ARRAY_UNDEF_CLEAR VMG_COMPAT_HASH_LISTASSIGN_COPY/ ]
+               qw/VMG_COMPAT_ARRAY_PUSH_NOLEN VMG_COMPAT_ARRAY_UNDEF_CLEAR/ ]
 );
 our @EXPORT_OK      = map { @$_ } values %EXPORT_TAGS;
 $EXPORT_TAGS{'all'} = [ @EXPORT_OK ];
index cc4aebd733f494f25da4abebb14430149d9da0df..6b858496ee3102ea3eaf93077eb8ccc3ece46546 100644 (file)
@@ -3,11 +3,11 @@
 use strict;
 use warnings;
 
-use Test::More tests => 9;
+use Test::More tests => 15;
 
 require Variable::Magic;
 
-for (qw/wizard gensig getsig cast getdata dispell SIG_MIN SIG_MAX SIG_NBR/) {
+for (qw/wizard gensig getsig cast getdata dispell SIG_MIN SIG_MAX SIG_NBR MGf_COPY MGf_DUP MGf_LOCAL VMG_UVAR VMG_COMPAT_ARRAY_PUSH_NOLEN VMG_COMPAT_ARRAY_UNDEF_CLEAR/) {
  eval { Variable::Magic->import($_) };
  ok(!$@, 'import ' . $_);
 }
index 7f1669a734941076b70eb60df223d15e820af06d..572f5e668e42fe18033cd0765ba7e4ef652bc152 100644 (file)
@@ -5,7 +5,7 @@ use warnings;
 
 use Test::More tests => 18;
 
-use Variable::Magic qw/wizard cast dispell MGf_COPY VMG_UVAR VMG_COMPAT_HASH_LISTASSIGN_COPY/;
+use Variable::Magic qw/wizard cast dispell MGf_COPY VMG_UVAR/;
 
 my @c = (0) x 12;
 my @x = (0) x 12;
@@ -56,13 +56,13 @@ ok(check(), 'hash : slice');
 
 %a = (a => 1, d => 3);
 ++$x[3];
-$x[5] += 2 if VMG_COMPAT_HASH_LISTASSIGN_COPY;
+$x[5] += 2 if VMG_UVAR;
 $x[9] += 2 if VMG_UVAR;
 ok(check(), 'hash : assign from list');
 
 %a = map { $_ => 1 } qw/a b d/;
 ++$x[3];
-$x[5] += 3 if VMG_COMPAT_HASH_LISTASSIGN_COPY;
+$x[5] += 3 if VMG_UVAR;
 $x[9] += 3 if VMG_UVAR;
 ok(check(), 'hash : assign from map');