OK, here's my quickie code. It won't catch fancy things like eval'd subs, etc., but it does what I need.
#!/usr/bin/perl
use strict;
my %used_sub = ();
my %declard_sub = ();
my @imported_sub = ();
my @reserved = ();
my $keywords_define_file = '/System/Library/Perl/darwin/CORE/keywords.
+h';
if (open F, $keywords_define_file) {
/^#define KEY_(\w+)/ and push @reserved, $1 while (<F>);
}
close F;
while (<>) {
while (/(?:\A|[^\%\@\$\w>])(\w+)\s*\(/g) {
$used_sub{$1}++;
}
while (/sub\s+(\w+)/g) {
$declard_sub{$1}++;
}
if (/^use\s+\S+\s+qw\((.*)\)/) {
push @imported_sub, $_ foreach split /\s+/, $1;
}
}
delete @used_sub{@reserved};
delete @used_sub{@imported_sub};
print join("\n",
'Declared subs (used):',
sort( grep {exists $used_sub{$_}} keys %declard_sub ),
'','',
'Declared subs (unused):',
sort( grep {!exists $used_sub{$_}} keys %declard_sub ),
'','',
'Used subs (declared):',
sort( grep {exists $declard_sub{$_}} keys %used_sub ),
'','',
'Used subs (undeclared):',
sort( grep {! exists $declard_sub{$_}} keys %used_sub ),
''
);
|