Home | History | Annotate | Line # | Download | only in libiberty
maint-tool revision 1.1
      1 #!/usr/bin/perl
      2 # -*- perl -*-
      3 
      4 #   Copyright (C) 2001, 2007
      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., 51 Franklin Street - Fifth Floor,
     21 # Boston, MA 02110-1301, USA.
     22 #
     23 # Originally written by DJ Delorie <dj (at] 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 
    149 	s/ VPARAMS//;
    150 	s/ *\177.*//;
    151 	s/,$//;
    152 	s/DEFUN\(//;
    153 	s/\(//;
    154 
    155 	next if /^static /;
    156 	next if /\s/;
    157 	next if /^_/;
    158 	next if $documented{$_};
    159 	next if /_H_?$/;
    160 
    161 	if ($seen_in{$_} ne $filename) {
    162 	    $saw{$_} ++;
    163 	}
    164 	$seen_in{$_} = $filename;
    165     }
    166 
    167     for $k (keys %saw) {
    168 	delete $saw{$k} if $saw{$k} > 1;
    169     }
    170 
    171     for $k (sort keys %saw) {
    172 	$fromfile{$seen_in{$k}} .= " " if $fromfile{$seen_in{$k}};
    173 	$fromfile{$seen_in{$k}} .= $k;
    174     }
    175 
    176     for $f (sort keys %fromfile) {
    177 	$out = "$f: $fromfile{$f}";
    178 	write;
    179     }
    180 }
    181 
    182 ######################################################################
    183 
    184 sub deps_for {
    185     my($f) = @_;
    186     my(%d);
    187     open(F, $f);
    188     %d = ();
    189     while (<F>) {
    190 	if (/^#\s*include\s+["<](.*)[">]/) {
    191 	    $d{$1} = 1;
    192 	}
    193     }
    194     close(F);
    195     return keys %d;
    196 }
    197 
    198 sub canonicalize {
    199     my ($p) = @_;
    200     0 while $p =~ s@/\./@/@g;
    201     0 while $p =~ s@^\./@@g;
    202     0 while $p =~ s@/[^/]+/\.\./@/@g;
    203     return $p;
    204 }
    205 
    206 sub locals_first {
    207     my ($a,$b) = @_;
    208     return -1 if $a eq "config.h";
    209     return  1 if $b eq "config.h";
    210     return $a cmp $b;
    211 }
    212 
    213 sub deps {
    214 
    215     $crule  = "\tif [ x\"\$(PICFLAG)\" != x ]; then \\\n";
    216     $crule .= "\t  \$(COMPILE.c) \$(PICFLAG) \$< -o pic/\$@; \\\n";
    217     $crule .= "\telse true; fi\n";
    218     $crule .= "\t\$(COMPILE.c) \$< \$(OUTPUT_OPTION)\n";
    219     $crule .= "\n";
    220 
    221     $incdir = shift @ARGV;
    222 
    223     opendir(INC, $incdir);
    224     while ($f = readdir INC) {
    225 	next unless $f =~ /\.h$/;
    226 	$mine{$f} = "\$(INCDIR)/$f";
    227 	$deps{$f} = join(' ', &deps_for("$incdir/$f"));
    228     }
    229     $mine{'config.h'} = "config.h";
    230 
    231     opendir(INC, $srcdir);
    232     while ($f = readdir INC) {
    233 	next unless $f =~ /\.h$/;
    234 	$mine{$f} = "\$(srcdir)/$f";
    235 	$deps{$f} = join(' ', &deps_for("$srcdir/$f"));
    236     }
    237     $mine{'config.h'} = "config.h";
    238 
    239     open(IN, "$srcdir/Makefile.in");
    240     open(OUT, ">$srcdir/Makefile.tmp");
    241     while (<IN>) {
    242 	last if /remainder of this file/;
    243 	print OUT;
    244     }
    245     print OUT "# The dependencies in the remainder of this file are automatically\n";
    246     print OUT "# generated by \"make maint-deps\".  Manual edits will be lost.\n\n";
    247 
    248     opendir(S, $srcdir);
    249     for $f (sort readdir S) {
    250 	if ($f =~ /\.c$/) {
    251 
    252 	    %scanned = ();
    253 	    @pending = &deps_for("$srcdir/$f");
    254 	    while (@pending) {
    255 		@tmp = @pending;
    256 		@pending = ();
    257 		for $p (@tmp) {
    258 		    next unless $mine{$p};
    259 		    if (!$scanned{$p}) {
    260 			push(@pending, split(' ', $deps{$p}));
    261 			$scanned{$p} = 1;
    262 		    }
    263 		}
    264 	    }
    265 	    @deps = sort { &locals_first($a,$b) } keys %scanned;
    266 	    $obj = $f;
    267 	    $obj =~ s/\.c$/.o/;
    268 	    $obj = "./$obj:";
    269 	    if ($#deps >= 0) {
    270 		print OUT "$obj \$(srcdir)/$f";
    271 		$len = length("$obj $f");
    272 		for $dt (@deps) {
    273 		    $d = $mine{$dt};
    274 		    if ($len + length($d) > 70) {
    275 			printf OUT " \\\n\t$d";
    276 			$len = 8 + length($d);
    277 		    } else {
    278 			print OUT " $d";
    279 			$len += length($d) + 1;
    280 		    }
    281 		}
    282 		print OUT "\n";
    283 	    } else {
    284 		print OUT "$obj \$(srcdir)/$f\n";
    285 	    }
    286 	    $c = $crule;
    287 	    $c =~ s@\$\<@\$\(srcdir\)\/$f@g;
    288 	    print OUT $c;
    289 	}
    290     }
    291     closedir(S);
    292     close(IN);
    293     close(OUT);
    294 
    295     rename("$srcdir/Makefile.tmp", "$srcdir/Makefile.in");
    296 }
    297