@ -46,6 +46,7 @@ public class Main extends Options {
new LongOpt ( "cp" , LongOpt . REQUIRED_ARGUMENT , null , 'c' ) ,
new LongOpt ( "cp" , LongOpt . REQUIRED_ARGUMENT , null , 'c' ) ,
new LongOpt ( "classpath" , LongOpt . REQUIRED_ARGUMENT , null , 'c' ) ,
new LongOpt ( "classpath" , LongOpt . REQUIRED_ARGUMENT , null , 'c' ) ,
new LongOpt ( "dest" , LongOpt . REQUIRED_ARGUMENT , null , 'd' ) ,
new LongOpt ( "dest" , LongOpt . REQUIRED_ARGUMENT , null , 'd' ) ,
new LongOpt ( "keep-going" , LongOpt . NO_ARGUMENT , null , 'k' ) ,
new LongOpt ( "help" , LongOpt . NO_ARGUMENT , null , 'h' ) ,
new LongOpt ( "help" , LongOpt . NO_ARGUMENT , null , 'h' ) ,
new LongOpt ( "version" , LongOpt . NO_ARGUMENT , null , 'V' ) ,
new LongOpt ( "version" , LongOpt . NO_ARGUMENT , null , 'V' ) ,
new LongOpt ( "verbose" , LongOpt . OPTIONAL_ARGUMENT , null , 'v' ) ,
new LongOpt ( "verbose" , LongOpt . OPTIONAL_ARGUMENT , null , 'v' ) ,
@ -102,6 +103,10 @@ public class Main extends Options {
"and packages with more then pkglimit used classes." ) ;
"and packages with more then pkglimit used classes." ) ;
err . println ( " " +
err . println ( " " +
"Limit 0 means never import. Default is 0,1." ) ;
"Limit 0 means never import. Default is 0,1." ) ;
err . println ( " -k, --keep-going " +
"After an error continue to decompile the other classes." ) ;
err . println ( " " +
"after an error decompiling one of them." ) ;
}
}
public static boolean handleOption ( int option , int longind , String arg ) {
public static boolean handleOption ( int option , int longind , String arg ) {
@ -120,11 +125,11 @@ public class Main extends Options {
return true ;
return true ;
}
}
public static void decompileClass ( String className , ClassPath classPath ,
public static boolean decompileClass
( String className , ClassPath classPath ,
String classPathStr ,
String classPathStr ,
ZipOutputStream destZip , String destDir ,
ZipOutputStream destZip , String destDir ,
TabbedPrintWriter writer ,
TabbedPrintWriter writer , ImportHandler imports ) {
ImportHandler imports ) {
try {
try {
ClassInfo clazz ;
ClassInfo clazz ;
try {
try {
@ -132,10 +137,10 @@ public class Main extends Options {
} catch ( IllegalArgumentException ex ) {
} catch ( IllegalArgumentException ex ) {
GlobalOptions . err . println
GlobalOptions . err . println
( "`" + className + "' is not a class name" ) ;
( "`" + className + "' is not a class name" ) ;
return ;
return false ;
}
}
if ( skipClass ( clazz ) )
if ( skipClass ( clazz ) )
return ;
return true ;
String filename =
String filename =
className . replace ( '.' , File . separatorChar ) + ".java" ;
className . replace ( '.' , File . separatorChar ) + ".java" ;
@ -167,21 +172,43 @@ public class Main extends Options {
writer . close ( ) ;
writer . close ( ) ;
/* Now is a good time to clean up */
/* Now is a good time to clean up */
System . gc ( ) ;
System . gc ( ) ;
return true ;
} catch ( FileNotFoundException ex ) {
} catch ( FileNotFoundException ex ) {
GlobalOptions . err . println
GlobalOptions . err . println
( "Can't read " + ex . getMessage ( ) + "." ) ;
( "Can't read " + ex . getMessage ( ) + "." ) ;
GlobalOptions . err . println
GlobalOptions . err . println
( "Check the class path (" + classPathStr +
( "Check the class path (" + classPathStr +
") and check that you use the java class name." ) ;
") and check that you use the java class name." ) ;
return false ;
} catch ( ClassFormatException ex ) {
} catch ( ClassFormatException ex ) {
GlobalOptions . err . println
GlobalOptions . err . println
( "Error while reading " + className + "." ) ;
( "Error while reading " + className + "." ) ;
ex . printStackTrace ( GlobalOptions . err ) ;
ex . printStackTrace ( GlobalOptions . err ) ;
return false ;
} catch ( IOException ex ) {
} catch ( IOException ex ) {
GlobalOptions . err . println
GlobalOptions . err . println
( "Can't write source of " + className + "." ) ;
( "Can't write source of " + className + "." ) ;
GlobalOptions . err . println ( "Check the permissions." ) ;
GlobalOptions . err . println ( "Check the permissions." ) ;
ex . printStackTrace ( GlobalOptions . err ) ;
ex . printStackTrace ( GlobalOptions . err ) ;
return false ;
} catch ( RuntimeException ex ) {
GlobalOptions . err . println
( "Error whilst decompiling " + className + "." ) ;
ex . printStackTrace ( GlobalOptions . err ) ;
return false ;
} catch ( InternalError ex ) {
/ * InternalError should not normally be
* caught , however we catch it here because
* some parts of JODE
* ( e . g . TransformExceptionHandlers . analyze ( ) )
* throw it .
* TODO : Replace InternalError with something else in
* places they can actually be thrown
* /
GlobalOptions . err . println
( "Internal error whilst decompiling " + className + "." ) ;
ex . printStackTrace ( GlobalOptions . err ) ;
return false ;
}
}
}
}
@ -223,11 +250,12 @@ public class Main extends Options {
int importClassLimit = ImportHandler . DEFAULT_CLASS_LIMIT ; ;
int importClassLimit = ImportHandler . DEFAULT_CLASS_LIMIT ; ;
int outputStyle = TabbedPrintWriter . BRACE_AT_EOL ;
int outputStyle = TabbedPrintWriter . BRACE_AT_EOL ;
int indentSize = 4 ;
int indentSize = 4 ;
boolean keepGoing = false ;
GlobalOptions . err . println ( GlobalOptions . copyright ) ;
GlobalOptions . err . println ( GlobalOptions . copyright ) ;
boolean errorInParams = false ;
boolean errorInParams = false ;
Getopt g = new Getopt ( "net.sf.jode.decompiler.Main" , params , "hVvc:d:D:i:s:" ,
Getopt g = new Getopt ( "net.sf.jode.decompiler.Main" , params , "hVvk c:d:D:i:s:" ,
longOptions , true ) ;
longOptions , true ) ;
for ( int opt = g . getopt ( ) ; opt ! = - 1 ; opt = g . getopt ( ) ) {
for ( int opt = g . getopt ( ) ; opt ! = - 1 ; opt = g . getopt ( ) ) {
switch ( opt ) {
switch ( opt ) {
@ -246,6 +274,9 @@ public class Main extends Options {
case 'd' :
case 'd' :
destDir = g . getOptarg ( ) ;
destDir = g . getOptarg ( ) ;
break ;
break ;
case 'k' :
keepGoing = true ;
break ;
case 'v' : {
case 'v' : {
String arg = g . getOptarg ( ) ;
String arg = g . getOptarg ( ) ;
if ( arg = = null )
if ( arg = = null )
@ -364,15 +395,22 @@ public class Main extends Options {
if ( entry . endsWith ( ".class" ) ) {
if ( entry . endsWith ( ".class" ) ) {
entry = entry . substring ( 0 , entry . length ( ) - 6 )
entry = entry . substring ( 0 , entry . length ( ) - 6 )
. replace ( '/' , '.' ) ;
. replace ( '/' , '.' ) ;
decompileClass ( entry , zipClassPath , classPathStr ,
if ( ! decompileClass ( entry , zipClassPath ,
classPathStr ,
destZip , destDir ,
destZip , destDir ,
writer , imports ) ;
writer , imports )
& & ! keepGoing )
break ;
}
}
}
}
} else
} else {
decompileClass ( params [ i ] , classPath , classPathStr ,
if ( ! decompileClass ( params [ i ] , classPath ,
classPathStr ,
destZip , destDir ,
destZip , destDir ,
writer , imports ) ;
writer , imports )
& & ! keepGoing )
break ;
}
} catch ( IOException ex ) {
} catch ( IOException ex ) {
GlobalOptions . err . println
GlobalOptions . err . println
( "Can't read zip file " + params [ i ] + "." ) ;
( "Can't read zip file " + params [ i ] + "." ) ;