-# See Plugin.pod for documentation\r
-package re::engine::Plugin;\r
-use 5.009005;\r
-use strict;\r
-use Carp 'croak';\r
-use Scalar::Util 'weaken';\r
-use XSLoader ();\r
-\r
-our $VERSION = '0.01';\r
-\r
-XSLoader::load __PACKAGE__, $VERSION;\r
-\r
-my $RE_ENGINE_PLUGIN = get_engine_plugin();\r
-my $NULL = 0;\r
-\r
-# How many? Used to cheat %^H\r
-my $callback = 0;\r
-# Valid callbacks\r
-my @callback = qw(comp exec intuit checkstr free dupe);\r
-# Where we store our CODE refs\r
-my %callback;\r
-\r
-sub import\r
-{\r
- my ($pkg, %sub) = @_;\r
-\r
- #$sub{$_} = sub {}\r
-\r
- for (@callback) {\r
- next unless exists $sub{$_};\r
- my $cb = delete $sub{$_};\r
-\r
- # Convert "package::sub" to CODE if it isn't CODE already\r
- unless (ref $cb eq 'CODE') {\r
- no strict 'refs';\r
- $cb = *{$cb}{CODE};\r
- }\r
-\r
- # Whine if we don't get a CODE ref or a valid package::sub name\r
- croak "'$_' is not CODE and neither is the *{$cb}{CODE} fallback"\r
- unless ref $cb eq 'CODE';\r
-\r
- # Get an ID to use\r
- my $id = $callback ++;\r
-\r
- # Insert into our callback storage,\r
- $callback{$_}->{$id} = $cb;\r
-\r
- # Weaken it so we don't end up hanging on to something the\r
- # caller doesn't care about anymore\r
- #weaken($callback{$_}->{$id}); # EEK, too weak!\r
-\r
- # Instert into our cache with a key we can retrive later\r
- # knowing the ID in %^H and what callback we're getting\r
- my $key = callback_key($_);\r
- $^H{$key} = $id;\r
- }\r
-\r
- $^H{regcomp} = $RE_ENGINE_PLUGIN;\r
-}\r
-\r
-sub unimport\r
-{\r
- my ($pkg) = @_;\r
-\r
- # Delete the regcomp hook\r
- delete $^H{regcomp} if $^H{regcomp} == $RE_ENGINE_PLUGIN;\r
-}\r
-\r
-sub callback_key\r
-{\r
- my ($name) = @_;\r
-\r
- sprintf "rep_%s", $name;\r
-}\r
-\r
-# Minimal function to be called from the XS\r
-sub get_callback\r
-{\r
- my ($name) = @_; # 'comp', 'exec', ...\r
-\r
- my $key = callback_key($name);\r
- my $h = (caller(0))[10];\r
- my $id = $h->{$key};\r
-\r
- my $cb = defined $id ? $callback{$name}->{$id} : 0;\r
-\r
- return $cb;\r
-}\r
-\r
-1;\r
+# See Plugin.pod for documentation
+package re::engine::Plugin;
+use 5.010;
+use strict;
+
+our ($VERSION, @ISA);
+
+BEGIN {
+ $VERSION = '0.12';
+ # All engines should subclass the core Regexp package
+ @ISA = 'Regexp';
+ require XSLoader;
+ XSLoader::load(__PACKAGE__, $VERSION);
+}
+
+my $RE_ENGINE_PLUGIN = ENGINE();
+
+sub import
+{
+ my ($pkg, %sub) = @_;
+
+ # Valid callbacks
+ my @callback = qw<comp exec free>;
+
+ for (@callback) {
+ next unless exists $sub{$_};
+ my $cb = $sub{$_};
+
+ unless (ref $cb eq 'CODE') {
+ require Carp;
+ Carp::croak("'$_' is not CODE");
+ }
+ }
+
+ $^H |= 0x020000;
+
+ $^H{+(__PACKAGE__)} = _tag(@sub{@callback});
+ $^H{regcomp} = $RE_ENGINE_PLUGIN;
+
+ return;
+}
+
+sub unimport
+{
+ # Delete the regcomp hook
+ delete $^H{regcomp}
+ if $^H{regcomp} == $RE_ENGINE_PLUGIN;
+
+ delete $^H{+(__PACKAGE__)};
+
+ return;
+}
+
+sub callbacks
+{
+ my ($re, %callback) = @_;
+
+ my %map = map { $_ => "_$_" } qw<exec free>;
+
+ for my $key (keys %callback) {
+ my $name = $map{$key};
+ next unless defined $name;
+ $re->$name($callback{$key});
+ }
+}
+
+sub num_captures
+{
+ my ($re, %callback) = @_;
+
+ for my $key (keys %callback) {
+ $key =~ y/a-z/A-Z/; # ASCII uc
+ my $name = '_num_capture_buff_' . $key;
+ $re->$name( $callback{$key} );
+ }
+}
+
+1;