diff --git a/trunk/src/com/jpexs/decompiler/flash/ConsoleAbortRetryIgnoreHandler.java b/trunk/src/com/jpexs/decompiler/flash/ConsoleAbortRetryIgnoreHandler.java new file mode 100644 index 000000000..f95dd8c91 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/ConsoleAbortRetryIgnoreHandler.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash; + +import java.util.Scanner; + +/** + * + * @author JPEXS + */ +public class ConsoleAbortRetryIgnoreHandler implements AbortRetryIgnoreHandler { + int errorCount = 0; + int errorMode; + int retryCount; + + public ConsoleAbortRetryIgnoreHandler(int errorMode, int retryCount) { + this.errorMode = errorMode; + this.retryCount = retryCount; + } + + @Override + public int handle(Throwable thrown) { + if (errorMode != AbortRetryIgnoreHandler.UNDEFINED){ + int result = errorMode; + + if (errorMode == AbortRetryIgnoreHandler.RETRY && errorCount < retryCount) { + errorCount++; + } + else { + result = AbortRetryIgnoreHandler.IGNORE; + } + + return result; + } + Scanner sc = new Scanner(System.in); + System.out.println("Error occured: " + thrown.getLocalizedMessage()); + String n = null; + do { + System.out.print("Select action: (A)bort, (R)Retry, (I)Ignore:"); + n = sc.nextLine(); + switch (n.toLowerCase()) { + case "a": + return AbortRetryIgnoreHandler.ABORT; + case "r": + return AbortRetryIgnoreHandler.RETRY; + case "i": + return AbortRetryIgnoreHandler.IGNORE; + } + } while (true); + } + + @Override + public AbortRetryIgnoreHandler getNewInstance() { + return new ConsoleAbortRetryIgnoreHandler(errorMode, retryCount); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/TagNode.java b/trunk/src/com/jpexs/decompiler/flash/TagNode.java index be9bf28c2..b59e97c22 100644 --- a/trunk/src/com/jpexs/decompiler/flash/TagNode.java +++ b/trunk/src/com/jpexs/decompiler/flash/TagNode.java @@ -319,7 +319,7 @@ public class TagNode { } catch (Exception | OutOfMemoryError | StackOverflowError ex) { Logger.getLogger(TagNode.class.getName()).log(Level.SEVERE, "Decompilation error", ex); if (handler != null) { - int action = handler.handle(ex); + int action = handler.getNewInstance().handle(ex); switch (action) { case AbortRetryIgnoreHandler.ABORT: throw ex; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java index 17650b1a4..0898262f4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.Configuration; +import com.jpexs.decompiler.flash.ConsoleAbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.EventListener; import com.jpexs.decompiler.flash.PercentListener; import com.jpexs.decompiler.flash.SWF; @@ -529,6 +530,8 @@ public class Main { System.out.println(" Values are boolean, you can use 0/1, true/false or yes/no."); System.out.println(" If no other parameters passed, configuration is saved. Otherwise it is used only once."); System.out.println(" DO NOT PUT space between comma (,) and next value."); + System.out.println(" 9) -onerror (abort|retryN|ignore)"); + System.out.println(" ...error handling mode. \"abort\" stops the exporting, \"retry\" tries the exporting N times, \"ignore\" ignores the current file"); System.out.println(); System.out.println("Examples:"); System.out.println("java -jar ffdec.jar myfile.swf"); @@ -540,6 +543,8 @@ public class Main { System.out.println("java -jar ffdec.jar -dumpSWF myfile.swf"); System.out.println("java -jar ffdec.jar -compress myfile.swf myfiledec.swf"); System.out.println("java -jar ffdec.jar -decompress myfiledec.swf myfile.swf"); + System.out.println("java -jar ffdec.jar -onerror ignore -export as \"C:\\decompiled\\\" myfile.swf"); + System.out.println("java -jar ffdec.jar -onerror retry 5 -export as \"C:\\decompiled\\\" myfile.swf"); System.out.println("java -jar ffdec.jar -config autoDeobfuscate=1,parallelSpeedUp=0 -export as \"C:\\decompiled\\\" myfile.swf"); System.out.println(""); System.out.println("Instead of \"java -jar ffdec.jar\" you can use ffdec.bat on Windows, ffdec.sh on Linux/MacOs"); @@ -671,61 +676,100 @@ public class Main { } else { Cache.setStorageType(Cache.STORAGE_MEMORY); } + + int errorMode = AbortRetryIgnoreHandler.UNDEFINED; + int retryCount = 0; if (args.length < pos + 1) { autoCheckForUpdates(); offerAssociation(); showModeFrame(); } else { - if (args[pos].equals("-config")) { - pos++; - if (args.length <= pos) { - System.err.println("Config values expected"); - badArguments(); - } - String cfgStr = args[pos]; - String cfgs[]; - if (cfgStr.contains(",")) { - cfgs = cfgStr.split(","); - } else { - cfgs = new String[]{cfgStr}; - } - - - - for (String c : cfgs) { - String cp[]; - if (c.contains("=")) { - cp = c.split("="); + boolean parameterProcessed = true; + while (parameterProcessed) { + parameterProcessed = false; + if (args[pos].equals("-config")) { + parameterProcessed = true; + pos++; + if (args.length <= pos) { + System.err.println("Config values expected"); + badArguments(); + } + String cfgStr = args[pos]; + String cfgs[]; + if (cfgStr.contains(",")) { + cfgs = cfgStr.split(","); } else { - cp = new String[]{c, "1"}; + cfgs = new String[]{cfgStr}; } - String key = cp[0]; - String value = cp[1]; - if (key.toLowerCase().equals("paralelSpeedUp".toLowerCase())) { - key = "parallelSpeedUp"; - } - for (String bk : commandlineConfigBoolean) { - if (key.toLowerCase().equals(bk.toLowerCase())) { - Boolean bValue = null; - if (value.equals("0") || value.toLowerCase().equals("false") || value.toLowerCase().equals("no") || value.toLowerCase().equals("off")) { - bValue = false; - } - if (value.equals("1") || value.toLowerCase().equals("true") || value.toLowerCase().equals("yes") || value.toLowerCase().equals("on")) { - bValue = true; - } - if (bValue != null) { - System.out.println("Config " + bk + " set to " + bValue); - Configuration.setConfig(bk, bValue); + + for (String c : cfgs) { + String cp[]; + if (c.contains("=")) { + cp = c.split("="); + } else { + cp = new String[]{c, "1"}; + } + String key = cp[0]; + String value = cp[1]; + if (key.toLowerCase().equals("paralelSpeedUp".toLowerCase())) { + key = "parallelSpeedUp"; + } + for (String bk : commandlineConfigBoolean) { + if (key.toLowerCase().equals(bk.toLowerCase())) { + Boolean bValue = null; + if (value.equals("0") || value.toLowerCase().equals("false") || value.toLowerCase().equals("no") || value.toLowerCase().equals("off")) { + bValue = false; + } + if (value.equals("1") || value.toLowerCase().equals("true") || value.toLowerCase().equals("yes") || value.toLowerCase().equals("on")) { + bValue = true; + } + if (bValue != null) { + System.out.println("Config " + bk + " set to " + bValue); + Configuration.setConfig(bk, bValue); + } } } } + pos++; + if (args.length <= pos) { + saveConfig(); + System.out.println("Configuration saved"); + return; + } } - pos++; - if (args.length <= pos) { - saveConfig(); - System.out.println("Configuration saved"); - return; + if (args[pos].equals("-onerror")) { + parameterProcessed = true; + pos++; + if (args.length <= pos) { + System.err.println("onerror parameter expected"); + badArguments(); + } + String errorModeParameter = args[pos]; + switch (errorModeParameter) { + case "abort": + errorMode = AbortRetryIgnoreHandler.ABORT; + break; + case "retry": + errorMode = AbortRetryIgnoreHandler.RETRY; + pos++; + if (args.length <= pos) { + System.err.println("onerror retry count parameter expected"); + badArguments(); + } + + try { + retryCount = Integer.parseInt(args[pos]); + } catch (NumberFormatException nex) { + System.err.println("Bad retry count number"); + } + break; + case "ignore": + errorMode = AbortRetryIgnoreHandler.IGNORE; + break; + } + + pos++; } } if (args[pos].equals("-removefromcontextmenu")) { @@ -774,26 +818,7 @@ public class Main { "xfl" }; - AbortRetryIgnoreHandler handler = new AbortRetryIgnoreHandler() { - @Override - public int handle(Throwable thrown) { - Scanner sc = new Scanner(System.in); - System.out.println("Error occured: " + thrown.getLocalizedMessage()); - String n = null; - do { - System.out.print("Select action: (A)bort, (R)Retry, (I)Ignore:"); - n = sc.nextLine(); - switch (n.toLowerCase()) { - case "a": - return AbortRetryIgnoreHandler.ABORT; - case "r": - return AbortRetryIgnoreHandler.RETRY; - case "i": - return AbortRetryIgnoreHandler.IGNORE; - } - } while (true); - } - }; + AbortRetryIgnoreHandler handler = new ConsoleAbortRetryIgnoreHandler(errorMode, retryCount); String exportFormat = args[pos + 1].toLowerCase(); if (!Arrays.asList(validExportFormats).contains(exportFormat)) { System.err.println("Invalid export format:" + exportFormat); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index 0e96799ad..8cb729200 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.Configuration; +import com.jpexs.decompiler.flash.ConsoleAbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.FrameNode; import com.jpexs.decompiler.flash.PackageNode; import com.jpexs.decompiler.flash.SWF; @@ -288,6 +289,12 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel return View.showOptionDialog(null, translate("error.occured").replace("%error%", thrown.getLocalizedMessage()), translate("error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, options, ""); } } + + @Override + public AbortRetryIgnoreHandler getNewInstance() { + // there are no non-static field in this class, so return the original instance + return this; + } }; public void setPercent(int percent) {