]> git.vpit.fr Git - perl/modules/re-engine-Hooks.git/commitdiff
Make sure the perl callback sample does not clobber PL_reg_state
authorVincent Pit <vince@profvince.com>
Sat, 31 Mar 2012 14:51:52 +0000 (16:51 +0200)
committerVincent Pit <vince@profvince.com>
Sat, 31 Mar 2012 14:51:52 +0000 (16:51 +0200)
And add a test for this.

MANIFEST
t/11-call-perl.t [new file with mode: 0644]
t/re-engine-Hooks-TestDist/TestDist.xs

index e81ec6d193d1a1df3a1ebbe33d9a0250c391758e..7d0d4afdda848cdf7f37ee8f4b3a56435cc07ada 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -109,6 +109,7 @@ src/update.pl
 t/00-load.t
 t/05-keys.t
 t/10-base.t
+t/11-call-perl.t
 t/20-multi.t
 t/91-pod.t
 t/92-pod-coverage.t
diff --git a/t/11-call-perl.t b/t/11-call-perl.t
new file mode 100644 (file)
index 0000000..d600d32
--- /dev/null
@@ -0,0 +1,50 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use blib 't/re-engine-Hooks-TestDist';
+
+use Test::More tests => 2 * 2;
+
+# Those tests must be ran inside eval STRING because the test distribution
+# can hold only one callback at a time.
+
+my @nodes;
+
+eval <<'TEST1';
+my $rx = do {
+ use re::engine::Hooks::TestDist 'custom' => sub { push @nodes, @_ };
+ qr/.(?:a|o).*/;
+};
+
+{
+ local $@;
+ eval {
+  "foo" =~ $rx;
+ };
+ is $@, '', 'calling perl code in the exec hook does not croak';
+ is_deeply \@nodes, [ qw<REG_ANY TRIE STAR END> ],
+            'calling perl code in the exec hook works correctly';
+}
+TEST1
+die $@ if $@;
+
+eval <<'TEST2';
+my $res;
+
+my $rx = do {
+ use re::engine::Hooks::TestDist 'custom' => sub { $res += ("durp" =~ /.urp/) };
+ qr/.(?:a|o).*/;
+};
+
+{
+ local $@;
+ eval {
+  "foo" =~ $rx;
+ };
+ is $@, '', 'a regexp match in the exec hook does not croak';
+ is $res, scalar(@nodes), 'a regexp match in the exec hook works correctly';
+}
+TEST2
+die $@ if $@;
index 0005b019b09b36074583c0b279d01a8f74934ffc..ef36ccb9303975b003576a92c5964f863c00212a 100644 (file)
@@ -48,6 +48,8 @@ STATIC void reht_custom_comp_node(pTHX_ regexp *rx, regnode *node) {
  node_name = PL_reg_name[OP(node)];
 }
 
+STATIC struct re_save_state reht_state_bak;
+
 STATIC void reht_custom_exec_node(pTHX_ regexp *rx, regnode *node, regmatch_info *reginfo, regmatch_state *st) {
  STRLEN      node_namelen;
  const char *node_name;
@@ -55,6 +57,10 @@ STATIC void reht_custom_exec_node(pTHX_ regexp *rx, regnode *node, regmatch_info
  node_name    = PL_reg_name[OP(node)];
  node_namelen = strlen(node_name);
 
+ /* The global regexp state may be overwritten if the Perl callback does a
+  * regexp match. */
+ reht_state_bak = PL_reg_state;
+
  dSP;
 
  ENTER;
@@ -69,6 +75,8 @@ STATIC void reht_custom_exec_node(pTHX_ regexp *rx, regnode *node, regmatch_info
 
  FREETMPS;
  LEAVE;
+
+ PL_reg_state = reht_state_bak;
 }
 
 /* --- XS ------------------------------------------------------------------ */