NAME

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

SYNOPSIS

# in perl
use Preproc::Tiny;
pp_files("main.c.pp");
my $result = pp_text($input);

# 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:
 @@ my $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_files

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

pp_text

Work horse of pp_files; receives the input string with template text and returns the output text after running the preprocessor.

INTERNALS

The module works by transforming the input file into perl code and executing it with eval.

If there is any error in the input that causes a compile error in the script, the module dies and shows the result perl code. 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

SEE ALSO

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

AUTHOR

Paulo Custodio, <pscust@cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2016-2026 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.