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'); |