Skip to content

Commit b1de243

Browse files
author
Chris White
committed
Added textual substitution of -D defines
1 parent 4c023d2 commit b1de243

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

perlpp.pl

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# http://darkness.codefu.org/wordpress/2003/03/perl-scoping/
66

77
package PerlPP;
8-
our $VERSION = '0.2.0';
8+
our $VERSION = '0.3.0-alpha';
99

1010
use v5.10; # provides // - http://perldoc.perl.org/perl5100delta.html
1111
use strict;
@@ -63,7 +63,11 @@ package PerlPP;
6363
my @Preprocessors = ();
6464
my @Postprocessors = ();
6565
my %Prefixes = (); # set by ExecuteCommand; used by PrepareString
66+
67+
# -D definitions. -Dfoo creates $Defs{foo}==true and $Defs_repl_text{foo}==''.
6668
my %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
6973
my @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

t/cmdline.t

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ my @testcases=(
3333
['-D_x', '<? print "yes" if $D{_x}; ?>',qr/^yes$/],
3434
['-D_1', '<? print "yes" if $D{_1}; ?>',qr/^yes$/],
3535

36+
# Definitions with --define
37+
['--define foo', '<? print "yes" if $D{foo}; ?>',qr/^yes$/],
38+
['--define foo=42 --define bar=127', '<?= $D{foo} * $D{bar} ?>',qr/^5334$/],
39+
3640
# Definitions: :define/:undef
3741
['','<?:define foo?><?:ifdef foo?>yes<?:else?>no<?:endif?>',qr/^yes$/],
3842
['','<?:define foo 42?><?:ifdef foo?>yes<?:else?>no<?:endif?>',qr/^yes$/],
@@ -50,6 +54,13 @@ my @testcases=(
5054
['', '<? $D{x}="%D always exists even if empty"; ?><?= $D{x} ?>',
5155
qr/^%D always exists even if empty$/],
5256

57+
# Textual substitution
58+
['-Dfoo=42','<? my $foo; ?>foo',qr/^42$/ ],
59+
['-Dfoo=\'"a phrase"\'','<? my $foo; ?>foo',qr/^a phrase$/ ],
60+
['-Dfoo=\"bar\"','_foo foo foobar barfoo',qr/^_foo bar foobar barfoo$/ ],
61+
['-Dfoo=\"bar\" --define barfoo','_foo foo foobar barfoo',
62+
qr/^_foo bar foobar barfoo$/ ],
63+
5364
# Conditionals
5465
['-Dfoo=42','<?:if foo==2?>yes<?:else?>no<?:endif?>',qr/^no$/ ],
5566
['-Dfoo=2','<?:if foo==2?>yes<?:else?>no<?:endif?>',qr/^yes$/ ],

0 commit comments

Comments
 (0)