]> git.vpit.fr Git - perl/modules/re-engine-Plugin.git/blob - README
Reuse the package name macro wherever possible
[perl/modules/re-engine-Plugin.git] / README
1 NAME
2     re::engine::Plugin - API to write custom regex engines
3
4 VERSION
5     Version 0.10
6
7 DESCRIPTION
8     As of perl 5.9.5 it's possible to lexically replace perl's built-in
9     regular expression engine with your own (see perlreapi and perlpragma).
10     This module provides a glue interface to the relevant parts of the perl
11     C API enabling you to write an engine in Perl instead of the C/XS
12     interface provided by the core.
13
14   The gory details
15     Each regex in perl is compiled into an internal "REGEXP" structure (see
16     perlreapi), this can happen either during compile time in the case of
17     patterns in the format "/pattern/" or runtime for "qr//" patterns, or
18     something inbetween depending on variable interpolation etc.
19
20     When this module is loaded into a scope it inserts a hook into
21     $^H{regcomp} (as described in perlreapi and perlpragma) to have each
22     regexp constructed in its lexical scope handled by this engine, but it
23     differs from other engines in that it also inserts other hooks into
24     "%^H" in the same scope that point to user-defined subroutines to use
25     during compilation, execution etc, these are described in "CALLBACKS"
26     below.
27
28     The callbacks (e.g. "comp") then get called with a re::engine::Plugin
29     object as their first argument. This object provies access to perl's
30     internal REGEXP struct in addition to its own state (e.g. a stash). The
31     methods on this object allow for altering the "REGEXP" struct's internal
32     state, adding new callbacks, etc.
33
34 CALLBACKS
35     Callbacks are specified in the "re::engine::Plugin" import list as
36     key-value pairs of names and subroutine references:
37
38         use re::engine::Plugin (
39             comp => sub {},
40             exec => sub {},
41         );
42
43     To write a custom engine which imports your functions into the caller's
44     scope use use the following snippet:
45
46         package re::engine::Example;
47         use re::engine::Plugin ();
48
49         sub import
50         {
51             # Sets the caller's $^H{regcomp} his %^H with our callbacks
52             re::engine::Plugin->import(
53                 comp => \&comp,
54                 exec => \&exec,
55             );
56         }
57
58        *unimport = \&re::engine::Plugin::unimport;
59
60         # Implementation of the engine
61         sub comp { ... }
62         sub exec { ... }
63
64         1;
65
66   comp
67         comp => sub {
68             my ($rx) = @_;
69
70             # return value discarded
71         }
72
73     Called when a regex is compiled by perl, this is always the first
74     callback to be called and may be called multiple times or not at all
75     depending on what perl sees fit at the time.
76
77     The first argument will be a freshly constructed "re::engine::Plugin"
78     object (think of it as $self) which you can interact with using the
79     methods below, this object will be passed around the other callbacks and
80     methods for the lifetime of the regex.
81
82     Calling "die" or anything that uses it (such as "carp") here will not be
83     trapped by an "eval" block that the pattern is in, i.e.
84
85        use Carp 'croak';
86        use re::engine::Plugin(
87            comp => sub {
88                my $rx = shift;
89                croak "Your pattern is invalid"
90                    unless $rx->pattern ~~ /pony/;
91            }
92        );
93
94        # Ignores the eval block
95        eval { /you die in C<eval>, you die for real/ };
96
97     This happens because the real subroutine call happens indirectly at
98     compile time and not in the scope of the "eval" block. This is how
99     perl's own engine would behave in the same situation if given an invalid
100     pattern such as "/(/".
101
102   exec
103         exec => sub {
104             my ($rx, $str) = @_;
105
106             # We always like ponies!
107             return 1 if $str ~~ /pony/;
108
109             # Failed to match
110             return;
111         }
112
113     Called when a regex is being executed, i.e. when it's being matched
114     against something. The scalar being matched against the pattern is
115     available as the second argument ($str) and through the str method. The
116     routine should return a true value if the match was successful, and a
117     false one if it wasn't.
118
119     This callback can also be specified on an individual basis with the
120     "callbacks" method.
121
122 METHODS
123   str
124         "str" ~~ /pattern/;
125         # in comp/exec/methods:
126         my $str = $rx->str;
127
128     The last scalar to be matched against the pattern or "undef" if there
129     hasn't been a match yet.
130
131     perl's own engine always stringifies the scalar being matched against a
132     given pattern, however a custom engine need not have such restrictions.
133     One could write a engine that matched a file handle against a pattern or
134     any other complex data structure.
135
136   pattern
137     The pattern that the engine was asked to compile, this can be either a
138     classic Perl pattern with modifiers like "/pat/ix" or "qr/pat/ix" or an
139     arbitary scalar. The latter allows for passing anything that doesn't fit
140     in a string and five modifier characters, such as hashrefs, objects,
141     etc.
142
143   mod
144         my %mod = $rx->mod;
145         say "has /ix" if %mod ~~ 'i' and %mod ~~ 'x';
146
147     A key-value pair list of the modifiers the pattern was compiled with.
148     The keys will zero or more of "imsxp" and the values will be true values
149     (so that you don't have to write "exists").
150
151     You don't get to know if the "eogc" modifiers were attached to the
152     pattern since these are internal to perl and shouldn't matter to regexp
153     engines.
154
155   stash
156         comp => sub { shift->stash( [ 1 .. 5 ) },
157         exec => sub { shift->stash }, # Get [ 1 .. 5 ]
158
159     Returns or sets a user defined stash that's passed around as part of the
160     $rx object, useful for passing around all sorts of data between the
161     callback routines and methods.
162
163   minlen
164         $rx->minlen($num);
165         my $minlen = $rx->minlen // "not set";
166
167     The minimum "length" a string must be to match the pattern, perl will
168     use this internally during matching to check whether the stringified
169     form of the string (or other object) being matched is at least this
170     long, if not the regexp engine in effect (that means you!) will not be
171     called at all.
172
173     The length specified will be used as a a byte length (using SvPV), not a
174     character length.
175
176   nparens
177   gofs
178   callbacks
179         # A dumb regexp engine that just tests string equality
180         use re::engine::Plugin comp => sub {
181             my ($re) = @_;
182
183             my $pat = $re->pattern;
184
185             $re->callbacks(
186                 exec => sub {
187                     my ($re, $str) = @_;
188                     return $pat eq $str;
189                 },
190             );
191         };
192
193     Takes a list of key-value pairs of names and subroutines, and replace
194     the callback currently attached to the regular expression for the type
195     given as the key by the code reference passed as the corresponding
196     value.
197
198     The only valid key is currently "exec". See "exec" for more details
199     about this callback.
200
201   num_captures
202         $re->num_captures(
203             FETCH => sub {
204                 my ($re, $paren) = @_;
205
206                 return "value";
207             },
208             STORE => sub {
209                 my ($re, $paren, $rhs) = @_;
210
211                 # return value discarded
212             },
213             LENGTH => sub {
214                 my ($re, $paren) = @_;
215
216                 return 123;
217             },
218         );
219
220     Takes a list of key-value pairs of names and subroutines that implement
221     numbered capture variables. "FETCH" will be called on value retrieval
222     ("say $1"), "STORE" on assignment ("$1 = "ook"") and "LENGTH" on "length
223     $1".
224
225     The second paramater of each routine is the paren number being
226     requested/stored, the following mapping applies for those numbers:
227
228         -2 => $` or ${^PREMATCH}
229         -1 => $' or ${^POSTMATCH}
230          0 => $& or ${^MATCH}
231          1 => $1
232          # ...
233
234     Assignment to capture variables makes it possible to implement something
235     like Perl 6 ":rw" semantics, and since it's possible to make the capture
236     variables return any scalar instead of just a string it becomes possible
237     to implement Perl 6 match object semantics (to name an example).
238
239   named_captures
240     TODO: implement
241
242     perl internals still needs to be changed to support this but when it's
243     done it'll allow the binding of "%+" and "%-" and support the Tie::Hash
244     methods FETCH, STORE, DELETE, CLEAR, EXISTS, FIRSTKEY, NEXTKEY and
245     SCALAR.
246
247 CONSTANTS
248   "REP_THREADSAFE"
249     True iff the module could have been built with thread-safety features
250     enabled.
251
252   "REP_FORKSAFE"
253     True iff this module could have been built with fork-safety features
254     enabled. This will always be true except on Windows where it's false for
255     perl 5.10.0 and below.
256
257 TAINTING
258     The only way to untaint an existing variable in Perl is to use it as a
259     hash key or referencing subpatterns from a regular expression match (see
260     perlsec), the latter only works in perl's regex engine because it
261     explicitly untaints capture variables which a custom engine will also
262     need to do if it wants its capture variables to be untanted.
263
264     There are basically two ways to go about this, the first and obvious one
265     is to make use of Perl'l lexical scoping which enables the use of its
266     built-in regex engine in the scope of the overriding engine's callbacks:
267
268         use re::engine::Plugin (
269             exec => sub {
270                 my ($re, $str) = @_; # $str is tainted
271
272                 $re->num_captures(
273                     FETCH => sub {
274                         my ($re, $paren) = @_;
275
276                         # This is perl's engine doing the match
277                         $str ~~ /(.*)/;
278
279                         # $1 has been untainted
280                         return $1;
281                     },
282                 );
283             },
284         );
285
286     The second is to use something like Taint::Util which flips the taint
287     flag on the scalar without invoking the perl's regex engine:
288
289         use Taint::Util;
290         use re::engine::Plugin (
291             exec => sub {
292                 my ($re, $str) = @_; # $str is tainted
293
294                 $re->num_captures(
295                     FETCH => sub {
296                         my ($re, $paren) = @_;
297
298                         # Copy $str and untaint the copy
299                         untaint(my $ret = $str);
300
301                         # Return the untainted value
302                         return $ret;
303                     },
304                 );
305             },
306         );
307
308     In either case a regex engine using perl's regex api or this module is
309     responsible for how and if it untaints its variables.
310
311 SEE ALSO
312     perlreapi, Taint::Util
313
314 TODO & CAVEATS
315     *here be dragons*
316
317     *   Engines implemented with this module don't support "s///" and "split
318         //", the appropriate parts of the "REGEXP" struct need to be wrapped
319         and documented.
320
321     *   Still not a complete wrapper for perlreapi in other ways, needs
322         methods for some "REGEXP" struct members, some callbacks aren't
323         implemented etc.
324
325     *   Support overloading operations on the "qr//" object, this allow
326         control over the of "qr//" objects in a manner that isn't limited by
327         "wrapped"/"wraplen".
328
329             $re->overload(
330                 '""'  => sub { ... },
331                 '@{}' => sub { ... },
332                 ...
333             );
334
335     *   Support the dispatch of arbitary methods from the re::engine::Plugin
336         qr// object to user defined subroutines via AUTOLOAD;
337
338             package re::engine::Plugin;
339             sub AUTOLOAD
340             {
341                 our $AUTOLOAD;
342                 my ($name) = $AUTOLOAD =~ /.*::(.*?)/;
343                 my $cv = getmeth($name); # or something like that
344                 goto &$cv;
345             }
346
347             package re::engine::SomeEngine;
348
349             sub comp
350             {
351                 my $re = shift;
352
353                 $re->add_method( # or something like that
354                     foshizzle => sub {
355                         my ($re, @arg) = @_; # re::engine::Plugin, 1..5
356                     },
357                 );
358             }
359
360             package main;
361             use re::engine::SomeEngine;
362             later:
363
364             my $re = qr//;
365             $re->foshizzle(1..5);
366
367     *   Implement the dupe callback, test this on a threaded perl (and learn
368         how to use threads and how they break the current model).
369
370     *   Allow the user to specify ->offs either as an array or a packed
371         string. Can pack() even pack I32? Only IV? int?
372
373     *   Add tests that check for different behavior when curpm is and is not
374         set.
375
376     *   Add tests that check the refcount of the stash and other things I'm
377         mucking with, run valgrind and make sure everything is destroyed
378         when it should.
379
380     *   Run the debugger on the testsuite and find cases when the intuit and
381         checkstr callbacks are called. Write wrappers around them and add
382         tests.
383
384 DEPENDENCIES
385     perl 5.10.
386
387     A C compiler. This module may happen to build with a C++ compiler as
388     well, but don't rely on it, as no guarantee is made in this regard.
389
390     XSLoader (standard since perl 5.6.0).
391
392 BUGS
393     Please report any bugs that aren't already listed at
394     <http://rt.cpan.org/Dist/Display.html?Queue=re-engine-Plugin> to
395     <http://rt.cpan.org/Public/Bug/Report.html?Queue=re-engine-Plugin>
396
397 AUTHORS
398     Ævar Arnfjörð Bjarmason "<avar at cpan.org>"
399
400     Vincent Pit "<perl at profvince.com>"
401
402 LICENSE
403     Copyright 2007,2008 Ævar Arnfjörð Bjarmason.
404
405     Copyright 2009,2010,2011,2013,2014 Vincent Pit.
406
407     This program is free software; you can redistribute it and/or modify it
408     under the same terms as Perl itself.
409