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@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 32if ($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 41exit 0; 42 43format STDOUT = 44^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~ 45$out 46 ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~ 47$out 48. 49 50###################################################################### 51 52sub 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 88sub 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 184sub 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 198sub 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 206sub 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 213sub 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