Skip to content

Commit

Permalink
Merge pull request #27 from cxw42/vnext
Browse files Browse the repository at this point in the history
v0.500.4
  • Loading branch information
cxw42 authored May 30, 2018
2 parents 4328bde + 39d4f10 commit d6e73ca
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 57 deletions.
6 changes: 6 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
Revision history for Text-PerlPP
(Note: GH = GitHub issue; # = RT issue)

0.500.4 2018/05/29
Updated tests

0.500.3 2018/05/28
Fixes to tests; updated documentation

0.500.2 2018/05/27
Fixes to installation package

Expand Down
1 change: 1 addition & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ t/04-include.t
t/05-external-command.t
t/06-macro.t
t/07-invalid.t
t/08-persistent-state.t
t/a.txt
t/b.txt
t/c.txt
Expand Down
35 changes: 34 additions & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ README.md.

REQUIRES

Perl 5.10+ and Getopt::Long 2.50. There is a fatpacked version that
Perl 5.10.1+ and Getopt::Long 2.50. There is a fatpacked version that
already includes Getopt::Long in the GitHub releases archive:
https://github.com/interpreters/perlpp/releases

Expand Down Expand Up @@ -45,13 +45,46 @@ Yet another alternative way of installing
- Copy lib/Text/PerlPP.pm to a directory in your @INC
- Copy bin/perlpp to a directory in your PATH.

DEVELOPING

We welcome contributions through the normal GitHub pull-request (PR) workflow.
The build system is straight ExtUtils::MakeMaker.

Before developing, run

perl Makefile.PL
cpanm --installdeps . # if you have cpanminus installed

Then, to test your code directly from the lib/ directory, run

make testhere

Before submitting a PR, please test with the normal

make ; make test

sequence, as well as with

make testhere
make testpacked

That last one tests the packed version made by pack.PL in blib/perlpp.
We test on p5p Perl 5.10.1 (cygwin x86) and 5.26.1 (cygwin x64),
and cperl 5.26.2c (cygwin x64).

SUPPORT AND DOCUMENTATION

After installing, you can find documentation for this module with the
perldoc command.

perldoc perlpp

describes syntax and invocation, while

perldoc Text::PerlPP

describes using perlpp within another program.

You can also look for information at:

GitHub (report bugs here)
Expand Down
44 changes: 20 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ PerlPP: Perl preprocessor
Translates **Text+Perl** to **Text**.
It can be used for any kind of text templating, e.g. code generation.
No external modules are required, just a single file.
Requires Perl 5.10+.
Requires Perl 5.10.1+.

PerlPP runs in two passes: it generates a Perl script from your input, and then
it runs the generated script. If you see `error at (eval ##)`
Expand Down Expand Up @@ -58,11 +58,11 @@ Perl code is included between `<?` and `?>` tags.
There are several modes, indicated by the character after the `<?`:

<? code mode: Perl code is between the tags.
<?= echo mode: prints a Perl expression
<?: internal-command mode: executed by PerlPP itself (see below)
<?= echo mode: prints a Perl expression.
<?: internal-command mode: executed by PerlPP itself.
<?/ code mode, beginning with printing a line break.
<?# comment mode: everything in <?# ... ?> is ignored.
<?! external mode: everything in <?! ... ?> is run as an external command
<?! external mode: everything in <?! ... ?> is run as an external command.

The code mode is started by `<?` followed by any number of whitespaces
or line breaks.
Expand All @@ -82,11 +82,11 @@ The Generated Script

The generated script:

- is in its own package, named based on the input filename
- `use`s `5.010`, `strict`, and `warnings`
- is in its own package, named based on the input filename and a unique number
- `use`s `5.010001`, `strict`, and `warnings`
- provides constants `true` (=`!!1`) and `false` (=`!!0`) (with `use constant`)
- Declares `my %D` and initializes `%D` based on any **-D** options you provide
- Declares `my %S` and initializes `%S` based on any **-s** options you provide
- declares `my %D` and initializes `%D` based on any **-D** options you provide
- declares `my %S` and initializes `%S` based on any **-s** options you provide

Other than that, everything in the script comes from your input file(s).
Use the **-E** option to see the generated script.
Expand Down Expand Up @@ -159,7 +159,7 @@ So `<?/ ... ?>` is effectively a shorthand for `<? print "\n"; ... ?>`.

The example

<?!echo Howdy!?>
<?! echo Howdy! ?>

produces the output

Expand Down Expand Up @@ -203,18 +203,21 @@ In this case words like `fooSomeWord` will become `barSomeWord`.

will run `some_perl_code;` at the time of script generation. Whatever output
the perl code produces will be included verbatim in the script output.
Within `some_perl_code`, the current PerlPP instance is available as `$PSelf`.

This can be used to dynamically select which files you want to include,
using the provided `Include()` function. For example:
using the provided `Include()` method. For example:

<?:macro my $fn="some_name"; Include $fn; ?>
<?:macro my $fn="some_name"; $PSelf->Include($fn); ?>

has the same effect as

<?:include some_name ?>

but `$fn` can be determined programmatically. Note that it is not currently
possible to select the filename to `Include` based on defines set with **-D**,
since those do not take effect until the script has been generated.
but `$fn` can be determined programmatically. Note that defines set with
**-D** or **-s** do not take effect effect until after the script has been
generated, which is after the macro code runs. However, those are available
as hashes `$PSelf->{Defs}` and `$PSelf->{Sets}` in macro code.

Capturing
---------
Expand Down Expand Up @@ -298,15 +301,16 @@ Tests with `<?:if NAME ... ?>` and `<?:elsif NAME ... ?>` have two restrictions:

For example, `<?:if FOO eq "something" ?>` (note the whitespace before `?>`!)
will work fine. However, if you want to test `(FOO+1)*3`, you will need
to use the full Perl code.
to use the full Perl code `<? if( (FOO+1)*3 == 42 ) { ... } ?>` instead of
`<?:if ?>` and `<?:endif?>`.

Other Features
--------------

### Custom Preprocessors

It's possible to create your own pre/post-processors in a `<?:macro ?>` block
using `PerlPP::AddPreprocessor` and `PerlPP::AddPostprocessor`.
using `$PSelf->AddPreprocessor` and `$PSelf->AddPostprocessor`.
This feature is used in [BigBenBox](https://github.com/d-ash/BigBenBox) for
generating code in the C programming language.

Expand All @@ -329,14 +333,6 @@ and create corresponding *~/.vim/after/syntax/FILETYPE.vim*

FILETYPE can be determined with `:set ft?`

## Developing PerlPP

Perlpp should run on any Perl v5.10+. However, it does require `Getopt::Long`
v2.50 or higher, so you might have to grab that from CPAN.
To run the tests, you also need to grab `IPC::Run3`.

The `Makefile` just runs the tests in `t/`; there is no build step.

## Copyright

Distributed under the MIT license --- see
Expand Down
2 changes: 1 addition & 1 deletion lib/Text/PerlPP.pm
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package Text::PerlPP;

# Semantic versioning, packed per Perl rules. Must always be at least one
# digit left of the decimal, and six digits right of the decimal.
our $VERSION = '0.500002';
our $VERSION = '0.500004';

use 5.010001;
use strict;
Expand Down
3 changes: 1 addition & 2 deletions t/02-basic.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use rlib 'lib';
use PerlPPTest;

use IPC::Run3;
(my $whereami = __FILE__) =~ s/02-basic\.t$//;
#diag join(' ', 'File is', __FILE__, 'whereami', $whereami);

Expand Down Expand Up @@ -39,7 +38,7 @@ my @testcases=(

); #@testcases

plan tests => count_tests(\@testcases, 1, 2);
plan tests => scalar count_tests(\@testcases, 1, 2);

for my $lrTest (@testcases) {
my ($testin, $refout, $referr) = @$lrTest;
Expand Down
2 changes: 1 addition & 1 deletion t/02-readme.t
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ RESULT
[ '<?= "!" . "?>foo<?= 42 ?><?" . "bar" ?>', '!foo42bar' ],
); #@testcases

plan tests => count_tests(\@testcases, 1, 2);
plan tests => scalar count_tests(\@testcases, 1, 2);

for my $lrTest (@testcases) {
my ($testin, $refout, $referr) = @$lrTest;
Expand Down
2 changes: 1 addition & 1 deletion t/03-cmdline.t
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ $testcases->load('-v','',qr/\bversion\b/)->

; #$testcases

plan tests => count_tests($testcases->arr, 3, 4);
plan tests => scalar count_tests($testcases->arr, 3, 4);

for my $lrTest (@{$testcases->arr}) {
my ($where, $opts, $testin, $out_re, $err_re) = @$lrTest;
Expand Down
2 changes: 1 addition & 1 deletion t/04-include.t
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ my @testcases=(
"a\nb\nc\n"],
); #@testcases

plan tests => count_tests(\@testcases, 2, 3);
plan tests => scalar count_tests(\@testcases, 2, 3);

for my $lrTest (@testcases) {
my ($lineno, $testin, $refout, $referr) = @$lrTest;
Expand Down
46 changes: 25 additions & 21 deletions t/05-external-command.t
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
#!/usr/bin/env perl
# Tests of perlpp <?!...?> external commands
# Tests of perlpp <?!...?> external commands.
#
# TODO: On non-Unix, test only `echo` with no parameters.
# Note: On non-Unix, we test only `echo` with no parameters.
# On non-Unix, non-Windows, we skip this because yours truly doesn't know
# enough about what external commands are available! :)

use rlib 'lib';
use PerlPPTest qw(:DEFAULT quote_string);
use List::Util 'any';

if(any { $_ eq $^O } 'VMS', 'os390', 'os400', 'riscos', 'amigaos') {
plan skip_all => "I don't know how to run this test on $^O";
exit;
my $os = $^O; # so we can mock $^O to test this test code!

if(any { $_ eq $os } 'VMS', 'os390', 'os400', 'riscos', 'amigaos') {
plan skip_all => "I don't know how to run this test on $os";
}

(my $whereami = __FILE__) =~ s/macro\.t$//;
Expand Down Expand Up @@ -38,26 +41,27 @@ do {
is($out, "howdy\n", "basic echo");
};

if (any { $_ eq $^O } 'dos', 'os2', 'MSWin') {
skip "I don't know how to run the rest of the tests on $^O", $ntests-1;
exit;
}
SKIP: {
if (any { $_ eq $os } 'dos', 'os2', 'MSWin32') {
skip "I don't know how to run the rest of the tests on $os", $ntests-1;
}

for my $lrTest (@testcases) {
my ($opts, $testin, $out_re, $err_re) = @$lrTest;
my ($out, $err);
for my $lrTest (@testcases) {
my ($opts, $testin, $out_re, $err_re) = @$lrTest;
my ($out, $err);

#diag "perlpp $opts <<<@{[quote_string $testin]}";
run_perlpp $opts, \$testin, \$out, \$err;
#diag "perlpp $opts <<<@{[quote_string $testin]}";
run_perlpp $opts, \$testin, \$out, \$err;

if(defined $out_re) {
like($out, $out_re);
}
if(defined $err_re) {
like($err, $err_re);
}
if(defined $out_re) {
like($out, $out_re);
}
if(defined $err_re) {
like($err, $err_re);
}

} # foreach test
} # foreach test
} #SKIP

# TODO test -o / --output, and processing input from files rather than stdin

Expand Down
2 changes: 1 addition & 1 deletion t/06-macro.t
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ my @testcases=(

); #@testcases

plan tests => count_tests(\@testcases, 2, 3);
plan tests => scalar count_tests(\@testcases, 2, 3);

for my $lrTest (@testcases) {
my ($opts, $testin, $out_re, $err_re) = @$lrTest;
Expand Down
28 changes: 28 additions & 0 deletions t/08-persistent-state.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!perl
# PerlPP: test persistence of state across calls to Main
use rlib 'lib';
use PerlPPTest;

# When testing perlpp as an external command, there is by definition no state
# persistence. Therefore, skip this test file.
if($ENV{PERLPP_NOUSE}) {
plan skip_all => 'Persistent state not tested in this configuration (PERLPP_NOUSE)';
}

plan tests => 3;

my ($in, $out, $err);
my @ioe=\($in, $out, $err);
my $instance = Text::PerlPP->new;

$in = '';
run_perlpp {instance=>$instance, args=>['-D','foo=42']}, @ioe;
is($out, '', 'first call returns nothing');
is($err, '', 'first call succeeds');

$in = 'foo';
run_perlpp {instance=>$instance}, @ioe;
is($out, '42', 'definition carries forward');

done_testing();
# vi: set ts=4 sts=4 sw=4 et ai: #
22 changes: 18 additions & 4 deletions t/lib/PerlPPTest.pm
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,29 @@ sub L {
} #L

# run_perlpp: Run perlpp
# Args: $lrArgs, $refStdin, $refStdout, $refStderr
# Args: $args, $refStdin, $refStdout, $refStderr
# $args can be: a string, in which case it is split with shellwords();
# an arrayref, in which case it is used as the args; or
# a hashref with (all optional):
# {args} string or arrayref as above
# {instance} an existing Text::PerlPP instance to use
sub run_perlpp {
#say STDERR "args ", Dumper(\@_);
#say STDERR "run_perlpp: ", Dumper(\@_);
my $lrArgs = shift;
my $instance;
if(ref $lrArgs eq 'HASH') {
$instance = $lrArgs->{instance}; # nonexistent => falsy, so it's OK
$lrArgs = $lrArgs->{args}; # or undef, which will become [] below.
#say STDERR "args updated: ", Dumper($lrArgs);
}

my $refStdin = shift // \(my $nullstdin);
my $refStdout = shift // \(my $nullstdout);
my $refStderr = shift // \(my $nullstderr);

my $retval;

$lrArgs = [shellwords($lrArgs)] if ref $lrArgs ne 'ARRAY';
$lrArgs = [shellwords($lrArgs // '')] if ref $lrArgs ne 'ARRAY';
#do { (my $args = Dumper($lrArgs)) =~ s/^/##/gm;
#say STDERR "## args:\n$args"; };

Expand Down Expand Up @@ -76,6 +88,8 @@ sub run_perlpp {

} else { # Run perl code under this perl
#say STDERR "# running perlpp internal";
$instance = Text::PerlPP->new unless $instance;

#say STDERR "# redirecting stdin";
open local(*STDIN), '<', $refStdin or die $!;
#say STDERR "# redirected stdin";
Expand All @@ -86,7 +100,7 @@ sub run_perlpp {
($$refStdout, $$refStderr, @result) = capture {
# Thanks to http://www.perlmonks.org/bare/?node_id=289391 by Zaxo
#say STDERR "# running perlpp";
my $result = Text::PerlPP->new->Main($lrArgs);
my $result = $instance->Main($lrArgs);
#say STDERR "# done running perlpp";
$result;
};
Expand Down

0 comments on commit d6e73ca

Please sign in to comment.