ppp Perl Preprocessor  
 

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