ppp
ppp is yet another preprocessor for Perl, written in Perl. So why use it? Because
it offers one feature that makes all the difference: Like all preprocessors, it
provides the effects of conditional compilation, but it does so offline.
Under normal usage, the code runs without the preprocessor. The preprocessor need only run
when one of the conditional compilation variables changes.
ppp provides the functionality of conditional compilation in-place. That is,
the .pl file is directly modified, but no information is discarded.
Instead, both sides of all #ifdefs remain in the run-time code, but
with their 'inactive' sides commented out. For example:
#ifdef FOO
FooIsDefined();
#else /* !FOO */
# FooIsNOTDefined();
#endif /* FOO */
The 'false' side code and the #ifdef structure are seen as comments, and thus ignored by the perl compiler.
If the value of 'FOO' changed in the above example, say from 'true' to 'false', then when the
ppp preprocessor is rerun, the code becomes:
#ifdef FOO
# FooIsDefined();
#else /* !FOO */
FooIsNOTDefined();
#endif /* FOO */
The code is still all there. Nothing is lost, and any #ifdef can have its sense reversed at any time.
Only when the value of the control variables of #ifdefs change is it necessary to re-run the preprocessor, and then only once.
So the semantics of conditional compilation are achieved statically. And thus one can have the effects
of conditional compilation without the run-time overhead.
For Perl scripts, this is a big win. We may modify those scripts all we want, and do not have to run
the preprocessor on each modification, nor on each time the script is run.
Main Features
- Ability to toggle the state of #ifdef constructs in-place. The #ifdefs/#ifndefs can be nested, and ppp will
toggle the comment state of their contents appropriately. All the while maintaining a maximum of one
comment character per line, including on the #ifdefs, regardless of the level of nesting.
- Ability to delete code in #ifdefs associated with specific variables.
Only code under #ifdefs for those variables are changed, all other code remains intact.
This allows you to cleanup code in a more reliable way than hand-deleting such code.
This encourages uses of #ifdefs, as they can be stripped later.
Supported preprocessor constructs
ppp supports the following standard preprocessor features:
- #define %var% [value]
- #define %pseudo_fn%([arg-list])
- #undef %var%
- #include "path"
- #ifdef %var% .. #else .. #endif
- #ifndef %var% .. #else .. #endif
- #if <expr> .. #else .. #endif
- Macro variable expansion
Extended preprocessor constructs:
ppp also adds the following extensions:
- Optional multi-line #defines without \'s at ends of each line. If the first line ends in a '\' right after the variable,
instead uses a terminating #enddef. So you can define blocks of code without modification:
#define VAR \
<code-line1>
<code-line2>
..
#enddef
- Optional macro arguments allows macros to expand with a variable number of arguments, and even
re-arrange them. The optional parameters are specified as '..' in the parameter list
and the expansion list. The '...' parameter can be used anywhere any other parameter can be used. For example:
#define Foo(...) print(...)
#define Add_X(...) foo('x', ...)
#define Rev(a, b, ...) bar(..., b, a)
- Macro variables can have leading '$' chars, so can replace Perl variables in code. For example:
#define $foo $bar
my $foo = 2; # After macro expansion: my $bar = 2
-
Macro expansion within quoted strings. This allows replacement of variables
with constants, often very useful when creating multiple versions of a file. It allows test code
to use variables, but release code to use constants.
To allow a macro to expand within a string, it is only necessary to
define flag PP_VARS_ACTIVE_IN_STRINGS. For example:
#ifdef RELEASE
#define PP_VARS_ACTIVE_IN_STRINGS
#define $VER 14
#define $VER_DATE 03/23/10
#define $VER_TYPE RELEASE
#undef PP_VARS_ACTIVE_IN_STRINGS
#endif
our $VERNO = "Ver $VER ($VER_DATE) $VER_TYPE";
Installation
The ppp preprocessor runs as a standalone script, and does not require perl to installed
anywhere, and does not require any modules other than the perl.exe executable and its .dll.
Back to Downloads Page
Last Updated: 1/21/13