From 7cb794195a805db12aa922368179516bc9a3376f Mon Sep 17 00:00:00 2001 From: Arnav Gupta Date: Wed, 24 Sep 2014 03:49:52 +0530 Subject: [PATCH 1/3] add option to save hex or bin to sketch folder Signed-off-by: Arnav Gupta --- app/src/processing/app/Editor.java | 89 +++++++++++++++++++--- app/src/processing/app/Sketch.java | 10 +-- app/src/processing/app/debug/Compiler.java | 26 ++++++- hardware/arduino/avr/platform.txt | 3 + hardware/arduino/sam/platform.txt | 3 + 5 files changed, 113 insertions(+), 18 deletions(-) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 953f9f44441..ca8c2cc434d 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -150,6 +150,8 @@ public class Editor extends JFrame implements RunnerListener { Runnable runHandler; Runnable presentHandler; + Runnable runAndSaveHandler; + Runnable presentAndSaveHandler; Runnable stopHandler; Runnable exportHandler; Runnable exportAppHandler; @@ -627,14 +629,14 @@ public void actionPerformed(ActionEvent e) { }); sketchMenu.add(item); -// item = newJMenuItemShift("Verify / Compile (verbose)", 'R'); -// item.addActionListener(new ActionListener() { -// public void actionPerformed(ActionEvent e) { -// handleRun(true); -// } -// }); -// sketchMenu.add(item); - + item = newJMenuItemShift("Compile and Save Hex", 'R'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleRunAndSave(false); + } + }); + sketchMenu.add(item); + // item = new JMenuItem("Stop"); // item.addActionListener(new ActionListener() { // public void actionPerformed(ActionEvent e) { @@ -1405,11 +1407,17 @@ protected void updateRedoState() { // abstract from the editor in this fashion. - public void setHandlers(Runnable runHandler, Runnable presentHandler, + public void setHandlers(Runnable runHandler, + Runnable presentHandler, + Runnable runAndSaveHandler, + Runnable presentAndSaveHandler, Runnable stopHandler, - Runnable exportHandler, Runnable exportAppHandler) { + Runnable exportHandler, + Runnable exportAppHandler) { this.runHandler = runHandler; this.presentHandler = presentHandler; + this.runAndSaveHandler = runHandler; + this.presentAndSaveHandler = presentHandler; this.stopHandler = stopHandler; this.exportHandler = exportHandler; this.exportAppHandler = exportAppHandler; @@ -1419,6 +1427,8 @@ public void setHandlers(Runnable runHandler, Runnable presentHandler, public void resetHandlers() { runHandler = new DefaultRunHandler(); presentHandler = new DefaultPresentHandler(); + runAndSaveHandler = new DefaultRunHandler(); + presentAndSaveHandler = new DefaultPresentHandler(); stopHandler = new DefaultStopHandler(); exportHandler = new DefaultExportHandler(); exportAppHandler = new DefaultExportAppHandler(); @@ -1903,13 +1913,35 @@ public void handleRun(final boolean verbose) { // placed on the event thread and causes a hang--bad idea all around. new Thread(verbose ? presentHandler : runHandler).start(); } + /** + * Implements Sketch → Run and Save Hex. + * @param verbose Set true to run with verbose output. + */ + public void handleRunAndSave(final boolean verbose) { + internalCloseRunner(); + running = true; + toolbar.activate(EditorToolbar.RUN); + status.progress(_("Compiling sketch...")); + + // do this to advance/clear the terminal window / dos prompt / etc + for (int i = 0; i < 10; i++) System.out.println(); + + // clear the console on each run, unless the user doesn't want to + if (Preferences.getBoolean("console.auto_clear")) { + console.clear(); + } + + // Cannot use invokeLater() here, otherwise it gets + // placed on the event thread and causes a hang--bad idea all around. + new Thread(verbose ? presentAndSaveHandler : runAndSaveHandler).start(); + } // DAM: in Arduino, this is compile class DefaultRunHandler implements Runnable { public void run() { try { sketch.prepare(); - sketch.build(false); + sketch.build(false, false); statusNotice(_("Done compiling.")); } catch (Exception e) { status.unprogress(); @@ -1926,7 +1958,7 @@ class DefaultPresentHandler implements Runnable { public void run() { try { sketch.prepare(); - sketch.build(true); + sketch.build(true, false); statusNotice(_("Done compiling.")); } catch (Exception e) { status.unprogress(); @@ -1937,6 +1969,39 @@ public void run() { toolbar.deactivate(EditorToolbar.RUN); } } +//DAM: in Arduino, this is compile + class DefaultRunAndSaveHandler implements Runnable { + public void run() { + try { + sketch.prepare(); + sketch.build(false, true); + statusNotice(_("Done compiling.")); + } catch (Exception e) { + status.unprogress(); + statusError(e); + } + + status.unprogress(); + toolbar.deactivate(EditorToolbar.RUN); + } + } + + // DAM: in Arduino, this is compile (with verbose output) + class DefaultPresentAndSaveHandler implements Runnable { + public void run() { + try { + sketch.prepare(); + sketch.build(true, true); + statusNotice(_("Done compiling.")); + } catch (Exception e) { + status.unprogress(); + statusError(e); + } + + status.unprogress(); + toolbar.deactivate(EditorToolbar.RUN); + } + } class DefaultStopHandler implements Runnable { public void run() { diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 4b2c6b44b4c..aa85cabc706 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -1504,8 +1504,8 @@ public RunnerException placeException(String message, * @return null if compilation failed, main class name if not * @throws RunnerException */ - public String build(boolean verbose) throws RunnerException { - return build(tempBuildFolder.getAbsolutePath(), verbose); + public String build(boolean verbose, boolean save) throws RunnerException { + return build(tempBuildFolder.getAbsolutePath(), verbose, save); } /** @@ -1558,7 +1558,7 @@ protected String buildPrefsString(Compiler compiler) { * * @return null if compilation failed, main class name if not */ - public String build(String buildPath, boolean verbose) throws RunnerException { + public String build(String buildPath, boolean verbose, boolean save) throws RunnerException { String primaryClassName = name + ".cpp"; Compiler compiler = new Compiler(this, buildPath, primaryClassName); File buildPrefsFile = new File(buildPath, BUILD_PREFS_FILE); @@ -1585,7 +1585,7 @@ public String build(String buildPath, boolean verbose) throws RunnerException { // compile the program. errors will happen as a RunnerException // that will bubble up to whomever called build(). - if (compiler.compile(verbose)) { + if (compiler.compile(verbose, save)) { size(compiler.getBuildPreferences()); return primaryClassName; } @@ -1607,7 +1607,7 @@ public boolean exportApplet(String appletPath, boolean usingProgrammer) // build the sketch editor.status.progressNotice(_("Compiling sketch...")); - String foundName = build(appletPath, false); + String foundName = build(appletPath, false, false); // (already reported) error during export, exit this function if (foundName == null) return false; diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 8a38db7e90a..3858506cfb1 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -55,6 +55,7 @@ public class Compiler implements MessageConsumer { private PreferencesMap prefs; private boolean verbose; + private boolean saveHex; private boolean sketchIsCompiled; private String targetArch; @@ -78,8 +79,9 @@ public Compiler(Sketch _sketch, String _buildPath, String _primaryClassName) * @return true if successful. * @throws RunnerException Only if there's a problem. Only then. */ - public boolean compile(boolean _verbose) throws RunnerException { + public boolean compile(boolean _verbose, boolean _save) throws RunnerException { verbose = _verbose || Preferences.getBoolean("build.verbose"); + saveHex = _save; sketchIsCompiled = false; objectFiles = new ArrayList(); @@ -142,6 +144,10 @@ public boolean compile(boolean _verbose) throws RunnerException { // 6. build the .hex file sketch.setCompilingProgress(80); compileHex(); + + // 7. Save the .hex file + sketch.setCompilingProgress(85); + saveHex(); sketch.setCompilingProgress(90); return true; @@ -790,6 +796,24 @@ void compileHex() throws RunnerException { } execAsynchronously(cmdArray); } + + // 7. Save the .hex file + void saveHex() throws RunnerException { + PreferencesMap dict = new PreferencesMap(prefs); + dict.put("ide_version", "" + Base.REVISION); + + String[] cmdArray; + try { + String hexPattern = prefs.get("recipe.hex.pattern"); + String hexPath = prefs.get("build.path") + "/" + hexPattern; + String savePath = sketch.getFolder().getAbsolutePath() + "/" + hexPattern; + String cmd = "cp -f " + hexPath + " " + savePath; + cmdArray = StringReplacer.formatAndSplit(cmd, dict, true); + } catch (Exception e) { + throw new RunnerException(e); + } + execAsynchronously(cmdArray); + } private static String prepareIncludes(List includeFolders) { String res = ""; diff --git a/hardware/arduino/avr/platform.txt b/hardware/arduino/avr/platform.txt index 9a2565fe65e..34685701cd8 100644 --- a/hardware/arduino/avr/platform.txt +++ b/hardware/arduino/avr/platform.txt @@ -67,6 +67,9 @@ recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.obj ## Create hex recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex" +## Save hex +recipe.hex.pattern={build.project_name}.hex + ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).* diff --git a/hardware/arduino/sam/platform.txt b/hardware/arduino/sam/platform.txt index 239674e0fa5..28f879f1aaf 100644 --- a/hardware/arduino/sam/platform.txt +++ b/hardware/arduino/sam/platform.txt @@ -71,6 +71,9 @@ recipe.objcopy.eep.pattern= ## Create hex recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" +## Save hex +recipe.hex.pattern={build.project_name}.bin + ## Compute size recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.regex=\.text\s+([0-9]+).* From 30a7714bf58544004c785df2160d813ff9df2c8c Mon Sep 17 00:00:00 2001 From: Arnav Gupta Date: Wed, 24 Sep 2014 03:57:46 +0530 Subject: [PATCH 2/3] make saving optional. Ctrl + R = Verify/Compile Ctrl + Shift + R = Compile and Save hex Signed-off-by: Arnav Gupta --- app/src/processing/app/Editor.java | 4 ++-- app/src/processing/app/debug/Compiler.java | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index ca8c2cc434d..b3cce479b83 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -1427,8 +1427,8 @@ public void setHandlers(Runnable runHandler, public void resetHandlers() { runHandler = new DefaultRunHandler(); presentHandler = new DefaultPresentHandler(); - runAndSaveHandler = new DefaultRunHandler(); - presentAndSaveHandler = new DefaultPresentHandler(); + runAndSaveHandler = new DefaultRunAndSaveHandler(); + presentAndSaveHandler = new DefaultPresentAndSaveHandler(); stopHandler = new DefaultStopHandler(); exportHandler = new DefaultExportHandler(); exportAppHandler = new DefaultExportAppHandler(); diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 3858506cfb1..1b58b697b9f 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -146,8 +146,10 @@ public boolean compile(boolean _verbose, boolean _save) throws RunnerException { compileHex(); // 7. Save the .hex file - sketch.setCompilingProgress(85); - saveHex(); + if (saveHex) { + sketch.setCompilingProgress(85); + saveHex(); + } sketch.setCompilingProgress(90); return true; From 8084fc5de6fe66dafa8d35f0bb9522c9a11f415e Mon Sep 17 00:00:00 2001 From: Arnav Gupta Date: Thu, 25 Sep 2014 20:03:32 +0530 Subject: [PATCH 3/3] move upload commands to sketch menu Signed-off-by: Arnav Gupta --- app/src/processing/app/Editor.java | 35 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index b3cce479b83..fb8aedd2b95 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -557,21 +557,6 @@ public void actionPerformed(ActionEvent e) { }); fileMenu.add(saveAsMenuItem); - item = newJMenuItem(_("Upload"), 'U'); - item.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - handleExport(false); - } - }); - fileMenu.add(item); - - item = newJMenuItemShift(_("Upload Using Programmer"), 'U'); - item.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - handleExport(true); - } - }); - fileMenu.add(item); fileMenu.addSeparator(); @@ -620,7 +605,7 @@ public void actionPerformed(ActionEvent e) { protected JMenu buildSketchMenu() { JMenuItem item; sketchMenu = new JMenu(_("Sketch")); - + item = newJMenuItem(_("Verify / Compile"), 'R'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -636,7 +621,23 @@ public void actionPerformed(ActionEvent e) { } }); sketchMenu.add(item); - + + item = newJMenuItem(_("Upload"), 'U'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleExport(false); + } + }); + sketchMenu.add(item); + + item = newJMenuItemShift(_("Upload Using Programmer"), 'U'); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handleExport(true); + } + }); + sketchMenu.add(item); + // item = new JMenuItem("Stop"); // item.addActionListener(new ActionListener() { // public void actionPerformed(ActionEvent e) {