mirror of https://github.com/l4ka/pistachio.git
204 lines
5.2 KiB
Perl
Executable File
204 lines
5.2 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
######################################################################
|
|
##
|
|
## Copyright (C) 2001, Karlsruhe University
|
|
##
|
|
## File path: stripcpp
|
|
## Description: Utility for stripping out certain cpp defined code.
|
|
##
|
|
## @LICENSE@
|
|
##
|
|
## $Id: stripcpp,v 1.1 2002/08/29 11:13:24 joshua Exp $
|
|
##
|
|
######################################################################
|
|
|
|
my @files, %defs;
|
|
|
|
|
|
## Parse args
|
|
while ($arg = shift) {
|
|
if ($arg =~ /^-D(\w+)(=(\S+))?/) {
|
|
$defs{$1} = $3 eq '' ? 1 : $3;
|
|
} elsif ($arg =~ /^-U(\w+)/) {
|
|
$undefs{$1} = 1;
|
|
} elsif ($arg =~ /^--?h(elp)?$/) {
|
|
USAGE (0);
|
|
} elsif ($arg =~ /^-/) {
|
|
USAGE (1);
|
|
} else {
|
|
push (@files, $arg);
|
|
}
|
|
}
|
|
|
|
USAGE (1) unless @files;
|
|
|
|
sub USAGE {
|
|
my $status = shift;
|
|
$0 =~ s,^(.*/),,;
|
|
print STDERR "USAGE: $0 [-Uvar...] [-Dvar...] [-Dvar=value..] file...\n\n";
|
|
exit $status;
|
|
}
|
|
|
|
## Slurp whole files
|
|
undef $/;
|
|
|
|
select (STDIN); $| = 1;
|
|
select (STDOUT); $| = 1;
|
|
|
|
## Modify files. This is not terribly efficient since we put the whole
|
|
## file into a string and perform a large number of regexp searches and
|
|
## replacements on it.
|
|
foreach $file (@files) {
|
|
open (F, $file) || die "open ($file): $!\n";
|
|
my $contents = <F>;
|
|
close F;
|
|
|
|
my $changed = 0;
|
|
my $num, $cnt = 0;
|
|
|
|
## Markup nested ifdefs
|
|
while ($contents =~ /^(\#\s*(if|ifn?def|elif|else|endif))/m) {
|
|
my $sub = "!!!";
|
|
if ($2 eq 'if' || $2 eq 'ifdef' || $2 eq 'ifndef') {
|
|
$cnt++;
|
|
$sub = "!!! beg<$cnt>";
|
|
} elsif ($2 eq 'elif') {
|
|
$sub = "!!! elif<$cnt>";
|
|
} elsif ($2 eq 'else') {
|
|
$sub = "!!! else<$cnt>";
|
|
} elsif ($2 eq 'endif') {
|
|
$sub = "!!! end<$cnt>";
|
|
$cnt--;
|
|
}
|
|
$contents =~ s/^(\#\s*(if|ifn?def|elif|else|endif))/$sub$1/m;
|
|
}
|
|
|
|
## Start fixing up our modifications and possibly removing blocks.
|
|
## Begin with the outhermost nesting.
|
|
$cnt = 1;
|
|
do {
|
|
$num = 0;
|
|
|
|
while ($contents =~ /^!!! (\w+)<$cnt>(\#\s*)(\w+)\s*(\W*(\w+).*)/m) {
|
|
my $cut = 0;
|
|
my $keep = 0;
|
|
my $firstblock = 0;
|
|
|
|
$firstblock = 1 if $3 eq 'if' || $3 eq 'ifdef' || $3 eq 'ifndef';
|
|
|
|
if ($3 eq 'ifdef') {
|
|
if ($undefs{$5}) { $cut = 1; }
|
|
elsif ($defs{$5}) { $keep = 1; }
|
|
}
|
|
elsif ($3 eq 'ifndef') {
|
|
if ($undefs{$5}) { $keep = 1; }
|
|
elsif ($defs{$5}) { $cut = 1; }
|
|
}
|
|
elsif ($3 eq 'if' || $3 eq 'elif') {
|
|
my $expr = $4;
|
|
my $elif = ($3 eq 'elif');
|
|
if ($expr =~ m,^[\(\s]*(!)?\s*defined\s*\(\s*(\w+)\s*\)\s*[\)\s]*(\s*/\*.*?\*/)*\s*$,) {
|
|
## Simple ifdef like expression
|
|
if ($undefs{$2}) {
|
|
if ($1 eq '!') { $keep = 1; }
|
|
else { $cut = 1; }
|
|
}
|
|
elsif ($defs{$2}) {
|
|
if ($1 eq '!') { $cut = 1; }
|
|
else { $keep = 1; }
|
|
}
|
|
} else {
|
|
## More complex expression
|
|
my $expr = $4;
|
|
my @words;
|
|
while ($expr =~ s/\bdefined\s*\(\s*(\w+)\s*\)//) {
|
|
push (@words, $1) if $defs{$1} || $undefs{$1};
|
|
}
|
|
if (@words) {
|
|
## Complex expression containing some of our defined words
|
|
my ($pfx, $line) = ($contents =~ /(.*?\n)!!! \w+<$cnt>(.*?)\n/s);
|
|
my $linenum = ($pfx =~ tr/\n/\n/) + 1;
|
|
my $fname = $file; $fname =~ s,^\./,,;
|
|
my $yesno;
|
|
print ("In file \"$fname\", line $linenum, complex expression:\n",
|
|
" $line\n",
|
|
"\nRemove block (y/n): ");
|
|
$/ = "\n";
|
|
do {
|
|
chomp ($yesno = <STDIN>);
|
|
} while ($yesno !~ /[yYnN]/);
|
|
undef $/;
|
|
$cut = ($yesno eq 'y' || $yesno eq 'Y') ? 1 : 0;
|
|
if (!$cut) {
|
|
## Remove subexpression(s)
|
|
foreach $word (@words) {
|
|
while ($line =~
|
|
s/\s*(&&|\|\|)\s*(!\s*)?defined\s*\(\s*$word\s*\)//) {}
|
|
while ($line =~
|
|
s/(!\s*)?defined\s*\(\s*$word\s*\)\s*(&&|\|\|)\s*//) {}
|
|
}
|
|
print "Writing new expression:\n $line\n";
|
|
$contents =~ s/\n!!! \w+<$cnt>.*?\n/\n$line\n/;
|
|
$changed = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($keep) {
|
|
## Keep the current block
|
|
if (!$firstblock) {
|
|
# Remove beginning of ifdef
|
|
$contents =~ s/(^|\n)\#\s*if(?!.*?\n\#\s*if).*?(\n!!! \w+<$cnt>)/\n$1/s;
|
|
}
|
|
$contents =~ s/\n!!! \w+<$cnt>.*?\n/\n/s;
|
|
$contents =~ /^!!! (else|elif|end)<$cnt>/m;
|
|
if ($1 eq 'end') {
|
|
# Just remove endif
|
|
$contents =~ s/\n!!! end<$cnt>.*?\n/\n/s;
|
|
} elsif ($1 eq 'else' || $1 eq 'elif') {
|
|
# Remove else or elif part too
|
|
$contents =~ s/\n!!! el(se|if)<$cnt>.*?\n!!! end<$cnt>.*?\n/\n/s;
|
|
}
|
|
$changed = 1;
|
|
}
|
|
|
|
elsif ($cut) {
|
|
## Remove current block
|
|
$contents =~ s/\n!!! \w+<$cnt>.*?(\n!!! \w+<$cnt>)/\n$1/s;
|
|
if ($firstblock) {
|
|
$contents =~ /^!!! (else|elif|end)<$cnt>/m;
|
|
if ($1 eq 'end') {
|
|
## Just remove endif
|
|
$contents =~ s/\n!!! end<$cnt>.*?\n/\n/s;
|
|
} elsif ($1 eq 'elif') {
|
|
## Convert elif into if
|
|
$contents =~ s/\n!!! elif<$cnt>(\#\s*)elif/\n$1if/s;
|
|
} elsif ($1 eq 'else') {
|
|
## Remove else and endif
|
|
$contents =~ s/\n!!! else<$cnt>.*?\n/\n/s;
|
|
$contents =~ s/\n!!! end<$cnt>.*?\n/\n/s;
|
|
}
|
|
}
|
|
$changed = 1;
|
|
}
|
|
|
|
else {
|
|
## Do not modify current block
|
|
$contents =~ s/(^|\n)!!! (\w+)<$cnt>/\n/s;
|
|
}
|
|
$num++;
|
|
}
|
|
|
|
## Increase nesting
|
|
$cnt++;
|
|
} while ($num > 0);
|
|
|
|
if ($changed) {
|
|
open (NEW, "> $file.new") || die "open (> $file.new): $!\n";
|
|
print NEW "$contents" || die "write ($file.new): $!\n";
|
|
close NEW;
|
|
rename "$file.new", "$file" || die "rename $file.new, $file: $!\n";
|
|
}
|
|
}
|