diff --git a/app/PdeCompiler.java b/app/PdeCompiler.java index b701eae47..17857db76 100644 --- a/app/PdeCompiler.java +++ b/app/PdeCompiler.java @@ -24,6 +24,8 @@ */ import java.io.*; +import java.util.*; +import java.util.zip.*; import javax.swing.*; @@ -130,9 +132,9 @@ public class PdeCompiler implements PdeMessageConsumer { Process process = Runtime.getRuntime().exec(command); new PdeMessageSiphon(process.getInputStream(), this); new PdeMessageSiphon(process.getErrorStream(), this); - - // wait for the process to finish. if we get interrupted before waitFor - // returns, continue waiting + + // wait for the process to finish. if interrupted + // before waitFor returns, continue waiting // boolean compiling = true; while (compiling) { @@ -298,6 +300,11 @@ public class PdeCompiler implements PdeMessageConsumer { abuffer.append(sep); abuffer.append(path); + if (!path.endsWith(File.separator)) { + path += File.separator; + } + //System.out.println("path is " + path); + String list[] = folder.list(); for (int i = 0; i < list.length; i++) { if (list[i].toLowerCase().endsWith(".jar") || @@ -310,6 +317,83 @@ public class PdeCompiler implements PdeMessageConsumer { } catch (IOException e) { e.printStackTrace(); // this would be odd } + //System.out.println("included path is " + abuffer.toString()); + magicImports(abuffer.toString()); return abuffer.toString(); } + + + static public String[] magicImports(String path) { + String imports[] = new String[100]; + int importCount = 0; + + String pieces[] = + BApplet.splitStrings(path, File.pathSeparatorChar); + + for (int i = 0; i < pieces.length; i++) { + //System.out.println("checking piece " + pieces[i]); + if (pieces[i].length() == 0) continue; + + if (pieces[i].toLowerCase().endsWith(".jar") || + pieces[i].toLowerCase().endsWith(".zip")) { + try { + ZipFile file = new ZipFile(pieces[i]); + Enumeration entries = file.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = (ZipEntry) entries.nextElement(); + if (entry.isDirectory()) { + String name = entry.getName(); + if (name.equals("META-INF/")) continue; + name = name.substring(0, name.length() - 1); + name = name.replace('/', '.'); + + if (importCount == imports.length) { + String temp[] = new String[importCount << 1]; + System.arraycopy(imports, 0, temp, 0, importCount); + imports = temp; + } + imports[importCount++] = name; + //System.out.println("import " + name + ".*;"); + } + //System.out.print(entry.isDirectory() ? "D " : "c "); + //System.out.println(entry.getName()); + } + } catch (IOException e) { + System.err.println("Error in file " + pieces[i]); + } + } else { + File dir = new File(pieces[i]); + if (dir.exists()) { + importCount = magicImportsRecursive(dir, null, + imports, importCount); + } + } + } + //return null; + String output[] = new String[importCount]; + System.arraycopy(imports, 0, output, 0, importCount); + return output; + } + + + static public int magicImportsRecursive(File dir, String sofar, + String imports[], + int importCount) { + String files[] = dir.list(); + for (int i = 0; i < files.length; i++) { + if (files[i].equals(".") || files[i].equals("..")) continue; + + File sub = new File(dir, files[i]); + if (sub.isDirectory()) { + String nowfar = (sofar == null) ? + files[i] : (sofar + "." + files[i]); + //System.out.println(nowfar); + imports[importCount++] = nowfar; + + importCount = magicImportsRecursive(sub, nowfar, + imports, importCount); + } + } + return importCount; + } } diff --git a/app/PdeEditor.java b/app/PdeEditor.java index 04fc34217..26310c034 100644 --- a/app/PdeEditor.java +++ b/app/PdeEditor.java @@ -100,6 +100,7 @@ public class PdeEditor extends JPanel { PdeRuntime runtime; boolean externalRuntime; + String externalPaths; File externalCode; static final int GRID_SIZE = 33; @@ -548,66 +549,91 @@ public class PdeEditor extends JPanel { // true if this should extend BApplet instead of BAppletGL boolean extendsNormal = base.normalItem.getState(); - PdePreprocessor preprocessor = null; - if (PdeBase.getBoolean("preprocessor.antlr", true)) { - preprocessor = new PdePreprocessor(program, buildPath); - try { - className = - preprocessor.writeJava(className, extendsNormal, false); + externalRuntime = false; + externalPaths = null; - } catch (antlr.RecognitionException ae) { - // this even returns a column - throw new PdeException(ae.getMessage(), - ae.getLine() - 1, ae.getColumn()); + externalCode = new File(sketchDir, "code"); + if (externalCode.exists()) { + externalRuntime = true; + externalPaths = PdeCompiler.includeFolder(externalCode); - } catch (PdeException pe) { - throw pe; - } catch (Exception ex) { - System.err.println("Uncaught exception type:" + ex.getClass()); - ex.printStackTrace(); - throw new PdeException(ex.toString()); - } - } else { // use the old oro processor (yech) - preprocessor = new PdePreprocessorOro(program, buildPath); + } else { + externalCode = null; + } + + // add the includes from the external code dir + // + String imports[] = null; + if (externalCode != null) { + //String includePaths = PdeCompiler.includeFolder(externalCode); + //imports = PdeCompiler.magicImports(includePaths); + imports = PdeCompiler.magicImports(externalPaths); + /* + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < imports.length; i++) { + buffer.append("import "); + buffer.append(imports[i]); + buffer.append(".*; "); + } + */ + //buffer.append(program); + //program = buffer.toString(); + } + //System.out.println("imports is " + imports); + + PdePreprocessor preprocessor = null; + if (PdeBase.getBoolean("preprocessor.antlr", true)) { + preprocessor = new PdePreprocessor(program, buildPath); + try { className = - preprocessor.writeJava(className, extendsNormal, false); + preprocessor.writeJava(className, imports, + extendsNormal, false); + + } catch (antlr.RecognitionException ae) { + // this even returns a column + throw new PdeException(ae.getMessage(), + ae.getLine() - 1, ae.getColumn()); + + } catch (PdeException pe) { + throw pe; + } catch (Exception ex) { + System.err.println("Uncaught exception type:" + ex.getClass()); + ex.printStackTrace(); + throw new PdeException(ex.toString()); } + } else { // use the old oro processor (yech) + preprocessor = new PdePreprocessorOro(program, buildPath); + className = + preprocessor.writeJava(className, imports, + extendsNormal, false); + } - externalRuntime = false; - if (PdePreprocessor.programType == PdePreprocessor.ADVANCED) { - externalRuntime = true; // we in advanced mode now, boy - } + if (PdePreprocessor.programType == PdePreprocessor.ADVANCED) { + externalRuntime = true; // we in advanced mode now, boy + } - externalCode = new File(sketchDir, "code"); - if (externalCode.exists()) { - externalRuntime = true; - } else { - externalCode = null; - } + // compile the program + // + PdeCompiler compiler = + new PdeCompiler(buildPath, className, externalCode, this); + // macos9 now officially broken.. see PdeCompilerJavac + //PdeCompiler compiler = + // ((PdeBase.platform == PdeBase.MACOS9) ? + // new PdeCompilerJavac(buildPath, className, this) : + // new PdeCompiler(buildPath, className, this)); - // compile the program - // - File includeFolder = null; - PdeCompiler compiler = - new PdeCompiler(buildPath, className, includeFolder, this); - // macos9 now officially broken.. see PdeCompilerJavac - //PdeCompiler compiler = - // ((PdeBase.platform == PdeBase.MACOS9) ? - // new PdeCompilerJavac(buildPath, className, this) : - // new PdeCompiler(buildPath, className, this)); + // run the compiler, and funnel errors to the leechErr + // which is a wrapped around + // (this will catch and parse errors during compilation + // the messageStream will call message() for 'compiler') + messageStream = new PdeMessageStream(compiler); + //PrintStream leechErr = new PrintStream(messageStream); + //boolean result = compiler.compileJava(leechErr); + //return compiler.compileJava(leechErr); + boolean success = + compiler.compileJava(new PrintStream(messageStream)); - // run the compiler, and funnel errors to the leechErr - // which is a wrapped around - // (this will catch and parse errors during compilation - // the messageStream will call message() for 'compiler') - messageStream = new PdeMessageStream(compiler); - //PrintStream leechErr = new PrintStream(messageStream); - //boolean result = compiler.compileJava(leechErr); - //return compiler.compileJava(leechErr); - boolean success = - compiler.compileJava(new PrintStream(messageStream)); - - return success ? className : null; + return success ? className : null; } @@ -689,16 +715,26 @@ public class PdeEditor extends JPanel { int numero2 = (int) (Math.random() * 10000); String className = TEMP_CLASS + "_" + numero1 + "_" + numero2; - // handle building the code className = build(program, className, tempBuildPath, false); - // if the compilation worked, run the applet if (className != null) { + if (externalPaths == null) { + externalPaths = + PdeCompiler.calcClassPath(null) + File.pathSeparator + + tempBuildPath; + } else { + externalPaths = + tempBuildPath + File.pathSeparator + + PdeCompiler.calcClassPath(null) + File.pathSeparator + + externalPaths; + } + // create a runtime object - runtime = new PdeRuntime(this, className); + runtime = new PdeRuntime(this, className, + externalRuntime, externalPaths); // if programType is ADVANCED // or the code/ folder is not empty -> or just exists (simpler) diff --git a/app/PdePreprocessor.java b/app/PdePreprocessor.java index 6e936ad5c..2d485ee14 100644 --- a/app/PdePreprocessor.java +++ b/app/PdePreprocessor.java @@ -92,7 +92,8 @@ public class PdePreprocessor { * * @return the classname of the exported Java */ - public String writeJava(String name, boolean extendsNormal, + public String writeJava(String name, String imports[], + boolean extendsNormal, boolean exporting) throws java.lang.Exception { // create a lexer with the stream reader, and tell it to handle @@ -156,7 +157,7 @@ public class PdePreprocessor { PrintStream stream = new PrintStream( new FileOutputStream(buildPath + File.separator + name + ".java")); - writeHeader(stream, extendsNormal, exporting, name); + writeHeader(stream, imports, extendsNormal, exporting, name); emitter.setOut(stream); emitter.print(rootNode); @@ -192,12 +193,18 @@ public class PdePreprocessor { * @param exporting Is this being exported from PDE? * @param name Name of the class being created. */ - void writeHeader(PrintStream out, boolean extendsNormal, boolean exporting, + void writeHeader(PrintStream out, String imports[], + boolean extendsNormal, boolean exporting, String name) { - if (programType < ADVANCED) { + if (imports != null) { + //System.out.println("imports not null"); + for (int i = 0; i < imports.length; i++) { + out.print("import " + imports[i] + ".*; "); + } + } - String extendsWhat = extendsNormal ? "BApplet" : "BAppletGL"; + if (programType < ADVANCED) { // spew out a bunch of java imports // @@ -211,6 +218,8 @@ public class PdePreprocessor { } } + String extendsWhat = extendsNormal ? "BApplet" : "BAppletGL"; + out.print("public class " + name + " extends " + extendsWhat + " {"); diff --git a/app/PdeRuntime.java b/app/PdeRuntime.java index 6025dac6c..5e209989d 100644 --- a/app/PdeRuntime.java +++ b/app/PdeRuntime.java @@ -49,11 +49,20 @@ public class PdeRuntime implements PdeMessageConsumer { boolean newMessage; int messageLineCount; - public PdeRuntime(PdeEditor editor, String className) { + boolean externalRuntime; + String externalPaths; + + + public PdeRuntime(PdeEditor editor, String className, + boolean externalRuntime, String externalPaths) { this.editor = editor; this.className = className; + + this.externalRuntime = externalRuntime; + this.externalPaths = externalPaths; } + public void start(Point windowLocation, PrintStream leechErr) throws PdeException { @@ -66,13 +75,23 @@ public class PdeRuntime implements PdeMessageConsumer { int x1 = parentLoc.x - 20; int y1 = parentLoc.y; + //externalPaths = + //externalPaths + PdeCompiler.calcClassPath(); try { - if (PdeBase.getBoolean("play.external", false)) { - String cmd = PdeBase.get("play.external.command"); - // "cmd /c " + not helpful? - process = Runtime.getRuntime().exec(cmd + " " + className + - " " + className + - " " + x1 + " " + y1); + //if (PdeBase.getBoolean("play.external", false)) { + //System.out.println(externalPaths); + + if (externalRuntime) { + //System.out.println("going external"); + String command[] = new String[] { + "java", + "-cp", + externalPaths, + "BApplet", + className + }; + + process = Runtime.getRuntime().exec(command); new PdeMessageSiphon(process.getInputStream(), this); new PdeMessageSiphon(process.getErrorStream(), this);