diff options
author | elliott_c <ocielliottc@users.noreply.github.com> | 2007-03-22 13:40:17 +0000 |
---|---|---|
committer | elliott_c <ocielliottc@users.noreply.github.com> | 2007-03-22 13:40:17 +0000 |
commit | 9b16789b03059f38cc434f9bc0d98dced00ef267 (patch) | |
tree | e57004bcbad72e76551400e83371f435f9b29585 | |
parent | a849dfc222253bc604fdbf3ece1ebaefb5a74aef (diff) | |
download | MPC-9b16789b03059f38cc434f9bc0d98dced00ef267.tar.gz |
ChangeLogTag: Thu Mar 22 14:36:53 UTC 2007 Chad Elliott <elliott_c@ociweb.com>
-rw-r--r-- | ChangeLog | 28 | ||||
-rwxr-xr-x | depgen.pl | 35 | ||||
-rw-r--r-- | modules/Depgen/DependencyEditor.pm | 118 | ||||
-rw-r--r-- | modules/Depgen/DependencyGenerator.pm | 77 | ||||
-rw-r--r-- | modules/Depgen/DependencyWriter.pm | 33 | ||||
-rw-r--r-- | modules/Depgen/DependencyWriterFactory.pm | 42 | ||||
-rw-r--r-- | modules/Depgen/Driver.pm | 255 | ||||
-rw-r--r-- | modules/Depgen/MakeDependencyWriter.pm | 32 | ||||
-rw-r--r-- | modules/Depgen/MakeObjectGenerator.pm | 47 | ||||
-rw-r--r-- | modules/Depgen/NMakeDependencyWriter.pm | 53 | ||||
-rw-r--r-- | modules/Depgen/NMakeObjectGenerator.pm | 28 | ||||
-rw-r--r-- | modules/Depgen/ObjectGenerator.pm | 32 | ||||
-rw-r--r-- | modules/Depgen/ObjectGeneratorFactory.pm | 42 | ||||
-rw-r--r-- | modules/Depgen/Preprocessor.pm | 147 | ||||
-rw-r--r-- | modules/Driver.pm | 3 | ||||
-rw-r--r-- | templates/make.mpd | 2 |
16 files changed, 973 insertions, 1 deletions
@@ -1,3 +1,31 @@ +Thu Mar 22 14:36:53 UTC 2007 Chad Elliott <elliott_c@ociweb.com> + + * depgen.pl: + * modules/Depgen/DependencyEditor.pm: + * modules/Depgen/DependencyGenerator.pm: + * modules/Depgen/DependencyWriter.pm: + * modules/Depgen/DependencyWriterFactory.pm: + * modules/Depgen/Driver.pm: + * modules/Depgen/MakeDependencyWriter.pm: + * modules/Depgen/MakeObjectGenerator.pm: + * modules/Depgen/NMakeDependencyWriter.pm: + * modules/Depgen/NMakeObjectGenerator.pm: + * modules/Depgen/ObjectGenerator.pm: + * modules/Depgen/ObjectGeneratorFactory.pm: + * modules/Depgen/Preprocessor.pm: + + Brought over my dependency generator from ACE. The core of this + dependency generator will be used by the ACE specific version + (just like the core of MPC). + + * modules/Driver.pm: + + Don't perform relative replacement for MPC_ROOT ever. + + * templates/make.mpd: + + Use the new dependency generator instead of makedepend. + Wed Mar 21 16:54:06 UTC 2007 Chad Elliott <elliott_c@ociweb.com> * docs/README: diff --git a/depgen.pl b/depgen.pl new file mode 100755 index 00000000..8d3a96a5 --- /dev/null +++ b/depgen.pl @@ -0,0 +1,35 @@ +eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' + & eval 'exec perl -w -S $0 $argv:q' + if 0; + +# ************************************************************ +# Description : Generate dependencies for Make and NMake. +# Author : Chad Elliott +# Create Date : 5/06/2002 +# $Id$ +# ************************************************************ + +# ************************************************************ +# Pragma Section +# ************************************************************ + +use strict; +use FindBin; +use File::Spec; +use File::Basename; + +my($basePath) = $FindBin::Bin; +if ($^O eq 'VMS') { + $basePath = File::Spec->rel2abs(dirname($0)) if ($basePath eq ''); + $basePath = VMS::Filespec::unixify($basePath); +} +unshift(@INC, $basePath . '/modules/Depgen'); + +require Driver; + +# ************************************************************ +# Main Section +# ************************************************************ + +my($driver) = new Driver(); +exit($driver->run(\@ARGV)); diff --git a/modules/Depgen/DependencyEditor.pm b/modules/Depgen/DependencyEditor.pm new file mode 100644 index 00000000..646ae2ae --- /dev/null +++ b/modules/Depgen/DependencyEditor.pm @@ -0,0 +1,118 @@ +package DependencyEditor; + +# ************************************************************ +# Description : Edits existing dependencies. +# Author : Chad Elliott +# Create Date : 2/10/2002 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; +use FileHandle; + +use DependencyGenerator; + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub new { + return bless { + }, $_[0]; +} + + +sub process { + my($self) = shift; + my($output) = shift; + my($type) = shift; + my($noinline) = shift; + my($macros) = shift; + my($ipaths) = shift; + my($replace) = shift; + my($exclude) = shift; + my($files) = shift; + + ## Back up the original file and receive the contents + my($contents) = undef; + if (-s $output) { + $contents = []; + if (!$self->backup($output, $contents)) { + print STDERR "ERROR: Unable to backup $output\n"; + return 1; + } + } + + ## Write out the new file + my($fh) = new FileHandle(); + if (open($fh, ">$output")) { + if (defined $contents) { + foreach my $line (@$contents) { + print $fh $line; + } + } + + print $fh "# DO NOT DELETE THIS LINE -- depgen.pl uses it.\n", + "# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.\n\n"; + + my($dep) = new DependencyGenerator($macros, $ipaths, $replace, + $type, $noinline, $exclude); + ## Sort the files so the dependencies are reproducible + foreach my $file (sort @$files) { + print $fh $dep->process($file), "\n"; + } + + print $fh "# IF YOU PUT ANYTHING HERE IT WILL GO AWAY\n"; + close($fh); + } + else { + print STDERR "ERROR: Unable to open $output for output\n"; + return 1; + } + + return 0; +} + + +sub backup { + my($self) = shift; + my($source) = shift; + my($contents) = shift; + my($status) = 0; + my($fh) = new FileHandle(); + my($backup) = "$source.bak"; + + if (open($fh, $source)) { + my($oh) = new FileHandle(); + if (open($oh, ">$backup")) { + my($record) = 1; + $status = 1; + while(<$fh>) { + print $oh $_; + if ($record) { + if (index($_, 'DO NOT DELETE') >= 0) { + $record = undef; + } + else { + push(@$contents, $_); + } + } + } + close($oh); + + ## Set file permission + my(@buf) = stat($source); + if (defined $buf[8] && defined $buf[9]) { + utime($buf[8], $buf[9], $backup); + } + } + close($fh); + } + return $status; +} + + +1; diff --git a/modules/Depgen/DependencyGenerator.pm b/modules/Depgen/DependencyGenerator.pm new file mode 100644 index 00000000..58caa43b --- /dev/null +++ b/modules/Depgen/DependencyGenerator.pm @@ -0,0 +1,77 @@ +package DependencyGenerator; + +# ************************************************************ +# Description : Runs the correct dependency generator on the file. +# Author : Chad Elliott +# Create Date : 2/10/2002 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; + +use Preprocessor; +use DependencyWriterFactory; +use ObjectGeneratorFactory; + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub new { + my($class) = shift; + my($macros) = shift; + my($ipaths) = shift; + my($replace) = shift; + my($type) = shift; + my($noinline) = shift; + my($exclude) = shift; + my($self) = bless {'pre' => new Preprocessor($macros, + $ipaths, $exclude), + 'replace' => $replace, + 'dwrite' => DependencyWriterFactory::create($type), + 'objgen' => ObjectGeneratorFactory::create($type), + 'noinline' => $noinline, + }, $class; + + ## Set the current working directory, but + ## escape regular expression special characters + $self->{'cwd'} = Cwd::getcwd() . '/'; + $self->{'cwd'} =~ s/([\+\-\\\$\[\]\(\)\.])/\\$1/g; + + ## Sort the replace keys to get the longest key first. This way + ## when we are replacing portions of the file path, we replace the + ## most we can. + my(@repkeys) = sort { length($b) <=> length($a) } keys %$replace; + $self->{'repkeys'} = \@repkeys; + + return $self; +} + + +sub process { + my($self) = shift; + my($file) = shift; + + ## Generate the dependency string + my($depstr) = $self->{'dwrite'}->process( + $self->{'objgen'}->process($file), + $self->{'pre'}->process($file, $self->{'noinline'})); + + ## Perform the replacements on the dependency string + if ($depstr =~ s/$self->{'cwd'}//go) { + } + else { + my($replace) = $self->{'replace'}; + foreach my $rep (@{$self->{'repkeys'}}) { + $depstr =~ s/$rep/$$replace{$rep}/g; + } + } + + return $depstr; +} + + +1; diff --git a/modules/Depgen/DependencyWriter.pm b/modules/Depgen/DependencyWriter.pm new file mode 100644 index 00000000..c0c82430 --- /dev/null +++ b/modules/Depgen/DependencyWriter.pm @@ -0,0 +1,33 @@ +package DependencyWriter; + +# ************************************************************ +# Description : Base class for all Dependency Writers. +# Author : Chad Elliott +# Create Date : 2/10/2002 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub new { + return bless { + }, $_[0]; +} + + +sub process { + #my($self) = shift; + #my($objects) = shift; + #my($files) = shift; + return ''; +} + + +1; diff --git a/modules/Depgen/DependencyWriterFactory.pm b/modules/Depgen/DependencyWriterFactory.pm new file mode 100644 index 00000000..fd530747 --- /dev/null +++ b/modules/Depgen/DependencyWriterFactory.pm @@ -0,0 +1,42 @@ +package DependencyWriterFactory; + +# ************************************************************ +# Description : Create DependencyWriter objects. +# Author : Chad Elliott +# Create Date : 5/23/2003 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; + +use DependencyWriter; + +# ************************************************************ +# Data Section +# ************************************************************ + +my($writers) = {}; + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub register { + $writers = shift; +} + + +sub create { + if (defined $$writers{$_[0]}) { + return $$writers{$_[0]}->new(); + } + + print STDERR "WARNING: Invalid dependency writer type: $_[0]\n"; + return new DependencyWriter(); +} + + +1; diff --git a/modules/Depgen/Driver.pm b/modules/Depgen/Driver.pm new file mode 100644 index 00000000..3f4e2cc9 --- /dev/null +++ b/modules/Depgen/Driver.pm @@ -0,0 +1,255 @@ +package Driver; + +# ************************************************************ +# Description : Generate dependencies for Make and NMake. +# Author : Chad Elliott +# Create Date : 3/21/2007 +# ************************************************************ + +# ************************************************************ +# Pragma Section +# ************************************************************ + +use strict; +use File::Basename; + +use DependencyEditor; + +# ************************************************************ +# Data Section +# ************************************************************ + +my($version) = '1.1'; +my($os) = ($^O eq 'MSWin32' ? 'Windows' : 'UNIX'); +my(%types) = (); +my(%defaults) = ('UNIX' => 'make', + 'Windows' => 'nmake', + ); + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub BEGIN { + my($fh) = new FileHandle(); + my(%writers) = (); + my(%generators) = (); + + ## Find all the dependency writers and object generators + foreach my $dir (@INC) { + if (opendir($fh, $dir)) { + foreach my $module (readdir($fh)) { + if ($module =~ /(.+)DependencyWriter\.pm$/) { + my($type) = lc($1); + my($class) = $module; + $class =~ s/\.pm$//; + require $module; + $writers{$type} = $class; + $types{$type} = 1; + } + elsif ($module =~ /(.+)ObjectGenerator\.pm$/) { + my($type) = lc($1); + my($class) = $module; + $class =~ s/\.pm$//; + require $module; + $generators{$type} = $class; + } + } + closedir($fh); + } + } + + ## Register them with the right factory + DependencyWriterFactory::register(\%writers); + ObjectGeneratorFactory::register(\%generators); +} + + +sub new { + my($class) = shift; + my($self) = bless {'automatic' => [], + }, $class; + + foreach my $add (@_) { + if ($add =~ /(UNIX|Windows)=(.*)/) { + $defaults{$1} = $2; + } + elsif ($add =~ /automatic=(.*)/) { + my(@auto) = split(/,/, $1); + $self->{'automatic'} = \@auto; + } + else { + print "WARNING: Unknown parameter: $add\n"; + } + } + + return $self; +} + + +sub usageAndExit { + my($self) = shift; + my($opt) = shift; + my($base) = basename($0); + + if (defined $opt) { + print "$opt.\n"; + } + + print "$base v$version\n" . + "Usage: $base [-D<MACRO>[=VALUE]] [-I<include dir>] ", + (defined $self->{'automatic'}->[0] ? "[-A] " : ''), + "[-R <VARNAME>]\n" . + " " . (" " x length($base)) . + " [-e <file>] [-f <output file>] [-i] [-t <type>] [-n]\n" . + " " . (" " x length($base)) . " <files...>\n" . + "\n"; + if (defined $self->{'automatic'}->[0]) { + print "-A Replace paths equal to the following variables with ", + "the corresponding \$()\n value: ", + join(', ', @{$self->{'automatic'}}), ".\n"; + } + print "-D This option sets a macro to an optional value.\n" . + "-I The -I option adds an include directory.\n" . + "-R Replace \$VARNAME paths with \$(VARNAME).\n" . + "-e Exclude dependencies generated by <file>, but not <file> " . + "itself.\n" . + "-f Specifies the output file. This file will be edited if it " . + "already\n exists.\n" . + "-i Do not print an error if no source files are provided.\n" . + "-n Do not include inline files (ending in .i or .inl) in the " . + "dependencies.\n" . + "-t Use specified type ("; + my(@keys) = sort keys %types; + for(my $i = 0; $i <= $#keys; ++$i) { + print "$keys[$i]" . + ($i != $#keys ? $i == $#keys - 1 ? ' or ' : ', ' : '');; + } + print ") instead of the default.\n" . + " The default is "; + @keys = sort keys %defaults; + for(my $i = 0; $i <= $#keys; ++$i) { + my($def) = $keys[$i]; + print $defaults{$def} . " on $def" . + ($i != $#keys ? $i == $#keys - 1 ? ' and ' : ', ' : ''); + } + print ".\n"; + exit(0); +} + + +sub setReplace { + my($self) = shift; + my($replace) = shift; + my($name) = shift; + my($value) = shift; + + if (defined $name) { + ## The key will be used in a regular expression. + ## So, we need to escape some special characters. + $name = File::Spec->canonpath($name); + $name =~ s/([\+\-\\\$\[\]\(\)\.])/\\$1/g; + + $$replace{$name} = $value; + } +} + + +sub run { + my($self) = shift; + my($args) = shift; + my($argc) = scalar(@$args); + my($type) = $defaults{$os}; + my($noinline) = undef; + my(@files) = (); + my(%macros) = (); + my(@ipaths) = (); + my(%replace) = (); + my(%exclude) = (); + my($output) = '-'; + my($needsrc) = 1; + + for(my $i = 0; $i < $argc; ++$i) { + my($arg) = $$args[$i]; + if ($arg =~ /^\-D(\w+)(=(.*))?/) { + $macros{$1} = $3; + } + elsif ($arg =~ /^\-I(.*)/) { + push(@ipaths, File::Spec->canonpath($1)); + } + elsif ($arg eq '-A') { + foreach my $auto (@{$self->{'automatic'}}) { + $self->setReplace(\%replace, $ENV{$auto}, '$(' . $auto . ')'); + } + } + elsif ($arg eq '-R') { + ++$i; + $arg = $$args[$i]; + if (defined $arg) { + my($val) = $ENV{$arg}; + if (defined $val) { + $self->setReplace(\%replace, $val, "\$($arg)"); + } + } + else { + $self->usageAndExit('Invalid use of -R'); + } + } + elsif ($arg eq '-e') { + ++$i; + $arg = $$args[$i]; + if (defined $arg) { + $exclude{$arg} = 1; + } + else { + $self->usageAndExit('Invalid use of -e'); + } + } + elsif ($arg eq '-f') { + ++$i; + $arg = $$args[$i]; + if (defined $arg) { + $output = $arg; + } + else { + $self->usageAndExit('Invalid use of -f'); + } + } + elsif ($arg eq '-i') { + $needsrc = undef; + } + elsif ($arg eq '-n') { + $noinline = 1; + } + elsif ($arg eq '-h') { + $self->usageAndExit(); + } + elsif ($arg eq '-t') { + ++$i; + $arg = $$args[$i]; + if (defined $arg && defined $types{$arg}) { + $type = $arg; + } + else { + $self->usageAndExit('Invalid use of -t'); + } + } + elsif ($arg =~ /^[\-+]/) { + ## We will ignore unknown options + ## Some options for aCC start with + + } + else { + push(@files, $arg); + } + } + + if (!defined $files[0]) { + if ($needsrc) { + $self->usageAndExit('No files specified'); + } + } + + my($editor) = new DependencyEditor(); + return $editor->process($output, $type, $noinline, \%macros, + \@ipaths, \%replace, \%exclude, \@files); +} diff --git a/modules/Depgen/MakeDependencyWriter.pm b/modules/Depgen/MakeDependencyWriter.pm new file mode 100644 index 00000000..ee9d0db4 --- /dev/null +++ b/modules/Depgen/MakeDependencyWriter.pm @@ -0,0 +1,32 @@ +package MakeDependencyWriter; + +# ************************************************************ +# Description : Generates generic Makefile dependencies. +# Author : Chad Elliott +# Create Date : 2/10/2002 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; +use DependencyWriter; + +use vars qw(@ISA); +@ISA = qw(DependencyWriter); + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub process { + my($objects) = $_[1]; + my($files) = $_[2]; + + ## Sort the dependencies to make them reproducible + return "@$objects: \\\n " . join(" \\\n ", sort @$files) . "\n"; +} + + +1; diff --git a/modules/Depgen/MakeObjectGenerator.pm b/modules/Depgen/MakeObjectGenerator.pm new file mode 100644 index 00000000..67e5cf17 --- /dev/null +++ b/modules/Depgen/MakeObjectGenerator.pm @@ -0,0 +1,47 @@ +package MakeObjectGenerator; + +# ************************************************************ +# Description : Generates object files for generic Makefiles. +# Author : Chad Elliott +# Create Date : 5/23/2003 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; +use ObjectGenerator; + +use vars qw(@ISA); +@ISA = qw(ObjectGenerator); + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub process { + my($noext) = $_[1]; + my(@objects) = (); + my(@exts) = ('o'); + my(@dirs) = (defined $ENV{VDIR} ? $ENV{VDIR} : ''); + $noext =~ s/\.[^\.]+$//o; + + if (defined $ENV{SOEXT}) { + push(@exts, $ENV{SOEXT}); + } + if (defined $ENV{VSHDIR}) { + push(@dirs, $ENV{VSHDIR}); + } + + foreach my $dirs (@dirs) { + foreach my $ext (@exts) { + push(@objects, "$dirs$noext.$ext"); + } + } + + return \@objects; +} + + +1; diff --git a/modules/Depgen/NMakeDependencyWriter.pm b/modules/Depgen/NMakeDependencyWriter.pm new file mode 100644 index 00000000..90340656 --- /dev/null +++ b/modules/Depgen/NMakeDependencyWriter.pm @@ -0,0 +1,53 @@ +package NMakeDependencyWriter; + +# ************************************************************ +# Description : Generates NMake dependencies. +# Author : Chad Elliott +# Create Date : 2/10/2002 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; +use DependencyWriter; + +use vars qw(@ISA); +@ISA = qw(DependencyWriter); + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub process { + my($sources) = $_[1]; + my($files) = $_[2]; + my($total) = 0; + + $$sources[0] =~ s/\//\\/g; + $$sources[0] =~ s/\\\\/\\/g; + my($dep) = "$$sources[0] :\\\n"; + + ## Sort the dependencies to make them reproducible + foreach my $file (sort @$files) { + $file =~ s/\//\\/g; + $file =~ s/\\\\/\\/g; + if ($file ne $$sources[0]) { + $dep .= "\t\"$file\"\\\n"; + ++$total; + } + } + + if ($total == 0) { + $dep = ''; + } + else { + $dep .= "\n\n"; + } + + return $dep; +} + + +1; diff --git a/modules/Depgen/NMakeObjectGenerator.pm b/modules/Depgen/NMakeObjectGenerator.pm new file mode 100644 index 00000000..ac4f11fa --- /dev/null +++ b/modules/Depgen/NMakeObjectGenerator.pm @@ -0,0 +1,28 @@ +package NMakeObjectGenerator; + +# ************************************************************ +# Description : Generates object files for NMake Makefiles. +# Author : Chad Elliott +# Create Date : 5/23/2003 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; +use ObjectGenerator; + +use vars qw(@ISA); +@ISA = qw(ObjectGenerator); + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub process { + return [ $_[1] ]; +} + + +1; diff --git a/modules/Depgen/ObjectGenerator.pm b/modules/Depgen/ObjectGenerator.pm new file mode 100644 index 00000000..d7e92070 --- /dev/null +++ b/modules/Depgen/ObjectGenerator.pm @@ -0,0 +1,32 @@ +package ObjectGenerator; + +# ************************************************************ +# Description : Base class for all Object Generators. +# Author : Chad Elliott +# Create Date : 5/23/2003 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub new { + return bless { + }, $_[0]; +} + + +sub process { + #my($self) = shift; + #my($file) = shift; + return []; +} + + +1; diff --git a/modules/Depgen/ObjectGeneratorFactory.pm b/modules/Depgen/ObjectGeneratorFactory.pm new file mode 100644 index 00000000..a9d90ae7 --- /dev/null +++ b/modules/Depgen/ObjectGeneratorFactory.pm @@ -0,0 +1,42 @@ +package ObjectGeneratorFactory; + +# ************************************************************ +# Description : Create ObjectGenerator objects. +# Author : Chad Elliott +# Create Date : 5/23/2003 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; + +use ObjectGenerator; + +# ************************************************************ +# Data Section +# ************************************************************ + +my($generators) = {}; + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub register { + $generators = shift; +} + + +sub create { + if (defined $$generators{$_[0]}) { + return $$generators{$_[0]}->new(); + } + + print STDERR "WARNING: Invalid object generator type: $_[0]\n"; + return new ObjectGenerator(); +} + + +1; diff --git a/modules/Depgen/Preprocessor.pm b/modules/Depgen/Preprocessor.pm new file mode 100644 index 00000000..66e5d206 --- /dev/null +++ b/modules/Depgen/Preprocessor.pm @@ -0,0 +1,147 @@ +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) = shift; + my($macros) = shift; + my($ipaths) = shift; + my($exclude) = shift; + return bless {'macros' => $macros, + 'ipaths' => $ipaths, + 'exclude' => $exclude, + 'files' => {}, + 'ifound' => {}, + 'recurse' => 0, + }, $class; +} + + +sub process { + my($self) = shift; + my($file) = shift; + my($noinline) = shift; + my($noincs) = shift; + my($fh) = new FileHandle(); + + if (open($fh, $file)) { + my($ifcount) = 0; + my(@zero) = (); + my($files) = $self->{'files'}; + my($recurse) = ++$self->{'recurse'}; + my($dir) = dirname($file); + + $$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) = undef; + 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); + + --$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; diff --git a/modules/Driver.pm b/modules/Driver.pm index 2a6c9dc4..63f89100 100644 --- a/modules/Driver.pm +++ b/modules/Driver.pm @@ -472,6 +472,9 @@ sub run { } } } + + ## Remove MPC_ROOT since we never want to expand it + delete $options->{'relative'}->{'MPC_ROOT'}; } ## Always add the current path to the include paths diff --git a/templates/make.mpd b/templates/make.mpd index 1e0e6130..b7889042 100644 --- a/templates/make.mpd +++ b/templates/make.mpd @@ -316,7 +316,7 @@ $(DEPENDENCIES): depend: <%if(source_files || pch_source)%> - -<%depgen("makedepend -Y")%> $(CFLAGS) $(CCFLAGS) $(CPPFLAGS) -f $(DEPENDENCIES) $(SRC) 2> $(NUL) + -<%depgen("$(MPC_ROOT)/depgen.pl")%> $(CFLAGS) $(CCFLAGS) $(CPPFLAGS) -f $(DEPENDENCIES) $(SRC) 2> $(NUL) <%else%> @-: <%endif%> |