This patch makes gjavah have the same behaviour as OpenJDK's javah in producing header files for any inner classes found in the classes being parsed.
ChangeLog: 2011-09-09 Andrew John Hughes <ahug...@redhat.com> PR classpath/45526: Produce header files for any inner classes found. * tools/gnu/classpath/tools/javah/Main.java: (parsed): Set of class names that have been parsed. (writeHeader(Map,Printer)): Take a general Map rather than a specific HashMap. (parseClasses(Iterator<Object>)): Factor out the parsing of class files into a separate method so it can be called recursively for inner classes. (getClass(String)): Remove redundant cast. -- Andrew :) Free Java Software Engineer Red Hat, Inc. (http://www.redhat.com) Support Free Java! Contribute to GNU Classpath and IcedTea http://www.gnu.org/software/classpath http://icedtea.classpath.org PGP Key: F5862A37 (https://keys.indymedia.org/) Fingerprint = EA30 D855 D50F 90CD F54D 0698 0713 C3ED F586 2A37
Index: tools/gnu/classpath/tools/javah/Main.java =================================================================== RCS file: /sources/classpath/classpath/tools/gnu/classpath/tools/javah/Main.java,v retrieving revision 1.13 diff -u -u -r1.13 Main.java --- tools/gnu/classpath/tools/javah/Main.java 3 Jun 2010 19:14:37 -0000 1.13 +++ tools/gnu/classpath/tools/javah/Main.java 9 Sep 2011 04:59:31 -0000 @@ -58,9 +58,11 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.Set; import java.util.Map; import org.objectweb.asm.ClassReader; +import org.objectweb.asm.tree.InnerClassNode; public class Main { @@ -101,6 +103,9 @@ // Map class names to lists of Text objects. HashMap<String,ArrayList<Text>> textMap = new HashMap<String,ArrayList<Text>>(); + // Set of classes which have been parsed + Set<String> parsed = new HashSet<String>(); + void readCommandFile(String textFileName) throws OptionException { FileInputStream fis; @@ -317,7 +322,7 @@ return result; } - private void writeHeaders(HashMap<File,ClassWrapper> klasses, Printer printer) + private void writeHeaders(Map<File,ClassWrapper> klasses, Printer printer) throws IOException { Iterator<Map.Entry<File,ClassWrapper>> i = klasses.entrySet().iterator(); @@ -332,6 +337,53 @@ } } + private Map<File,ClassWrapper> parseClasses(Iterator<Object> inputs) + throws IOException + { + Map<File,ClassWrapper> results = new HashMap<File,ClassWrapper>(); + while (inputs.hasNext()) + { + // Let user specify either kind of class name or a + // file name. + Object item = inputs.next(); + ClassWrapper klass; + File filename; + if (item instanceof File) + { + // Load class from file. + if (verbose) + System.err.println("[reading file " + item + "]"); + klass = getClass((File) item); + filename = new File(klass.name); + } + else + { + // Load class given the class name. + String className = ((String) item).replace('.', '/'); + if (verbose) + System.err.println("[reading class " + className + "]"); + // Use the name the user specified, even if it is + // different from the ultimate class name. + filename = new File(className); + klass = getClass(className); + } + results.put(filename, klass); + parsed.add(item.toString()); + + // Check to see if there are inner classes to also parse + Iterator<?> innerClasses = klass.innerClasses.iterator(); + HashSet<Object> innerNames = new HashSet<Object>(); + while (innerClasses.hasNext()) + { + String innerName = ((InnerClassNode) innerClasses.next()).name; + if (!parsed.contains(innerName)) + innerNames.add(innerName); + } + results.putAll(parseClasses(innerNames.iterator())); + } + return results; + } + protected void postParse(String[] names) { // Nothing here. @@ -385,40 +437,12 @@ } } - Iterator<Object> i = klasses.iterator(); - HashMap<File,ClassWrapper> results = new HashMap<File,ClassWrapper>(); - while (i.hasNext()) - { - // Let user specify either kind of class name or a - // file name. - Object item = i.next(); - ClassWrapper klass; - File filename; - if (item instanceof File) - { - // Load class from file. - if (verbose) - System.err.println("[reading file " + item + "]"); - klass = getClass((File) item); - filename = new File(klass.name); - } - else - { - // Load class given the class name. - String className = ((String) item).replace('.', '/'); - if (verbose) - System.err.println("[reading class " + className + "]"); - // Use the name the user specified, even if it is - // different from the ultimate class name. - filename = new File(className); - klass = getClass(className); - } - results.put(filename, klass); - } + Map<File, ClassWrapper> results = parseClasses(klasses.iterator()); writeHeaders(results, printer); } + public ArrayList<Text> getClassTextList(String name) { return textMap.get(name); @@ -457,7 +481,7 @@ ClassWrapper result = readClass(is); classMap.put(name, result); } - return (ClassWrapper) classMap.get(name); + return classMap.get(name); } public static void main(String[] args) throws IOException