1214571Sdim#!/usr/bin/perl
2214571Sdim# -*- perl -*-
3214571Sdim
4214571Sdim#   Copyright (C) 2001-2020 Free Software Foundation, Inc.
5214571Sdim#
6214571Sdim# This file is part of the libiberty library.
7214571Sdim# Libiberty is free software; you can redistribute it and/or
8214571Sdim# modify it under the terms of the GNU Library General Public
9214571Sdim# License as published by the Free Software Foundation; either
10214571Sdim# version 2 of the License, or (at your option) any later version.
11214571Sdim#
12214571Sdim# Libiberty is distributed in the hope that it will be useful,
13214571Sdim# but WITHOUT ANY WARRANTY; without even the implied warranty of
14214571Sdim# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15214571Sdim# Library General Public License for more details.
16214571Sdim#
17214571Sdim# You should have received a copy of the GNU Library General Public
18214571Sdim# License along with libiberty; see the file COPYING.LIB.  If not,
19214571Sdim# write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20214571Sdim# Boston, MA 02110-1301, USA.
21214571Sdim#
22214571Sdim# Originally written by DJ Delorie <dj@redhat.com>
23214571Sdim
24214571Sdim
25214571Sdim# This is a trivial script which checks the lists of C and O files in
26214571Sdim# the Makefile for consistency.
27214571Sdim
28214571Sdim$mode = shift;
29214571Sdim$srcdir = ".";
30214571Sdim
31214571Sdimif ($mode eq "-s") {
32214571Sdim    $srcdir = shift;
33214571Sdim    $mode = shift;
34214571Sdim}
35214571Sdim
36214571Sdim&missing() if $mode eq "missing";
37214571Sdim&undoc() if $mode eq "undoc";
38214571Sdim&deps() if $mode eq "deps";
39214571Sdim
40214571Sdimexit 0;
41214571Sdim
42214571Sdimformat STDOUT =
43214571Sdim^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~
44214571Sdim$out
45214571Sdim        ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
46214571Sdim$out
47214571Sdim.
48214571Sdim
49214571Sdim######################################################################
50214571Sdim
51214571Sdimsub missing {
52214571Sdim
53214571Sdim    opendir(S, $srcdir);
54214571Sdim    while ($f = readdir S) {
55214571Sdim	$have{$f} = 1;
56214571Sdim    }
57214571Sdim    closedir(S);
58214571Sdim    opendir(S, ".");
59214571Sdim    while ($f = readdir S) {
60214571Sdim	$have{$f} = 1;
61214571Sdim    }
62214571Sdim    closedir(S);
63214571Sdim
64214571Sdim    for $a (@ARGV) {
65214571Sdim	$listed{$a} = 1;
66214571Sdim	$have{$a} = 0;
67214571Sdim    }
68214571Sdim
69214571Sdim    for $f (sort keys %have) {
70214571Sdim	next unless $have{$f};
71214571Sdim	if ($f =~ /\.c$/) {
72214571Sdim	    print "S $f\n";
73214571Sdim	}
74214571Sdim    }
75214571Sdim    for $f (sort keys %listed) {
76214571Sdim	if ($f =~ /(.*)\.c$/) {
77214571Sdim	    $base = $1;
78214571Sdim	    if (! $listed{"./$base.o"}) {
79214571Sdim		print "O $f\n";
80214571Sdim	    }
81214571Sdim	}
82214571Sdim    }
83214571Sdim}
84214571Sdim
85214571Sdim######################################################################
86214571Sdim
87214571Sdimsub undoc {
88214571Sdim
89214571Sdim    opendir(S, $srcdir);
90214571Sdim    while ($file = readdir S) {
91214571Sdim	if ($file =~ /\.texi$/) {
92214571Sdim	    open(T, "$srcdir/$file");
93214571Sdim	    while (<T>) {
94214571Sdim		if (/^\@deftype[^\(]* ([^\s\(]+) *\(/) {
95214571Sdim		    $documented{$1} = 1;
96214571Sdim		}
97214571Sdim	    }
98214571Sdim	    close(T);
99214571Sdim	}
100214571Sdim	if ($file =~ /\.c$/) {
101214571Sdim	    open(C, "$srcdir/$file");
102214571Sdim	    while (<C>) {
103214571Sdim		if (/\@undocumented (\S+)/) {
104214571Sdim		    $documented{$1} = 1;
105214571Sdim		}
106214571Sdim		if (/^static /) {
107214571Sdim		    if (! /[\(;]/) {
108214571Sdim			s/[\r\n]+$/ /;
109214571Sdim			$_ .= <C>;
110214571Sdim		    }
111214571Sdim		    while ($_ =~ /\([^\)]*$/) {
112214571Sdim			s/[\r\n]+$/ /;
113214571Sdim			$_ .= <C>;
114214571Sdim		    }
115214571Sdim		}
116214571Sdim		s/ VPARAMS([ \(])/$1/;
117214571Sdim		s/PREFIX\(([^\)]*)\)/byte_$1/;
118214571Sdim		if (/^static [^\(]* ([^\s\(]+) *\(.*\)$/) {
119214571Sdim		    $documented{$1} = 1;
120214571Sdim		}
121214571Sdim	    }
122214571Sdim	}
123214571Sdim    }
124214571Sdim    closedir(D);
125214571Sdim
126214571Sdim    # $out = join(' ', sort keys %documented);
127214571Sdim    # write;
128214571Sdim    # print "\n";
129214571Sdim
130214571Sdim    system "etags $srcdir/*.c $srcdir/../include/*.h";
131214571Sdim    open(TAGS, "TAGS");
132214571Sdim    while (<TAGS>) {
133214571Sdim	s/[\r\n]+$//;
134214571Sdim	if (/^\014$/) {
135214571Sdim	    $filename = <TAGS>;
136214571Sdim	    $filename =~ s/[\r\n]+$//;
137214571Sdim	    $filename =~ s/,\d+$//;
138214571Sdim	    $filename =~ s@.*[/\\]@@;
139214571Sdim	    next;
140214571Sdim	}
141214571Sdim	if ($filename =~ /\.c$/ ) {
142214571Sdim	    next unless /^[_a-zA-Z]/;
143214571Sdim	} else {
144214571Sdim	    next unless /^\# *define/;
145214571Sdim	    s/\# *define *//;
146214571Sdim	}
147214571Sdim
148214571Sdim	s/ VPARAMS//;
149214571Sdim	s/ *\177.*//;
150214571Sdim	s/,$//;
151214571Sdim	s/DEFUN\(//;
152214571Sdim	s/\(//;
153214571Sdim
154214571Sdim	next if /^static /;
155214571Sdim	next if /\s/;
156214571Sdim	next if /^_/;
157214571Sdim	next if $documented{$_};
158214571Sdim	next if /_H_?$/;
159214571Sdim
160214571Sdim	if ($seen_in{$_} ne $filename) {
161214571Sdim	    $saw{$_} ++;
162214571Sdim	}
163214571Sdim	$seen_in{$_} = $filename;
164214571Sdim    }
165214571Sdim
166214571Sdim    for $k (keys %saw) {
167214571Sdim	delete $saw{$k} if $saw{$k} > 1;
168214571Sdim    }
169214571Sdim
170214571Sdim    for $k (sort keys %saw) {
171214571Sdim	$fromfile{$seen_in{$k}} .= " " if $fromfile{$seen_in{$k}};
172214571Sdim	$fromfile{$seen_in{$k}} .= $k;
173214571Sdim    }
174214571Sdim
175214571Sdim    for $f (sort keys %fromfile) {
176214571Sdim	$out = "$f: $fromfile{$f}";
177214571Sdim	write;
178214571Sdim    }
179214571Sdim}
180214571Sdim
181214571Sdim######################################################################
182214571Sdim
183214571Sdimsub deps_for {
184214571Sdim    my($f) = @_;
185214571Sdim    my(%d);
186214571Sdim    open(F, $f);
187214571Sdim    %d = ();
188214571Sdim    while (<F>) {
189214571Sdim	if (/^#\s*include\s+["<](.*)[">]/) {
190214571Sdim	    $d{$1} = 1;
191214571Sdim	}
192214571Sdim    }
193214571Sdim    close(F);
194214571Sdim    return keys %d;
195214571Sdim}
196214571Sdim
197214571Sdimsub canonicalize {
198214571Sdim    my ($p) = @_;
199214571Sdim    0 while $p =~ s@/\./@/@g;
200214571Sdim    0 while $p =~ s@^\./@@g;
201214571Sdim    0 while $p =~ s@/[^/]+/\.\./@/@g;
202214571Sdim    return $p;
203214571Sdim}
204214571Sdim
205214571Sdimsub locals_first {
206214571Sdim    my ($a,$b) = @_;
207214571Sdim    return -1 if $a eq "config.h";
208214571Sdim    return  1 if $b eq "config.h";
209214571Sdim    return $a cmp $b;
210214571Sdim}
211214571Sdim
212214571Sdimsub deps {
213214571Sdim
214214571Sdim    $crule  = "\tif [ x\"\$(PICFLAG)\" != x ]; then \\\n";
215214571Sdim    $crule .= "\t  \$(COMPILE.c) \$(PICFLAG) \$< -o pic/\$@; \\\n";
216214571Sdim    $crule .= "\telse true; fi\n";
217214571Sdim    $crule .= "\tif [ x\"\$(NOASANFLAG)\" != x ]; then \\\n";
218214571Sdim    $crule .= "\t  \$(COMPILE.c) \$(PICFLAG) \$(NOASANFLAG) \$< -o noasan/\$@; \\\n";
219214571Sdim    $crule .= "\telse true; fi\n";
220214571Sdim    $crule .= "\t\$(COMPILE.c) \$< \$(OUTPUT_OPTION)\n";
221214571Sdim    $crule .= "\n";
222214571Sdim
223214571Sdim    $incdir = shift @ARGV;
224214571Sdim
225214571Sdim    opendir(INC, $incdir);
226214571Sdim    while ($f = readdir INC) {
227214571Sdim	next unless $f =~ /\.h$/ || $f =~ /\.def$/;
228214571Sdim	$mine{$f} = "\$(INCDIR)/$f";
229214571Sdim	$deps{$f} = join(' ', &deps_for("$incdir/$f"));
230214571Sdim    }
231214571Sdim    $mine{'config.h'} = "config.h";
232214571Sdim
233214571Sdim    opendir(INC, $srcdir);
234214571Sdim    while ($f = readdir INC) {
235214571Sdim	next unless $f =~ /\.h$/;
236214571Sdim	$mine{$f} = "\$(srcdir)/$f";
237214571Sdim	$deps{$f} = join(' ', &deps_for("$srcdir/$f"));
238214571Sdim    }
239214571Sdim    $mine{'config.h'} = "config.h";
240214571Sdim
241214571Sdim    open(IN, "$srcdir/Makefile.in");
242214571Sdim    open(OUT, ">$srcdir/Makefile.tmp");
243214571Sdim    while (<IN>) {
244214571Sdim	last if /remainder of this file/;
245214571Sdim	print OUT;
246214571Sdim    }
247214571Sdim    print OUT "# The dependencies in the remainder of this file are automatically\n";
248214571Sdim    print OUT "# generated by \"make maint-deps\".  Manual edits will be lost.\n\n";
249214571Sdim
250214571Sdim    opendir(S, $srcdir);
251214571Sdim    for $f (sort readdir S) {
252214571Sdim	if ($f =~ /\.c$/) {
253214571Sdim
254214571Sdim	    %scanned = ();
255214571Sdim	    @pending = &deps_for("$srcdir/$f");
256214571Sdim	    while (@pending) {
257214571Sdim		@tmp = @pending;
258214571Sdim		@pending = ();
259214571Sdim		for $p (@tmp) {
260214571Sdim		    next unless $mine{$p};
261214571Sdim		    if (!$scanned{$p}) {
262214571Sdim			push(@pending, split(' ', $deps{$p}));
263214571Sdim			$scanned{$p} = 1;
264214571Sdim		    }
265214571Sdim		}
266214571Sdim	    }
267214571Sdim	    @deps = sort { &locals_first($a,$b) } keys %scanned;
268214571Sdim	    $obj = $f;
269214571Sdim	    $obj =~ s/\.c$/.\$(objext)/;
270214571Sdim	    $obj = "./$obj:";
271214571Sdim	    if ($#deps >= 0) {
272214571Sdim		print OUT "$obj \$(srcdir)/$f";
273214571Sdim		$len = length("$obj $f");
274214571Sdim		for $dt (@deps) {
275214571Sdim		    $d = $mine{$dt};
276214571Sdim		    if ($len + length($d) > 70) {
277214571Sdim			printf OUT " \\\n\t$d";
278214571Sdim			$len = 8 + length($d);
279214571Sdim		    } else {
280214571Sdim			print OUT " $d";
281214571Sdim			$len += length($d) + 1;
282214571Sdim		    }
283214571Sdim		}
284214571Sdim		print OUT "\n";
285214571Sdim	    } else {
286214571Sdim		print OUT "$obj \$(srcdir)/$f\n";
287214571Sdim	    }
288214571Sdim	    $c = $crule;
289214571Sdim	    $c =~ s@\$\<@\$\(srcdir\)\/$f@g;
290214571Sdim	    print OUT $c;
291214571Sdim	}
292214571Sdim    }
293214571Sdim    closedir(S);
294214571Sdim    close(IN);
295214571Sdim    close(OUT);
296214571Sdim
297214571Sdim    rename("$srcdir/Makefile.tmp", "$srcdir/Makefile.in");
298214571Sdim}
299214571Sdim