# This perl script determines class dependencies for Java projects.  It is 
# very crude.
#
#
# This script is meant to be run from a Java project directory in which there
# is a makefile which is run with the simple command 
#
#	make  
#
# The makefile should specify only the same project directory as 
# the CLASSPATH.  Eg.,  (bmj.exe is the name of Borland's Java compiler.)
#
#	bmj.exe -classpath d:\myprojects { -p MyPackage1 MyPackage2 }
#
# When the compiler fails because it can't find the JDK or JBCL or JFC
# classes which your project imports, the perl script will parse the error
# messages and execute the system command to copy the missing class files.  
# For example, if the compiler generates the following error,
#
#
# error #910: initialization error: borland.compiler.symtab.LoadError; 
#	neither class nor source found for java.lang.Object;
#
# 
# This perl script will execute the command,
#
#
# xcopy e:\javasoft\jre124\lib\java\lang\Object.class 
#	d:\gcross\myprograms\
#
#
# This copies the missing .class file from the directory where the 
# JRE's rt.jar has been uncompressed.  This allows us to copy only 
# exactly those .class files from the JDK which we need for our application
# so we can minimize the size of our deployable archive.  This script 
# can determine class dependencies for JBCL, or any other Java packages.
#
# Usage:
#
# To run this perl script simply type,
#
#	perl thisfile.pl <projdir> <jredir>
#
# from the directory where 'makefile' for your project is located (the <> 
# means you have to put something relative to your situation here). 
# <projdir> is the full path to your Java project directory, for example,
# 'd:\myprojects'. <jredir> is the full path to the directory where the 
# runtime archives (eg. rt.jar, jbcl2.0-rt.zip, jgl3.1.0.zip, swing.jar) 
# has been uncompressed.
#
# As an example, I have my project in the directory d:\myprojects.  
# I have uncompressed the JRE 1.2 Beta 4's rt.jar file into the directory
# e:\javasoft\jre\lib. Therefore I call the perl script with,
#
# 	perl thisfile.pl d:\myprojects e:\javasoft\jre\lib
#
# This script generates a log files with any errors it might have 
# encountered, including those from running make.exe. 
#
# George Cross, Borland JBuilder Tech Support, October 1998
# Written with Perl 5.004_02
#

use File::Basename;

$projdir = $ARGV[0]."\\";
$jredir = $ARGV[1]."\\";
$javacerrorlog = ".bmjerr.log";
$errorlog = "error.log";
%filescopied = ();

$haveerrors = 1;		# flag indicating the compile still failed

open(LOGFILE,">>".$errorlog);

# 
# While the compiler still gives errors about missing .class files
# keep copying over the ones it is complaining about
#

while ($haveerrors) {

	$haveerrors = 0;
	$cmd = "make > ".$javacerrorlog."\n";
	ExecAndCheck($cmd);

	#
	# If $_ matches this pattern, find the missing class and copy it.
	#

	open (INFILE, "<".$javacerrorlog);
	foreach (<INFILE>){
		if (/error .* neither class nor source found for (.*)(;|\s)/s
			&& 
			! exists $filescopied{$1}){

			$filescopied{$1}=0;
			$haveerrors = 1;
			$class = $1;
			$class =~ tr/./\\/;
			$class = $class.".class";

			$todirname = $projdir.dirname($class)."\\";
			$cmd = "xcopy ".$jredir.$class." ".$todirname."\n";
			ExecAndCheck($cmd);
		}
		elsif ((/error .* class (.*) not found in/s 
			|| 
			/error .* variable (.*) not found in/s)
			&&
			!exists $filescopied{$1}){
			
			$filescopied{$1}=0;
			$haveerrors = 1;
			$class = $1.".*";
			$cmd = "xcopy ".$jredir.$class." ".$projdir." /s\n";
			ExecAndCheck($cmd);
		}
	}
	close(INFILE);
}

close(LOGFILE);

open (DEPSFILE, ">dependency.list");
foreach (keys %filescopied){ print DEPSFILE $_."\n"};
close DEPSFILE;




sub ExecAndCheck()
{
#	print @_[0]."\n";
	if (system @_[0]){
		print LOGFILE @_[0]."\n";
	}
}
