diff --git a/jode/jode/Decompiler.java b/jode/jode/Decompiler.java index 91f43eb..82c9042 100644 --- a/jode/jode/Decompiler.java +++ b/jode/jode/Decompiler.java @@ -25,6 +25,12 @@ public class Decompiler { public final static String email = "jochen@gnu.org"; public final static String copyright = "Jode (c) 1998,1999 Jochen Hoenicke <"+email+">"; + + public final static int TAB_SIZE_MASK = 0x0f; + public final static int BRACE_AT_EOL = 0x10; + public final static int SUN_STYLE = 0x14; + public final static int GNU_STYLE = 0x02; + public static PrintStream err = System.err; public static boolean isVerbose = false; public static boolean isDebugging = false; @@ -36,6 +42,7 @@ public class Decompiler { public static boolean doChecks = false; public static boolean prettyLocals = false; public static boolean immediateOutput = false; + public static int outputStyle = SUN_STYLE; public static int importPackageLimit = 3; public static int importClassLimit = 3; @@ -58,6 +65,8 @@ public class Decompiler { "use `pretty' names for local variables."); err.println("\t--cp "+ "search for classes in specified classpath."); + err.println("\t--style {sun|gnu}"+ + " specifies indentation style"); err.println("\t--import "); err.println("\t "+ "import classes used more than clslimit times"); @@ -108,7 +117,18 @@ public class Decompiler { doChecks = true; else if (params[i].equals("--pretty")) prettyLocals = true; - else if (params[i].equals("--import")) { + else if (params[i].equals("--style")) { + String style = params[++i]; + if (style.equals("sun")) + outputStyle = SUN_STYLE; + else if (style.equals("gnu")) + outputStyle = GNU_STYLE; + else { + err.println("Unknown style: "+style); + usage(); + return; + } + } else if (params[i].equals("--import")) { importPackageLimit = Integer.parseInt(params[++i]); importClassLimit = Integer.parseInt(params[++i]); } else if (params[i].equals("--cp")) { @@ -131,7 +151,7 @@ public class Decompiler { JodeEnvironment env = new JodeEnvironment(classPath); TabbedPrintWriter writer = null; if (destDir == null) - writer = new TabbedPrintWriter(System.out, " "); + writer = new TabbedPrintWriter(System.out); for (; i< params.length; i++) { try { if (destDir != null) { @@ -140,11 +160,11 @@ public class Decompiler { params[i].replace('.', File.separatorChar)+".java"); File directory = new File(file.getParent()); if (!directory.exists() && !directory.mkdirs()) { - err.println("Could not create directory "+directory.getPath()+", " + err.println("Could not create directory " + +directory.getPath()+", " +"check permissions."); } - writer = new TabbedPrintWriter - (new FileOutputStream(file), " "); + writer = new TabbedPrintWriter(new FileOutputStream(file)); } env.doClass(params[i], writer); } catch (IOException ex) { diff --git a/jode/jode/decompiler/TabbedPrintWriter.java b/jode/jode/decompiler/TabbedPrintWriter.java index 475fb25..57a8df4 100644 --- a/jode/jode/decompiler/TabbedPrintWriter.java +++ b/jode/jode/decompiler/TabbedPrintWriter.java @@ -22,46 +22,119 @@ import java.io.*; public class TabbedPrintWriter { boolean atbol; - String tabstr; - StringBuffer indent; + int indentsize; + int currentIndent = 0; + String indentStr = ""; PrintWriter pw; - public TabbedPrintWriter (OutputStream os, String tabstr) { - pw = new PrintWriter(os); - this.tabstr=tabstr; - indent = new StringBuffer(); + public TabbedPrintWriter (OutputStream os) { + pw = new PrintWriter(os, true); + this.indentsize = (Decompiler.outputStyle & Decompiler.TAB_SIZE_MASK); atbol = true; } - public TabbedPrintWriter (Writer os, String tabstr) { - pw = new PrintWriter(os); - this.tabstr=tabstr; - indent = new StringBuffer(); + public TabbedPrintWriter (Writer os) { + pw = new PrintWriter(os, true); + this.indentsize = (Decompiler.outputStyle & Decompiler.TAB_SIZE_MASK); atbol = true; } + /** + * Convert the numeric indentation to a string. + */ + public void makeIndentStr() { + int tabs = (currentIndent >> 3); + // This is a very fast implementation. + if (tabs <= 20) + indentStr = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t " + .substring(20 - tabs, 20 + (currentIndent&7)); + else { + /* the slow way */ + StringBuffer sb = new StringBuffer(tabs+7); + while (tabs > 20) { + sb.append("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"); + tabs -= 20; + } + sb.append("\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t " + .substring(20 - tabs, tabs + (currentIndent&7))); + indentStr = sb.toString(); + } + } + public void tab() { - indent.append(tabstr); + currentIndent += indentsize; + makeIndentStr(); } public void untab() { - indent.setLength(indent.length()-tabstr.length()); + currentIndent -= indentsize; + makeIndentStr(); } - public void println(String str) throws java.io.IOException { - if (atbol) { - pw.print(indent); - } + private String newline = System.getProperty("line.separator"); + +// public void write(String str) { +// if (atbol) +// super.write(indentStr); +// super.write(str); +// atbol = (str.equals(newline)); +// } + + public void println(String str) { + if (atbol) + pw.print(indentStr); pw.println(str); - pw.flush(); atbol = true; } - public void print(String str) throws java.io.IOException { - if (atbol) { - pw.print(indent); - } + public void println() { + pw.println(); + atbol = true; + } + + public void print(String str) { + if (atbol) + pw.print(indentStr); pw.print(str); atbol = false; } + + /** + * Print a opening brace with the current indentation style. + * Called at the end of the line of the instance that opens the + * brace. It doesn't do a tab stop after opening the brace. + */ + public void openBrace() { + if ((Decompiler.outputStyle & Decompiler.BRACE_AT_EOL) != 0) + if (atbol) + println("{"); + else + println(" {"); + else { + println(); + if (currentIndent > 0) + tab(); + println("{"); + } + } + + public void closeBraceContinue() { + if ((Decompiler.outputStyle & Decompiler.BRACE_AT_EOL) != 0) + print("} "); + else { + println("}"); + if (currentIndent > 0) + untab(); + } + } + + public void closeBrace() { + if ((Decompiler.outputStyle & Decompiler.BRACE_AT_EOL) != 0) + println("}"); + else { + println("}"); + if (currentIndent > 0) + untab(); + } + } }