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