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.