xref: /netbsd-src/external/gpl3/binutils.old/dist/libiberty/maint-tool (revision e992f068c547fd6e84b3f104dc2340adcc955732)
116dce513Schristos#!/usr/bin/perl
216dce513Schristos# -*- perl -*-
316dce513Schristos
4*e992f068Schristos#   Copyright (C) 2001-2022 Free Software Foundation, Inc.
516dce513Schristos#
616dce513Schristos# This file is part of the libiberty library.
716dce513Schristos# Libiberty is free software; you can redistribute it and/or
816dce513Schristos# modify it under the terms of the GNU Library General Public
916dce513Schristos# License as published by the Free Software Foundation; either
1016dce513Schristos# version 2 of the License, or (at your option) any later version.
1116dce513Schristos#
1216dce513Schristos# Libiberty is distributed in the hope that it will be useful,
1316dce513Schristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
1416dce513Schristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1516dce513Schristos# Library General Public License for more details.
1616dce513Schristos#
1716dce513Schristos# You should have received a copy of the GNU Library General Public
1816dce513Schristos# License along with libiberty; see the file COPYING.LIB.  If not,
1916dce513Schristos# write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
2016dce513Schristos# Boston, MA 02110-1301, USA.
2116dce513Schristos#
2216dce513Schristos# Originally written by DJ Delorie <dj@redhat.com>
2316dce513Schristos
2416dce513Schristos
2516dce513Schristos# This is a trivial script which checks the lists of C and O files in
2616dce513Schristos# the Makefile for consistency.
2716dce513Schristos
2816dce513Schristos$mode = shift;
2916dce513Schristos$srcdir = ".";
3016dce513Schristos
3116dce513Schristosif ($mode eq "-s") {
3216dce513Schristos    $srcdir = shift;
3316dce513Schristos    $mode = shift;
3416dce513Schristos}
3516dce513Schristos
3616dce513Schristos&missing() if $mode eq "missing";
3716dce513Schristos&undoc() if $mode eq "undoc";
3816dce513Schristos&deps() if $mode eq "deps";
3916dce513Schristos
4016dce513Schristosexit 0;
4116dce513Schristos
4216dce513Schristosformat STDOUT =
4316dce513Schristos^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~
4416dce513Schristos$out
4516dce513Schristos        ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
4616dce513Schristos$out
4716dce513Schristos.
4816dce513Schristos
4916dce513Schristos######################################################################
5016dce513Schristos
5116dce513Schristossub missing {
5216dce513Schristos
5316dce513Schristos    opendir(S, $srcdir);
5416dce513Schristos    while ($f = readdir S) {
5516dce513Schristos	$have{$f} = 1;
5616dce513Schristos    }
5716dce513Schristos    closedir(S);
5816dce513Schristos    opendir(S, ".");
5916dce513Schristos    while ($f = readdir S) {
6016dce513Schristos	$have{$f} = 1;
6116dce513Schristos    }
6216dce513Schristos    closedir(S);
6316dce513Schristos
6416dce513Schristos    for $a (@ARGV) {
6516dce513Schristos	$listed{$a} = 1;
6616dce513Schristos	$have{$a} = 0;
6716dce513Schristos    }
6816dce513Schristos
6916dce513Schristos    for $f (sort keys %have) {
7016dce513Schristos	next unless $have{$f};
7116dce513Schristos	if ($f =~ /\.c$/) {
7216dce513Schristos	    print "S $f\n";
7316dce513Schristos	}
7416dce513Schristos    }
7516dce513Schristos    for $f (sort keys %listed) {
7616dce513Schristos	if ($f =~ /(.*)\.c$/) {
7716dce513Schristos	    $base = $1;
7816dce513Schristos	    if (! $listed{"./$base.o"}) {
7916dce513Schristos		print "O $f\n";
8016dce513Schristos	    }
8116dce513Schristos	}
8216dce513Schristos    }
8316dce513Schristos}
8416dce513Schristos
8516dce513Schristos######################################################################
8616dce513Schristos
8716dce513Schristossub undoc {
8816dce513Schristos
8916dce513Schristos    opendir(S, $srcdir);
9016dce513Schristos    while ($file = readdir S) {
9116dce513Schristos	if ($file =~ /\.texi$/) {
9216dce513Schristos	    open(T, "$srcdir/$file");
9316dce513Schristos	    while (<T>) {
9416dce513Schristos		if (/^\@deftype[^\(]* ([^\s\(]+) *\(/) {
9516dce513Schristos		    $documented{$1} = 1;
9616dce513Schristos		}
9716dce513Schristos	    }
9816dce513Schristos	    close(T);
9916dce513Schristos	}
10016dce513Schristos	if ($file =~ /\.c$/) {
10116dce513Schristos	    open(C, "$srcdir/$file");
10216dce513Schristos	    while (<C>) {
10316dce513Schristos		if (/\@undocumented (\S+)/) {
10416dce513Schristos		    $documented{$1} = 1;
10516dce513Schristos		}
10616dce513Schristos		if (/^static /) {
10716dce513Schristos		    if (! /[\(;]/) {
10816dce513Schristos			s/[\r\n]+$/ /;
10916dce513Schristos			$_ .= <C>;
11016dce513Schristos		    }
11116dce513Schristos		    while ($_ =~ /\([^\)]*$/) {
11216dce513Schristos			s/[\r\n]+$/ /;
11316dce513Schristos			$_ .= <C>;
11416dce513Schristos		    }
11516dce513Schristos		}
11616dce513Schristos		s/ VPARAMS([ \(])/$1/;
11716dce513Schristos		s/PREFIX\(([^\)]*)\)/byte_$1/;
11816dce513Schristos		if (/^static [^\(]* ([^\s\(]+) *\(.*\)$/) {
11916dce513Schristos		    $documented{$1} = 1;
12016dce513Schristos		}
12116dce513Schristos	    }
12216dce513Schristos	}
12316dce513Schristos    }
12416dce513Schristos    closedir(D);
12516dce513Schristos
12616dce513Schristos    # $out = join(' ', sort keys %documented);
12716dce513Schristos    # write;
12816dce513Schristos    # print "\n";
12916dce513Schristos
13016dce513Schristos    system "etags $srcdir/*.c $srcdir/../include/*.h";
13116dce513Schristos    open(TAGS, "TAGS");
13216dce513Schristos    while (<TAGS>) {
13316dce513Schristos	s/[\r\n]+$//;
13416dce513Schristos	if (/^\014$/) {
13516dce513Schristos	    $filename = <TAGS>;
13616dce513Schristos	    $filename =~ s/[\r\n]+$//;
13716dce513Schristos	    $filename =~ s/,\d+$//;
13816dce513Schristos	    $filename =~ s@.*[/\\]@@;
13916dce513Schristos	    next;
14016dce513Schristos	}
14116dce513Schristos	if ($filename =~ /\.c$/ ) {
14216dce513Schristos	    next unless /^[_a-zA-Z]/;
14316dce513Schristos	} else {
14416dce513Schristos	    next unless /^\# *define/;
14516dce513Schristos	    s/\# *define *//;
14616dce513Schristos	}
14716dce513Schristos
14816dce513Schristos	s/ VPARAMS//;
14916dce513Schristos	s/ *\177.*//;
15016dce513Schristos	s/,$//;
15116dce513Schristos	s/DEFUN\(//;
15216dce513Schristos	s/\(//;
15316dce513Schristos
15416dce513Schristos	next if /^static /;
15516dce513Schristos	next if /\s/;
15616dce513Schristos	next if /^_/;
15716dce513Schristos	next if $documented{$_};
15816dce513Schristos	next if /_H_?$/;
15916dce513Schristos
16016dce513Schristos	if ($seen_in{$_} ne $filename) {
16116dce513Schristos	    $saw{$_} ++;
16216dce513Schristos	}
16316dce513Schristos	$seen_in{$_} = $filename;
16416dce513Schristos    }
16516dce513Schristos
16616dce513Schristos    for $k (keys %saw) {
16716dce513Schristos	delete $saw{$k} if $saw{$k} > 1;
16816dce513Schristos    }
16916dce513Schristos
17016dce513Schristos    for $k (sort keys %saw) {
17116dce513Schristos	$fromfile{$seen_in{$k}} .= " " if $fromfile{$seen_in{$k}};
17216dce513Schristos	$fromfile{$seen_in{$k}} .= $k;
17316dce513Schristos    }
17416dce513Schristos
17516dce513Schristos    for $f (sort keys %fromfile) {
17616dce513Schristos	$out = "$f: $fromfile{$f}";
17716dce513Schristos	write;
17816dce513Schristos    }
17916dce513Schristos}
18016dce513Schristos
18116dce513Schristos######################################################################
18216dce513Schristos
18316dce513Schristossub deps_for {
18416dce513Schristos    my($f) = @_;
18516dce513Schristos    my(%d);
18616dce513Schristos    open(F, $f);
18716dce513Schristos    %d = ();
18816dce513Schristos    while (<F>) {
18916dce513Schristos	if (/^#\s*include\s+["<](.*)[">]/) {
19016dce513Schristos	    $d{$1} = 1;
19116dce513Schristos	}
19216dce513Schristos    }
19316dce513Schristos    close(F);
19416dce513Schristos    return keys %d;
19516dce513Schristos}
19616dce513Schristos
19716dce513Schristossub canonicalize {
19816dce513Schristos    my ($p) = @_;
19916dce513Schristos    0 while $p =~ s@/\./@/@g;
20016dce513Schristos    0 while $p =~ s@^\./@@g;
20116dce513Schristos    0 while $p =~ s@/[^/]+/\.\./@/@g;
20216dce513Schristos    return $p;
20316dce513Schristos}
20416dce513Schristos
20516dce513Schristossub locals_first {
20616dce513Schristos    my ($a,$b) = @_;
20716dce513Schristos    return -1 if $a eq "config.h";
20816dce513Schristos    return  1 if $b eq "config.h";
20916dce513Schristos    return $a cmp $b;
21016dce513Schristos}
21116dce513Schristos
21216dce513Schristossub deps {
21316dce513Schristos
21416dce513Schristos    $crule  = "\tif [ x\"\$(PICFLAG)\" != x ]; then \\\n";
21516dce513Schristos    $crule .= "\t  \$(COMPILE.c) \$(PICFLAG) \$< -o pic/\$@; \\\n";
21616dce513Schristos    $crule .= "\telse true; fi\n";
21716dce513Schristos    $crule .= "\tif [ x\"\$(NOASANFLAG)\" != x ]; then \\\n";
21816dce513Schristos    $crule .= "\t  \$(COMPILE.c) \$(PICFLAG) \$(NOASANFLAG) \$< -o noasan/\$@; \\\n";
21916dce513Schristos    $crule .= "\telse true; fi\n";
22016dce513Schristos    $crule .= "\t\$(COMPILE.c) \$< \$(OUTPUT_OPTION)\n";
22116dce513Schristos    $crule .= "\n";
22216dce513Schristos
22316dce513Schristos    $incdir = shift @ARGV;
22416dce513Schristos
22516dce513Schristos    opendir(INC, $incdir);
22616dce513Schristos    while ($f = readdir INC) {
22716dce513Schristos	next unless $f =~ /\.h$/ || $f =~ /\.def$/;
22816dce513Schristos	$mine{$f} = "\$(INCDIR)/$f";
22916dce513Schristos	$deps{$f} = join(' ', &deps_for("$incdir/$f"));
23016dce513Schristos    }
23116dce513Schristos    $mine{'config.h'} = "config.h";
23216dce513Schristos
23316dce513Schristos    opendir(INC, $srcdir);
23416dce513Schristos    while ($f = readdir INC) {
23516dce513Schristos	next unless $f =~ /\.h$/;
23616dce513Schristos	$mine{$f} = "\$(srcdir)/$f";
23716dce513Schristos	$deps{$f} = join(' ', &deps_for("$srcdir/$f"));
23816dce513Schristos    }
23916dce513Schristos    $mine{'config.h'} = "config.h";
24016dce513Schristos
24116dce513Schristos    open(IN, "$srcdir/Makefile.in");
24216dce513Schristos    open(OUT, ">$srcdir/Makefile.tmp");
24316dce513Schristos    while (<IN>) {
24416dce513Schristos	last if /remainder of this file/;
24516dce513Schristos	print OUT;
24616dce513Schristos    }
24716dce513Schristos    print OUT "# The dependencies in the remainder of this file are automatically\n";
24816dce513Schristos    print OUT "# generated by \"make maint-deps\".  Manual edits will be lost.\n\n";
24916dce513Schristos
25016dce513Schristos    opendir(S, $srcdir);
25116dce513Schristos    for $f (sort readdir S) {
25216dce513Schristos	if ($f =~ /\.c$/) {
25316dce513Schristos
25416dce513Schristos	    %scanned = ();
25516dce513Schristos	    @pending = &deps_for("$srcdir/$f");
25616dce513Schristos	    while (@pending) {
25716dce513Schristos		@tmp = @pending;
25816dce513Schristos		@pending = ();
25916dce513Schristos		for $p (@tmp) {
26016dce513Schristos		    next unless $mine{$p};
26116dce513Schristos		    if (!$scanned{$p}) {
26216dce513Schristos			push(@pending, split(' ', $deps{$p}));
26316dce513Schristos			$scanned{$p} = 1;
26416dce513Schristos		    }
26516dce513Schristos		}
26616dce513Schristos	    }
26716dce513Schristos	    @deps = sort { &locals_first($a,$b) } keys %scanned;
26816dce513Schristos	    $obj = $f;
26916dce513Schristos	    $obj =~ s/\.c$/.\$(objext)/;
27016dce513Schristos	    $obj = "./$obj:";
27116dce513Schristos	    if ($#deps >= 0) {
27216dce513Schristos		print OUT "$obj \$(srcdir)/$f";
27316dce513Schristos		$len = length("$obj $f");
27416dce513Schristos		for $dt (@deps) {
27516dce513Schristos		    $d = $mine{$dt};
27616dce513Schristos		    if ($len + length($d) > 70) {
27716dce513Schristos			printf OUT " \\\n\t$d";
27816dce513Schristos			$len = 8 + length($d);
27916dce513Schristos		    } else {
28016dce513Schristos			print OUT " $d";
28116dce513Schristos			$len += length($d) + 1;
28216dce513Schristos		    }
28316dce513Schristos		}
28416dce513Schristos		print OUT "\n";
28516dce513Schristos	    } else {
28616dce513Schristos		print OUT "$obj \$(srcdir)/$f\n";
28716dce513Schristos	    }
28816dce513Schristos	    $c = $crule;
28916dce513Schristos	    $c =~ s@\$\<@\$\(srcdir\)\/$f@g;
29016dce513Schristos	    print OUT $c;
29116dce513Schristos	}
29216dce513Schristos    }
29316dce513Schristos    closedir(S);
29416dce513Schristos    close(IN);
29516dce513Schristos    close(OUT);
29616dce513Schristos
29716dce513Schristos    rename("$srcdir/Makefile.tmp", "$srcdir/Makefile.in");
29816dce513Schristos}
299