r9834: More tests for the upgrade from Samba3
[gd/samba/.git] / source4 / script / minimal_includes.pl
1 #!/usr/bin/perl -w
2 # find a list of #include lines in C code that might not be needed
3 # usually called with something like this:
4 #    minimal_includes.pl `find . -name "*.c"`
5 # Andrew Tridgell <tridge@samba.org>
6
7 use strict;
8 use Data::Dumper;
9 use Getopt::Long;
10
11 my $opt_help = 0;
12 my $opt_remove = 0;
13
14 #####################################################################
15 # write a string into a file
16 sub FileSave($$)
17 {
18     my($filename) = shift;
19     my($v) = shift;
20     local(*FILE);
21     open(FILE, ">$filename") || die "can't open $filename";    
22     print FILE $v;
23     close(FILE);
24 }
25
26 sub load_lines($)
27 {
28         my $fname = shift;
29         my @lines = split(/^/m, `cat $fname`);
30         return @lines;
31 }
32
33 sub save_lines($$)
34 {
35         my $fname = shift;
36         my $lines = shift;
37         my $data = join('', @{$lines});
38         FileSave($fname, $data);
39 }
40
41 sub test_compile($)
42 {
43         my $fname = shift;
44         my $obj;
45         if ($fname =~ s/(.*)\.c$/$1.o/) {
46                 $obj = "$1.o";
47         } else {
48                 return "NOT A C FILE";
49         }
50         unlink($obj);
51         my $ret = `make $obj 2>&1`;
52         if (!unlink("$obj")) {
53                 return "COMPILE FAILED";
54         }
55         return $ret;
56 }
57
58 sub test_include($$$$)
59 {
60         my $fname = shift;
61         my $lines = shift;
62         my $i = shift;
63         my $original = shift;
64         my $line = $lines->[$i];
65
66         $lines->[$i] = "";
67         save_lines("_testcompile.c", $lines);
68         
69         my $out = test_compile("_testcompile.c");
70         $out =~ s/_testcompile.c/$fname/g;
71
72         if ($out eq $original) {
73                 if ($opt_remove) {
74                         print "$fname: removing $line\n";
75                         save_lines($fname, $lines);
76                         return;
77                 }
78                 print "$fname: might be able to remove $line\n";
79         }
80
81         $lines->[$i] = $line;
82         unlink("_testcompile.c");
83 }
84
85 sub process_file($)
86 {
87         my $fname = shift;
88         my @lines = load_lines($fname);
89         my $num_lines = $#lines;
90
91         my $original = test_compile($fname);
92
93         if ($original eq "COMPILE FAILED") {
94                 print "Failed to compile $fname\n";
95                 return;
96         }
97
98         print "Processing $fname (with $num_lines lines)\n";
99         
100         my $if_level = 0;
101
102         for (my $i=0;$i<=$num_lines;$i++) {
103                 my $line = $lines[$i];
104                 if ($line =~ /^\#\s*if/) {
105                         $if_level++;
106                 }
107                 if ($line =~ /^\#\s*endif/) {
108                         $if_level--;
109                 }
110                 if ($if_level == 0 &&
111                     $line =~ /^\#\s*include/ && 
112                     !($line =~ /needed/)) {
113                         test_include($fname, \@lines, $i, $original);
114                 }
115         }
116 }
117
118
119 #########################################
120 # display help text
121 sub ShowHelp()
122 {
123     print "
124            minimise includes
125            Copyright (C) tridge\@samba.org
126
127            Usage: minimal_includes.pl [options] <C files....>
128            
129            Options:
130                  --help       show help
131                  --remove     remove includes, don't just list them
132 ";
133 }
134
135
136 # main program
137 GetOptions (
138             'h|help|?' => \$opt_help,
139             'remove' => \$opt_remove,
140             );
141
142 if ($opt_help) {
143         ShowHelp();
144         exit(0);
145 }
146
147 for (my $i=0;$i<=$#ARGV;$i++) {
148         my $fname = $ARGV[$i];
149         process_file($fname);
150 }