ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/staticperl/perl/lib/Filter/Simple.pm
Revision: 1.1
Committed: Thu Jun 30 14:27:12 2005 UTC (21 years, 4 months ago) by root
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

# Content
1 package Filter::Simple;
2
3 use Text::Balanced ':ALL';
4
5 use vars qw{ $VERSION @EXPORT };
6
7 $VERSION = '0.78';
8
9 use Filter::Util::Call;
10 use Carp;
11
12 @EXPORT = qw( FILTER FILTER_ONLY );
13
14
15 sub import {
16 if (@_>1) { shift; goto &FILTER }
17 else { *{caller()."::$_"} = \&$_ foreach @EXPORT }
18 }
19
20 sub FILTER (&;$) {
21 my $caller = caller;
22 my ($filter, $terminator) = @_;
23 local $SIG{__WARN__} = sub{};
24 *{"${caller}::import"} = gen_filter_import($caller,$filter,$terminator);
25 *{"${caller}::unimport"} = gen_filter_unimport($caller);
26 }
27
28 sub fail {
29 croak "FILTER_ONLY: ", @_;
30 }
31
32 my $exql = sub {
33 my @bits = extract_quotelike $_[0], qr//;
34 return unless $bits[0];
35 return \@bits;
36 };
37
38 my $ws = qr/\s+/;
39 my $id = qr/\b(?!([ysm]|q[rqxw]?|tr)\b)\w+/;
40 my $EOP = qr/\n\n|\Z/;
41 my $CUT = qr/\n=cut.*$EOP/;
42 my $pod_or_DATA = qr/
43 ^=(?:head[1-4]|item) .*? $CUT
44 | ^=pod .*? $CUT
45 | ^=for .*? $EOP
46 | ^=begin \s* (\S+) .*? \n=end \s* \1 .*? $EOP
47 | ^__(DATA|END)__\r?\n.*
48 /smx;
49
50 my %extractor_for = (
51 quotelike => [ $ws, $id, { MATCH => \&extract_quotelike } ],
52 regex => [ $ws, $pod_or_DATA, $id, $exql ],
53 string => [ $ws, $pod_or_DATA, $id, $exql ],
54 code => [ $ws, { DONT_MATCH => $pod_or_DATA },
55 $id, { DONT_MATCH => \&extract_quotelike } ],
56 executable => [ $ws, { DONT_MATCH => $pod_or_DATA } ],
57 all => [ { MATCH => qr/(?s:.*)/ } ],
58 );
59
60 my %selector_for = (
61 all => sub { my ($t)=@_; sub{ $_=$$_; $t->(@_); $_} },
62 executable=> sub { my ($t)=@_; sub{ref() ? $_=$$_ : $t->(@_); $_} },
63 quotelike => sub { my ($t)=@_; sub{ref() && do{$_=$$_; $t->(@_)}; $_} },
64 regex => sub { my ($t)=@_;
65 sub{ref() or return $_;
66 my ($ql,undef,$pre,$op,$ld,$pat) = @$_;
67 return $_->[0] unless $op =~ /^(qr|m|s)/
68 || !$op && ($ld eq '/' || $ld eq '?');
69 $_ = $pat;
70 $t->(@_);
71 $ql =~ s/^(\s*\Q$op\E\s*\Q$ld\E)\Q$pat\E/$1$_/;
72 return "$pre$ql";
73 };
74 },
75 string => sub { my ($t)=@_;
76 sub{ref() or return $_;
77 local *args = \@_;
78 my ($pre,$op,$ld1,$str1,$rd1,$ld2,$str2,$rd2,$flg) = @{$_}[2..10];
79 return $_->[0] if $op =~ /^(qr|m)/
80 || !$op && ($ld1 eq '/' || $ld1 eq '?');
81 if (!$op || $op eq 'tr' || $op eq 'y') {
82 local *_ = \$str1;
83 $t->(@args);
84 }
85 if ($op =~ /^(tr|y|s)/) {
86 local *_ = \$str2;
87 $t->(@args);
88 }
89 my $result = "$pre$op$ld1$str1$rd1";
90 $result .= $ld2 if $ld1 =~ m/[[({<]/; #])}>
91 $result .= "$str2$rd2$flg";
92 return $result;
93 };
94 },
95 );
96
97
98 sub gen_std_filter_for {
99 my ($type, $transform) = @_;
100 return sub { my (@pieces, $instr);
101 $DB::single=1;
102 for (extract_multiple($_,$extractor_for{$type})) {
103 if (ref()) { push @pieces, $_; $instr=0 }
104 elsif ($instr) { $pieces[-1] .= $_ }
105 else { push @pieces, $_; $instr=1 }
106 }
107 if ($type eq 'code') {
108 my $count = 0;
109 local $placeholder = qr/\Q$;\E(?:\C{4})\Q$;\E/;
110 my $extractor = qr/\Q$;\E(\C{4})\Q$;\E/;
111 $_ = join "",
112 map { ref $_ ? $;.pack('N',$count++).$; : $_ }
113 @pieces;
114 @pieces = grep { ref $_ } @pieces;
115 $transform->(@_);
116 s/$extractor/${$pieces[unpack('N',$1)]}/g;
117 }
118 else {
119 my $selector = $selector_for{$type}->($transform);
120 $_ = join "", map $selector->(@_), @pieces;
121 }
122 }
123 };
124
125 sub FILTER_ONLY {
126 my $caller = caller;
127 while (@_ > 1) {
128 my ($what, $how) = splice(@_, 0, 2);
129 fail "Unknown selector: $what"
130 unless exists $extractor_for{$what};
131 fail "Filter for $what is not a subroutine reference"
132 unless ref $how eq 'CODE';
133 push @transforms, gen_std_filter_for($what,$how);
134 }
135 my $terminator = shift;
136
137 my $multitransform = sub {
138 foreach my $transform ( @transforms ) {
139 $transform->(@_);
140 }
141 };
142 no warnings 'redefine';
143 *{"${caller}::import"} =
144 gen_filter_import($caller,$multitransform,$terminator);
145 *{"${caller}::unimport"} = gen_filter_unimport($caller);
146 }
147
148 my $ows = qr/(?:[ \t]+|#[^\n]*)*/;
149
150 sub gen_filter_import {
151 my ($class, $filter, $terminator) = @_;
152 my %terminator;
153 my $prev_import = *{$class."::import"}{CODE};
154 return sub {
155 my ($imported_class, @args) = @_;
156 my $def_terminator =
157 qr/^(?:\s*no\s+$imported_class\s*;$ows|__(?:END|DATA)__)\r?$/;
158 if (!defined $terminator) {
159 $terminator{terminator} = $def_terminator;
160 }
161 elsif (!ref $terminator || ref $terminator eq 'Regexp') {
162 $terminator{terminator} = $terminator;
163 }
164 elsif (ref $terminator ne 'HASH') {
165 croak "Terminator must be specified as scalar or hash ref"
166 }
167 elsif (!exists $terminator->{terminator}) {
168 $terminator{terminator} = $def_terminator;
169 }
170 filter_add(
171 sub {
172 my ($status, $lastline);
173 my $count = 0;
174 my $data = "";
175 while ($status = filter_read()) {
176 return $status if $status < 0;
177 if ($terminator{terminator} &&
178 m/$terminator{terminator}/) {
179 $lastline = $_;
180 last;
181 }
182 $data .= $_;
183 $count++;
184 $_ = "";
185 }
186 $_ = $data;
187 $filter->($imported_class, @args) unless $status < 0;
188 if (defined $lastline) {
189 if (defined $terminator{becomes}) {
190 $_ .= $terminator{becomes};
191 }
192 elsif ($lastline =~ $def_terminator) {
193 $_ .= $lastline;
194 }
195 }
196 return $count;
197 }
198 );
199 if ($prev_import) {
200 goto &$prev_import;
201 }
202 elsif ($class->isa('Exporter')) {
203 $class->export_to_level(1,@_);
204 }
205 }
206 }
207
208 sub gen_filter_unimport {
209 my ($class) = @_;
210 my $prev_unimport = *{$class."::unimport"}{CODE};
211 return sub {
212 filter_del();
213 goto &$prev_unimport if $prev_unimport;
214 }
215 }
216
217 1;
218
219 __END__
220
221 =head1 NAME
222
223 Filter::Simple - Simplified source filtering
224
225
226 =head1 SYNOPSIS
227
228 # in MyFilter.pm:
229
230 package MyFilter;
231
232 use Filter::Simple;
233
234 FILTER { ... };
235
236 # or just:
237 #
238 # use Filter::Simple sub { ... };
239
240 # in user's code:
241
242 use MyFilter;
243
244 # this code is filtered
245
246 no MyFilter;
247
248 # this code is not
249
250
251 =head1 DESCRIPTION
252
253 =head2 The Problem
254
255 Source filtering is an immensely powerful feature of recent versions of Perl.
256 It allows one to extend the language itself (e.g. the Switch module), to
257 simplify the language (e.g. Language::Pythonesque), or to completely recast the
258 language (e.g. Lingua::Romana::Perligata). Effectively, it allows one to use
259 the full power of Perl as its own, recursively applied, macro language.
260
261 The excellent Filter::Util::Call module (by Paul Marquess) provides a
262 usable Perl interface to source filtering, but it is often too powerful
263 and not nearly as simple as it could be.
264
265 To use the module it is necessary to do the following:
266
267 =over 4
268
269 =item 1.
270
271 Download, build, and install the Filter::Util::Call module.
272 (If you have Perl 5.7.1 or later, this is already done for you.)
273
274 =item 2.
275
276 Set up a module that does a C<use Filter::Util::Call>.
277
278 =item 3.
279
280 Within that module, create an C<import> subroutine.
281
282 =item 4.
283
284 Within the C<import> subroutine do a call to C<filter_add>, passing
285 it either a subroutine reference.
286
287 =item 5.
288
289 Within the subroutine reference, call C<filter_read> or C<filter_read_exact>
290 to "prime" $_ with source code data from the source file that will
291 C<use> your module. Check the status value returned to see if any
292 source code was actually read in.
293
294 =item 6.
295
296 Process the contents of $_ to change the source code in the desired manner.
297
298 =item 7.
299
300 Return the status value.
301
302 =item 8.
303
304 If the act of unimporting your module (via a C<no>) should cause source
305 code filtering to cease, create an C<unimport> subroutine, and have it call
306 C<filter_del>. Make sure that the call to C<filter_read> or
307 C<filter_read_exact> in step 5 will not accidentally read past the
308 C<no>. Effectively this limits source code filters to line-by-line
309 operation, unless the C<import> subroutine does some fancy
310 pre-pre-parsing of the source code it's filtering.
311
312 =back
313
314 For example, here is a minimal source code filter in a module named
315 BANG.pm. It simply converts every occurrence of the sequence C<BANG\s+BANG>
316 to the sequence C<die 'BANG' if $BANG> in any piece of code following a
317 C<use BANG;> statement (until the next C<no BANG;> statement, if any):
318
319 package BANG;
320
321 use Filter::Util::Call ;
322
323 sub import {
324 filter_add( sub {
325 my $caller = caller;
326 my ($status, $no_seen, $data);
327 while ($status = filter_read()) {
328 if (/^\s*no\s+$caller\s*;\s*?$/) {
329 $no_seen=1;
330 last;
331 }
332 $data .= $_;
333 $_ = "";
334 }
335 $_ = $data;
336 s/BANG\s+BANG/die 'BANG' if \$BANG/g
337 unless $status < 0;
338 $_ .= "no $class;\n" if $no_seen;
339 return 1;
340 })
341 }
342
343 sub unimport {
344 filter_del();
345 }
346
347 1 ;
348
349 This level of sophistication puts filtering out of the reach of
350 many programmers.
351
352
353 =head2 A Solution
354
355 The Filter::Simple module provides a simplified interface to
356 Filter::Util::Call; one that is sufficient for most common cases.
357
358 Instead of the above process, with Filter::Simple the task of setting up
359 a source code filter is reduced to:
360
361 =over 4
362
363 =item 1.
364
365 Download and install the Filter::Simple module.
366 (If you have Perl 5.7.1 or later, this is already done for you.)
367
368 =item 2.
369
370 Set up a module that does a C<use Filter::Simple> and then
371 calls C<FILTER { ... }>.
372
373 =item 3.
374
375 Within the anonymous subroutine or block that is passed to
376 C<FILTER>, process the contents of $_ to change the source code in
377 the desired manner.
378
379 =back
380
381 In other words, the previous example, would become:
382
383 package BANG;
384 use Filter::Simple;
385
386 FILTER {
387 s/BANG\s+BANG/die 'BANG' if \$BANG/g;
388 };
389
390 1 ;
391
392 Note that the source code is passed as a single string, so any regex that
393 uses C<^> or C<$> to detect line boundaries will need the C</m> flag.
394
395 =head2 Disabling or changing <no> behaviour
396
397 By default, the installed filter only filters up to a line consisting of one of
398 the three standard source "terminators":
399
400 no ModuleName; # optional comment
401
402 or:
403
404 __END__
405
406 or:
407
408 __DATA__
409
410 but this can be altered by passing a second argument to C<use Filter::Simple>
411 or C<FILTER> (just remember: there's I<no> comma after the initial block when
412 you use C<FILTER>).
413
414 That second argument may be either a C<qr>'d regular expression (which is then
415 used to match the terminator line), or a defined false value (which indicates
416 that no terminator line should be looked for), or a reference to a hash
417 (in which case the terminator is the value associated with the key
418 C<'terminator'>.
419
420 For example, to cause the previous filter to filter only up to a line of the
421 form:
422
423 GNAB esu;
424
425 you would write:
426
427 package BANG;
428 use Filter::Simple;
429
430 FILTER {
431 s/BANG\s+BANG/die 'BANG' if \$BANG/g;
432 }
433 qr/^\s*GNAB\s+esu\s*;\s*?$/;
434
435 or:
436
437 FILTER {
438 s/BANG\s+BANG/die 'BANG' if \$BANG/g;
439 }
440 { terminator => qr/^\s*GNAB\s+esu\s*;\s*?$/ };
441
442 and to prevent the filter's being turned off in any way:
443
444 package BANG;
445 use Filter::Simple;
446
447 FILTER {
448 s/BANG\s+BANG/die 'BANG' if \$BANG/g;
449 }
450 ""; # or: 0
451
452 or:
453
454 FILTER {
455 s/BANG\s+BANG/die 'BANG' if \$BANG/g;
456 }
457 { terminator => "" };
458
459 B<Note that, no matter what you set the terminator pattern to,
460 the actual terminator itself I<must> be contained on a single source line.>
461
462
463 =head2 All-in-one interface
464
465 Separating the loading of Filter::Simple:
466
467 use Filter::Simple;
468
469 from the setting up of the filtering:
470
471 FILTER { ... };
472
473 is useful because it allows other code (typically parser support code
474 or caching variables) to be defined before the filter is invoked.
475 However, there is often no need for such a separation.
476
477 In those cases, it is easier to just append the filtering subroutine and
478 any terminator specification directly to the C<use> statement that loads
479 Filter::Simple, like so:
480
481 use Filter::Simple sub {
482 s/BANG\s+BANG/die 'BANG' if \$BANG/g;
483 };
484
485 This is exactly the same as:
486
487 use Filter::Simple;
488 BEGIN {
489 Filter::Simple::FILTER {
490 s/BANG\s+BANG/die 'BANG' if \$BANG/g;
491 };
492 }
493
494 except that the C<FILTER> subroutine is not exported by Filter::Simple.
495
496
497 =head2 Filtering only specific components of source code
498
499 One of the problems with a filter like:
500
501 use Filter::Simple;
502
503 FILTER { s/BANG\s+BANG/die 'BANG' if \$BANG/g };
504
505 is that it indiscriminately applies the specified transformation to
506 the entire text of your source program. So something like:
507
508 warn 'BANG BANG, YOU'RE DEAD';
509 BANG BANG;
510
511 will become:
512
513 warn 'die 'BANG' if $BANG, YOU'RE DEAD';
514 die 'BANG' if $BANG;
515
516 It is very common when filtering source to only want to apply the filter
517 to the non-character-string parts of the code, or alternatively to I<only>
518 the character strings.
519
520 Filter::Simple supports this type of filtering by automatically
521 exporting the C<FILTER_ONLY> subroutine.
522
523 C<FILTER_ONLY> takes a sequence of specifiers that install separate
524 (and possibly multiple) filters that act on only parts of the source code.
525 For example:
526
527 use Filter::Simple;
528
529 FILTER_ONLY
530 code => sub { s/BANG\s+BANG/die 'BANG' if \$BANG/g },
531 quotelike => sub { s/BANG\s+BANG/CHITTY CHITTY/g };
532
533 The C<"code"> subroutine will only be used to filter parts of the source
534 code that are not quotelikes, POD, or C<__DATA__>. The C<quotelike>
535 subroutine only filters Perl quotelikes (including here documents).
536
537 The full list of alternatives is:
538
539 =over
540
541 =item C<"code">
542
543 Filters only those sections of the source code that are not quotelikes, POD, or
544 C<__DATA__>.
545
546 =item C<"executable">
547
548 Filters only those sections of the source code that are not POD or C<__DATA__>.
549
550 =item C<"quotelike">
551
552 Filters only Perl quotelikes (as interpreted by
553 C<&Text::Balanced::extract_quotelike>).
554
555 =item C<"string">
556
557 Filters only the string literal parts of a Perl quotelike (i.e. the
558 contents of a string literal, either half of a C<tr///>, the second
559 half of an C<s///>).
560
561 =item C<"regex">
562
563 Filters only the pattern literal parts of a Perl quotelike (i.e. the
564 contents of a C<qr//> or an C<m//>, the first half of an C<s///>).
565
566 =item C<"all">
567
568 Filters everything. Identical in effect to C<FILTER>.
569
570 =back
571
572 Except for C<< FILTER_ONLY code => sub {...} >>, each of
573 the component filters is called repeatedly, once for each component
574 found in the source code.
575
576 Note that you can also apply two or more of the same type of filter in
577 a single C<FILTER_ONLY>. For example, here's a simple
578 macro-preprocessor that is only applied within regexes,
579 with a final debugging pass that prints the resulting source code:
580
581 use Regexp::Common;
582 FILTER_ONLY
583 regex => sub { s/!\[/[^/g },
584 regex => sub { s/%d/$RE{num}{int}/g },
585 regex => sub { s/%f/$RE{num}{real}/g },
586 all => sub { print if $::DEBUG };
587
588
589
590 =head2 Filtering only the code parts of source code
591
592 Most source code ceases to be grammatically correct when it is broken up
593 into the pieces between string literals and regexes. So the C<'code'>
594 component filter behaves slightly differently from the other partial filters
595 described in the previous section.
596
597 Rather than calling the specified processor on each individual piece of
598 code (i.e. on the bits between quotelikes), the C<'code'> partial filter
599 operates on the entire source code, but with the quotelike bits
600 "blanked out".
601
602 That is, a C<'code'> filter I<replaces> each quoted string, quotelike,
603 regex, POD, and __DATA__ section with a placeholder. The
604 delimiters of this placeholder are the contents of the C<$;> variable
605 at the time the filter is applied (normally C<"\034">). The remaining
606 four bytes are a unique identifier for the component being replaced.
607
608 This approach makes it comparatively easy to write code preprocessors
609 without worrying about the form or contents of strings, regexes, etc.
610 For convenience, during a C<'code'> filtering operation, Filter::Simple
611 provides a package variable (C<$Filter::Simple::placeholder>) that contains
612 a pre-compiled regex that matches any placeholder. Placeholders can be
613 moved and re-ordered within the source code as needed.
614
615 Once the filtering has been applied, the original strings, regexes,
616 POD, etc. are re-inserted into the code, by replacing each
617 placeholder with the corresponding original component.
618
619 For example, the following filter detects concatentated pairs of
620 strings/quotelikes and reverses the order in which they are
621 concatenated:
622
623 package DemoRevCat;
624 use Filter::Simple;
625
626 FILTER_ONLY code => sub { my $ph = $Filter::Simple::placeholder;
627 s{ ($ph) \s* [.] \s* ($ph) }{ $2.$1 }gx
628 };
629
630 Thus, the following code:
631
632 use DemoRevCat;
633
634 my $str = "abc" . q(def);
635
636 print "$str\n";
637
638 would become:
639
640 my $str = q(def)."abc";
641
642 print "$str\n";
643
644 and hence print:
645
646 defabc
647
648
649 =head2 Using Filter::Simple with an explicit C<import> subroutine
650
651 Filter::Simple generates a special C<import> subroutine for
652 your module (see L<"How it works">) which would normally replace any
653 C<import> subroutine you might have explicitly declared.
654
655 However, Filter::Simple is smart enough to notice your existing
656 C<import> and Do The Right Thing with it.
657 That is, if you explicitly define an C<import> subroutine in a package
658 that's using Filter::Simple, that C<import> subroutine will still
659 be invoked immediately after any filter you install.
660
661 The only thing you have to remember is that the C<import> subroutine
662 I<must> be declared I<before> the filter is installed. If you use C<FILTER>
663 to install the filter:
664
665 package Filter::TurnItUpTo11;
666
667 use Filter::Simple;
668
669 FILTER { s/(\w+)/\U$1/ };
670
671 that will almost never be a problem, but if you install a filtering
672 subroutine by passing it directly to the C<use Filter::Simple>
673 statement:
674
675 package Filter::TurnItUpTo11;
676
677 use Filter::Simple sub{ s/(\w+)/\U$1/ };
678
679 then you must make sure that your C<import> subroutine appears before
680 that C<use> statement.
681
682
683 =head2 Using Filter::Simple and Exporter together
684
685 Likewise, Filter::Simple is also smart enough
686 to Do The Right Thing if you use Exporter:
687
688 package Switch;
689 use base Exporter;
690 use Filter::Simple;
691
692 @EXPORT = qw(switch case);
693 @EXPORT_OK = qw(given when);
694
695 FILTER { $_ = magic_Perl_filter($_) }
696
697 Immediately after the filter has been applied to the source,
698 Filter::Simple will pass control to Exporter, so it can do its magic too.
699
700 Of course, here too, Filter::Simple has to know you're using Exporter
701 before it applies the filter. That's almost never a problem, but if you're
702 nervous about it, you can guarantee that things will work correctly by
703 ensuring that your C<use base Exporter> always precedes your
704 C<use Filter::Simple>.
705
706
707 =head2 How it works
708
709 The Filter::Simple module exports into the package that calls C<FILTER>
710 (or C<use>s it directly) -- such as package "BANG" in the above example --
711 two automagically constructed
712 subroutines -- C<import> and C<unimport> -- which take care of all the
713 nasty details.
714
715 In addition, the generated C<import> subroutine passes its own argument
716 list to the filtering subroutine, so the BANG.pm filter could easily
717 be made parametric:
718
719 package BANG;
720
721 use Filter::Simple;
722
723 FILTER {
724 my ($die_msg, $var_name) = @_;
725 s/BANG\s+BANG/die '$die_msg' if \${$var_name}/g;
726 };
727
728 # and in some user code:
729
730 use BANG "BOOM", "BAM"; # "BANG BANG" becomes: die 'BOOM' if $BAM
731
732
733 The specified filtering subroutine is called every time a C<use BANG> is
734 encountered, and passed all the source code following that call, up to
735 either the next C<no BANG;> (or whatever terminator you've set) or the
736 end of the source file, whichever occurs first. By default, any C<no
737 BANG;> call must appear by itself on a separate line, or it is ignored.
738
739
740 =head1 AUTHOR
741
742 Damian Conway (damian@conway.org)
743
744 =head1 COPYRIGHT
745
746 Copyright (c) 2000-2001, Damian Conway. All Rights Reserved.
747 This module is free software. It may be used, redistributed
748 and/or modified under the same terms as Perl itself.