From 8e9f7a630af6f79ebe6fa20ee97e51cf4ef0f030 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 28 Jan 2020 15:07:37 +0100 Subject: [PATCH 1/3] Fix exception on compiler errors with column numbers Error messages are detected and parsed using a regex. Part of this regex matches the optional column number. The code that handled this assumed that a missing column would result in less elements in the matches array, but a regex always results in one element per set of parenthesis in the regex, which will be null if no capture was made for that element. In practice, this meant that if no column was present in the error message, a NullPointerException would be raised. Furthermore, gcc 9 seems to have started outputting omitting column numbers (instead of printing 0) for some errors (such as unterminated #ifdef), which exposed this problem. This commit fixes this by simply using the fixed match numbers to take apart the regex match, and by checking for a null column number (all other captures are non-optional, so no need to check there). --- arduino-core/src/cc/arduino/Compiler.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/arduino-core/src/cc/arduino/Compiler.java b/arduino-core/src/cc/arduino/Compiler.java index d1aa1f2bdce..1663bbd9f32 100644 --- a/arduino-core/src/cc/arduino/Compiler.java +++ b/arduino-core/src/cc/arduino/Compiler.java @@ -516,16 +516,13 @@ public void message(String s) { if (pieces != null) { String msg = ""; - int errorIdx = pieces.length - 1; - String error = pieces[errorIdx]; String filename = pieces[1]; int line = PApplet.parseInt(pieces[2]); - int col; - if (errorIdx > 3) { + int col = -1; + if (pieces[3] != null) { col = PApplet.parseInt(pieces[3].substring(1)); - } else { - col = -1; } + String error = pieces[5]; if (error.trim().equals("SPI.h: No such file or directory")) { error = tr("Please import the SPI library from the Sketch > Import Library menu."); From e387c23b608434c10fd46a758958186dcc3c4c6a Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 28 Jan 2020 15:16:41 +0100 Subject: [PATCH 2/3] Slightly simplify error message rebuilding This removes some duplicate code for with and without column number by building the column number string separately first. --- arduino-core/src/cc/arduino/Compiler.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arduino-core/src/cc/arduino/Compiler.java b/arduino-core/src/cc/arduino/Compiler.java index 1663bbd9f32..608bf23b01a 100644 --- a/arduino-core/src/cc/arduino/Compiler.java +++ b/arduino-core/src/cc/arduino/Compiler.java @@ -582,11 +582,8 @@ public void message(String s) { String fileName = ex.getCodeFile().getPrettyName(); int lineNum = ex.getCodeLine() + 1; int colNum = ex.getCodeColumn(); - if (colNum != -1) { - s = fileName + ":" + lineNum + ":" + colNum + ": error: " + error + msg; - } else { - s = fileName + ":" + lineNum + ": error: " + error + msg; - } + String column = (colNum != -1) ? (":" + colNum) : ""; + s = fileName + ":" + lineNum + column + ": error: " + error + msg; } if (ex != null) { From 3d4b026b506afd56d516144cf3c558d956c75758 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 28 Jan 2020 15:23:22 +0100 Subject: [PATCH 3/3] Preserve "fatal" in compiler errors When transforming compiler errors (to make filenames more friendly), it would match "fatal error" or "error" but then always reconstruct as "error", modifying the compiler error in a way that is not intended. This commit fixes that, as well as the previous hardcoding of the "error: " prefix when rebuilding the error message, by capturing this entire prefix and simply reproducing it in the resulting error message. --- arduino-core/src/cc/arduino/Compiler.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arduino-core/src/cc/arduino/Compiler.java b/arduino-core/src/cc/arduino/Compiler.java index 608bf23b01a..c2c5b0ff624 100644 --- a/arduino-core/src/cc/arduino/Compiler.java +++ b/arduino-core/src/cc/arduino/Compiler.java @@ -134,7 +134,7 @@ enum BuilderAction { } } - private static final Pattern ERROR_FORMAT = Pattern.compile("(.+\\.\\w+):(\\d+)(:\\d+)*:\\s*(fatal)?\\s*error:\\s*(.*)\\s*", Pattern.MULTILINE | Pattern.DOTALL); + private static final Pattern ERROR_FORMAT = Pattern.compile("(.+\\.\\w+):(\\d+)(:\\d+)*:\\s*((fatal)?\\s*error:\\s*)(.*)\\s*", Pattern.MULTILINE | Pattern.DOTALL); private final File pathToSketch; private final Sketch sketch; @@ -522,7 +522,8 @@ public void message(String s) { if (pieces[3] != null) { col = PApplet.parseInt(pieces[3].substring(1)); } - String error = pieces[5]; + String errorPrefix = pieces[4]; + String error = pieces[6]; if (error.trim().equals("SPI.h: No such file or directory")) { error = tr("Please import the SPI library from the Sketch > Import Library menu."); @@ -583,7 +584,7 @@ public void message(String s) { int lineNum = ex.getCodeLine() + 1; int colNum = ex.getCodeColumn(); String column = (colNum != -1) ? (":" + colNum) : ""; - s = fileName + ":" + lineNum + column + ": error: " + error + msg; + s = fileName + ":" + lineNum + column + ": " + errorPrefix + error + msg; } if (ex != null) {