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
|
#!/usr/bin/perl -w
#
# Pass this program a list of .pm files. It parses them (halfheartedly,
# it works on my code, may not on your code), and generates an inheritcance
# graph of the modules.
#
# Remember: I have a copy of this in debconf and a copy in stool. Keep them
# sync'd.
use strict;
my %kids;
my %iskid;
my %descs;
foreach my $file (@ARGV) {
my $package='';
my $desc='';
my @isa=();
open (IN,$file) || die "$file: $!";
while (<IN>) {
if (/package\s(\w+.*?);/) {
$package=$1;
}
# Gag. This just looks for @ISA= lines and use base.
if (/(?:use\s+base\s+|\@ISA\s*=\s*)(?:q(?:w|q)?(?:\(|{)|"|')(.*?)(?:}|\)|'|")/) {
push @isa, split(/\s+/, $1);
}
if (/.*::.*\s+-\s+(.*)/) {
$desc=$1;
}
}
close IN;
if ($package) {
$descs{$package}=$desc;
foreach (@isa) {
$kids{$_}{$package}=1;
$iskid{$package}=1;
}
}
}
my %seen;
# Print out one item.
sub printitem {
my $text=shift;
my $item=shift;
print $text . (' ' x (40 - length $text));
print $descs{$item} if exists $descs{$item};
print "\n";
}
# Recursively print out tree structure.
sub printkids {
my $parent=shift;
my $spacer=shift;
foreach my $kid (sort keys %{$kids{$parent}}) {
next if $seen{$kid};
$seen{$kid}=1;
# Strip off text in name that comes from any common parents.
$_=$kid;
foreach my $p (split(/::/,$parent)) {
s/^$p\:://;
}
printitem($spacer.$_, $kid);
printkids($kid, " $spacer");
}
}
# Print all parents with thier kids under them.
# It's important to only print toplevel parents, which is why
# %iskid comes into play.
foreach my $parent (sort keys %kids) {
next if $iskid{$parent};
printitem($parent, $parent);
printkids($parent, " ");
}
|