diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 1d540c374..5f8a09b5d 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -1373,6 +1373,9 @@ public class Sketch { for (SketchCode sc : code) { if (sc.isExtension("ino") || sc.isExtension("pde")) { sc.setPreprocOffset(bigCount); + // These #line directives help the compiler report errors with + // correct the filename and line number (issue 281 & 907) + bigCode.append("#line 1 \"" + sc.getFileName() + "\"\n"); bigCode.append(sc.getProgram()); bigCode.append('\n'); bigCount += sc.getLineCount(); @@ -1542,54 +1545,16 @@ public class Sketch { public RunnerException placeException(String message, String dotJavaFilename, int dotJavaLine) { - int codeIndex = 0; //-1; - int codeLine = -1; - -// System.out.println("placing " + dotJavaFilename + " " + dotJavaLine); -// System.out.println("code count is " + getCodeCount()); - - // first check to see if it's a .java file - for (int i = 0; i < getCodeCount(); i++) { - SketchCode code = getCode(i); - if (!code.isExtension(getDefaultExtension())) { - if (dotJavaFilename.equals(code.getFileName())) { - codeIndex = i; - codeLine = dotJavaLine; - return new RunnerException(message, codeIndex, codeLine); - } - } - } - - // If not the preprocessed file at this point, then need to get out - if (!dotJavaFilename.equals(name + ".cpp")) { - return null; - } - - // if it's not a .java file, codeIndex will still be 0 - // this section searches through the list of .pde files - codeIndex = 0; - for (int i = 0; i < getCodeCount(); i++) { - SketchCode code = getCode(i); - - if (code.isExtension(getDefaultExtension())) { -// System.out.println("preproc offset is " + code.getPreprocOffset()); -// System.out.println("looking for line " + dotJavaLine); - if (code.getPreprocOffset() <= dotJavaLine) { - codeIndex = i; -// System.out.println("i'm thinkin file " + i); - codeLine = dotJavaLine - code.getPreprocOffset(); - } - } - } - // could not find a proper line number, so deal with this differently. - // but if it was in fact the .java file we're looking for, though, - // send the error message through. - // this is necessary because 'import' statements will be at a line - // that has a lower number than the preproc offset, for instance. -// if (codeLine == -1 && !dotJavaFilename.equals(name + ".java")) { -// return null; -// } - return new RunnerException(message, codeIndex, codeLine); + // Placing errors is simple, because we inserted #line directives + // into the preprocessed source. The compiler gives us correct + // the file name and line number. :-) + for (int codeIndex = 0; codeIndex < getCodeCount(); codeIndex++) { + SketchCode code = getCode(codeIndex); + if (dotJavaFilename.equals(code.getFileName())) { + return new RunnerException(message, codeIndex, dotJavaLine); + } + } + return null; } diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 20fa361b4..80122ec6a 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -46,6 +46,7 @@ public class Compiler implements MessageConsumer { String buildPath; String primaryClassName; boolean verbose; + boolean sketchIsCompiled; RunnerException exception; @@ -68,6 +69,7 @@ public class Compiler implements MessageConsumer { this.buildPath = buildPath; this.primaryClassName = primaryClassName; this.verbose = verbose; + this.sketchIsCompiled = false; // the pms object isn't used for anything but storage MessageStream pms = new MessageStream(this); @@ -130,6 +132,7 @@ public class Compiler implements MessageConsumer { findFilesInPath(buildPath, "c", false), findFilesInPath(buildPath, "cpp", false), boardPreferences)); + sketchIsCompiled = true; // 2. compile the libraries, outputting .o files to: // @@ -513,14 +516,20 @@ public class Compiler implements MessageConsumer { //msg = _("\nThe 'Keyboard' class is only supported on the Arduino Leonardo.\n\n"); } - RunnerException e = sketch.placeException(error, pieces[1], PApplet.parseInt(pieces[2]) - 1); + RunnerException e = null; + if (!sketchIsCompiled) { + // Place errors when compiling the sketch, but never while compiling libraries + // or the core. The user's sketch might contain the same filename! + e = sketch.placeException(error, pieces[1], PApplet.parseInt(pieces[2]) - 1); + } // replace full file path with the name of the sketch tab (unless we're // in verbose mode, in which case don't modify the compiler output) if (e != null && !verbose) { SketchCode code = sketch.getCode(e.getCodeIndex()); - String fileName = code.isExtension(sketch.getDefaultExtension()) ? code.getPrettyName() : code.getFileName(); - s = fileName + ":" + e.getCodeLine() + ": error: " + pieces[3] + msg; + String fileName = (code.isExtension("ino") || code.isExtension("pde")) ? code.getPrettyName() : code.getFileName(); + int lineNum = e.getCodeLine() + 1; + s = fileName + ":" + lineNum + ": error: " + pieces[3] + msg; } if (exception == null && e != null) { diff --git a/app/src/processing/app/preproc/PdePreprocessor.java b/app/src/processing/app/preproc/PdePreprocessor.java index 2b4f03e85..4f848c922 100644 --- a/app/src/processing/app/preproc/PdePreprocessor.java +++ b/app/src/processing/app/preproc/PdePreprocessor.java @@ -205,7 +205,7 @@ public class PdePreprocessor { for (int i = 0; i < prototypes.size(); i++) { out.print(prototypes.get(i) + "\n"); } - + out.println("#line 1"); out.print(program.substring(prototypeInsertionPoint)); }