#!/usr/local/bin/perl # jxref - Build a cross-reference index file for the specified packages. # Works very simplistically by looking for the names of other classes within # source files. This is not a full parser and can be fooled by the following # situations, amongst others: # - having two classes with the same name in different packages # - having more than one class in the same source file (eg. inner classes) # - having a method or variable called the same as a class name # Rolf Howarth, Parallax Solutions Ltd. Mar 1997 $| = 1; die "Usage: jxref ...\n" unless ($#ARGV >= 2); # Note that the javadoc prefix is used to generate links to javadoc documentation # and can be used if the output is being placed in a different directory from the # javadoc generated files or if you have long package names and the package directories # are not specified relative to the root. $images = "images"; # URL location of javadoc bullet images # Process command line arguments and set options $html = shift @ARGV; $prefix = shift @ARGV; @packages = @ARGV; # Build up list of target files foreach $package (@packages) { @files = <$package/*.java>; $package =~ tr,/,.,; push(@allfiles, @files); foreach $file ( @files ) { $class = ""; ($class) = ($file =~ m,/(\w+).java$,); if (! $class) { die "Error in $file\n"; } $package{$class} .= $package." "; } } open(OUT, ">$html") || die "Failed to create $html"; print OUT " Java Cross Reference Index\n Index     Notes

Java Cross Reference Index

\n
\n"; foreach $file (@allfiles) { $class = ""; ($class) = ($file =~ m,/(\w+).java$,); $multiLineComment = 0; print "\rProcessing $file "; open(SRC, $file) || die "Failed to open $file : $!\n"; while () { process($_); } close SRC; } print "\rWriting $html \n"; foreach $class (sort keys %package) { $package = $package{$class}; chop $package; $referenced = $referenced{$class}; chop $referenced; @x = split(/ /, $referenced); $referenced = join(", ", sort @x); $referenced =~ s,(\w+),\1,g; $implemented = $implemented{$class}; chop $implemented; @x = split(/ /, $implemented); $implemented = join(", ", sort @x); $implemented =~ s,(\w+),\1,g; $constructor = $constructor{$class}; chop $constructor; @x = split(/ /, $constructor); $constructor = join(", ", sort @x); $constructor =~ s,(\w+),\1,g; $subclassed = $subclassed{$class}; chop $subclassed; @x = split(/ /, $subclassed); $subclassed = join(", ", sort @x); $subclassed =~ s,(\w+),\1,g; $uses = $uses{$class}; $extends = $extends{$class}; chop $uses; @x = split(/ /, $uses); $uses = ""; foreach $x (@x) { $uses .= ", " if ($uses); $uses .= ""; $x = "$x" if ($extends =~ m/\b$x\b/); $uses .= "$x"; } print OUT "\n"; if ($package !~ / /) { print OUT "
$class ($package)\n"; } else { $package =~ s/ / & /g; $package =~ s,([A-Za-z_.]+),\1,g; print OUT "
$class (Ambiguous: $package)\n"; } print OUT "
\n"; print OUT "
Implemented by:
$implemented
\n" if ($implemented); print OUT "
Subclassed by:
$subclassed
\n" if ($subclassed); print OUT "
Constructed within:
$constructor
\n" if ($constructor); print OUT "
Referenced by:
$referenced
\n" if ($referenced); print OUT " Not referenced from anywhere\n" unless ($constructor || $referenced || $subclassed); print OUT "
Itself references or extends:
$uses
\n" if ($uses); print OUT "

\n"; } print OUT "

\n
Government Health Warning: This index is based on string matching, not a full parser. It will be inaccurate, therefore: if you have any methods or variables named the same as any of your classes, if you have classes with the same name in different packages, or if you have more than one class in the same source file. Bear in mind that some classes include test harnesses which may obscure the real meaning of the class when studying the cross references. A referenced class is marked in bold if anything within this source file (including things like inner classes) extends the referenced class.
Auto-generated by jxref on ".`date`."\n\n"; sub process { local($line,$noindent) = @_; my @match; # Remove trailing spaces, newline and ^M characters $line =~ s/\s*$//; # Process end and start of multi line comments if ($multiLineComment) { if ($line =~ m,\*/,) { $multiLineComment = 0; } return; } if ($line =~ m,/\*,) { $multiLineComment = 1 unless (m,/\*.*\*/,); return; } # remove leading space $line =~ s/^\s*//; # Special case - quoted strings including comment characters!! if (@match = $line =~ m,([^"]*)(".*//.*")(.*),) { process($match[2],1); # no indent processing return; } # Process single line comments if (@match = $line =~ m,^(.*)(//.*)$,) { if ($match[0]) { process($match[0], $noindent); } return; } # Process quoted strings if (@match = $line =~ m,([^"]*)("[^"]*")(.*),) { process($match[0], $noindent); process($match[2],1); # no indent processing return; } return unless ($line); # See what we reference @x = split(/\W/, $line); foreach $x (@x) { if ($x ne $class && $package{$x} && $uses{$class} !~ m/\b$x\b/) { $uses{$class} .= $x . " "; } } if ($line =~ m/\bextends\s+(\w+)/) { $x = $1; # See what extends us if ($package{$x} && $subclassed{$x} !~ m/\b$class\b/) { $subclassed{$x} .= $class . " "; } # See what we extend if ($x ne $class && $extends{$class} !~ m/\b$x\b/) { $extends{$class} .= $x . " "; } $line =~ s/\bextends\s+\w+//; } # See what implements us if ($line =~ m/implements\s+([A-Za-z_ ,]+)/) { @x = split(/\W/, $1); foreach $x (@x) { if ($package{$x} && $implemented{$x} !~ m/\b$class\b/) { $implemented{$x} .= $class . " "; } } $line =~ s/implements\s+[A-Za-z_ ,]+//; } # See what constructs us while ($line =~ m/\bnew\s+(\w+)/) { if ($package{$1} && $constructor{$1} !~ m/\b$class\b/) { $constructor{$1} .= $class . " "; } $line =~ s/\bnew\s+\w+//; } # See if there are any other types of references to us @x = split(/\W/, $line); foreach $x (@x) { #print "$x " if ($x =~ m/^[A-Z]/); if ($x ne $class && $package{$x} && $referenced{$x} !~ m/\b$class\b/) { $referenced{$x} .= $class . " "; } } }