diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index e1c79956f..914cd3487 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -35,6 +35,7 @@ import cc.arduino.packages.DiscoveryManager; import processing.app.debug.TargetBoard; import processing.app.debug.TargetPackage; import processing.app.debug.TargetPlatform; +import processing.app.helpers.CommandlineParser; import processing.app.helpers.FileUtils; import processing.app.helpers.GUIUserNotifier; import processing.app.helpers.OSUtils; @@ -211,8 +212,6 @@ public class Base { return BaseNoGui.absoluteFile(path); } - protected static enum ACTION { GUI, NOOP, VERIFY, UPLOAD, GET_PREF }; - public Base(String[] args) throws Exception { getPlatform().init(); if (OSUtils.isMacOS()) @@ -237,117 +236,9 @@ public class Base { // Setup board-dependent variables. onBoardOrPortChange(); - ACTION action = ACTION.GUI; - boolean doVerboseBuild = false; - boolean doVerboseUpload = false; - boolean forceSavePrefs = false; - String getPref = null; - List filenames = new LinkedList(); + CommandlineParser parser = CommandlineParser.newCommandlineParser(args); - // Map of possible actions and corresponding options - final Map actions = new HashMap(); - actions.put("--verify", ACTION.VERIFY); - actions.put("--upload", ACTION.UPLOAD); - actions.put("--get-pref", ACTION.GET_PREF); - - // Check if any files were passed in on the command line - for (int i = 0; i < args.length; i++) { - ACTION a = actions.get(args[i]); - if (a != null) { - if (action != ACTION.GUI && action != ACTION.NOOP) { - String[] valid = actions.keySet().toArray(new String[0]); - String mess = I18n.format(_("Can only pass one of: {0}"), PApplet.join(valid, ", ")); - showError(null, mess, 3); - } - if (a == ACTION.GET_PREF) { - i++; - if (i >= args.length) - showError(null, _("Argument required for --get-pref"), 3); - getPref = args[i]; - } - action = a; - continue; - } - if (args[i].equals("--verbose") || args[i].equals("-v")) { - doVerboseBuild = true; - doVerboseUpload = true; - if (action == ACTION.GUI) - action = ACTION.NOOP; - continue; - } - if (args[i].equals("--verbose-build")) { - doVerboseBuild = true; - if (action == ACTION.GUI) - action = ACTION.NOOP; - continue; - } - if (args[i].equals("--verbose-upload")) { - doVerboseUpload = true; - if (action == ACTION.GUI) - action = ACTION.NOOP; - continue; - } - if (args[i].equals("--board")) { - i++; - if (i >= args.length) - showError(null, _("Argument required for --board"), 3); - processBoardArgument(args[i]); - if (action == ACTION.GUI) - action = ACTION.NOOP; - continue; - } - if (args[i].equals("--port")) { - i++; - if (i >= args.length) - showError(null, _("Argument required for --port"), 3); - selectSerialPort(args[i]); - if (action == ACTION.GUI) - action = ACTION.NOOP; - continue; - } - if (args[i].equals("--curdir")) { - i++; - if (i >= args.length) - showError(null, _("Argument required for --curdir"), 3); - // Argument should be already processed by Base.main(...) - continue; - } - if (args[i].equals("--pref")) { - i++; - if (i >= args.length) - showError(null, _("Argument required for --pref"), 3); - processPrefArgument(args[i]); - if (action == ACTION.GUI) - action = ACTION.NOOP; - continue; - } - if (args[i].equals("--save-prefs")) { - forceSavePrefs = true; - continue; - } - if (args[i].equals("--preferences-file")) { - i++; - if (i >= args.length) - showError(null, _("Argument required for --preferences-file"), 3); - // Argument should be already processed by Base.main(...) - continue; - } - if (args[i].startsWith("--")) - showError(null, I18n.format(_("unknown option: {0}"), args[i]), 3); - - filenames.add(args[i]); - } - - if ((action == ACTION.UPLOAD || action == ACTION.VERIFY) && filenames.size() != 1) - showError(null, _("Must specify exactly one sketch file"), 3); - - if ((action == ACTION.NOOP || action == ACTION.GET_PREF) && filenames.size() != 0) - showError(null, _("Cannot specify any sketch files"), 3); - - if ((action != ACTION.UPLOAD && action != ACTION.VERIFY) && (doVerboseBuild || doVerboseUpload)) - showError(null, _("--verbose, --verbose-upload and --verbose-build can only be used together with --verify or --upload"), 3); - - for (String path: filenames) { + for (String path: parser.getFilenames()) { // Correctly resolve relative paths File file = absoluteFile(path); @@ -363,13 +254,13 @@ public class Base { } } - boolean showEditor = (action == ACTION.GUI); - if (!forceSavePrefs) + boolean showEditor = parser.isGuiMode(); + if (!parser.isForceSavePrefs()) Preferences.setDoSave(showEditor); if (handleOpen(file, nextEditorLocation(), showEditor) == null) { String mess = I18n.format(_("Failed to open sketch: \"{0}\""), path); // Open failure is fatal in upload/verify mode - if (action == ACTION.VERIFY || action == ACTION.UPLOAD) + if (parser.isVerifyOrUploadMode()) showError(null, mess, 2); else showWarning(null, mess, null); @@ -381,12 +272,10 @@ public class Base { // them. Preferences.save(); - switch (action) { - case VERIFY: - case UPLOAD: + if (parser.isVerifyOrUploadMode()) { // Set verbosity for command line build - Preferences.set("build.verbose", "" + doVerboseBuild); - Preferences.set("upload.verbose", "" + doVerboseUpload); + Preferences.set("build.verbose", "" + parser.isDoVerboseBuild()); + Preferences.set("upload.verbose", "" + parser.isDoVerboseUpload()); // Make sure these verbosity preferences are only for the // current session @@ -394,7 +283,7 @@ public class Base { Editor editor = editors.get(0); - if (action == ACTION.UPLOAD) { + if (parser.isUploadMode()) { // Build and upload editor.exportHandler.run(); } else { @@ -409,8 +298,8 @@ public class Base { // No errors exit gracefully System.exit(0); - break; - case GUI: + } + else if (parser.isGuiMode()) { // Check if there were previously opened sketches to be restored restoreSketches(); @@ -423,29 +312,20 @@ public class Base { if (Preferences.getBoolean("update.check")) { new UpdateCheck(this); } - break; - case NOOP: + } + else if (parser.isNoOpMode()) { // Do nothing (intended for only changing preferences) System.exit(0); - break; - case GET_PREF: - String value = Preferences.get(getPref, null); + } + else if (parser.isGetPrefMode()) { + String value = Preferences.get(parser.getGetPref(), null); if (value != null) { System.out.println(value); System.exit(0); } else { System.exit(4); } - break; - } - } - - protected void processBoardArgument(String selectBoard) { - BaseNoGui.processBoardArgument(selectBoard); - } - - protected void processPrefArgument(String arg) { - BaseNoGui.processPrefArgument(arg); + } } /** diff --git a/app/src/processing/app/BaseNoGui.java b/app/src/processing/app/BaseNoGui.java index 287ad1fb5..d793108fb 100644 --- a/app/src/processing/app/BaseNoGui.java +++ b/app/src/processing/app/BaseNoGui.java @@ -553,62 +553,6 @@ public class BaseNoGui { PreferencesData.init(absoluteFile(preferencesFile)); } - static protected void processBoardArgument(String selectBoard) { - // No board selected? Nothing to do - if (selectBoard == null) - return; - - String[] split = selectBoard.split(":", 4); - - if (split.length < 3) { - showError(null, I18n.format(_("{0}: Invalid board name, it should be of the form \"package:arch:board\" or \"package:arch:board:options\""), selectBoard), 3); - } - - TargetPackage targetPackage = getTargetPackage(split[0]); - if (targetPackage == null) { - showError(null, I18n.format(_("{0}: Unknown package"), split[0]), 3); - } - - TargetPlatform targetPlatform = targetPackage.get(split[1]); - if (targetPlatform == null) { - showError(null, I18n.format(_("{0}: Unknown architecture"), split[1]), 3); - } - - TargetBoard targetBoard = targetPlatform.getBoard(split[2]); - if (targetBoard == null) { - showError(null, I18n.format(_("{0}: Unknown board"), split[2]), 3); - } - - selectBoard(targetBoard); - - if (split.length > 3) { - String[] options = split[3].split(","); - for (String option : options) { - String[] keyValue = option.split("=", 2); - - if (keyValue.length != 2) - showError(null, I18n.format(_("{0}: Invalid option, should be of the form \"name=value\""), option, targetBoard.getId()), 3); - String key = keyValue[0].trim(); - String value = keyValue[1].trim(); - - if (!targetBoard.hasMenu(key)) - showError(null, I18n.format(_("{0}: Invalid option for board \"{1}\""), key, targetBoard.getId()), 3); - if (targetBoard.getMenuLabel(key, value) == null) - showError(null, I18n.format(_("{0}: Invalid option for \"{1}\" option for board \"{2}\""), value, key, targetBoard.getId()), 3); - - PreferencesData.set("custom_" + key, targetBoard.getId() + "_" + value); - } - } - } - - static protected void processPrefArgument(String arg) { - String[] split = arg.split("=", 2); - if (split.length != 2 || split[0].isEmpty()) - showError(null, I18n.format(_("{0}: Invalid argument to --pref, should be of the form \"pref=value\""), arg), 3); - - PreferencesData.set(split[0], split[1]); - } - /** * Recursively remove all files within a directory, * used with removeDir(), or when the contents of a dir @@ -759,7 +703,7 @@ public class BaseNoGui { return res; } - static protected void selectBoard(TargetBoard targetBoard) { + static public void selectBoard(TargetBoard targetBoard) { TargetPlatform targetPlatform = targetBoard.getContainerPlatform(); TargetPackage targetPackage = targetPlatform.getContainerPackage(); diff --git a/app/src/processing/app/helpers/CommandlineParser.java b/app/src/processing/app/helpers/CommandlineParser.java new file mode 100644 index 000000000..330509065 --- /dev/null +++ b/app/src/processing/app/helpers/CommandlineParser.java @@ -0,0 +1,245 @@ +package processing.app.helpers; + +import static processing.app.I18n._; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import processing.app.BaseNoGui; +import processing.app.I18n; +import processing.app.PreferencesData; +import processing.app.debug.TargetBoard; +import processing.app.debug.TargetPackage; +import processing.app.debug.TargetPlatform; +import processing.app.legacy.PApplet; + +public class CommandlineParser { + + protected static enum ACTION { GUI, NOOP, VERIFY, UPLOAD, GET_PREF }; + + private ACTION action = ACTION.GUI; + private boolean doVerboseBuild = false; + private boolean doVerboseUpload = false; + private boolean forceSavePrefs = false; + private String getPref = null; + private List filenames = new LinkedList(); + + public static CommandlineParser newCommandlineParser(String[] args) { + return new CommandlineParser(args); + } + + private CommandlineParser(String[] args) { + parseArguments(args); + checkAction(); + } + + private void parseArguments(String[] args) { + // Map of possible actions and corresponding options + final Map actions = new HashMap(); + actions.put("--verify", ACTION.VERIFY); + actions.put("--upload", ACTION.UPLOAD); + actions.put("--get-pref", ACTION.GET_PREF); + + // Check if any files were passed in on the command line + for (int i = 0; i < args.length; i++) { + ACTION a = actions.get(args[i]); + if (a != null) { + if (action != ACTION.GUI && action != ACTION.NOOP) { + String[] valid = actions.keySet().toArray(new String[0]); + String mess = I18n.format(_("Can only pass one of: {0}"), PApplet.join(valid, ", ")); + BaseNoGui.showError(null, mess, 3); + } + if (a == ACTION.GET_PREF) { + i++; + if (i >= args.length) + BaseNoGui.showError(null, _("Argument required for --get-pref"), 3); + getPref = args[i]; + } + action = a; + continue; + } + if (args[i].equals("--verbose") || args[i].equals("-v")) { + doVerboseBuild = true; + doVerboseUpload = true; + if (action == ACTION.GUI) + action = ACTION.NOOP; + continue; + } + if (args[i].equals("--verbose-build")) { + doVerboseBuild = true; + if (action == ACTION.GUI) + action = ACTION.NOOP; + continue; + } + if (args[i].equals("--verbose-upload")) { + doVerboseUpload = true; + if (action == ACTION.GUI) + action = ACTION.NOOP; + continue; + } + if (args[i].equals("--board")) { + i++; + if (i >= args.length) + BaseNoGui.showError(null, _("Argument required for --board"), 3); + processBoardArgument(args[i]); + if (action == ACTION.GUI) + action = ACTION.NOOP; + continue; + } + if (args[i].equals("--port")) { + i++; + if (i >= args.length) + BaseNoGui.showError(null, _("Argument required for --port"), 3); + BaseNoGui.selectSerialPort(args[i]); + if (action == ACTION.GUI) + action = ACTION.NOOP; + continue; + } + if (args[i].equals("--curdir")) { + i++; + if (i >= args.length) + BaseNoGui.showError(null, _("Argument required for --curdir"), 3); + // Argument should be already processed by Base.main(...) + continue; + } + if (args[i].equals("--pref")) { + i++; + if (i >= args.length) + BaseNoGui.showError(null, _("Argument required for --pref"), 3); + processPrefArgument(args[i]); + if (action == ACTION.GUI) + action = ACTION.NOOP; + continue; + } + if (args[i].equals("--save-prefs")) { + forceSavePrefs = true; + continue; + } + if (args[i].equals("--preferences-file")) { + i++; + if (i >= args.length) + BaseNoGui.showError(null, _("Argument required for --preferences-file"), 3); + // Argument should be already processed by Base.main(...) + continue; + } + if (args[i].startsWith("--")) + BaseNoGui.showError(null, I18n.format(_("unknown option: {0}"), args[i]), 3); + + filenames.add(args[i]); + } + } + + private void checkAction() { + if ((action == ACTION.UPLOAD || action == ACTION.VERIFY) && filenames.size() != 1) + BaseNoGui.showError(null, _("Must specify exactly one sketch file"), 3); + + if ((action == ACTION.NOOP || action == ACTION.GET_PREF) && filenames.size() != 0) + BaseNoGui.showError(null, _("Cannot specify any sketch files"), 3); + + if ((action != ACTION.UPLOAD && action != ACTION.VERIFY) && (doVerboseBuild || doVerboseUpload)) + BaseNoGui.showError(null, _("--verbose, --verbose-upload and --verbose-build can only be used together with --verify or --upload"), 3); + } + + private void processBoardArgument(String selectBoard) { + // No board selected? Nothing to do + if (selectBoard == null) + return; + + String[] split = selectBoard.split(":", 4); + + if (split.length < 3) { + BaseNoGui.showError(null, I18n.format(_("{0}: Invalid board name, it should be of the form \"package:arch:board\" or \"package:arch:board:options\""), selectBoard), 3); + } + + TargetPackage targetPackage = BaseNoGui.getTargetPackage(split[0]); + if (targetPackage == null) { + BaseNoGui.showError(null, I18n.format(_("{0}: Unknown package"), split[0]), 3); + } + + TargetPlatform targetPlatform = targetPackage.get(split[1]); + if (targetPlatform == null) { + BaseNoGui.showError(null, I18n.format(_("{0}: Unknown architecture"), split[1]), 3); + } + + TargetBoard targetBoard = targetPlatform.getBoard(split[2]); + if (targetBoard == null) { + BaseNoGui.showError(null, I18n.format(_("{0}: Unknown board"), split[2]), 3); + } + + BaseNoGui.selectBoard(targetBoard); + + if (split.length > 3) { + String[] options = split[3].split(","); + for (String option : options) { + String[] keyValue = option.split("=", 2); + + if (keyValue.length != 2) + BaseNoGui.showError(null, I18n.format(_("{0}: Invalid option, should be of the form \"name=value\""), option, targetBoard.getId()), 3); + String key = keyValue[0].trim(); + String value = keyValue[1].trim(); + + if (!targetBoard.hasMenu(key)) + BaseNoGui.showError(null, I18n.format(_("{0}: Invalid option for board \"{1}\""), key, targetBoard.getId()), 3); + if (targetBoard.getMenuLabel(key, value) == null) + BaseNoGui.showError(null, I18n.format(_("{0}: Invalid option for \"{1}\" option for board \"{2}\""), value, key, targetBoard.getId()), 3); + + PreferencesData.set("custom_" + key, targetBoard.getId() + "_" + value); + } + } + } + + private void processPrefArgument(String arg) { + String[] split = arg.split("=", 2); + if (split.length != 2 || split[0].isEmpty()) + BaseNoGui.showError(null, I18n.format(_("{0}: Invalid argument to --pref, should be of the form \"pref=value\""), arg), 3); + + PreferencesData.set(split[0], split[1]); + } + + public boolean isDoVerboseBuild() { + return doVerboseBuild; + } + + public boolean isDoVerboseUpload() { + return doVerboseUpload; + } + + public boolean isForceSavePrefs() { + return forceSavePrefs; + } + + public String getGetPref() { + return getPref; + } + + public List getFilenames() { + return filenames; + } + + public boolean isGetPrefMode() { + return action == ACTION.GET_PREF; + } + + public boolean isGuiMode() { + return action == ACTION.GUI; + } + + public boolean isNoOpMode() { + return action == ACTION.NOOP; + } + + public boolean isUploadMode() { + return action == ACTION.UPLOAD; + } + + public boolean isVerifyMode() { + return action == ACTION.VERIFY; + } + + public boolean isVerifyOrUploadMode() { + return isVerifyMode() || isUploadMode(); + } + +}