189857Sobrien#!/usr/bin/perl
289857Sobrien# -*- perl -*-
389857Sobrien
489857Sobrien#   Copyright (C) 2001
589857Sobrien#   Free Software Foundation
689857Sobrien#
789857Sobrien# This file is part of the libiberty library.
889857Sobrien# Libiberty is free software; you can redistribute it and/or
989857Sobrien# modify it under the terms of the GNU Library General Public
1089857Sobrien# License as published by the Free Software Foundation; either
1189857Sobrien# version 2 of the License, or (at your option) any later version.
1289857Sobrien#
1389857Sobrien# Libiberty is distributed in the hope that it will be useful,
1489857Sobrien# but WITHOUT ANY WARRANTY; without even the implied warranty of
1589857Sobrien# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1689857Sobrien# Library General Public License for more details.
1789857Sobrien#
1889857Sobrien# You should have received a copy of the GNU Library General Public
1989857Sobrien# License along with libiberty; see the file COPYING.LIB.  If not,
20218822Sdim# write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
21218822Sdim# Boston, MA 02110-1301, USA.
2289857Sobrien#
2389857Sobrien# Originally written by DJ Delorie <dj@redhat.com>
2489857Sobrien
2589857Sobrien
2689857Sobrien# This is a trivial script which checks the lists of C and O files in
2789857Sobrien# the Makefile for consistency.
2889857Sobrien
2989857Sobrien$mode = shift;
3089857Sobrien$srcdir = ".";
3189857Sobrien
3289857Sobrienif ($mode eq "-s") {
3389857Sobrien    $srcdir = shift;
3489857Sobrien    $mode = shift;
3589857Sobrien}
3689857Sobrien
3789857Sobrien&missing() if $mode eq "missing";
3889857Sobrien&undoc() if $mode eq "undoc";
3989857Sobrien&deps() if $mode eq "deps";
4089857Sobrien
4189857Sobrienexit 0;
4289857Sobrien
4389857Sobrienformat STDOUT =
4489857Sobrien^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~
4589857Sobrien$out
4689857Sobrien        ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
4789857Sobrien$out
4889857Sobrien.
4989857Sobrien
5089857Sobrien######################################################################
5189857Sobrien
5289857Sobriensub missing {
5389857Sobrien
5489857Sobrien    opendir(S, $srcdir);
5589857Sobrien    while ($f = readdir S) {
5689857Sobrien	$have{$f} = 1;
5789857Sobrien    }
5889857Sobrien    closedir(S);
5989857Sobrien    opendir(S, ".");
6089857Sobrien    while ($f = readdir S) {
6189857Sobrien	$have{$f} = 1;
6289857Sobrien    }
6389857Sobrien    closedir(S);
6489857Sobrien
6589857Sobrien    for $a (@ARGV) {
6689857Sobrien	$listed{$a} = 1;
6789857Sobrien	$have{$a} = 0;
6889857Sobrien    }
6989857Sobrien
7089857Sobrien    for $f (sort keys %have) {
7189857Sobrien	next unless $have{$f};
7289857Sobrien	if ($f =~ /\.c$/) {
7389857Sobrien	    print "S $f\n";
7489857Sobrien	}
7589857Sobrien    }
7689857Sobrien    for $f (sort keys %listed) {
7789857Sobrien	if ($f =~ /(.*)\.c$/) {
7889857Sobrien	    $base = $1;
7989857Sobrien	    if (! $listed{"$base.o"}) {
8089857Sobrien		print "O $f\n";
8189857Sobrien	    }
8289857Sobrien	}
8389857Sobrien    }
8489857Sobrien}
8589857Sobrien
8689857Sobrien######################################################################
8789857Sobrien
8889857Sobriensub undoc {
8989857Sobrien
9089857Sobrien    opendir(S, $srcdir);
9189857Sobrien    while ($file = readdir S) {
9289857Sobrien	if ($file =~ /\.texi$/) {
9389857Sobrien	    open(T, "$srcdir/$file");
9489857Sobrien	    while (<T>) {
9589857Sobrien		if (/^\@deftype[^\(]* ([^\s\(]+) *\(/) {
9689857Sobrien		    $documented{$1} = 1;
9789857Sobrien		}
9889857Sobrien	    }
9989857Sobrien	    close(T);
10089857Sobrien	}
10189857Sobrien	if ($file =~ /\.c$/) {
10289857Sobrien	    open(C, "$srcdir/$file");
10389857Sobrien	    while (<C>) {
10489857Sobrien		if (/\@undocumented (\S+)/) {
10589857Sobrien		    $documented{$1} = 1;
10689857Sobrien		}
10789857Sobrien		if (/^static /) {
10889857Sobrien		    if (! /[\(;]/) {
10989857Sobrien			s/[\r\n]+$/ /;
11089857Sobrien			$_ .= <C>;
11189857Sobrien		    }
11289857Sobrien		    while ($_ =~ /\([^\)]*$/) {
11389857Sobrien			s/[\r\n]+$/ /;
11489857Sobrien			$_ .= <C>;
11589857Sobrien		    }
11689857Sobrien		}
11789857Sobrien		s/ VPARAMS([ \(])/$1/;
11889857Sobrien		s/PREFIX\(([^\)]*)\)/byte_$1/;
11989857Sobrien		if (/^static [^\(]* ([^\s\(]+) *\(.*\)$/) {
12089857Sobrien		    $documented{$1} = 1;
12189857Sobrien		}
12289857Sobrien	    }
12389857Sobrien	}
12489857Sobrien    }
12589857Sobrien    closedir(D);
12689857Sobrien
12789857Sobrien    # $out = join(' ', sort keys %documented);
12889857Sobrien    # write;
12989857Sobrien    # print "\n";
13089857Sobrien
13189857Sobrien    system "etags $srcdir/*.c $srcdir/../include/*.h";
13289857Sobrien    open(TAGS, "TAGS");
13389857Sobrien    while (<TAGS>) {
13489857Sobrien	s/[\r\n]+$//;
13589857Sobrien	if (/^\014$/) {
13689857Sobrien	    $filename = <TAGS>;
13789857Sobrien	    $filename =~ s/[\r\n]+$//;
13889857Sobrien	    $filename =~ s/,\d+$//;
13989857Sobrien	    $filename =~ s@.*[/\\]@@;
14089857Sobrien	    next;
14189857Sobrien	}
14289857Sobrien	if ($filename =~ /\.c$/ ) {
14389857Sobrien	    next unless /^[_a-zA-Z]/;
14489857Sobrien	} else {
14589857Sobrien	    next unless /^\# *define/;
14689857Sobrien	    s/\# *define *//;
14789857Sobrien	}
14889857Sobrien
14989857Sobrien	s/ VPARAMS//;
15089857Sobrien	s/ *\177.*//;
15189857Sobrien	s/,$//;
15289857Sobrien	s/DEFUN\(//;
15389857Sobrien	s/\(//;
15489857Sobrien
15589857Sobrien	next if /^static /;
15689857Sobrien	next if /\s/;
15789857Sobrien	next if /^_/;
15889857Sobrien	next if $documented{$_};
15989857Sobrien	next if /_H_?$/;
16089857Sobrien
16189857Sobrien	if ($seen_in{$_} ne $filename) {
16289857Sobrien	    $saw{$_} ++;
16389857Sobrien	}
16489857Sobrien	$seen_in{$_} = $filename;
16589857Sobrien    }
16689857Sobrien
16789857Sobrien    for $k (keys %saw) {
16889857Sobrien	delete $saw{$k} if $saw{$k} > 1;
16989857Sobrien    }
17089857Sobrien
17189857Sobrien    for $k (sort keys %saw) {
17289857Sobrien	$fromfile{$seen_in{$k}} .= " " if $fromfile{$seen_in{$k}};
17389857Sobrien	$fromfile{$seen_in{$k}} .= $k;
17489857Sobrien    }
17589857Sobrien
17689857Sobrien    for $f (sort keys %fromfile) {
17789857Sobrien	$out = "$f: $fromfile{$f}";
17889857Sobrien	write;
17989857Sobrien    }
18089857Sobrien}
18189857Sobrien
18289857Sobrien######################################################################
18389857Sobrien
18489857Sobriensub deps_for {
18589857Sobrien    my($f) = @_;
18689857Sobrien    my(%d);
18789857Sobrien    open(F, $f);
18889857Sobrien    %d = ();
18989857Sobrien    while (<F>) {
19089857Sobrien	if (/^#\s*include\s+["<](.*)[">]/) {
19189857Sobrien	    $d{$1} = 1;
19289857Sobrien	}
19389857Sobrien    }
19489857Sobrien    close(F);
19589857Sobrien    return keys %d;
19689857Sobrien}
19789857Sobrien
19889857Sobriensub canonicalize {
19989857Sobrien    my ($p) = @_;
20089857Sobrien    0 while $p =~ s@/\./@/@g;
20189857Sobrien    0 while $p =~ s@^\./@@g;
20289857Sobrien    0 while $p =~ s@/[^/]+/\.\./@/@g;
20389857Sobrien    return $p;
20489857Sobrien}
20589857Sobrien
20689857Sobriensub locals_first {
20789857Sobrien    my ($a,$b) = @_;
20889857Sobrien    return -1 if $a eq "config.h";
20989857Sobrien    return  1 if $b eq "config.h";
21089857Sobrien    return $a cmp $b;
21189857Sobrien}
21289857Sobrien
21389857Sobriensub deps {
21489857Sobrien
215130561Sobrien    $crule  = "\tif [ x\"\$(PICFLAG)\" != x ]; then \\\n";
216130561Sobrien    $crule .= "\t  \$(COMPILE.c) \$(PICFLAG) \$< -o pic/\$@; \\\n";
217130561Sobrien    $crule .= "\telse true; fi\n";
218130561Sobrien    $crule .= "\t\$(COMPILE.c) \$< \$(OUTPUT_OPTION)\n";
219130561Sobrien    $crule .= "\n";
220130561Sobrien
22189857Sobrien    $incdir = shift @ARGV;
22289857Sobrien
22389857Sobrien    opendir(INC, $incdir);
22489857Sobrien    while ($f = readdir INC) {
22589857Sobrien	next unless $f =~ /\.h$/;
22689857Sobrien	$mine{$f} = "\$(INCDIR)/$f";
22789857Sobrien	$deps{$f} = join(' ', &deps_for("$incdir/$f"));
22889857Sobrien    }
22989857Sobrien    $mine{'config.h'} = "config.h";
23089857Sobrien
231130561Sobrien    opendir(INC, $srcdir);
232130561Sobrien    while ($f = readdir INC) {
233130561Sobrien	next unless $f =~ /\.h$/;
234130561Sobrien	$mine{$f} = "\$(srcdir)/$f";
235130561Sobrien	$deps{$f} = join(' ', &deps_for("$srcdir/$f"));
236130561Sobrien    }
237130561Sobrien    $mine{'config.h'} = "config.h";
238130561Sobrien
23989857Sobrien    open(IN, "$srcdir/Makefile.in");
24089857Sobrien    open(OUT, ">$srcdir/Makefile.tmp");
24189857Sobrien    while (<IN>) {
24289857Sobrien	last if /remainder of this file/;
24389857Sobrien	print OUT;
24489857Sobrien    }
24589857Sobrien    print OUT "# The dependencies in the remainder of this file are automatically\n";
24689857Sobrien    print OUT "# generated by \"make maint-deps\".  Manual edits will be lost.\n\n";
24789857Sobrien
24889857Sobrien    opendir(S, $srcdir);
24989857Sobrien    for $f (sort readdir S) {
25089857Sobrien	if ($f =~ /\.c$/) {
25189857Sobrien
25289857Sobrien	    %scanned = ();
25389857Sobrien	    @pending = &deps_for("$srcdir/$f");
25489857Sobrien	    while (@pending) {
25589857Sobrien		@tmp = @pending;
25689857Sobrien		@pending = ();
25789857Sobrien		for $p (@tmp) {
25889857Sobrien		    next unless $mine{$p};
25989857Sobrien		    if (!$scanned{$p}) {
26089857Sobrien			push(@pending, split(' ', $deps{$p}));
26189857Sobrien			$scanned{$p} = 1;
26289857Sobrien		    }
26389857Sobrien		}
26489857Sobrien	    }
26589857Sobrien	    @deps = sort { &locals_first($a,$b) } keys %scanned;
26689857Sobrien	    $obj = $f;
26789857Sobrien	    $obj =~ s/\.c$/.o/;
268130561Sobrien	    $obj = "./$obj:";
26989857Sobrien	    if ($#deps >= 0) {
270130561Sobrien		print OUT "$obj \$(srcdir)/$f";
271130561Sobrien		$len = length("$obj $f");
27289857Sobrien		for $dt (@deps) {
27389857Sobrien		    $d = $mine{$dt};
27489857Sobrien		    if ($len + length($d) > 70) {
27589857Sobrien			printf OUT " \\\n\t$d";
27689857Sobrien			$len = 8 + length($d);
27789857Sobrien		    } else {
27889857Sobrien			print OUT " $d";
27989857Sobrien			$len += length($d) + 1;
28089857Sobrien		    }
28189857Sobrien		}
28289857Sobrien		print OUT "\n";
283130561Sobrien	    } else {
284130561Sobrien		print OUT "$obj \$(srcdir)/$f\n";
28589857Sobrien	    }
286130561Sobrien	    $c = $crule;
287130561Sobrien	    $c =~ s@\$\<@\$\(srcdir\)\/$f@g;
288130561Sobrien	    print OUT $c;
28989857Sobrien	}
29089857Sobrien    }
29189857Sobrien    closedir(S);
29289857Sobrien    close(IN);
29389857Sobrien    close(OUT);
29489857Sobrien
29589857Sobrien    rename("$srcdir/Makefile.tmp", "$srcdir/Makefile.in");
29689857Sobrien}
297