55# http://darkness.codefu.org/wordpress/2003/03/perl-scoping/
66
77package PerlPP ;
8- our $VERSION = ' 0.2.0 ' ;
8+ our $VERSION = ' 0.3.0-alpha ' ;
99
1010use v5.10; # provides // - http://perldoc.perl.org/perl5100delta.html
1111use strict;
@@ -63,7 +63,11 @@ package PerlPP;
6363my @Preprocessors = ();
6464my @Postprocessors = ();
6565my %Prefixes = (); # set by ExecuteCommand; used by PrepareString
66+
67+ # -D definitions. -Dfoo creates $Defs{foo}==true and $Defs_repl_text{foo}==''.
6668my %Defs = (); # Command-line -D arguments
69+ my $Defs_RE = false; # Regex that matches any -D name
70+ my %Defs_repl_text = (); # Replacement text for -D names
6771
6872# Output-buffer stack
6973my @OutputBuffers = (); # each entry is a two-element array
@@ -156,9 +160,16 @@ sub PrepareString {
156160 my $s = shift ;
157161 my $pref ;
158162
163+ # Replace -D options. Do this before prefixes so that we don't create
164+ # prefix matches. TODO? combine the defs and prefixes into one RE?
165+ $s =~ s / $Defs_RE/ $Defs_repl_text {$1 }/ g if $Defs_RE ;
166+
167+ # Replace prefixes
159168 foreach $pref ( keys %Prefixes ) {
160169 $s =~ s / (^|\W )\Q $pref\E / $1 $Prefixes { $pref }/ g ;
161170 }
171+
172+ # Quote it for printing
162173 return QuoteString( $s );
163174}
164175
@@ -513,8 +524,9 @@ sub Main {
513524
514525 # Definitions
515526
516- # Transfer parameters from the command line (-D) to the processed file.
517- # The parameters are in %D, by analogy with -D.
527+ # Transfer parameters from the command line (-D) to the processed file,
528+ # as textual representations of expressions.
529+ # The parameters are in %D at runtime, by analogy with -S and %S.
518530 print " my %D = (\n " ;
519531 for my $defname (keys %{$opts {DEFS }}) {
520532 my $val = ${$opts {DEFS }}{$defname } // ' true' ;
@@ -530,9 +542,26 @@ sub Main {
530542 # Save a copy for use at generation time
531543 %Defs = map { my $v = eval (${$opts {DEFS }}{$_ });
532544 warn " Could not evaluate -D \" $_ \" : $@ " if $@ ;
533- $_ => $v
545+ $_ => ($v // true)
546+ }
547+ keys %{$opts {DEFS }};
548+
549+ # Set up regex for text substitution of Defs.
550+ # Modified from http://www.perlmonks.org/?node_id=989740 by
551+ # AnomalousMonk, http://www.perlmonks.org/?node_id=634253
552+ if (%{$opts {DEFS }}) {
553+ my $rx_search =
554+ ' \b(' . (join ' |' , map quotemeta , keys %{$opts {DEFS }}) . ' )\b' ;
555+ $Defs_RE = qr {$rx_search } ;
556+
557+ # Save the replacement values. If a value cannot be evaluated,
558+ # use the name so the replacement will not change the text.
559+ %Defs_repl_text =
560+ map { my $v = eval (${$opts {DEFS }}{$_ });
561+ ($@ || !defined ($v )) ? ($_ => $_ ) : ($_ => (' ' . $v ))
534562 }
535563 keys %{$opts {DEFS }};
564+ }
536565
537566 # Initial code from the command line, if any
538567 print $opts {EVAL }, " \n " if $opts {EVAL };
@@ -549,6 +578,9 @@ sub Main {
549578 } else {
550579 StartOB(); # output of the Perl script
551580 my $result ; # save any errors from the eval
581+
582+ # TODO hide %Defs and others of our variables we don't want
583+ # $script to access.
552584 eval ( $script ); $result =$@ ;
553585
554586 if ($result ) { # Report errors to console and shell
@@ -680,5 +712,5 @@ =head1 COPYRIGHT
680712
681713=cut
682714
683- # vi: set ts=4 sts=0 sw=4 noet ai: #
715+ # vi: set ts=4 sts=0 sw=4 noet ai fo-=o : #
684716
0 commit comments