Re: [Lxr-general] Finding unreferenced functions
Brought to you by:
ajlittoz
|
From: Tom S. <to...@pl...> - 2005-01-06 17:14:08
|
On Thu, 2005-01-06 at 07:25 -0800, Michael O'Connor wrote:
> Hi,
>
> Apologies if this has been asked before. I'm wondering if anyone's tried using
> lxr on a codebase to find unreferenced / unused functions. I tried this on a C
> / C++ codebase I've been working in and found it very useful as part of a
> clean-up exercise.
Here is what I have done. I am not sure exactly what version of LXR I
am running, here is the CVS Id from the ident script:
# $Id: ident,v 1.6 1998/04/30 11:58:16 argggh Exp $
Here are some bits to add to Common.pm:
sub uiref {
my ($desc, $pr, @args) = @_;
return("<a href=\"unref".
&urlargs(($pr ? "pr=$pr" : ""),
@args).
"\"\>$desc</a>");
}
This goes at the end of titleexpand:
} elsif ($who eq 'unref') {
return($Conf->sourcerootname.' unreferenced identifier search');
}
This goes after the 'find' part in modeexpand:
if ($who eq 'unref') {
push(@mlist, "<b><i>unreferenced identifier search</i></b>");
} else {
push(@mlist, &uiref("unreferenced identifier search", ""));
}
This goes after the 'find' part in varlinks:
} elsif ($who eq 'unref') {
$vallink = &uiref($val, $identifier, "$var=$val");
}
========================================================================
Here is my file called "unref". It is just a modification of the ident
script, and it belongs in the same directory.
#!/usr/bin/perl
# unref -- Find unreferenced identifiers
#
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
######################################################################
use lib 'lib/';
use LXR::Common;
use LXR::Config;
use DB_File;
my $sort_by_identifier = 0;
sub unref {
print("<form method=get action=\"unref\">\n");
foreach ($Conf->allvariables) {
if ($Conf->variable($_) ne $Conf->vardefault($_)) {
print("<input type=hidden name=\"",$_, "\" ",
"value=\"", $Conf->variable($_), "\">\n");
}
}
print(
"Pathname regexp: <input type=text name=\"pr\" ",
"value=\"",$pathname_regexp,"\" size=60>\n",
"<input type=submit value=\"Go get it\">\n",
"</form>\n"
);
tie(%xref, "DB_File", $Conf->dbdir."/xref",
O_RDONLY, 0644, $DB_HASH) ||
&fatal("Could not open \"".$Conf->dbdir."/xref\"");
tie(%fileidx, "DB_File", $Conf->dbdir."/fileidx",
O_RDONLY, 0644, $DB_HASH) ||
&fatal("Could not open \"".$Conf->dbdir."/fileidx\"");
if ($pathname_regexp) {
while (($identifier, $data) = each(%xref)) {
# Ignore C++ destructors, because they are implicitly
# referenced by delete()
if ($identifier =~ /^~/) {
next;
}
@refs = split(/\t/, $data);
unless (@refs) {
next;
}
@filtered_refs = grep(/^R/, @refs);
if (int(@filtered_refs) > 2) {
next;
}
foreach (@filtered_refs) {
if (/^R(.+):([\d,]+)/) {
$fnam = $fileidx{$1};
@fpos = split(/,/, $2);
unless ($fnam =~ /$pathname_regexp/) {
next;
}
# ignore definitions in .h files
if ($fnam =~ /\.h$|\._h$/) {
next;
}
if ($#fpos == 0) {
if ($sort_by_identifier) {
$unref_ident{$identifier} = &fileref(
"$fnam, line $fpos[0]",
"/$fnam",
$fpos[0]
);
} else {
$unref_ident{
&fileref(
"$fnam, line $fpos[0]",
"/$fnam",
$fpos[0]
)
} = $identifier;
}
}
}
}
}
untie(%fileidx);
untie(%xref);
@keylist = keys(%unref_ident);
print("<h1>Unreferenced identifiers (", $#keylist, ")</h1>\n");
print("<table>\n");
if ($sort_by_identifier) {
print("<tr><th>Identifier</th><th>File</th></tr>\n");
foreach $identifier (sort(@keylist)) {
print(
"<tr><td>",
&idref($identifier, $identifier),
"</td><td>",
$unref_ident{$identifier},
"</td></tr>\n"
);
}
} else {
print("<tr><th>File</th><th>Identifier</th></tr>\n");
foreach $fref (sort(@keylist)) {
print(
"<tr><td>",
$fref,
"</td><td>",
&idref($unref_ident{$fref}, $unref_ident{$fref}),
"</td></tr>\n"
);
}
}
print("</table>\n");
} else {
print(
"<p>You must specify a pathname regexp.",
" Use '.' to match all files."
);
}
}
($Conf, $HTTP, $Path) = &init;
$pathname_regexp = $HTTP->{'param'}->{'pr'};
&makeheader('unref');
&unref;
&makefooter('unref');
|