From af961ba2c8b2f69d0b962e086202de9fee694544 Mon Sep 17 00:00:00 2001 From: benfry Date: Sat, 17 Jul 2004 01:14:24 +0000 Subject: [PATCH] openstream fixes, changes to compiling of pde files --- app/PdeCode.java | 1 + app/PdeCompiler.java | 19 ++++ app/PdeMessageSiphon.java | 4 +- app/PdeSketch.java | 219 +++++++++++++++++++++++--------------- core/PApplet.java | 26 +++-- todo.txt | 11 +- 6 files changed, 182 insertions(+), 98 deletions(-) diff --git a/app/PdeCode.java b/app/PdeCode.java index fe8dff9a2..b407776a2 100644 --- a/app/PdeCode.java +++ b/app/PdeCode.java @@ -35,6 +35,7 @@ public class PdeCode { //PdeHistory history; // TODO add history information String preprocName; // name of .java file after preproc + int lineOffset; // where this code starts relative to the concat'd code public PdeCode(String name, File file, int flavor) { diff --git a/app/PdeCompiler.java b/app/PdeCompiler.java index 8b6dfbabb..d223a3764 100644 --- a/app/PdeCompiler.java +++ b/app/PdeCompiler.java @@ -183,6 +183,7 @@ public class PdeCompiler implements PdeMessageConsumer { // discerning the imagery, consider how cows regurgitate their food // to digest it, and the fact that they have five stomaches. // + //System.out.println("throwing up " + exception); if (exception != null) throw exception; // if the result isn't a known, expected value it means that something @@ -229,6 +230,8 @@ public class PdeCompiler implements PdeMessageConsumer { // iterate through the project files to see who's causing the trouble for (int i = 0; i < sketch.codeCount; i++) { + if (sketch.code[i].preprocName == null) continue; + partialTempPath = buildPathSubst + sketch.code[i].preprocName; partialStartIndex = s.indexOf(partialTempPath); if (partialStartIndex != -1) { @@ -252,6 +255,21 @@ public class PdeCompiler implements PdeMessageConsumer { int lineNumber = Integer.parseInt(s1.substring(0, colon)); //System.out.println("pde / line number: " + lineNumber); + if (fileIndex == 0) { // main class, figure out which tab + for (int i = 1; i < sketch.codeCount; i++) { + if (sketch.code[i].flavor == PdeSketch.PDE) { + if (sketch.code[i].lineOffset < lineNumber) { + fileIndex = i; + //System.out.println("i'm thinkin file " + i); + } + } + } + if (fileIndex != 0) { // if found another culprit + lineNumber -= sketch.code[fileIndex].lineOffset; + //System.out.println("i'm sayin line " + lineNumber); + } + } + //String s2 = s1.substring(colon + 2); int err = s1.indexOf("Error:"); if (err != -1) { @@ -270,6 +288,7 @@ public class PdeCompiler implements PdeMessageConsumer { String description = s1.substring(err + "Error:".length()); description = description.trim(); //System.out.println("description = " + description); + //System.out.println("creating exception " + exception); exception = new PdeException(description, fileIndex, lineNumber-1, -1); // NOTE!! major change here, this exception will be queued diff --git a/app/PdeMessageSiphon.java b/app/PdeMessageSiphon.java index 844a28f0b..ddb357780 100644 --- a/app/PdeMessageSiphon.java +++ b/app/PdeMessageSiphon.java @@ -39,7 +39,9 @@ class PdeMessageSiphon implements Runnable { this.consumer = consumer; thread = new Thread(this); - thread.setPriority(Thread.MIN_PRIORITY); + // don't set priority too low, otherwise exceptions won't + // bubble up in time (i.e. compile errors) + //thread.setPriority(Thread.MIN_PRIORITY); thread.start(); } diff --git a/app/PdeSketch.java b/app/PdeSketch.java index 6d9d4d5d2..852d029d0 100644 --- a/app/PdeSketch.java +++ b/app/PdeSketch.java @@ -973,14 +973,130 @@ public class PdeSketch { externalRuntime = true; } - // first run preproc on the 'main' file, using the sugg class name - // then for code 1..count - // if .java, write programs[i] to buildpath - // if .pde, run preproc to buildpath - // if no class def'd for the pde file, then complain + + // 1. concatenate all .pde files to the 'main' pde + // store line number for starting point of each code bit + + StringBuffer bigCode = new StringBuffer(code[0].program); + int bigCount = countLines(code[0].program); + + for (int i = 1; i < codeCount; i++) { + if (code[i].flavor == PDE) { + code[i].lineOffset = ++bigCount; + bigCode.append('\n'); + bigCode.append(code[i].program); + bigCount += countLines(code[i].program); + code[i].preprocName = null; // don't compile me + } + } + + + // 2. run preproc on that code using the sugg class name + // to create a single .java file and write to buildpath String primaryClassName = null; + PdePreprocessor preprocessor = new PdePreprocessor(); + try { + // if (i != 0) preproc will fail if a pde file is not + // java mode, since that's required + String className = + preprocessor.write(bigCode.toString(), buildPath, + suggestedClassName, importPackageList); + if (className == null) { + throw new PdeException("Could not find main class"); + // this situation might be perfectly fine, + // (i.e. if the file is empty) + //System.out.println("No class found in " + code[i].name); + //System.out.println("(any code in that file will be ignored)"); + //System.out.println(); + + } else { + code[0].preprocName = className + ".java"; + } + + // store this for the compiler and the runtime + primaryClassName = className; + //System.out.println("primary class " + primaryClassName); + + // check if the 'main' file is in java mode + if (PdePreprocessor.programType == PdePreprocessor.JAVA) { + externalRuntime = true; // we in advanced mode now, boy + } + + } catch (antlr.RecognitionException re) { + // this even returns a column + int errorFile = 0; + int errorLine = re.getLine() - 1; + for (int i = 1; i < codeCount; i++) { + if ((code[i].flavor == PDE) && + (code[i].lineOffset < errorLine)) { + errorFile = i; + } + } + errorLine -= code[errorFile].lineOffset; + + throw new PdeException(re.getMessage(), errorFile, + errorLine, re.getColumn()); + + } catch (antlr.TokenStreamRecognitionException tsre) { + // while this seems to store line and column internally, + // there doesn't seem to be a method to grab it.. + // so instead it's done using a regexp + PatternMatcher matcher = new Perl5Matcher(); + PatternCompiler compiler = new Perl5Compiler(); + // line 3:1: unexpected char: 0xA0 + String mess = "^line (\\d+):(\\d+):\\s"; + + Pattern pattern = null; + try { + pattern = compiler.compile(mess); + } catch (MalformedPatternException e) { + PdeBase.showWarning("Internal Problem", + "An internal error occurred while trying\n" + + "to compile the sketch. Please report\n" + + "this online at http://processing.org/bugs", e); + } + + PatternMatcherInput input = + new PatternMatcherInput(tsre.toString()); + if (matcher.contains(input, pattern)) { + MatchResult result = matcher.getMatch(); + + int errorLine = Integer.parseInt(result.group(1).toString()) - 1; + int errorColumn = Integer.parseInt(result.group(2).toString()); + int errorFile = 0; + for (int i = 1; i < codeCount; i++) { + if ((code[i].flavor == PDE) && + (code[i].lineOffset < errorLine)) { + errorFile = i; + } + } + errorLine -= code[errorFile].lineOffset; + + throw new PdeException(tsre.getMessage(), + errorFile, errorLine, errorColumn); + + } else { + // this is bad, defaults to the main class.. hrm. + throw new PdeException(tsre.toString(), 0, -1, -1); + } + + } catch (PdeException pe) { + // PdeExceptions are caught here and re-thrown, so that they don't + // get lost in the more general "Exception" handler below. + throw pe; + + } catch (Exception ex) { + // TODO better method for handling this? + System.err.println("Uncaught exception type:" + ex.getClass()); + ex.printStackTrace(); + throw new PdeException(ex.toString()); + } + + + // 3. then loop over the code[] and save each .java file + for (int i = 0; i < codeCount; i++) { if (code[i].flavor == JAVA) { // no pre-processing services necessary for java files @@ -996,88 +1112,6 @@ public class PdeSketch { " to the build folder"); } code[i].preprocName = filename; - - } else if (code[i].flavor == PDE) { - PdePreprocessor preprocessor = new PdePreprocessor(); - try { - // if (i != 0) preproc will fail if a pde file is not - // java mode, since that's required - //System.out.println("build path is " + buildPath); - String className = - preprocessor.write(code[i].program, buildPath, - (i == 0) ? suggestedClassName : null, - importPackageList); - if (className == null) { - // this situation might be perfectly fine, - // (i.e. if the file is empty) - System.out.println("No class found in " + code[i].name); - System.out.println("(any code in that file will be ignored)"); - System.out.println(); - - } else { - code[i].preprocName = className + ".java"; - } - - if (i == 0) { - // store this for the compiler and the runtime - primaryClassName = className; - //System.out.println("primary class " + primaryClassName); - - // check if the 'main' file is in java mode - if (PdePreprocessor.programType == PdePreprocessor.JAVA) { - externalRuntime = true; // we in advanced mode now, boy - } - } - - } catch (antlr.RecognitionException re) { - // this even returns a column - throw new PdeException(re.getMessage(), i, - re.getLine() - 1, re.getColumn()); - - } catch (antlr.TokenStreamRecognitionException tsre) { - // while this seems to store line and column internally, - // there doesn't seem to be a method to grab it.. - // so instead it's done using a regexp - PatternMatcher matcher = new Perl5Matcher(); - PatternCompiler compiler = new Perl5Compiler(); - // line 3:1: unexpected char: 0xA0 - String mess = "^line (\\d+):(\\d+):\\s"; - - Pattern pattern = null; - try { - pattern = compiler.compile(mess); - } catch (MalformedPatternException e) { - PdeBase.showWarning("Internal Problem", - "An internal error occurred while trying\n" + - "to compile the sketch. Please report\n" + - "this online at http://processing.org/bugs", e); - } - - PatternMatcherInput input = - new PatternMatcherInput(tsre.toString()); - if (matcher.contains(input, pattern)) { - MatchResult result = matcher.getMatch(); - - int line = Integer.parseInt(result.group(1).toString()); - int column = Integer.parseInt(result.group(2).toString()); - throw new PdeException(tsre.getMessage(), i, line-1, column); - - } else { - //throw new PdeException(tsre.toString()); - throw new PdeException(tsre.toString(), i, -1, -1); - } - - } catch (PdeException pe) { - // PdeExceptions are caught here and re-thrown, so that they don't - // get lost in the more general "Exception" handler below. - throw pe; - - } catch (Exception ex) { - // TODO better method for handling this? - System.err.println("Uncaught exception type:" + ex.getClass()); - ex.printStackTrace(); - throw new PdeException(ex.toString()); - } } } @@ -1090,6 +1124,17 @@ public class PdeSketch { return success ? primaryClassName : null; } + + protected int countLines(String what) { + char c[] = what.toCharArray(); + int count = 0; + for (int i = 0; i < c.length; i++) { + if (c[i] == '\n') count++; + } + return count; + } + + /** * Called by PdeEditor to handle someone having selected 'export'. * Pops up a dialog box for export options, and then calls the diff --git a/core/PApplet.java b/core/PApplet.java index aa32b6177..eed74f2ca 100644 --- a/core/PApplet.java +++ b/core/PApplet.java @@ -1666,23 +1666,23 @@ public class PApplet extends Applet public PFont loadFont(String filename) { try { String lower = filename.toLowerCase(); - InputStream input = null; + InputStream input = openStream(filename); - if (lower.endsWith(".vlw")) { - input = openStream(filename); + if (lower.endsWith(".vlw.gz")) { + input = new GZIPInputStream(input); - } else if (lower.endsWith(".vlw.gz")) { - input = new GZIPInputStream(openStream(filename)); - - } else { - throw new IOException("don't know what type of file that is"); + } else if (!lower.endsWith(".vlw")) { + throw new IOException("I don't know how to load a font named " + + filename); } return new PFont(input); - } catch (IOException e) { + //} catch (IOException e) { + } catch (Exception e) { System.err.println("Could not load font " + filename); System.err.println("Make sure that the font has been copied"); System.err.println("to the data folder of your sketch."); + System.err.println(); e.printStackTrace(); } return null; @@ -1716,6 +1716,14 @@ public class PApplet extends Applet if (stream != null) return stream; try { + try { + String location = folder + File.separator + "data"; + File file = new File(location, filename); + stream = new FileInputStream(file); + if (stream != null) return stream; + + } catch (Exception e) { } // ignored + try { stream = new FileInputStream(new File("data", filename)); if (stream != null) return stream; diff --git a/todo.txt b/todo.txt index 897277567..0d4183a90 100644 --- a/todo.txt +++ b/todo.txt @@ -18,11 +18,20 @@ X do the same for windows, with sketchbook as a subfolder o don't exit p5 if platform is unknown o "save as" needs to update the editorheader X couldn't replicate this +X MAJOR: make .pde files embed themselves into the main class -_ make additional .pde files embed themselves into the main class +_ openStream returning 'null' really horked up the letters applet +_ no System.out was coming through +_ System.err was getting cut off before finishing + +_ "paste" isn't setting the "modified" bit for PdeEditor +_ i.e. cut -> new file -> paste doesn't mark any as changed _ processing.net -> PClient, PServer +_ change font api to not use leading() as a way to reset the leading +_ don't change the size of a font when in screen space mode + _ readUntil() should do the proper thing if the data is not available _ i.e. either return null, or block until it's available? -> ret null