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