diff options
Diffstat (limited to 'ACE/MPC/modules/Depgen/Preprocessor.pm')
-rw-r--r-- | ACE/MPC/modules/Depgen/Preprocessor.pm | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/ACE/MPC/modules/Depgen/Preprocessor.pm b/ACE/MPC/modules/Depgen/Preprocessor.pm new file mode 100644 index 00000000000..4dea2fc4117 --- /dev/null +++ b/ACE/MPC/modules/Depgen/Preprocessor.pm @@ -0,0 +1,145 @@ +package Preprocessor; + +# ************************************************************ +# Description : Preprocesses the supplied file. +# Author : Chad Elliott +# Create Date : 2/10/2002 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; +use FileHandle; +use File::Basename; + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub new { + my($class, $macros, $ipaths, $exclude) = @_; + return bless {'macros' => $macros, + 'ipaths' => $ipaths, + 'exclude' => $exclude, + 'files' => {}, + 'ifound' => {}, + 'recurse' => 0, + }, $class; +} + + +sub process { + my($self, $file, $noinline, $noincs) = @_; + my $fh = new FileHandle(); + + ## Open the file, but if we can't we'll just silently ignore it. + if (open($fh, $file)) { + my @zero; + my $ifcount = 0; + my $files = $self->{'files'}; + my $dir = dirname($file); + + ## We only need to keep track of recursion inside this block + my $recurse = ++$self->{'recurse'}; + + $$files{$file} = []; + while(<$fh>) { + ## As an optimization, use a very simple regular expression on the + ## outside that all of the inner regular expressions have in + ## common. That way we go down the path of if elsif only if it is + ## even possible due to the outside regular expression. + ## index() is faster than a regular expression, so use index first. + next if (index($_, '#') == -1 || not /^\s*#/); + + ## Remove same line c comments (no need to worry about c++ + ## comments due to the regular expressions) inside this if statement. + ## This saves about 5% off of processing the ace directory + ## and we only need to strip comments if we are actually + ## going to look at the string. + $_ =~ s/\/\*.*\*\///o; + + if (/^\s*#\s*endif/) { + --$ifcount; + if (defined $zero[0] && $ifcount == $zero[$#zero]) { + pop(@zero); + } + } + elsif (/^\s*#\s*if\s+0/) { + push(@zero, $ifcount); + ++$ifcount; + } + elsif (/^\s*#\s*if/) { + ++$ifcount; + } + elsif (!defined $zero[0] && + /^\s*#\s*include\s+[<"]([^">]+)[">]/o) { + ## Locate the include file + my $inc; + if (exists $self->{'ifound'}->{$1}) { + $inc = $self->{'ifound'}->{$1}; + } + else { + foreach my $dirp (@{$self->{'ipaths'}}) { + if (-r "$dirp/$1") { + $inc = "$dirp/$1"; + last; + } + } + + if (!defined $inc) { + ## If the file we're currently looking at contains a + ## directory name then, we need to look for include + ## files in that directory. + if (-r "$dir/$1") { + $inc = "$dir/$1"; + } + } + $self->{'ifound'}->{$1} = $inc; + } + + ## If we've found the include file, then process it too. + next if (not defined $inc); + + $inc =~ s/\\/\//go; + if (!$noinline || + ($recurse == 1 || $inc !~ /\.i(nl)?$/o)) { + push(@{$$files{$file}}, $inc); + if (!defined $$files{$inc}) { + ## Process this file, but do not return the include files + if (!defined $self->{'exclude'}->{substr($inc, rindex($inc, '/') + 1)}) { + $self->process($inc, $noinline, 1); + } + } + } + } + } + close($fh); + + ## We only need to keep track of recursion inside this block + --$self->{'recurse'}; + } + + ## This has to be outside the if (open(... + ## If the last file to be processed isn't accessable then + ## we still need to return the array reference of includes. + if (!$noincs) { + my @files = ($file); + my %ifiles; + + foreach my $processed (@files) { + foreach my $inc (@{$self->{'files'}->{$processed}}) { + if (!defined $ifiles{$inc}) { + $ifiles{$inc} = 1; + push(@files, $inc); + } + } + } + shift(@files); + return \@files; + } +} + + +1; |