ocr-tools/tools/yapp.pl

287 lines
4.4 KiB
Perl

#!/usr/bin/env perl
#
# Yet another preprocessor
#
# $Id: yapp,v 1.5 1997/10/24 07:51:05 mhw Exp $
#
%vars = ('' => '$');
@incPath = (".");
sub Error
{
print STDERR $_[0], "\n";
exit(1);
}
sub VarSubst
{
my ($varName, $undefOkay) = @_;
if (defined($vars{$varName}))
{
return $vars{$varName};
}
elsif (!$undefOkay)
{
&Error("Undefined variable '$varName' in $fileName line $.");
}
}
sub NullFilter
{
0;
}
sub IfFilter
{
local $_ = $_[0];
if (/^##else(\s+.*)?/)
{
return 1;
}
elsif (/^##endif(\s+.*)?/)
{
return 2;
}
else
{
return 0;
}
}
sub DoFile
{
local $fileName = $_[0];
my $path;
local *FILE;
if ($fileName =~ m|^/|)
{
$path = $fileName;
}
else
{
for $dir (@incPath)
{
if (-e "$dir/$fileName")
{
$path = "$dir/$fileName";
last;
}
}
}
if ($path eq "")
{
&Error("Can't find '$fileName', from $fileName line $.");
}
open(FILE, "<$path") || &Error("Can't open $path: $!");
&DoOpenFile(*FILE, *NullFilter, 0);
close(FILE) || die;
0;
}
sub DoPrepass
{
local ($_, $skipFlag) = @_;
return "" if /^###/;
s/\s*###.*//; # Strip comments
s/\${(\w+)}/&VarSubst($1, $skipFlag)/eg; # Do variable substitutions
$_;
}
sub DoOpenFile
{
local *FILE = $_[0];
local *filter = $_[1];
my $skipFlag = $_[2];
my $result;
local $_;
while (<FILE>)
{
$_ = &DoPrepass($_, $skipFlag);
if ($result = &filter($_))
{
return $result;
}
elsif (/^##(\w*)(\s+(.*))?/)
{
my ($cmd, $params) = ($1, $3);
if ($cmd =~ /^if/)
{
my $condition;
my $ifStartLine = $.;
if ($cmd eq "if")
{
if ($params =~ /^(\d+)\s*$/)
{
$condition = int($1);
}
elsif ($params =~ /^(\d+)\s*([=!]=|[<>]=?)\s*(\d+)\s*$/)
{
my ($left, $op, $right) = ($1, $2, $3);
$condition = eval($left . $op . $right);
}
elsif ($params =~ /^(\S+)\s*(eq|ne)\s*(\S+)\s*$/)
{
my ($left, $op, $right) = ($1, $2, $3);
$left =~ s/([\\'])/\\$1/g;
$right =~ s/([\\'])/\\$1/g;
$condition = eval("'$left' $op '$right'");
}
else
{
&Error("Invalid ##if params: '$params' " .
"in $fileName line $.");
}
}
elsif ($cmd =~ /^ifn?def$/)
{
if ($params =~ /^(\w+)\s*$/)
{
$condition = defined($vars{$1});
$condition = !$condition if ($cmd eq "ifndef");
}
else
{
&Error("Invalid ##$cmd param: '$params' " .
"in $fileName line $.");
}
}
# Do main body of if
$result = &DoOpenFile(*FILE, *IfFilter,
$skipFlag || !$condition);
if ($result == 1) # an '##else' was found
{
# Handle else
$result = &DoOpenFile(*FILE, *IfFilter,
$skipFlag || $condition);
}
if ($result == 1) # a second '##else' was found
{
&Error("Two ##else's in a row in $fileName line $.");
}
elsif ($result == 0) # EOF was encountered
{
&Error("Unterminated ##if " .
"in $fileName line $ifStartLine");
}
}
elsif ($cmd eq "include")
{
if ($skipFlag)
{
}
elsif ($params =~ /^"(.*)"\s*$/)
{
my $incFile = $1;
&DoFile($incFile);
}
else
{
&Error("Invalid ##include params: '$params'");
}
}
elsif ($cmd eq "set")
{
if ($params =~ /^(\w+)=<<(")(.*)"\s*$/ or
$params =~ /^(\w+)=<<(')(.*)'\s*$/)
{
my $varName = $1;
my $quoteChar = $2;
my $endTag = $3 . "\n";
my $value;
while (<FILE>)
{
if ($_ eq $endTag)
{
chop $value;
last;
}
else
{
if ($quoteChar eq '"')
{
$_ = &DoPrepass($_, $skipFlag);
}
$value .= $_;
}
}
if (!$skipFlag)
{
$vars{$varName} = $value;
}
}
elsif ($params =~ /^(\w+)="(.*)"\s*$/ or
$params =~ /^(\w+)=(\S*)\s*$/)
{
if (!$skipFlag)
{
$vars{$1} = $2;
}
}
else
{
&Error("Invalid ##set command: '$params'");
}
}
else
{
&Error("Unrecognized command: '$_'");
}
}
elsif (!$skipFlag)
{
print;
}
}
return 0;
}
$optEnable = 1;
foreach (@ARGV)
{
if ($optEnable and /^-/)
{
if (/^--$/)
{
$optEnable = 0;
}
elsif (/^-D(\w+)=(.*)$/)
{
$vars{$1} = $2;
}
elsif (/^-I(.*)$/)
{
unshift @incPath, $1;
}
else
{
&Error("Unrecognized option: '$_'");
}
}
else
{
&DoFile($_);
}
}
#
# vi: ai ts=4
# vim: si
#