Update of /cvsroot/mahogany/M/extra/scripts
In directory sc8-pr-cvs1:/tmp/cvs-serv29729/extra/scripts
Modified Files:
include.pl
Log Message:
Include dependencies cleanup, stage two (final so far)
Index: include.pl
===================================================================
RCS file: /cvsroot/mahogany/M/extra/scripts/include.pl,v
retrieving revision 1.1
retrieving revision 1.2
diff -b -u -2 -r1.1 -r1.2
--- include.pl 15 Sep 2003 17:01:35 -0000 1.1
+++ include.pl 18 Sep 2003 16:30:37 -0000 1.2
@@ -2,30 +2,86 @@
# FIXME: This script should be made more portable using parameters
+# FIXME: Forward declarations don't really work
+# FIXME: Find unterminated USE_PCH blocks
+# FIXME: Stronger checking for "// for wxSomeClass" comments
use File::Find;
use File::Temp qw/ tempfile /;
+use File::Basename;
-$source = '/home/main/store/cvs-track/mahogany/source';
+$base = '/home/main/store/cvs-track/mahogany/source';
$build = '/home/main/store/cvs-track/mahogany/build';
$compiler =
-"c++ -fsyntax-only -c -I$build/include -I$source/include -DDEBUG"
+"c++ -fsyntax-only -c -I$build/include -I$base/include -DDEBUG"
." -DDEBUG_main -I/usr/lib/wx/include/gtkd-2.4 -D__WXDEBUG__ -D__WXGTK__"
-." -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -I$source/extra/include"
-." -I$build/extra/src/c-client -I$source/extra/src/compface"
-." -I$source/src/wx/vcard -fno-exceptions -fno-rtti -fno-operator-names"
+." -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -I$base/extra/include"
+." -I$build/extra/src/c-client -I$base/extra/src/compface"
+." -I$base/src/wx/vcard -fno-exceptions -fno-rtti -fno-operator-names"
." -O0 -Wall -x c++ -Werror";
[EMAIL PROTECTED] = ("$build/include", "$base/include",
+ "/usr/lib/wx/include/gtkd-2.4", "$base/extra/include",
+ "$build/extra/src/c-client", "$base/extra/src/compface",
+ "$base/src/wx/vcard", "/usr/include", "/usr/include/linux");
-find \&AllFiles, '.';
-#$_ = 'wxFiltersDialog.cpp';
-#chdir 'src/gui';
-#AllFiles();
[EMAIL PROTECTED] = FindIncludes("include/Mpch.h");
+$precompiled{$_} = 1 foreach (@precompiled);
[EMAIL PROTECTED] = FindIncludes("/usr/include/wx/wx.h");
+$precompiled{$_} = 1 foreach (@precompiled);
+
+if( $#ARGV >= 0 )
+{
+ if( $ARGV[0] eq '--eval' )
+ {
+ $program = $ARGV[1];
+ print eval($program),"\n",$@;
+ }
+ if( $ARGV[0] eq '--one' )
+ {
+ $header_mode='.cpp';
+ $header_mode='.h' if $ARGV[1] =~ /\.h/;
+ chdir(dirname($ARGV[1]));
+ if( $#ARGV >= 2 )
+ {
+ TestInclude(basename($ARGV[1]),$ARGV[2]);
+ }
+ else
+ {
+ CheckFile(basename($ARGV[1]));
+ }
+ }
+ if( $ARGV[0] eq '--statistics' )
+ {
+ CalculateStatistics();
+ }
+ if( $ARGV[0] eq '--fast' )
+ {
+ $fast = 1;
+ Run();
+ }
+ exit;
+}
+
+$fast = 0;
+Run();
+
+sub Run
+{
+ $header_mode='.h';
+ find { preprocess => \&SortFiles, wanted => \&AllIncludes }, '.';
+ $header_mode='.cpp';
+ find { preprocess => \&SortFiles, wanted => \&AllFiles }, '.';
+}
sub CompileFile
{
my ($source) = shift(@_);
+ my ($verbose) = shift(@_);
+ return CompileInclude($source,$verbose) if $header_mode eq '.h';
my ($output,$outputfile) = tempfile();
close $output or die;
- system "$compiler $source >$outputfile 2>&1";
+ system "$compiler $source".($verbose ? "" : " >$outputfile 2>&1");
+ my ($result) = $?;
unlink $outputfile or die;
+ return $result;
}
@@ -34,11 +90,26 @@
my(@includes);
local *SOURCE;
+ my ($precompile_section) = 0;
open(SOURCE,shift(@_)) or die;
while(<SOURCE>)
{
+ $precompile_section = 1 if /# *ifndef +((USE_PCH)|(WX_PRECOMP))/;
+ $precompile_section = 0 if m%# *endif *// *((USE_PCH)|(WX_PRECOMP))%;
next if ! /^ *# *include/;
- /["<](.*)[">]/ or die;
+ /["<]([^"]*)[">]/ or die;
push @includes,$1;
+ $precompile_include = $precompiled{$1} ? 1 : 0;
+ if( $precompile_section != $precompile_include )
+ {
+ warn " $1 - precompile mismatch\n";
+ }
+ if( $header_mode eq '.h' )
+ {
+ if( $1 eq 'Mpch.h' || $1 eq 'Mcommon.h' || $1 eq 'Mconfig.h' )
+ {
+ warn " $1 - should be in cpp file\n";
+ }
+ }
}
close(SOURCE) or die;
@@ -46,15 +117,41 @@
}
+sub ScanForward
+{
+ my ($include) = shift(@_);
+ local *SOURCE;
+ my (@classes);
+
+ return if $include =~ /^std/;
+ return if $include =~ m#^wx/#;
+ open(SOURCE,$include) or open(SOURCE,"$base/include/$include")
+ or return;
+ while(<SOURCE>)
+ {
+ push @classes,"class $2;\n" if /^class +(WXDLLEXPORT +)?(\w+)/;
+ push @classes,"$1\n" if /^(#include *[<"].*[">])/;
+ }
+ close(SOURCE) or die;
+
+ return @classes;
+}
+
sub RemoveInclude
{
my ($source) = shift(@_);
my ($include) = shift(@_);
+ my ($replace) = shift(@_);
local *SOURCE;
my ($scratch,$scratchname) = tempfile();
+ print $scratch ScanForward($include);
open(SOURCE,$source) or die;
while(<SOURCE>)
{
- next if /^ *# *include *["<]$include[">]/;
+ if( /^ *# *include *["<]$include[">]/ )
+ {
+ print $scratch $replace;
+ next;
+ }
print $scratch $_;
}
@@ -65,23 +162,279 @@
}
+sub BaseInclude
+{
+ my($include)=shift(@_);
+ $include eq 'Mpch.h' || $include eq 'Mcommon.h'
+ || $include eq 'wx/wxprec.h' || $include eq 'windows.h'
+ || $include eq 'wx/msw/winundef.h';
+}
+
+sub ValidateInclude
+{
+ my($source)=shift(@_);
+ my($include)=shift(@_);
+ return 0 if BaseInclude $include;
+ return 0 if basename($source,'.cpp') eq basename($include,'.h');
+ return 0 if $include =~ /.c$/ || $include =~ /.cpp$/;
+ return 1;
+}
+
+sub IsConditional
+{
+ my($source)=shift(@_);
+ my($include)=shift(@_);
+ my($scratchname) = RemoveInclude($source,$include,'#error IsCompiledIn');
+ my($result) = CompileFile($scratchname,0) == 0;
+ unlink $scratchname or die;
+ $result;
+}
+
+sub FindForProtection
+{
+ my($source)=shift(@_);
+ my($include)=shift(@_);
+ my($protected)='';
+ open(SOURCE,$source) or die;
+ while(<SOURCE>)
+ {
+ if( /^ *# *include *["<]$include[">]/ )
+ {
+ m#// *[Ff]or +(\w+)#;
+ $protected = $1;
+ }
+ }
+ close(SOURCE) or die;
+ return $protected;
+}
+
+sub IsFairlyForProtected
+{
+ my($source)=shift(@_);
+ my($include)=shift(@_);
+ my($protected)=FindForProtection($source,$include);
+ my($fair)=0;
+ return 0 if $protected eq '';
+ open(SOURCE,$source) or die;
+ while(<SOURCE>)
+ {
+ $fair = $fair || /$protected/;
+ }
+ close(SOURCE) or die;
+ return $fair;
+}
+
+sub TestInclude
+{
+ my($source)=shift(@_);
+ my($include)=shift(@_);
+ return if !ValidateInclude $source,$include;
+ my($scratchname) = RemoveInclude $source,$include;
+ if( CompileFile($scratchname,0) == 0 )
+ {
+ my ($conditional) = IsConditional($source,$include);
+ warn " $include - conditional\n" if $conditional;
+ my ($protected) = IsFairlyForProtected($source,$include);
+ warn " $include - protected\n" if $protected;
+ warn " $include\n" if !$conditional && !$protected;
+ }
+ else { warn " $include - essential\n"; }
+ unlink $scratchname or die;
+}
+
sub AllFiles
{
return if ! /.cpp$/;
my($source)=$_;
- warn "$File::Find::dir $source\n";
- CompileFile $source;
- if($? != 0)
+ CheckFile($source);
+}
+
+sub SortFiles
+{
+ my(@sorted)=sort { $a cmp $b } @_; # Swap $a and $b to reverse order
+ return @sorted;
+}
+
+sub WrapInclude
+{
+ my ($include) = shift(@_);
+ my ($scratch,$scratchname) = tempfile();
+ print $scratch "#include \"Mpch.h\"\n";
+ print $scratch "#include \"Mcommon.h\"\n";
+ my ($dir) = "";
+ if( !( $include =~ m#^/# ) )
{
- warn " Compilation without change failed\n";
- return;
+ my ($basedir) = $File::Find::dir;
+ $basedir = dirname($ARGV[1]) if $#ARGV >= 1;
+ $dir = "$2/" if $basedir =~ m#^(\./)?include/(.*)#;
}
- @includes = FindIncludes $source;
+ print $scratch "#include \"$dir$include\"\n";
+ close($scratch) or die;
+ return $scratchname;
+}
+
+sub CompileInclude
+{
+ my ($include) = shift(@_);
+ my ($verbose) = shift(@_);
+ local $header_mode = '.cpp';
+ my ($scratchname) = WrapInclude($include);
+ my ($result) = CompileFile($scratchname,$verbose);
+ unlink $scratchname or die;
+ return $result;
+}
+
+sub AllIncludes
+{
+ return if ! /\.h$/;
+ return if $File::Find::dir =~ m#/extra/#;
+ my($include)=$_;
+ CheckFile($include);
+}
+
+sub CheckFile
+{
+ my ($file) = shift(@_);
+ warn "$File::Find::dir $file\n";
+ if( !$fast )
+ {
+ my ($status) = CompileFile($file,1);
+ return if $status != 0;
+ }
+ my (@includes) = FindIncludes $file;
+ if( !$fast )
+ {
foreach $include (@includes)
{
- next if $include eq 'Mpch.h' || $include eq 'Mcommon.h';
- $scratchname = RemoveInclude $source,$include;
- CompileFile $scratchname;
- unlink $scratchname or die;
- warn " $include\n" if $? == 0;
+ TestInclude $file,$include;
+ }
+ }
+}
+
+sub CollectExtensionFiles
+{
+ return if substr($_,-length($extension)) ne $extension;
+ push @cppfiles,$File::Find::name;
+}
+
+sub FindExtensionFiles
+{
+ local $extension = shift(@_);
+ local @cppfiles;
+ find { preprocess => \&SortFiles,
+ wanted => \&CollectExtensionFiles }, '.';
+ return @cppfiles;
+}
+
+sub IncludePath
+{
+ my ($parent) = shift(@_);
+ my ($file) = shift(@_);
+ foreach(@includepath)
+ {
+ return "$_/$file" if -e "$_/$file";
+ }
+ return dirname($parent)."/$file";
+}
+
+sub IgnoreInclude
+{
+ my ($file) = shift(@_);
+ #return 1 if $file eq 'stdarg.h'; # Virtual file
+ return 1 if $file =~ m#^/usr/#; # Don't look at system files at all
+ return 1 if $file =~ m#wx/\w+/#; # We don't have MSW headers on Linux
+ #return 1 if $file =~ m#windows.h#; # No such file on Linux
+ #return 1 if $file =~ m#wx/listbook.h#; # wxWindows 2.5
+ #return 1 if # C++ headers are placed randomely
+# $file eq 'string' || $file eq 'iostream.h' || $file eq 'fstream.h'
+# || $file eq 'iostream' || $file eq 'fstream';
+ return 1 if $file =~ m#shortsym.h#; # C-client mess
+# return 1 if $file =~ m#/wx/#; # Our wxWindows extensions
+ return 1 if $file =~ m#\.\./classes/MObject.cpp#; # Filters.cpp TEST hack
+ return 1 if $file =~ m#libmal.h#; # PalmOS
+ return 1 if $file =~ m#wxllist.h#; # More wxWindows extensions
+ return 1 if $file =~ m#wxlparser.h#; # More wxWindows extensions
+ return 1 if $file =~ m#wxlwindow.h#; # More wxWindows extensions
+ return 1 if $file =~ m#Mpch.h#; # Don't count precompiled headers
+ return 0;
+}
+
+sub FindIncludesRecursivelyHelper
+{
+ my ($file) = shift(@_);
+ local *SOURCE;
+
+ return if IgnoreInclude($file);
+ open(SOURCE,$file) or die $file;
+ while(<SOURCE>)
+ {
+ next if ! /^ *# *include *[<"]([^"]*)[">]/; # Count system includes too
+ my ($include) = $1;
+ if( $dependencies{$include} != 1 )
+ {
+ $dependencies{$include} = 1;
+ FindIncludesRecursivelyHelper(IncludePath($file,$include))
+ if /^ *# *include *"([^"]*)"/; # Don't follow system includes
+ }
+ }
+ close(SOURCE) or die;
+}
+
+sub FindIncludesRecursively
+{
+ my ($file) = shift(@_);
+ local %dependencies;
+ FindIncludesRecursivelyHelper($file);
+ return keys %dependencies;
+}
+
+sub StatisticsForExtension
+{
+ my ($extension) = shift(@_);
+ my (@filelist) = FindExtensionFiles($extension);
+ my (%depcount);
+ foreach my $file (@filelist)
+ {
+ $depcount{$file} = scalar(FindIncludesRecursively($file));
+ }
+ @filelist = sort { $depcount{$a} <=> $depcount{$b} } @filelist;
+ foreach my $file (@filelist)
+ {
+ printf "%3d $file\n",$depcount{$file};
+ }
+}
+
+sub InvertedDependencies
+{
+ my (@filelist) = FindExtensionFiles(".cpp");
+ my (%eachinclude);
+ foreach my $file (@filelist)
+ {
+ foreach my $include (FindIncludesRecursively($file))
+ {
+ $eachinclude{$include}{$file} = 1;
+ }
+ }
+ my (%depcount);
+ $depcount{$_} = scalar(keys %{$eachinclude{$_}})
+ foreach (keys %eachinclude);
+ @sortedlist = sort { $depcount{$a} <=> $depcount{$b} } keys %eachinclude;
+ foreach my $include (@sortedlist)
+ {
+ printf "%3d $include\n",$depcount{$include};
+ }
+}
+
+sub CalculateStatistics
+{
+ print "Recursive include counts for sources\n";
+ StatisticsForExtension(".cpp");
+ print "Recursive include counts for headers\n";
+ StatisticsForExtension(".h");
+ print "Recursive usage counts for headers\n";
+ InvertedDependencies();
+ if( -e $ARGV[1] )
+ {
+ print "One file dependencies\n";
+ print join("\n",FindIncludesRecursively($ARGV[1])),"\n";
}
}
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates