This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / libiberty / maint-tool
1 #!/usr/bin/perl
2 # -*- perl -*-
3
4 #   Copyright (C) 2001
5 #   Free Software Foundation
6 #
7 # This file is part of the libiberty library.
8 # Libiberty is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Library General Public
10 # License as published by the Free Software Foundation; either
11 # version 2 of the License, or (at your option) any later version.
12 #
13 # Libiberty is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 # Library General Public License for more details.
17 #
18 # You should have received a copy of the GNU Library General Public
19 # License along with libiberty; see the file COPYING.LIB.  If not,
20 # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 # Boston, MA 02111-1307, USA.
22 #
23 # Originally written by DJ Delorie <dj@redhat.com>
24
25
26 # This is a trivial script which checks the lists of C and O files in
27 # the Makefile for consistency.
28
29 $mode = shift;
30 $srcdir = ".";
31
32 if ($mode eq "-s") {
33     $srcdir = shift;
34     $mode = shift;
35 }
36
37 &missing() if $mode eq "missing";
38 &undoc() if $mode eq "undoc";
39 &deps() if $mode eq "deps";
40
41 exit 0;
42
43 format STDOUT =
44 ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~
45 $out
46         ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
47 $out
48 .
49
50 ######################################################################
51
52 sub missing {
53
54     opendir(S, $srcdir);
55     while ($f = readdir S) {
56         $have{$f} = 1;
57     }
58     closedir(S);
59     opendir(S, ".");
60     while ($f = readdir S) {
61         $have{$f} = 1;
62     }
63     closedir(S);
64
65     for $a (@ARGV) {
66         $listed{$a} = 1;
67         $have{$a} = 0;
68     }
69
70     for $f (sort keys %have) {
71         next unless $have{$f};
72         if ($f =~ /\.c$/) {
73             print "S $f\n";
74         }
75     }
76     for $f (sort keys %listed) {
77         if ($f =~ /(.*)\.c$/) {
78             $base = $1;
79             if (! $listed{"$base.o"}) {
80                 print "O $f\n";
81             }
82         }
83     }
84 }
85
86 ######################################################################
87
88 sub undoc {
89
90     opendir(S, $srcdir);
91     while ($file = readdir S) {
92         if ($file =~ /\.texi$/) {
93             open(T, "$srcdir/$file");
94             while (<T>) {
95                 if (/^\@deftype[^\(]* ([^\s\(]+) *\(/) {
96                     $documented{$1} = 1;
97                 }
98             }
99             close(T);
100         }
101         if ($file =~ /\.c$/) {
102             open(C, "$srcdir/$file");
103             while (<C>) {
104                 if (/\@undocumented (\S+)/) {
105                     $documented{$1} = 1;
106                 }
107                 if (/^static /) {
108                     if (! /[\(;]/) {
109                         s/[\r\n]+$/ /;
110                         $_ .= <C>;
111                     }
112                     while ($_ =~ /\([^\)]*$/) {
113                         s/[\r\n]+$/ /;
114                         $_ .= <C>;
115                     }
116                 }
117                 s/ VPARAMS([ \(])/$1/;
118                 s/PREFIX\(([^\)]*)\)/byte_$1/;
119                 if (/^static [^\(]* ([^\s\(]+) *\(.*\)$/) {
120                     $documented{$1} = 1;
121                 }
122             }
123         }
124     }
125     closedir(D);
126
127     # $out = join(' ', sort keys %documented);
128     # write;
129     # print "\n";
130
131     system "etags $srcdir/*.c $srcdir/../include/*.h";
132     open(TAGS, "TAGS");
133     while (<TAGS>) {
134         s/[\r\n]+$//;
135         if (/^\014$/) {
136             $filename = <TAGS>;
137             $filename =~ s/[\r\n]+$//;
138             $filename =~ s/,\d+$//;
139             $filename =~ s@.*[/\\]@@;
140             next;
141         }
142         if ($filename =~ /\.c$/ ) {
143             next unless /^[_a-zA-Z]/;
144         } else {
145             next unless /^\# *define/;
146             s/\# *define *//;
147         }
148         next if $filename =~ /mpw\.c/;
149
150         s/ VPARAMS//;
151         s/ *\177.*//;
152         s/,$//;
153         s/DEFUN\(//;
154         s/\(//;
155
156         next if /^static /;
157         next if /\s/;
158         next if /^_/;
159         next if $documented{$_};
160         next if /_H_?$/;
161
162         if ($seen_in{$_} ne $filename) {
163             $saw{$_} ++;
164         }
165         $seen_in{$_} = $filename;
166     }
167
168     for $k (keys %saw) {
169         delete $saw{$k} if $saw{$k} > 1;
170     }
171
172     for $k (sort keys %saw) {
173         $fromfile{$seen_in{$k}} .= " " if $fromfile{$seen_in{$k}};
174         $fromfile{$seen_in{$k}} .= $k;
175     }
176
177     for $f (sort keys %fromfile) {
178         $out = "$f: $fromfile{$f}";
179         write;
180     }
181 }
182
183 ######################################################################
184
185 sub deps_for {
186     my($f) = @_;
187     my(%d);
188     open(F, $f);
189     %d = ();
190     while (<F>) {
191         if (/^#\s*include\s+["<](.*)[">]/) {
192             $d{$1} = 1;
193         }
194     }
195     close(F);
196     return keys %d;
197 }
198
199 sub canonicalize {
200     my ($p) = @_;
201     0 while $p =~ s@/\./@/@g;
202     0 while $p =~ s@^\./@@g;
203     0 while $p =~ s@/[^/]+/\.\./@/@g;
204     return $p;
205 }
206
207 sub locals_first {
208     my ($a,$b) = @_;
209     return -1 if $a eq "config.h";
210     return  1 if $b eq "config.h";
211     return $a cmp $b;
212 }
213
214 sub deps {
215
216     $incdir = shift @ARGV;
217
218     opendir(INC, $incdir);
219     while ($f = readdir INC) {
220         next unless $f =~ /\.h$/;
221         $mine{$f} = "\$(INCDIR)/$f";
222         $deps{$f} = join(' ', &deps_for("$incdir/$f"));
223     }
224     $mine{'config.h'} = "config.h";
225
226     open(IN, "$srcdir/Makefile.in");
227     open(OUT, ">$srcdir/Makefile.tmp");
228     while (<IN>) {
229         last if /remainder of this file/;
230         print OUT;
231     }
232     print OUT "# The dependencies in the remainder of this file are automatically\n";
233     print OUT "# generated by \"make maint-deps\".  Manual edits will be lost.\n\n";
234
235     opendir(S, $srcdir);
236     for $f (sort readdir S) {
237         if ($f =~ /\.c$/) {
238
239             %scanned = ();
240             @pending = &deps_for("$srcdir/$f");
241             while (@pending) {
242                 @tmp = @pending;
243                 @pending = ();
244                 for $p (@tmp) {
245                     next unless $mine{$p};
246                     if (!$scanned{$p}) {
247                         push(@pending, split(' ', $deps{$p}));
248                         $scanned{$p} = 1;
249                     }
250                 }
251             }
252             @deps = sort { &locals_first($a,$b) } keys %scanned;
253             $obj = $f;
254             $obj =~ s/\.c$/.o/;
255             $obj = "$obj:";
256             if ($#deps >= 0) {
257                 print OUT $obj;
258                 $len = length($obj);
259                 for $dt (@deps) {
260                     $d = $mine{$dt};
261                     if ($len + length($d) > 70) {
262                         printf OUT " \\\n\t$d";
263                         $len = 8 + length($d);
264                     } else {
265                         print OUT " $d";
266                         $len += length($d) + 1;
267                     }
268                 }
269                 print OUT "\n";
270             }
271         }
272     }
273     closedir(S);
274     close(IN);
275     close(OUT);
276
277     rename("$srcdir/Makefile.tmp", "$srcdir/Makefile.in");
278 }