NAME

Preproc::Tiny - Minimal stand-alone preprocessor for code generation using perl

SYNOPSIS

   # in perl
   use Preproc::Tiny;
   pp("main.c.pp");
   
   # in the shell
   $ pp.pl main.c.pp

DESCRIPTION

This preprocessor originated from the need to generate C++ code in a flexible way and without having to adapt to limitations of the several mini-languages of other templating engines available in CPAN. The template language used is just perl.

Being a Tiny module, it has no external dependencies and can be used by just copying the pp.pl file to any executable directory.

The input file has to have a .pp extension. The .pp is removed to generate the output file, e.g.

   $ pp.pl main.c.pp   # parses main.c.pp and generates main.c

Inside the input file, the default action is to copy plain text to the output file, e.g.

   // main.c.pp:
   int main() { return 0; }
   
   // main.c:
   int main() { return 0; }

Any text after '@@' is interpreted as perl code and executed. The global variable $OUT contains the text to be dumped to the output file, e.g.

   // main.c.pp:
   @@ $ret = 0;
   int main() { 
      return @@ $OUT .= $ret.";";
   }
  
   // main.c:
   int main() { 
      return 0;
   }

Perl code can also be interpolated inside the text and span multiple lines by enclosing it between '[@' and '@]', e.g.

   // main.c.pp:
   [@ 
      use strict;
      use warnings;
      my $ret = 0;
   @]
   int main() { 
      return [@ $OUT .= $ret @];
   }
   
   // main.c:
   
   int main() { 
      return 0;
   }

The extra newline after the closing quote can be removed by using '-@]', e.g.

   // main.c.pp:
   [@ 
      use strict;
      use warnings;
      my $ret = 0;
   -@]
   int main() { 
      return [@ $OUT .= $ret @];
   }
   
   // main.c:
   int main() { 
      return 0;
   }

The common case of appending text in the perl section has the shortcut '[@>', e.g.

   // main.c.pp:
   [@ 
      use strict;
      use warnings;
      my $ret = 0;
   -@]
   int main() { 
      return [@> $ret @];
   }
   
   // main.c:
   int main() { 
      return 0;
   }

Global actions can be executed by manipulating the $OUT variable, e.g.

   // main.c.pp:
   int main() {
      return 0;  // comment
   }
   @@ $OUT =~ s!//.*!!g;
   
   // main.c:
   int main() {
      return 0;
   }

Any perl control structure can be used in the code blocks, e.g.

   // main.c.pp:
   @@ $ok = 1;
   int main() {
      return [@ if ($ok) { @] 0 [@ } else { @] 1 [@ } @];
   }
   
   // main.c:
   int main() {
      return  0 ;
   }

EXPORTS

pp

Input argument is the list of the input file names; runs the preprocessor for each input and generates the corresponding output file.

INTERNALS

The module works by transforming the input file into a perl script and executing it. At the end the perl script is removed.

If there is any error in the input that causes a compile error in the script, the module dies and does not remove the script. This allows the error to be investigated, e.g.

   // main.c.pp
   @@ ok=1

causes the error:

   Can't modify constant item in scalar assignment at main.c.pl line N

The file main.c.pl is kept for investigating the error.

SEE ALSO

Template toolkit from CPAN as a full-fledged templating system.

AUTHOR

Paulo Custodio, <pscust@cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2016 by Paulo Custodio

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.22.1 or, at your option, any later version of Perl 5 you may have available.