#!/usr/bin/env perl # find-java # Michael Ernst # Find Java source code or class files (.java or .class) on CLASSPATH. # The output is in the order in which files are found on CLASSPATH. # The argument classes may be qualified with package names, delimited by # either "/" or ".". Trailing ".java" or ".class" are stripped. # Flags: # -i means check in all the packages imported by the specified file. # This gives the possible interpretations of a class name used that file. # Examples: # find-java IntList DataStructures.IntList daikon/Ppt.java # find-java -i Sample12.java IntList # Also see the JWhich program; this should perhaps be merged into it. use strict; use English; $WARNING = 1; if (scalar(@ARGV) == 0) { print "Usage: find-java [-i javafile] class ...\n"; exit; } my @dirs = split(/:/, $ENV{"CLASSPATH"}); # This was necessary when I joined against dirs, not classes. # push @dirs, ""; if ($ARGV[0] eq "-i") { shift @ARGV; $ifile = shift @ARGV; open (IFILE, $ifile) or die "Can't open $ifile"; my @pkgs = (); my $line; while (defined($line = )) { if ($line =~ /import[ \t]+([^ \t]+)\.[^. ;]+;/) { push @pkgs, $1; } } my @newargv = (@ARGV); for my $class (@ARGV) { for my $pkg (@pkgs) { push @newargv, "$pkg.$class"; } } @ARGV = @newargv; } # print "ARGV=", join(";", @ARGV), "\n"; my @classes = (""); # empty initial arg to make "join" work. for my $class (@ARGV) { $class =~ s/\.java$//; $class =~ s/\.class$//; $class =~ s/\./\//; push @classes, "/$class.java "; push @classes, "/$class.class "; } my $ls_arg = ""; for my $dir (@dirs) { $ls_arg .= join($dir, @classes); } # I can't depend on "ls" because it sorts its output. # # I used sort when I used to supply "ls" arguments in the wrong order. # # print "ls $ls_arg 2>&1 | grep -v 'No such file or directory' | grep -v 'Not a directory'\n"; # exec "ls $ls_arg 2>&1 | grep -v 'No such file or directory' | grep -v 'Not a directory'"; my @files = split(/ /, $ls_arg); for my $file (@files) { if (-e $file) { print $file, "\n"; } }