]> git.vpit.fr Git - perl/modules/re-engine-Plugin.git/blob - Plugin.pod
4bb2674022e294bd3e335abea4c0141a8d901c7b
[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 This callback can also be specified on an individual basis with the
126 L</callbacks> method.
127
128 =head1 METHODS
129
130 =head2 str
131
132     "str" ~~ /pattern/;
133     # in comp/exec/methods:
134     my $str = $rx->str;
135
136 The last scalar to be matched against the L<pattern|/pattern> or
137 C<undef> if there hasn't been a match yet.
138
139 perl's own engine always stringifies the scalar being matched against
140 a given pattern, however a custom engine need not have such
141 restrictions. One could write a engine that matched a file handle
142 against a pattern or any other complex data structure.
143
144 =head2 pattern
145
146 The pattern that the engine was asked to compile, this can be either a
147 classic Perl pattern with modifiers like C</pat/ix> or C<qr/pat/ix> or
148 an arbitary scalar. The latter allows for passing anything that
149 doesn't fit in a string and five L<modifier|/mod> characters, such as
150 hashrefs, objects, etc.
151
152 =head2 mod
153
154     my %mod = $rx->mod;
155     say "has /ix" if %mod ~~ 'i' and %mod ~~ 'x';
156
157 A key-value pair list of the modifiers the pattern was compiled with.
158 The keys will zero or more of C<imsxp> and the values will be true
159 values (so that you don't have to write C<exists>).
160
161 You don't get to know if the C<eogc> modifiers were attached to the
162 pattern since these are internal to perl and shouldn't matter to
163 regexp engines.
164
165 =head2 stash
166
167     comp => sub { shift->stash( [ 1 .. 5 ) },
168     exec => sub { shift->stash }, # Get [ 1 .. 5 ]
169
170 Returns or sets a user defined stash that's passed around as part of
171 the C<$rx> object, useful for passing around all sorts of data between
172 the callback routines and methods.
173
174 =head2 minlen
175
176     $rx->minlen($num);
177     my $minlen = $rx->minlen // "not set";
178
179 The minimum C<length> a string must be to match the pattern, perl will
180 use this internally during matching to check whether the stringified
181 form of the string (or other object) being matched is at least this
182 long, if not the regexp engine in effect (that means you!) will not be
183 called at all.
184
185 The length specified will be used as a a byte length (using
186 L<SvPV|perlapi/SvPV>), not a character length.
187
188 =head2 nparens
189
190 =head2 gofs
191
192 =head2 callbacks
193
194     # A dumb regexp engine that just tests string equality
195     use re::engine::Plugin comp => sub {
196         my ($re) = @_;
197
198         my $pat = $re->pattern;
199
200         $re->callbacks(
201             exec => sub {
202                 my ($re, $str) = @_;
203                 return $pat eq $str;
204             },
205         );
206     };
207
208 Takes a list of key-value pairs of names and subroutines, and replace the
209 callback currently attached to the regular expression for the type given as
210 the key by the code reference passed as the corresponding value.
211
212 The only valid key is currently C<exec>. See L</exec> for more details about
213 this callback.
214
215 =head2 num_captures
216
217     $re->num_captures(
218         FETCH => sub {
219             my ($re, $paren) = @_;
220
221             return "value";
222         },
223         STORE => sub {
224             my ($re, $paren, $rhs) = @_;
225
226             # return value discarded
227         },
228         LENGTH => sub {
229             my ($re, $paren) = @_;
230
231             return 123;
232         },
233     );
234
235 Takes a list of key-value pairs of names and subroutines that
236 implement numbered capture variables. C<FETCH> will be called on value
237 retrieval (C<say $1>), C<STORE> on assignment (C<$1 = "ook">) and
238 C<LENGTH> on C<length $1>.
239
240 The second paramater of each routine is the paren number being
241 requested/stored, the following mapping applies for those numbers:
242
243     -2 => $` or ${^PREMATCH}
244     -1 => $' or ${^POSTMATCH}
245      0 => $& or ${^MATCH}
246      1 => $1
247      # ...
248
249 Assignment to capture variables makes it possible to implement
250 something like Perl 6 C<:rw> semantics, and since it's possible to
251 make the capture variables return any scalar instead of just a string
252 it becomes possible to implement Perl 6 match object semantics (to
253 name an example).
254
255 =head2 named_captures
256
257 B<TODO>: implement
258
259 perl internals still needs to be changed to support this but when it's
260 done it'll allow the binding of C<%+> and C<%-> and support the
261 L<Tie::Hash> methods FETCH, STORE, DELETE, CLEAR, EXISTS, FIRSTKEY,
262 NEXTKEY and SCALAR.
263
264 =head1 Tainting
265
266 The only way to untaint an existing variable in Perl is to use it as a
267 hash key or referencing subpatterns from a regular expression match
268 (see L<perlsec|perlsec/Laundering and Detecting Tainted Data>), the
269 latter only works in perl's regex engine because it explicitly
270 untaints capture variables which a custom engine will also need to do
271 if it wants its capture variables to be untanted.
272
273 There are basically two ways to go about this, the first and obvious
274 one is to make use of Perl'l lexical scoping which enables the use of
275 its built-in regex engine in the scope of the overriding engine's
276 callbacks:
277
278     use re::engine::Plugin (
279         exec => sub {
280             my ($re, $str) = @_; # $str is tainted
281
282             $re->num_captures(
283                 FETCH => sub {
284                     my ($re, $paren) = @_;
285
286                     # This is perl's engine doing the match
287                     $str ~~ /(.*)/;
288
289                     # $1 has been untainted
290                     return $1;
291                 },
292             );
293         },
294     );
295
296 The second is to use something like L<Taint::Util> which flips the
297 taint flag on the scalar without invoking the perl's regex engine:
298
299     use Taint::Util;
300     use re::engine::Plugin (
301         exec => sub {
302             my ($re, $str) = @_; # $str is tainted
303
304             $re->num_captures(
305                 FETCH => sub {
306                     my ($re, $paren) = @_;
307
308                     # Copy $str and untaint the copy
309                     untaint(my $ret = $str);
310
311                     # Return the untainted value
312                     return $ret;
313                 },
314             );
315         },
316     );
317
318 In either case a regex engine using perl's L<regex api|perlapi> or
319 this module is responsible for how and if it untaints its variables.
320
321 =head1 SEE ALSO
322
323 L<perlreapi>, L<Taint::Util>
324
325 =head1 TODO / CAVEATS
326
327 I<here be dragons>
328
329 =over
330
331 =item *
332
333 Engines implemented with this module don't support C<s///> and C<split
334 //>, the appropriate parts of the C<REGEXP> struct need to be wrapped
335 and documented.
336
337 =item *
338
339 Still not a complete wrapper for L<perlreapi> in other ways, needs
340 methods for some C<REGEXP> struct members, some callbacks aren't
341 implemented etc.
342
343 =item *
344
345 Support overloading operations on the C<qr//> object, this allow
346 control over the of C<qr//> objects in a manner that isn't limited by
347 C<wrapped>/C<wraplen>.
348
349     $re->overload(
350         '""'  => sub { ... },
351         '@{}' => sub { ... },
352         ...
353     );
354
355 =item *
356
357 Support the dispatch of arbitary methods from the re::engine::Plugin
358 qr// object to user defined subroutines via AUTOLOAD;
359
360     package re::engine::Plugin;
361     sub AUTOLOAD
362     {
363         our $AUTOLOAD;
364         my ($name) = $AUTOLOAD =~ /.*::(.*?)/;
365         my $cv = getmeth($name); # or something like that
366         goto &$cv;
367     }
368
369     package re::engine::SomeEngine;
370
371     sub comp
372     {
373         my $re = shift;
374
375         $re->add_method( # or something like that
376             foshizzle => sub {
377                 my ($re, @arg) = @_; # re::engine::Plugin, 1..5
378             },
379         );
380     }
381
382     package main;
383     use re::engine::SomeEngine;
384     later:
385
386     my $re = qr//;
387     $re->foshizzle(1..5);
388
389 =item *
390
391 Implement the dupe callback, test this on a threaded perl (and learn
392 how to use threads and how they break the current model).
393
394 =item *
395
396 Allow the user to specify ->offs either as an array or a packed
397 string. Can pack() even pack I32? Only IV? int?
398
399 =item *
400
401 Add tests that check for different behavior when curpm is and is not
402 set.
403
404 =item *
405
406 Add tests that check the refcount of the stash and other things I'm
407 mucking with, run valgrind and make sure everything is destroyed when
408 it should.
409
410 =item *
411
412 Run the debugger on the testsuite and find cases when the intuit and
413 checkstr callbacks are called. Write wrappers around them and add
414 tests.
415
416 =back
417
418 =head1 BUGS
419
420 Please report any bugs that aren't already listed at
421 L<http://rt.cpan.org/Dist/Display.html?Queue=re-engine-Plugin> to
422 L<http://rt.cpan.org/Public/Bug/Report.html?Queue=re-engine-Plugin>
423
424 =head1 AUTHORS
425
426 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason C<< <avar at cpan.org> >>
427
428 Vincent Pit C<< <perl at profvince.com> >>
429
430 =head1 LICENSE
431
432 Copyright 2007-2008 E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason.
433
434 Copyright 2009 Vincent Pit.
435
436 This program is free software; you can redistribute it and/or modify it
437 under the same terms as Perl itself.
438
439 =cut