* ylwrap: Revert to previous version.
[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     $crule  = "\tif [ x\"\$(PICFLAG)\" != x ]; then \\\n";
217     $crule .= "\t  \$(COMPILE.c) \$(PICFLAG) \$< -o pic/\$@; \\\n";
218     $crule .= "\telse true; fi\n";
219     $crule .= "\t\$(COMPILE.c) \$< \$(OUTPUT_OPTION)\n";
220     $crule .= "\n";
221
222     $incdir = shift @ARGV;
223
224     opendir(INC, $incdir);
225     while ($f = readdir INC) {
226         next unless $f =~ /\.h$/;
227         $mine{$f} = "\$(INCDIR)/$f";
228         $deps{$f} = join(' ', &deps_for("$incdir/$f"));
229     }
230     $mine{'config.h'} = "config.h";
231
232     opendir(INC, $srcdir);
233     while ($f = readdir INC) {
234         next unless $f =~ /\.h$/;
235         $mine{$f} = "\$(srcdir)/$f";
236         $deps{$f} = join(' ', &deps_for("$srcdir/$f"));
237     }
238     $mine{'config.h'} = "config.h";
239
240     open(IN, "$srcdir/Makefile.in");
241     open(OUT, ">$srcdir/Makefile.tmp");
242     while (<IN>) {
243         last if /remainder of this file/;
244         print OUT;
245     }
246     print OUT "# The dependencies in the remainder of this file are automatically\n";
247     print OUT "# generated by \"make maint-deps\".  Manual edits will be lost.\n\n";
248
249     opendir(S, $srcdir);
250     for $f (sort readdir S) {
251         if ($f =~ /\.c$/) {
252
253             %scanned = ();
254             @pending = &deps_for("$srcdir/$f");
255             while (@pending) {
256                 @tmp = @pending;
257                 @pending = ();
258                 for $p (@tmp) {
259                     next unless $mine{$p};
260                     if (!$scanned{$p}) {
261                         push(@pending, split(' ', $deps{$p}));
262                         $scanned{$p} = 1;
263                     }
264                 }
265             }
266             @deps = sort { &locals_first($a,$b) } keys %scanned;
267             $obj = $f;
268             $obj =~ s/\.c$/.o/;
269             $obj = "./$obj:";
270             if ($#deps >= 0) {
271                 print OUT "$obj \$(srcdir)/$f";
272                 $len = length("$obj $f");
273                 for $dt (@deps) {
274                     $d = $mine{$dt};
275                     if ($len + length($d) > 70) {
276                         printf OUT " \\\n\t$d";
277                         $len = 8 + length($d);
278                     } else {
279                         print OUT " $d";
280                         $len += length($d) + 1;
281                     }
282                 }
283                 print OUT "\n";
284             } else {
285                 print OUT "$obj \$(srcdir)/$f\n";
286             }
287             $c = $crule;
288             $c =~ s@\$\<@\$\(srcdir\)\/$f@g;
289             print OUT $c;
290         }
291     }
292     closedir(S);
293     close(IN);
294     close(OUT);
295
296     rename("$srcdir/Makefile.tmp", "$srcdir/Makefile.in");
297 }