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