113 lines
1.5 KiB
Perl
113 lines
1.5 KiB
Perl
#!/usr/local/bin/perl
|
|
|
|
require 'getopts.pl';
|
|
|
|
$files="files";
|
|
%have=();
|
|
%missing=();
|
|
%name=();
|
|
%func=();
|
|
|
|
&Getopts('Ff:');
|
|
|
|
&load_file("files");
|
|
foreach $file (@ARGV)
|
|
{ &do_nm($file); }
|
|
|
|
if (defined($opt_f))
|
|
{
|
|
%a=();
|
|
$r=&list_files($opt_f,"",*a);
|
|
if ($opt_F)
|
|
{
|
|
foreach (sort split(/\n/,$r))
|
|
{ print "$_\n"; }
|
|
}
|
|
else
|
|
{ print $r; }
|
|
}
|
|
else
|
|
{
|
|
for (sort keys %have)
|
|
{
|
|
print "$_:$have{$_}\n";
|
|
}
|
|
}
|
|
|
|
sub list_files
|
|
{
|
|
local($f,$o,*done)=@_;
|
|
local($a,$_,$ff,$ret);
|
|
|
|
return if $f =~ /^\s*$/;
|
|
|
|
$done{$f}=1;
|
|
$ret.=$f."\n" if $opt_F;
|
|
foreach (split(/ /,$have{$f}))
|
|
{
|
|
$ret.="$o$f:$_\n" unless $opt_F;
|
|
}
|
|
|
|
foreach (split(/ /,$missing{$f}))
|
|
{
|
|
$ff=$func{$_};
|
|
next if defined($done{$ff});
|
|
$ret.=&list_files($ff,$o." ");
|
|
}
|
|
$ret;
|
|
}
|
|
|
|
sub do_nm
|
|
{
|
|
local($file)=@_;
|
|
local($fname)="";
|
|
|
|
open(IN,"nm $file|") || die "unable to run 'nm $file|':$!\n";
|
|
while (<IN>)
|
|
{
|
|
chop;
|
|
next if /^\s*$/;
|
|
if (/^(.*)\.o:\s*$/)
|
|
{
|
|
$fname="$1.c";
|
|
next;
|
|
}
|
|
($type,$name)=/^.{8} (.) (.+)/;
|
|
# print "$fname $type $name\n";
|
|
|
|
if ($type eq "T")
|
|
{
|
|
$have{$fname}.="$name ";
|
|
$func{$name}=$fname;
|
|
}
|
|
elsif ($type eq "U")
|
|
{
|
|
$missing{$fname}.="$name ";
|
|
}
|
|
}
|
|
close(IN);
|
|
}
|
|
|
|
sub load_file
|
|
{
|
|
local($file)=@_;
|
|
|
|
open(IN,"<$files") || die "unable to open $files:$!\n";
|
|
|
|
while (<IN>)
|
|
{
|
|
chop;
|
|
next if /^\s*$/;
|
|
($n)=/\/([^\/\s]+)\s+/;
|
|
($fn)=/^(\S+)\s/;
|
|
# print "$n - $fn\n";
|
|
if (defined($name{$n}))
|
|
{ print "$n already exists\n"; }
|
|
else
|
|
{ $name{$n}=$fn; }
|
|
}
|
|
close(IN);
|
|
@name=%name;
|
|
}
|
|
|
|
|