1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#!/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;
}
|