From 07fdd9c037aade650fdcf583b9caa742d2adbe5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Fri, 12 Aug 2016 23:10:40 +0200 Subject: [PATCH] P-code docs - fix broken html when unknown instruction operands --- .../decompiler/flash/docs/As3PCodeDocs.java | 712 +++++++++--------- 1 file changed, 356 insertions(+), 356 deletions(-) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/docs/As3PCodeDocs.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/docs/As3PCodeDocs.java index a9f721bf5..eafdcf770 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/docs/As3PCodeDocs.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/docs/As3PCodeDocs.java @@ -1,356 +1,356 @@ -package com.jpexs.decompiler.flash.docs; - -import com.jpexs.decompiler.flash.ApplicationInfo; -import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2InstructionFlag; -import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; -import com.jpexs.helpers.Cache; -import com.jpexs.helpers.Helper; -import com.jpexs.helpers.utf8.Utf8Helper; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.ResourceBundle; -import java.util.Set; -import java.util.TimeZone; -import java.util.TreeSet; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Generator for AVM2 instruction set documentation. - * - * @author JPEXS - */ -public class As3PCodeDocs { - - private static ResourceBundle prop; - - private static Map flagDescriptions = new HashMap<>(); - - private static Cache docsCache = Cache.getInstance(false, true, "as3DocsCache"); - - private static Map nameToDef = new HashMap<>(); - - static final String NEWLINE = "\r\n"; - - static { - prop = ResourceBundle.getBundle("com.jpexs.decompiler.flash.locales.docs.pcode.AS3"); - for (InstructionDefinition def : AVM2Code.allInstructionSet) { - if (def == null) { - continue; - } - nameToDef.put(def.instructionName, def); - } - - for (AVM2InstructionFlag flg : AVM2InstructionFlag.values()) { - String flagIdent = makeIdent(flg.toString()); - String flagDescription = getProperty("instructionFlag." + flagIdent); - flagDescriptions.put(flg, flagDescription); - } - } - - private static String makeIdent(String name) { - StringBuilder identName = new StringBuilder(); - boolean cap = false; - for (int i = 0; i < name.length(); i++) { - char c = name.charAt(i); - if (c == '_') { - cap = true; - continue; - } - if (cap) { - identName.append(c); - cap = false; - } else { - identName.append(Character.toLowerCase(c)); - } - } - return identName.toString(); - } - - public static String getDocsForIns(String insName, boolean showDataSize, boolean ui, boolean withStyle) { - if (!nameToDef.containsKey(insName)) { - return null; - } - return getDocsForIns(nameToDef.get(insName), showDataSize, ui, withStyle); - } - - private static String getProperty(String name) { - if (prop.containsKey(name)) { - return Helper.escapeHTML(prop.getString(name)); - } - return null; - } - - private static String htmlFooter() { - StringBuilder sb = new StringBuilder(); - - sb.append(""); - return sb.toString(); - } - - private static String meta(String name, String content) { - return "\t\t" + NEWLINE; - } - - private static String metaProp(String name, String content) { - return "\t\t" + NEWLINE; - } - - private static String meta(String name, Date content) { - return "\t\t" + NEWLINE; - } - - private static String htmlHeader(String js, String style) { - Date dateGenerated = new Date(); - StringBuilder sb = new StringBuilder(); - sb.append("").append(NEWLINE). - append("").append(NEWLINE). - append("\t").append(NEWLINE); - if (style != null && !style.isEmpty()) { - sb.append("\t\t").append(NEWLINE); - } - if (js != null && !js.isEmpty()) { - sb.append("\t\t").append(NEWLINE); - } - sb.append("\t\t").append(NEWLINE). - append(meta("generator", ApplicationInfo.applicationVerName)). - append(meta("description", getProperty("ui.list.pageDescription"))). - append(metaProp("og:title", getProperty("ui.list.pageTitle"))). - append(metaProp("og:type", "article")). - append(metaProp("og:description", getProperty("ui.list.pageDescription"))). - append(meta("date", dateGenerated)). - append("\t\t").append(getProperty("ui.list.documentTitle")).append("").append(NEWLINE). - append("\t").append(NEWLINE); - return sb.toString(); - } - - public static String getDocsForIns(InstructionDefinition def, boolean showDataSize, boolean ui, boolean standalone) { - final String cacheKey = def.instructionName + "|" + (showDataSize ? 1 : 0) + "|" + (ui ? 1 : 0) + "|" + (standalone ? 1 : 0); - String v = docsCache.get(cacheKey); - if (v != null) { - return v; - } - - StringBuilder sb = new StringBuilder(); - if (standalone) { - sb.append(htmlHeader("", getStyle())); - } - String insName = def.instructionName; - - String insShortDescription = getProperty("instruction." + insName + ".shortDescription"); - String insDescription = getProperty("instruction." + insName + ".description"); - String stackBefore = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? "" : getProperty("instruction." + insName + ".stackBefore"); - String stackAfter = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? "" : getProperty("instruction." + insName + ".stackAfter"); - if (stackBefore.trim().isEmpty()) { - stackBefore = getProperty("ui.stack.before.empty"); - } else { - stackBefore = getProperty("ui.stack.before") + stackBefore; - } - if (stackAfter.trim().isEmpty()) { - stackAfter = getProperty("ui.stack.before.empty"); - } else { - stackAfter = getProperty("ui.stack.before") + stackAfter; - } - stackBefore = "" + stackBefore + ""; - stackAfter = "" + stackAfter + ""; - - String stack = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? getProperty("ui.unknown") : stackBefore + "" + getProperty("ui.stack.to") + "" + stackAfter; - String operandsDoc = def.hasFlag(AVM2InstructionFlag.UNKNOWN_OPERANDS) ? getProperty("ui.unknown") : getProperty("instruction." + insName + ".operands"); - - sb.append("<"); - sb.append(standalone ? "body" : "div"); - sb.append(" class=\"instruction"); - - for (AVM2InstructionFlag fl : def.flags) { - sb.append(" instruction-flag-").append(makeIdent(fl.toString())); - } - sb.append("\">"); - - sb.append("
").append(String.format("0x%02X", def.instructionCode)).append(" ").append(insName).append(""); - - if (def.hasFlag(AVM2InstructionFlag.UNKNOWN_OPERANDS)) { - sb.append(" ").append(getProperty("ui.unknown")).append(NEWLINE); - } else { - String[] operandsDocs = operandsDoc.split(", ?"); - boolean first = true; - if (def.operands.length > 0) { - sb.append(" "); - } - for (int i = 0; i < def.operands.length; i++) { - int op = def.operands[i]; - String opDoc = operandsDocs[i]; - String operandTypeRaw = AVM2Code.operandTypeToString(op, false); - String operandTypeCombined = AVM2Code.operandTypeToString(op, true); - if (operandTypeCombined.contains(", ")) { - String[] operandTypesCombined = operandTypeCombined.split(", ?"); - String[] operandTypesRaw = operandTypeRaw.split(", ?"); - - for (int j = 0; j < operandTypesCombined.length; j++) { - if (!first) { - sb.append(", "); - } else { - first = false; - } - opDoc = operandsDocs[i + j]; - operandTypeCombined = operandTypesCombined[j]; - operandTypeRaw = operandTypesRaw[j]; - operandTypeRaw = getProperty("operandType." + operandTypeRaw + (ui ? ".uiName" : ".name")); - if (opDoc.equals("...")) { - sb.append("..."); - } else { - sb.append(opDoc); - sb.append(":").append(showDataSize ? operandTypeCombined : operandTypeRaw); - } - } - } else { - if (!first) { - sb.append(", "); - } else { - first = false; - } - operandTypeRaw = getProperty("operandType." + operandTypeRaw + (ui ? ".uiName" : ".name")); - - if (opDoc.equals(operandTypeRaw)) { - sb.append(showDataSize ? operandTypeCombined : operandTypeRaw); - } else { - sb.append(opDoc).append(":").append(showDataSize ? operandTypeCombined : operandTypeRaw); - } - } - } - sb.append("
").append(NEWLINE); - } - - sb.append("
").append(insShortDescription).append("
").append(NEWLINE); - - if (!insDescription.trim().isEmpty()) { - sb.append("
").append("").append(getProperty("ui.description")).append("").append(insDescription).append("
").append(NEWLINE); - } - sb.append("
").append(getProperty("ui.stack")).append("").append(stack).append("").append("
").append(NEWLINE); - boolean flagsPrinted = false; - - AVM2InstructionFlag[] flags = def.flags.clone(); - Arrays.sort(flags, Enum::compareTo); - - for (AVM2InstructionFlag fl : flags) { - if (!flagsPrinted) { - flagsPrinted = true; - sb.append("").append(getProperty("ui.flags")).append("").append("
").append(NEWLINE).append("
    ").append(NEWLINE); - } - sb.append("\t
  • ").append(flagDescriptions.get(fl)); - if (fl == AVM2InstructionFlag.DEPRECATED) { - String depDetail = getProperty("instruction." + insName + ".deprecated"); - if (depDetail != null) { - sb.append(": ").append(depDetail).append(""); - } - } - sb.append("
  • ").append(NEWLINE); - } - if (flagsPrinted) { - sb.append("
").append(NEWLINE); - } - sb.append("").append(NEWLINE); - if (standalone) { - sb.append(htmlFooter()); - } - String r = sb.toString(); - docsCache.put(cacheKey, r); - return r; - } - - public static String getStyle() { - String cached = docsCache.get("__style"); - if (cached != null) { - return cached; - } - String style = ""; - InputStream is = As3PCodeDocs.class.getResourceAsStream("/com/jpexs/decompiler/flash/docs/docs.css"); - if (is == null) { - Logger.getLogger(As3PCodeDocs.class.getName()).log(Level.SEVERE, "docs.css needed for documentation not found"); - } else { - style = new String(Helper.readStream(is), Utf8Helper.charset); - } - - docsCache.put("__style", style); - return style; - } - - public static String getJs() { - String cached = docsCache.get("__js"); - if (cached != null) { - return cached; - } - String js = ""; - InputStream is = As3PCodeDocs.class.getResourceAsStream("/com/jpexs/decompiler/flash/docs/docs.js"); - if (is == null) { - Logger.getLogger(As3PCodeDocs.class.getName()).log(Level.SEVERE, "docs.js needed for documentation not found"); - } else { - js = new String(Helper.readStream(is), Utf8Helper.charset); - } - - docsCache.put("__js", js); - return js; - } - - private static String getISO8601StringForDate(Date date) { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - return dateFormat.format(date); - } - - public static String getAllInstructionDocs() { - - String jsData = ""; - jsData += "var txt_filter_hide = \"" + getProperty("ui.filter.hide") + "\";" + NEWLINE; - jsData += "var txt_filter_byname = \"" + getProperty("ui.filter.byname") + "\";" + NEWLINE; - jsData += "var txt_filter_order = \"" + getProperty("ui.filter.order") + "\";" + NEWLINE; - jsData += "var txt_filter_order_code = \"" + getProperty("ui.filter.order.code") + "\";" + NEWLINE; - jsData += "var txt_filter_order_name = \"" + getProperty("ui.filter.order.name") + "\";" + NEWLINE; - - jsData += "var order_set = \"name\";"; - jsData += "var flags_set = {};" + NEWLINE; - jsData += "var flags = {};" + NEWLINE; - for (AVM2InstructionFlag f : AVM2InstructionFlag.values()) { - jsData += "flags[\"" + makeIdent(f.toString()) + "\"] = \"" + Helper.escapeJavaString(flagDescriptions.get(f)) + "\";" + NEWLINE; - jsData += "flags_set[\"" + makeIdent(f.toString()) + "\"] = false;" + NEWLINE; - } - - AVM2InstructionFlag[] hideFlags = new AVM2InstructionFlag[]{AVM2InstructionFlag.NO_FLASH_PLAYER}; - for (AVM2InstructionFlag f : hideFlags) { - jsData += "flags_set[\"" + makeIdent(f.toString()) + "\"] = true;" + NEWLINE; - } - - StringBuilder sb = new StringBuilder(); - sb.append(htmlHeader(jsData + getJs(), getStyle())); - sb.append("\t\t

").append(getProperty("ui.list.heading")).append("

").append(NEWLINE); - sb.append(""); - sb.append("\t\t
    ").append(NEWLINE); - Set s = new TreeSet<>(nameToDef.keySet()); - for (String name : s) { - InstructionDefinition def = nameToDef.get(name); - if (def == null) { - continue; - } - sb.append("\t\t\t
  • ").append(NEWLINE); - sb.append("\t\t\t\t").append(getDocsForIns(def, true, false, false).trim().replace(NEWLINE, NEWLINE + "\t\t\t\t")).append(NEWLINE); - sb.append("\t\t\t
  • ").append(NEWLINE); - } - sb.append("\t\t
").append(NEWLINE); - sb.append("\t").append(NEWLINE); - sb.append(htmlFooter()); - return sb.toString(); - } - - public static void main(String[] args) throws UnsupportedEncodingException { - System.out.println(getAllInstructionDocs()); - } -} +package com.jpexs.decompiler.flash.docs; + +import com.jpexs.decompiler.flash.ApplicationInfo; +import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2InstructionFlag; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.helpers.Cache; +import com.jpexs.helpers.Helper; +import com.jpexs.helpers.utf8.Utf8Helper; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Generator for AVM2 instruction set documentation. + * + * @author JPEXS + */ +public class As3PCodeDocs { + + private static ResourceBundle prop; + + private static Map flagDescriptions = new HashMap<>(); + + private static Cache docsCache = Cache.getInstance(false, true, "as3DocsCache"); + + private static Map nameToDef = new HashMap<>(); + + static final String NEWLINE = "\r\n"; + + static { + prop = ResourceBundle.getBundle("com.jpexs.decompiler.flash.locales.docs.pcode.AS3"); + for (InstructionDefinition def : AVM2Code.allInstructionSet) { + if (def == null) { + continue; + } + nameToDef.put(def.instructionName, def); + } + + for (AVM2InstructionFlag flg : AVM2InstructionFlag.values()) { + String flagIdent = makeIdent(flg.toString()); + String flagDescription = getProperty("instructionFlag." + flagIdent); + flagDescriptions.put(flg, flagDescription); + } + } + + private static String makeIdent(String name) { + StringBuilder identName = new StringBuilder(); + boolean cap = false; + for (int i = 0; i < name.length(); i++) { + char c = name.charAt(i); + if (c == '_') { + cap = true; + continue; + } + if (cap) { + identName.append(c); + cap = false; + } else { + identName.append(Character.toLowerCase(c)); + } + } + return identName.toString(); + } + + public static String getDocsForIns(String insName, boolean showDataSize, boolean ui, boolean withStyle) { + if (!nameToDef.containsKey(insName)) { + return null; + } + return getDocsForIns(nameToDef.get(insName), showDataSize, ui, withStyle); + } + + private static String getProperty(String name) { + if (prop.containsKey(name)) { + return Helper.escapeHTML(prop.getString(name)); + } + return null; + } + + private static String htmlFooter() { + StringBuilder sb = new StringBuilder(); + + sb.append(""); + return sb.toString(); + } + + private static String meta(String name, String content) { + return "\t\t" + NEWLINE; + } + + private static String metaProp(String name, String content) { + return "\t\t" + NEWLINE; + } + + private static String meta(String name, Date content) { + return "\t\t" + NEWLINE; + } + + private static String htmlHeader(String js, String style) { + Date dateGenerated = new Date(); + StringBuilder sb = new StringBuilder(); + sb.append("").append(NEWLINE). + append("").append(NEWLINE). + append("\t").append(NEWLINE); + if (style != null && !style.isEmpty()) { + sb.append("\t\t").append(NEWLINE); + } + if (js != null && !js.isEmpty()) { + sb.append("\t\t").append(NEWLINE); + } + sb.append("\t\t").append(NEWLINE). + append(meta("generator", ApplicationInfo.applicationVerName)). + append(meta("description", getProperty("ui.list.pageDescription"))). + append(metaProp("og:title", getProperty("ui.list.pageTitle"))). + append(metaProp("og:type", "article")). + append(metaProp("og:description", getProperty("ui.list.pageDescription"))). + append(meta("date", dateGenerated)). + append("\t\t").append(getProperty("ui.list.documentTitle")).append("").append(NEWLINE). + append("\t").append(NEWLINE); + return sb.toString(); + } + + public static String getDocsForIns(InstructionDefinition def, boolean showDataSize, boolean ui, boolean standalone) { + final String cacheKey = def.instructionName + "|" + (showDataSize ? 1 : 0) + "|" + (ui ? 1 : 0) + "|" + (standalone ? 1 : 0); + String v = docsCache.get(cacheKey); + if (v != null) { + return v; + } + + StringBuilder sb = new StringBuilder(); + if (standalone) { + sb.append(htmlHeader("", getStyle())); + } + String insName = def.instructionName; + + String insShortDescription = getProperty("instruction." + insName + ".shortDescription"); + String insDescription = getProperty("instruction." + insName + ".description"); + String stackBefore = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? "" : getProperty("instruction." + insName + ".stackBefore"); + String stackAfter = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? "" : getProperty("instruction." + insName + ".stackAfter"); + if (stackBefore.trim().isEmpty()) { + stackBefore = getProperty("ui.stack.before.empty"); + } else { + stackBefore = getProperty("ui.stack.before") + stackBefore; + } + if (stackAfter.trim().isEmpty()) { + stackAfter = getProperty("ui.stack.before.empty"); + } else { + stackAfter = getProperty("ui.stack.before") + stackAfter; + } + stackBefore = "" + stackBefore + ""; + stackAfter = "" + stackAfter + ""; + + String stack = def.hasFlag(AVM2InstructionFlag.UNKNOWN_STACK) ? getProperty("ui.unknown") : stackBefore + "" + getProperty("ui.stack.to") + "" + stackAfter; + String operandsDoc = def.hasFlag(AVM2InstructionFlag.UNKNOWN_OPERANDS) ? getProperty("ui.unknown") : getProperty("instruction." + insName + ".operands"); + + sb.append("<"); + sb.append(standalone ? "body" : "div"); + sb.append(" class=\"instruction"); + + for (AVM2InstructionFlag fl : def.flags) { + sb.append(" instruction-flag-").append(makeIdent(fl.toString())); + } + sb.append("\">"); + + sb.append("
").append(String.format("0x%02X", def.instructionCode)).append(" ").append(insName).append(""); + + if (def.hasFlag(AVM2InstructionFlag.UNKNOWN_OPERANDS)) { + sb.append(" ").append(getProperty("ui.unknown")).append(NEWLINE); + } else { + String[] operandsDocs = operandsDoc.split(", ?"); + boolean first = true; + if (def.operands.length > 0) { + sb.append(" "); + } + for (int i = 0; i < def.operands.length; i++) { + int op = def.operands[i]; + String opDoc = operandsDocs[i]; + String operandTypeRaw = AVM2Code.operandTypeToString(op, false); + String operandTypeCombined = AVM2Code.operandTypeToString(op, true); + if (operandTypeCombined.contains(", ")) { + String[] operandTypesCombined = operandTypeCombined.split(", ?"); + String[] operandTypesRaw = operandTypeRaw.split(", ?"); + + for (int j = 0; j < operandTypesCombined.length; j++) { + if (!first) { + sb.append(", "); + } else { + first = false; + } + opDoc = operandsDocs[i + j]; + operandTypeCombined = operandTypesCombined[j]; + operandTypeRaw = operandTypesRaw[j]; + operandTypeRaw = getProperty("operandType." + operandTypeRaw + (ui ? ".uiName" : ".name")); + if (opDoc.equals("...")) { + sb.append("..."); + } else { + sb.append(opDoc); + sb.append(":").append(showDataSize ? operandTypeCombined : operandTypeRaw); + } + } + } else { + if (!first) { + sb.append(", "); + } else { + first = false; + } + operandTypeRaw = getProperty("operandType." + operandTypeRaw + (ui ? ".uiName" : ".name")); + + if (opDoc.equals(operandTypeRaw)) { + sb.append(showDataSize ? operandTypeCombined : operandTypeRaw); + } else { + sb.append(opDoc).append(":").append(showDataSize ? operandTypeCombined : operandTypeRaw); + } + } + } + } + sb.append("
").append(NEWLINE); + + sb.append("
").append(insShortDescription).append("
").append(NEWLINE); + + if (!insDescription.trim().isEmpty()) { + sb.append("
").append("").append(getProperty("ui.description")).append("").append(insDescription).append("
").append(NEWLINE); + } + sb.append("
").append(getProperty("ui.stack")).append("").append(stack).append("").append("
").append(NEWLINE); + boolean flagsPrinted = false; + + AVM2InstructionFlag[] flags = def.flags.clone(); + Arrays.sort(flags, Enum::compareTo); + + for (AVM2InstructionFlag fl : flags) { + if (!flagsPrinted) { + flagsPrinted = true; + sb.append("").append(getProperty("ui.flags")).append("").append("
").append(NEWLINE).append("
    ").append(NEWLINE); + } + sb.append("\t
  • ").append(flagDescriptions.get(fl)); + if (fl == AVM2InstructionFlag.DEPRECATED) { + String depDetail = getProperty("instruction." + insName + ".deprecated"); + if (depDetail != null) { + sb.append(": ").append(depDetail).append(""); + } + } + sb.append("
  • ").append(NEWLINE); + } + if (flagsPrinted) { + sb.append("
").append(NEWLINE); + } + sb.append("").append(NEWLINE); + if (standalone) { + sb.append(htmlFooter()); + } + String r = sb.toString(); + docsCache.put(cacheKey, r); + return r; + } + + public static String getStyle() { + String cached = docsCache.get("__style"); + if (cached != null) { + return cached; + } + String style = ""; + InputStream is = As3PCodeDocs.class.getResourceAsStream("/com/jpexs/decompiler/flash/docs/docs.css"); + if (is == null) { + Logger.getLogger(As3PCodeDocs.class.getName()).log(Level.SEVERE, "docs.css needed for documentation not found"); + } else { + style = new String(Helper.readStream(is), Utf8Helper.charset); + } + + docsCache.put("__style", style); + return style; + } + + public static String getJs() { + String cached = docsCache.get("__js"); + if (cached != null) { + return cached; + } + String js = ""; + InputStream is = As3PCodeDocs.class.getResourceAsStream("/com/jpexs/decompiler/flash/docs/docs.js"); + if (is == null) { + Logger.getLogger(As3PCodeDocs.class.getName()).log(Level.SEVERE, "docs.js needed for documentation not found"); + } else { + js = new String(Helper.readStream(is), Utf8Helper.charset); + } + + docsCache.put("__js", js); + return js; + } + + private static String getISO8601StringForDate(Date date) { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + return dateFormat.format(date); + } + + public static String getAllInstructionDocs() { + + String jsData = ""; + jsData += "var txt_filter_hide = \"" + getProperty("ui.filter.hide") + "\";" + NEWLINE; + jsData += "var txt_filter_byname = \"" + getProperty("ui.filter.byname") + "\";" + NEWLINE; + jsData += "var txt_filter_order = \"" + getProperty("ui.filter.order") + "\";" + NEWLINE; + jsData += "var txt_filter_order_code = \"" + getProperty("ui.filter.order.code") + "\";" + NEWLINE; + jsData += "var txt_filter_order_name = \"" + getProperty("ui.filter.order.name") + "\";" + NEWLINE; + + jsData += "var order_set = \"name\";"; + jsData += "var flags_set = {};" + NEWLINE; + jsData += "var flags = {};" + NEWLINE; + for (AVM2InstructionFlag f : AVM2InstructionFlag.values()) { + jsData += "flags[\"" + makeIdent(f.toString()) + "\"] = \"" + Helper.escapeJavaString(flagDescriptions.get(f)) + "\";" + NEWLINE; + jsData += "flags_set[\"" + makeIdent(f.toString()) + "\"] = false;" + NEWLINE; + } + + AVM2InstructionFlag[] hideFlags = new AVM2InstructionFlag[]{AVM2InstructionFlag.NO_FLASH_PLAYER}; + for (AVM2InstructionFlag f : hideFlags) { + jsData += "flags_set[\"" + makeIdent(f.toString()) + "\"] = true;" + NEWLINE; + } + + StringBuilder sb = new StringBuilder(); + sb.append(htmlHeader(jsData + getJs(), getStyle())); + sb.append("\t\t

").append(getProperty("ui.list.heading")).append("

").append(NEWLINE); + sb.append(""); + sb.append("\t\t
    ").append(NEWLINE); + Set s = new TreeSet<>(nameToDef.keySet()); + for (String name : s) { + InstructionDefinition def = nameToDef.get(name); + if (def == null) { + continue; + } + sb.append("\t\t\t
  • ").append(NEWLINE); + sb.append("\t\t\t\t").append(getDocsForIns(def, true, false, false).trim().replace(NEWLINE, NEWLINE + "\t\t\t\t")).append(NEWLINE); + sb.append("\t\t\t
  • ").append(NEWLINE); + } + sb.append("\t\t
").append(NEWLINE); + sb.append("\t").append(NEWLINE); + sb.append(htmlFooter()); + return sb.toString(); + } + + public static void main(String[] args) throws UnsupportedEncodingException { + System.out.println(getAllInstructionDocs()); + } +}