void applyDirectives() { findRemoveDirectives(true); StringBuffer buffer = new StringBuffer(); String head = "", toe = "; \n"; if (crispBox.isSelected()) buffer.append(head + "crisp=true" + toe); if (!fontField.getText().trim().equals("")) buffer.append(head + "font=\"" + fontField.getText().trim() + "\"" + toe); if (globalKeyEventsBox.isSelected()) buffer.append(head + "globalKeyEvents=true" + toe); if (pauseOnBlurBox.isSelected()) buffer.append(head + "pauseOnBlur=true" + toe); if (!preloadField.getText().trim().equals("")) buffer.append(head + "preload=\"" + preloadField.getText().trim() + "\"" + toe); /*if ( transparentBox.isSelected() ) buffer.append( head + "transparent=true" + toe );*/ Sketch sketch = editor.getSketch(); SketchCode code = sketch.getCode(0); // first tab if (buffer.length() > 0) { code.setProgram("/* @pjs " + buffer.toString() + " */\n\n" + code.getProgram()); if (sketch.getCurrentCode() == code) // update textarea if on first tab { editor.setText(sketch.getCurrentCode().getProgram()); editor.setSelection(0, 0); } sketch.setModified(false); sketch.setModified(true); } }
// TODO Why is this necessary? Why isn't Sketch.isModified() used? private static boolean isSketchModified(Sketch sketch) { for (SketchCode sc : sketch.getCode()) { if (sc.isModified()) { return true; } } return false; }
void findRemoveDirectives(boolean clean) { // if ( clean ) editor.startCompoundEdit(); Sketch sketch = editor.getSketch(); for (int i = 0; i < sketch.getCodeCount(); i++) { SketchCode code = sketch.getCode(i); String program = code.getProgram(); StringBuffer buffer = new StringBuffer(); Matcher m = pjsPattern.matcher(program); while (m.find()) { String mm = m.group(); // TODO this urgently needs tests .. /* remove framing */ mm = mm.replaceAll("^\\/\\*\\s*@pjs", "").replaceAll("\\s*\\*\\/\\s*$", ""); /* fix multiline nice formatting */ mm = mm.replaceAll("[\\s]*([^;\\s\\n\\r]+)[\\s]*,[\\s]*[\\n\\r]+", "$1,"); /* fix multiline version without semicolons */ mm = mm.replaceAll("[\\s]*([^;\\s\\n\\r]+)[\\s]*[\\n\\r]+", "$1;"); mm = mm.replaceAll("\n", " ").replaceAll("\r", " "); // System.out.println(mm); if (clean) { m.appendReplacement(buffer, ""); } else { String[] directives = mm.split(";"); for (String d : directives) { // System.out.println(d); parseDirective(d); } } } if (clean) { m.appendTail(buffer); // TODO: not working! code.setProgram(buffer.toString()); code.setModified(true); } } if (clean) { // editor.stopCompoundEdit(); editor.setText(sketch.getCurrentCode().getProgram()); sketch.setModified(false); sketch.setModified(true); } }
/** * Part of the MessageConsumer interface, this is called * whenever a piece (usually a line) of error message is spewed * out from the compiler. The errors are parsed for their contents * and line number, which is then reported back to Editor. */ public void message(String s) { int i; System.out.println("**************[ROBOTIS]***********************************"); // remove the build path so people only see the filename // can't use replaceAll() because the path may have characters in it which // have meaning in a regular expression. if (!verbose) { while ((i = s.indexOf(buildPath + File.separator)) != -1) { s = s.substring(0, i) + s.substring(i + (buildPath + File.separator).length()); } } // look for error line, which contains file name, line number, // and at least the first line of the error message String errorFormat = "([\\w\\d_]+.\\w+):(\\d+):\\s*error:\\s*(.*)\\s*"; String[] pieces = PApplet.match(s, errorFormat); // if (pieces != null && exception == null) { // exception = sketch.placeException(pieces[3], pieces[1], PApplet.parseInt(pieces[2]) - 1); // if (exception != null) exception.hideStackTrace(); // } if (pieces != null) { String error = pieces[3], msg = ""; if (pieces[3].trim().equals("SPI.h: No such file or directory")) { error = _("Please import the SPI library from the Sketch > Import Library menu."); msg = _("\nAs of Arduino 0019, the Ethernet library depends on the SPI library." + "\nYou appear to be using it or another library that depends on the SPI library.\n\n"); } if (pieces[3].trim().equals("'BYTE' was not declared in this scope")) { error = _("The 'BYTE' keyword is no longer supported."); msg = _("\nAs of Arduino 1.0, the 'BYTE' keyword is no longer supported." + "\nPlease use Serial.write() instead.\n\n"); } if (pieces[3].trim().equals("no matching function for call to 'Server::Server(int)'")) { error = _("The Server class has been renamed EthernetServer."); msg = _("\nAs of Arduino 1.0, the Server class in the Ethernet library " + "has been renamed to EthernetServer.\n\n"); } if (pieces[3].trim().equals("no matching function for call to 'Client::Client(byte [4], int)'")) { error = _("The Client class has been renamed EthernetClient."); msg = _("\nAs of Arduino 1.0, the Client class in the Ethernet library " + "has been renamed to EthernetClient.\n\n"); } if (pieces[3].trim().equals("'Udp' was not declared in this scope")) { error = _("The Udp class has been renamed EthernetUdp."); msg = _("\nAs of Arduino 1.0, the Udp class in the Ethernet library " + "has been renamed to EthernetUdp.\n\n"); } if (pieces[3].trim().equals("'class TwoWire' has no member named 'send'")) { error = _("Wire.send() has been renamed Wire.write()."); msg = _("\nAs of Arduino 1.0, the Wire.send() function was renamed " + "to Wire.write() for consistency with other libraries.\n\n"); } if (pieces[3].trim().equals("'class TwoWire' has no member named 'receive'")) { error = _("Wire.receive() has been renamed Wire.read()."); msg = _("\nAs of Arduino 1.0, the Wire.receive() function was renamed " + "to Wire.read() for consistency with other libraries.\n\n"); } if (pieces[3].trim().equals("'Mouse' was not declared in this scope")) { error = _("'Mouse' only supported on the Arduino Leonardo"); //msg = _("\nThe 'Mouse' class is only supported on the Arduino Leonardo.\n\n"); } if (pieces[3].trim().equals("'Keyboard' was not declared in this scope")) { error = _("'Keyboard' only supported on the Arduino Leonardo"); //msg = _("\nThe 'Keyboard' class is only supported on the Arduino Leonardo.\n\n"); } 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("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) { exception = e; exception.hideStackTrace(); } } System.err.print(s); }
/** * Part of the MessageConsumer interface, this is called whenever a piece (usually a line) of * error message is spewed out from the compiler. The errors are parsed for their contents and * line number, which is then reported back to Editor. */ public void message(String s) { // This receives messages as full lines, so a newline needs // to be added as they're printed to the console. // ignore cautions if (s.indexOf("warning") != -1) { return; } // ignore this line; the real error is on the next one if (s.indexOf("In file included from") != -1) { return; } // jikes always uses a forward slash character as its separator, // so replace any platform-specific separator characters before // attemping to compare // // String buildPathSubst = buildPath.replace(File.separatorChar, '/') + "/"; String buildPathSubst = buildPath.replace(File.separatorChar, File.separatorChar) + File.separatorChar; String partialTempPath = null; int partialStartIndex = -1; // s.indexOf(partialTempPath); int fileIndex = -1; // use this to build a better exception // check the main sketch file first. partialTempPath = buildPathSubst + primaryClassName; partialStartIndex = s.indexOf(partialTempPath); if (partialStartIndex != -1) { fileIndex = 0; } else { // wasn't there, check the other (non-pde) files in the sketch. // iterate through the project files to see who's causing the trouble for (int i = 0; i < sketch.getCodeCount(); i++) { if (sketch.getCode(i).isExtension("pde")) { continue; } partialTempPath = buildPathSubst + sketch.getCode(i).getFileName(); // System.out.println(partialTempPath); partialStartIndex = s.indexOf(partialTempPath); if (partialStartIndex != -1) { fileIndex = i; // System.out.println("fileIndex is " + fileIndex); break; } } // + className + ".java"; } // if the partial temp path appears in the error message... // // int partialStartIndex = s.indexOf(partialTempPath); if (partialStartIndex != -1) { // skip past the path and parse the int after the first colon // String s1 = s.substring(partialStartIndex + partialTempPath.length() + 1); // System.out.println(s1); int colon = s1.indexOf(':'); if (s1.indexOf("In function") != -1 || colon == -1) { System.err.print(s1); // firstErrorFound = true; return; } int lineNumber; try { lineNumber = Integer.parseInt(s1.substring(0, colon)); } catch (NumberFormatException e) { System.err.print(s1); return; } // System.out.println("pde / line number: " + lineNumber); if (fileIndex == 0) { // main class, figure out which tab for (int i = 1; i < sketch.getCodeCount(); i++) { if (sketch.getCode(i).isExtension("pde")) { // System.out.println("preprocOffset "+ sketch.getCode(i).getPreprocOffset()); if (sketch.getCode(i).getPreprocOffset() < lineNumber) { fileIndex = i; // System.out.println("i'm thinkin file " + i); } } } // XXX: DAM: if the lineNumber is less than sketch.getCode(0).getPreprocOffset() // we shouldn't subtract anything from it, as the error is above the // location where the function prototypes and #include "Platform.h" // were inserted. lineNumber -= sketch.getCode(fileIndex).getPreprocOffset(); } // String s2 = s1.substring(colon + 2); int err = s1.indexOf(":"); if (err != -1) { // if the first error has already been found, then this must be // (at least) the second error found if (firstErrorFound) { secondErrorFound = true; return; } // if executing at this point, this is *at least* the first error firstErrorFound = true; err += ":".length(); String description = s1.substring(err); description = description.trim(); System.err.print(description); // System.out.println("description = " + description); // System.out.println("creating exception " + exception); exception = new RunnerException(description, fileIndex, lineNumber - 1, -1, false); // NOTE!! major change here, this exception will be queued // here to be thrown by the compile() function // editor.error(exception); } else { System.err.println("i suck: " + s); } } else { // this isn't the start of an error line, so don't attempt to parse // a line number out of it. // if the second error hasn't been discovered yet, these lines // are probably associated with the first error message, // which is already in the status bar, and are likely to be // of interest to the user, so spit them to the console. // if (!secondErrorFound) { System.err.println(s); } } }