diff options
-rwxr-xr-x | source4/script/minimal_includes.pl | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/source4/script/minimal_includes.pl b/source4/script/minimal_includes.pl new file mode 100755 index 0000000000..963dc10f8b --- /dev/null +++ b/source4/script/minimal_includes.pl @@ -0,0 +1,150 @@ +#!/usr/bin/perl -w +# find a list of #include lines in C code that might not be needed +# usually called with something like this: +# minimal_includes.pl `find . -name "*.c"` +# Andrew Tridgell <tridge@samba.org> + +use strict; +use Data::Dumper; +use Getopt::Long; + +my $opt_help = 0; +my $opt_remove = 0; + +##################################################################### +# write a string into a file +sub FileSave($$) +{ + my($filename) = shift; + my($v) = shift; + local(*FILE); + open(FILE, ">$filename") || die "can't open $filename"; + print FILE $v; + close(FILE); +} + +sub load_lines($) +{ + my $fname = shift; + my @lines = split(/^/m, `cat $fname`); + return @lines; +} + +sub save_lines($$) +{ + my $fname = shift; + my $lines = shift; + my $data = join('', @{$lines}); + FileSave($fname, $data); +} + +sub test_compile($) +{ + my $fname = shift; + my $obj; + if ($fname =~ s/(.*)\.c$/$1.o/) { + $obj = "$1.o"; + } else { + return "NOT A C FILE"; + } + unlink($obj); + my $ret = `make $obj 2>&1`; + if (!unlink("$obj")) { + return "COMPILE FAILED"; + } + return $ret; +} + +sub test_include($$$$) +{ + my $fname = shift; + my $lines = shift; + my $i = shift; + my $original = shift; + my $line = $lines->[$i]; + + $lines->[$i] = ""; + save_lines("_testcompile.c", $lines); + + my $out = test_compile("_testcompile.c"); + $out =~ s/_testcompile.c/$fname/g; + + if ($out eq $original) { + if ($opt_remove) { + print "$fname: removing $line\n"; + save_lines($fname, $lines); + return; + } + print "$fname: might be able to remove $line\n"; + } + + $lines->[$i] = $line; + unlink("_testcompile.c"); +} + +sub process_file($) +{ + my $fname = shift; + my @lines = load_lines($fname); + my $num_lines = $#lines; + + my $original = test_compile($fname); + + if ($original eq "COMPILE FAILED") { + print "Failed to compile $fname\n"; + return; + } + + print "Processing $fname (with $num_lines lines)\n"; + + my $if_level = 0; + + for (my $i=0;$i<=$num_lines;$i++) { + my $line = $lines[$i]; + if ($line =~ /^\#\s*if/) { + $if_level++; + } + if ($line =~ /^\#\s*endif/) { + $if_level--; + } + if ($if_level == 0 && + $line =~ /^\#\s*include/ && + !($line =~ /needed/)) { + test_include($fname, \@lines, $i, $original); + } + } +} + + +######################################### +# display help text +sub ShowHelp() +{ + print " + minimise includes + Copyright (C) tridge\@samba.org + + Usage: minimal_includes.pl [options] <C files....> + + Options: + --help show help + --remove remove includes, don't just list them +"; +} + + +# main program +GetOptions ( + 'h|help|?' => \$opt_help, + 'remove' => \$opt_remove, + ); + +if ($opt_help) { + ShowHelp(); + exit(0); +} + +for (my $i=0;$i<=$#ARGV;$i++) { + my $fname = $ARGV[$i]; + process_file($fname); +} |