Browse Source

* first version of javapp that can create a compilable Pascal import
unit for at least java.lang.*, java.util.* java.io.* and java.security.*,
using the following command line paramters:
-a sun. -a com.sun. -a javax. -protected java.lang. java.util. java.io. java.security. -o java_base

git-svn-id: branches/jvmbackend@18405 -

Jonas Maebe 14 years ago
parent
commit
8199b2c6a9
29 changed files with 2704 additions and 616 deletions
  1. 9 0
      .gitattributes
  2. 4 2
      utils/javapp/src/fpc/tools/javapp/AttrData.java
  3. 4 1
      utils/javapp/src/fpc/tools/javapp/CPX.java
  4. 4 1
      utils/javapp/src/fpc/tools/javapp/CPX2.java
  5. 15 8
      utils/javapp/src/fpc/tools/javapp/ClassData.java
  6. 84 0
      utils/javapp/src/fpc/tools/javapp/ClassIdentifierInfo.java
  7. 71 0
      utils/javapp/src/fpc/tools/javapp/ClassListBuilder.java
  8. 4 1
      utils/javapp/src/fpc/tools/javapp/Constants.java
  9. 4 1
      utils/javapp/src/fpc/tools/javapp/FieldData.java
  10. 8 3
      utils/javapp/src/fpc/tools/javapp/InnerClassData.java
  11. 251 7
      utils/javapp/src/fpc/tools/javapp/JavapEnvironment.java
  12. 530 352
      utils/javapp/src/fpc/tools/javapp/JavapPrinter.java
  13. 4 1
      utils/javapp/src/fpc/tools/javapp/LineNumData.java
  14. 4 1
      utils/javapp/src/fpc/tools/javapp/LocVarData.java
  15. 359 167
      utils/javapp/src/fpc/tools/javapp/Main.java
  16. 64 47
      utils/javapp/src/fpc/tools/javapp/MethodData.java
  17. 426 0
      utils/javapp/src/fpc/tools/javapp/PascalClassData.java
  18. 74 0
      utils/javapp/src/fpc/tools/javapp/PascalFieldData.java
  19. 12 0
      utils/javapp/src/fpc/tools/javapp/PascalInnerClassData.java
  20. 95 0
      utils/javapp/src/fpc/tools/javapp/PascalKeywords.java
  21. 79 0
      utils/javapp/src/fpc/tools/javapp/PascalMethodData.java
  22. 100 0
      utils/javapp/src/fpc/tools/javapp/PascalTypeSignature.java
  23. 410 0
      utils/javapp/src/fpc/tools/javapp/PascalUnit.java
  24. 4 1
      utils/javapp/src/fpc/tools/javapp/RuntimeConstants.java
  25. 5 2
      utils/javapp/src/fpc/tools/javapp/StackMapData.java
  26. 5 2
      utils/javapp/src/fpc/tools/javapp/StackMapTableData.java
  27. 4 1
      utils/javapp/src/fpc/tools/javapp/Tables.java
  28. 4 1
      utils/javapp/src/fpc/tools/javapp/TrapData.java
  29. 67 17
      utils/javapp/src/fpc/tools/javapp/TypeSignature.java

+ 9 - 0
.gitattributes

@@ -12907,6 +12907,8 @@ utils/javapp/src/fpc/tools/javapp/AttrData.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/CPX.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/CPX2.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/ClassData.java svneol=native#text/plain
+utils/javapp/src/fpc/tools/javapp/ClassIdentifierInfo.java svneol=native#text/plain
+utils/javapp/src/fpc/tools/javapp/ClassListBuilder.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/Constants.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/FieldData.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/InnerClassData.java svneol=native#text/plain
@@ -12916,6 +12918,13 @@ utils/javapp/src/fpc/tools/javapp/LineNumData.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/LocVarData.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/Main.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/MethodData.java svneol=native#text/plain
+utils/javapp/src/fpc/tools/javapp/PascalClassData.java svneol=native#text/plain
+utils/javapp/src/fpc/tools/javapp/PascalFieldData.java svneol=native#text/plain
+utils/javapp/src/fpc/tools/javapp/PascalInnerClassData.java svneol=native#text/plain
+utils/javapp/src/fpc/tools/javapp/PascalKeywords.java svneol=native#text/plain
+utils/javapp/src/fpc/tools/javapp/PascalMethodData.java svneol=native#text/plain
+utils/javapp/src/fpc/tools/javapp/PascalTypeSignature.java svneol=native#text/plain
+utils/javapp/src/fpc/tools/javapp/PascalUnit.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/RuntimeConstants.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/StackMapData.java svneol=native#text/plain
 utils/javapp/src/fpc/tools/javapp/StackMapTableData.java svneol=native#text/plain

+ 4 - 2
utils/javapp/src/fpc/tools/javapp/AttrData.java

@@ -22,10 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.io.*;
 

+ 4 - 1
utils/javapp/src/fpc/tools/javapp/CPX.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 /**
  * Stores constant pool entry information with one field.

+ 4 - 1
utils/javapp/src/fpc/tools/javapp/CPX2.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 /**
  *  Stores constant pool entry information with two fields.

+ 15 - 8
utils/javapp/src/fpc/tools/javapp/ClassData.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;
@@ -41,23 +44,23 @@ public class ClassData implements RuntimeConstants {
     private int minor_version;
     private int major_version;
     private int cpool_count;
-    private Object cpool[];
-    private int access;
+    protected Object cpool[];
+    protected int access;
     private int this_class = 0;;
     private int super_class;
     private int interfaces_count;
     private int[] interfaces = new int[0];;
     private int fields_count;
-    private FieldData[] fields;
+    protected FieldData[] fields;
     private int methods_count;
-    private MethodData[] methods;
-    private InnerClassData[] innerClasses;
+    protected MethodData[] methods;
+    protected InnerClassData[] innerClasses;
     private int attributes_count;
     private AttrData[] attrs;
     private String classname;
     private String superclassname;
     private int source_cpx=0;
-    private byte tags[];
+    protected byte tags[];
     private Hashtable indexHashAscii = new Hashtable();
     private String pkgPrefix="";
     private int pkgPrefixLen=0;
@@ -79,6 +82,10 @@ public class ClassData implements RuntimeConstants {
         }
     }
 
+    protected InnerClassData NewInnerClassData() {
+    	return new InnerClassData(this);
+    }
+    
     /**
      * Reads and stores class file information.
      */
@@ -138,7 +145,7 @@ public class ClassData implements RuntimeConstants {
                            throw new ClassFormatError("invalid attr length");
                        innerClasses=new InnerClassData[num];
                        for (int j = 0; j < num; j++) {
-                           InnerClassData innerClass=new InnerClassData(this);
+                           InnerClassData innerClass=NewInnerClassData();
                            innerClass.read(in);
                            innerClasses[j]=innerClass;
                        }

+ 84 - 0
utils/javapp/src/fpc/tools/javapp/ClassIdentifierInfo.java

@@ -0,0 +1,84 @@
+package fpc.tools.javapp;
+
+import java.util.HashMap;
+
+public class ClassIdentifierInfo {
+	
+	protected static HashMap<String,ClassIdentifierInfo> identifierStore = new HashMap<String,ClassIdentifierInfo>();
+	
+	String[] superClasses;
+	HashMap<String,String> identifiers;
+
+	protected ClassIdentifierInfo(String[] superClasses) {
+		identifiers = new HashMap<String,String>();
+		this.superClasses = superClasses;
+	}
+	
+	public static void registerClassInfo(String className, String superClass, String[] superIntf) {
+		if (identifierStore.get(className) == null) {
+			String[] combinedSuperInfo;
+			if (superIntf.length==0) {
+				combinedSuperInfo = new String[superClass!=null?1:0];
+			} else {
+				combinedSuperInfo = new String[superIntf.length+1];
+				for (int i = 0; i < superIntf.length; i++)
+					combinedSuperInfo[i] = superIntf[i];
+			}
+			// also sets java.lang.Object for interfaces, but doesn't matter since those
+			// identifiers cannot be used by any class implementing this interface anyway
+			// (since they will inherit from java.lang.Interface)
+			if (superClass != null)
+				combinedSuperInfo[combinedSuperInfo.length-1] = superClass;
+			
+			ClassIdentifierInfo classIdInfo = new ClassIdentifierInfo(combinedSuperInfo);
+			identifierStore.put(className,classIdInfo);
+		}
+	}
+
+	private String checkSafeIdentifierName(String id) {
+		for (int i = 0; i < superClasses.length; i++) {
+			id = getSafeIdentifierNameForClass(superClasses[i],id);
+		}
+		id = PascalKeywords.escapeIfPascalKeyword(id);
+		String testName = id.toUpperCase();
+		String orgName;
+		if (id.indexOf('$') != -1) {
+			System.out.println("  Warning, cannot represent identifier '"+id+"', hiding");
+			id = id.replace("$","__");
+		}
+		while (((orgName = identifiers.get(testName)) != null) &&
+				!orgName.equals(id)) {
+			id = id + "_";
+			testName = testName + "_";
+		}
+		return id;
+	}
+
+	private String addIdentifier(String id) {
+		String testName = id.toUpperCase();
+		for (int i = 0; i < superClasses.length; i++) {
+			id = getSafeIdentifierNameForClass(superClasses[i],id);
+		}
+		id = checkSafeIdentifierName(id);
+		identifiers.put(testName, id);
+		return id;
+	}
+	
+	
+	public static String AddIdentifierNameForClass(String className, String identifier) {
+		ClassIdentifierInfo classIdInfo = identifierStore.get(className);
+		if (classIdInfo == null) {
+			throw new IllegalStateException("Class info for "+className+" not registered");
+		}
+		return classIdInfo.addIdentifier(identifier);
+	}
+	
+	public static String getSafeIdentifierNameForClass(String className, String identifier) {
+		ClassIdentifierInfo classIdInfo = identifierStore.get(className);
+		if (classIdInfo == null) {
+			throw new IllegalStateException("Class info for "+className+" not registered");
+		}
+		return classIdInfo.checkSafeIdentifierName(identifier);
+	}
+	
+}

+ 71 - 0
utils/javapp/src/fpc/tools/javapp/ClassListBuilder.java

@@ -0,0 +1,71 @@
+package fpc.tools.javapp;
+
+import java.io.File;  
+import java.io.IOException;
+import java.net.URL;  
+import java.util.ArrayList;  
+import java.util.Enumeration;
+import java.util.List;  
+  
+public class ClassListBuilder {  
+  
+    public static Class[] getClassesInPackage(String pckgname) {  
+        File directory = getPackageDirectory(pckgname);  
+        if (!directory.exists()) {  
+            throw new IllegalArgumentException("Could not get directory resource for package " + pckgname + ".");  
+        }  
+  
+        return getClassesInPackage(pckgname, directory);  
+    }  
+  
+    private static Class[] getClassesInPackage(String pckgname, File directory) {  
+        List<Class> classes = new ArrayList<Class>();  
+        for (String filename : directory.list()) {  
+            if (filename.endsWith(".class")) {  
+                String classname = buildClassname(pckgname, filename);  
+                try {  
+                    classes.add(Class.forName(classname));  
+                } catch (ClassNotFoundException e) {  
+                    System.err.println("Error creating class " + classname);  
+                }  
+            }  
+        }  
+        return classes.toArray(new Class[classes.size()]);  
+    }  
+  
+    private static String buildClassname(String pckgname, String filename) {  
+        return pckgname + '.' + filename.replace(".class", "");  
+    }  
+  
+    private static File getPackageDirectory(String pckgname) {  
+        ClassLoader cld = Thread.currentThread().getContextClassLoader();  
+        if (cld == null) {  
+            throw new IllegalStateException("Can't get class loader.");  
+        }
+        Enumeration<URL> resources;
+        try {
+        	resources = cld.getResources(pckgname.replace('.', '/'));
+        } catch (IOException e) {
+        	throw new IllegalStateException("can't get resourcs.");
+        }
+        System.out.println("Found any elements: "+resources.hasMoreElements());
+        while (resources.hasMoreElements()) {
+            System.out.println(resources.nextElement().getPath());
+        }
+        
+        URL resource = cld.getResource(pckgname.replace('.', '/'));  
+        if (resource == null) {  
+            throw new RuntimeException("Package " + pckgname + " not found on classpath.");  
+        }  
+  
+        return new File(resource.getFile());  
+    }  
+  /*
+    public static void main(String[] args) {  
+        Class[] classes = getClassesInPackage("com.mycomp");  
+        for (Class c : classes) {  
+            System.out.println("Found: " + c.getCanonicalName());  
+        }  
+    }  
+*/  
+}  

+ 4 - 1
utils/javapp/src/fpc/tools/javapp/Constants.java

@@ -22,10 +22,13 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 /**
  * This interface defines constant that are used

+ 4 - 1
utils/javapp/src/fpc/tools/javapp/FieldData.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;

+ 8 - 3
utils/javapp/src/fpc/tools/javapp/InnerClassData.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.io.*;
 import java.util.*;
@@ -63,9 +66,11 @@ class InnerClassData  implements RuntimeConstants {
      * Returns the access of this class or interface.
      */
     public String[] getAccess(){
-        Vector v = new Vector();
+        Vector<String> v = new Vector<String>();
         if ((access & ACC_PUBLIC)   !=0) v.addElement("public");
-        if ((access & ACC_FINAL)    !=0) v.addElement("final");
+        if ((access & ACC_PROTECTED)   !=0) v.addElement("protected");
+        if ((access & ACC_PRIVATE)    !=0) v.addElement("private");
+        if ((access & ACC_FINAL)   !=0) v.addElement("final");
         if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
         String[] accflags = new String[v.size()];
         v.copyInto(accflags);

+ 251 - 7
utils/javapp/src/fpc/tools/javapp/JavapEnvironment.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;
@@ -61,18 +64,23 @@ public class JavapEnvironment {
     // JavapEnvironment flag settings
     boolean showLineAndLocal = false;
     int showAccess = PACKAGE;
-    boolean showDisassembled = false;
     boolean showVerbose = false;
-    boolean showInternalSigs = false;
     String classPathString = null;
     String bootClassPathString = null;
     String extDirsString = null;
-    boolean extDirflag = false;
+    boolean extDirflag;
     boolean nothingToDo = true;
     boolean showallAttr = false;
     String classpath = null;
-    int searchpath = start;
+    String outputName = "java";
+    ArrayList<String> excludePrefixes;
+    ArrayList<String> skelPrefixes;
 
+    public JavapEnvironment() {
+    	excludePrefixes = new ArrayList<String>();
+    	skelPrefixes = new ArrayList<String>();
+    }
+    
     /**
      *  According to which flags are set,
      *  returns file input stream for classfile to disassemble.
@@ -80,7 +88,8 @@ public class JavapEnvironment {
 
     public InputStream getFileInputStream(String Name){
         InputStream fileInStream = null;
-        searchpath = cmdboot;
+        int searchpath = cmdboot;
+        extDirflag = false;
         try{
             if(searchpath == cmdboot){
                 if(bootClassPathString != null){
@@ -259,7 +268,7 @@ public class JavapEnvironment {
         }
         else return (resolveclasspathhelper(classpath, classname));
     }
-
+    
 
     /**
      * Returns file input stream for classfile to disassemble if exdir is set.
@@ -352,4 +361,239 @@ public class JavapEnvironment {
         }
         return null;
     }
+    
+    
+    
+    protected SortedSet<String> getJarEntries(String jarname) {
+    	SortedSet<String> res = new TreeSet<String>();
+
+    	try{
+    		JarFile jfile = new JarFile(jarname);
+    		Enumeration<JarEntry> entries = jfile.entries();
+    		while (entries.hasMoreElements()) {
+    			JarEntry entry = entries.nextElement();
+    			String name = entry.getName();    			
+    			int classpos = name.lastIndexOf(".class");
+    			if ((classpos != -1) &&
+    					!PascalClassData.isInnerClass(name.substring(0, classpos)) &&
+    					!entry.isDirectory()) {
+    				res.add(name.substring(0, classpos));
+    			}
+    		}
+    	}catch(FileNotFoundException fnexce){
+//    		fnexce.printStackTrace();
+//    		error("cant read file");
+//    		error("fatal exception");
+    	}catch(IOException ioexc){
+//    		ioexc.printStackTrace();
+//    		error("fatal exception");
+    	}
+    	return res;
+    }
+
+
+    protected SortedSet<String> getDirEntries(File fileobj, boolean includeJarEntries) {
+    	SortedSet<String> res = new TreeSet<String>();
+
+    	File[] filelist = fileobj.listFiles();
+    	for(int i = 0; i < filelist.length; i++){
+    		//file is a jar file.
+    		String fname = filelist[i].toString();
+    		if(includeJarEntries &&
+    				fname.endsWith(".jar")){
+    			res.addAll(getJarEntries(fname));
+    		}
+    		else if (fname.endsWith(".class")) {
+    			int classpos = fname.lastIndexOf(".class");
+    			if (classpos != -1)
+    				fname = fname.substring(0, classpos);
+    			if (!PascalClassData.isInnerClass(fname))
+    				res.add(fname);
+    		}
+    	}
+    	return res;
+    }
+
+    /**
+     * Returns list of non-nested classes found in a path
+     */
+    public SortedSet<String> getExdirEntries(String path){
+    	File fileobj = new File(path);
+    	if(fileobj.isDirectory()){
+    		return getDirEntries(fileobj,true);
+    	}
+    	return new TreeSet<String>();
+    }
+
+    
+    /**
+     * Returns list of non-nested classes found in class path
+     */
+    public SortedSet<String>  getClasspathEntries(String path){
+        File fileobj = new File(path);
+        if(fileobj.isDirectory()){
+        	return getDirEntries(fileobj, false);
+
+        }else if(fileobj.toString().endsWith(".jar")){
+        	return getJarEntries(fileobj.toString());
+        }
+        return new TreeSet<String>();
+    }
+
+    
+    /**
+     * Return a list of all non-nested classes in the currently set exdir classpath
+     */
+    public SortedSet<String> getAllExdirEntries(){
+    	SortedSet<String> res;
+        if(classpath.indexOf(File.pathSeparator) != -1){
+        	res = new TreeSet<String>();
+            //separates path
+            StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
+            while(st.hasMoreTokens()){
+                String path = st.nextToken();
+                res.addAll(getExdirEntries(path));
+            }
+        }else res = getExdirEntries(classpath);
+
+        return res;
+    }
+
+    /**
+     * Return a list of all non-nested classes in the currently set classpath
+     */
+    public SortedSet<String> getAllClasspathEntries(){
+    	SortedSet<String> res;
+        if(classpath.indexOf(File.pathSeparator) != -1){
+        	res = new TreeSet<String>();
+            StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
+            //separates path.
+            while(st.hasMoreTokens()){
+                String path = (st.nextToken()).trim();
+                res.addAll(getClasspathEntries(path));
+            }
+        }
+        else res = getClasspathEntries(classpath);
+        return res;
+    }
+
+
+    public SortedSet<String> getAllEntries(){
+    	if (extDirflag)
+    	  return getAllExdirEntries();
+    	else
+      	  return getAllClasspathEntries();
+    }
+    
+    
+    public SortedSet<String> getClassesList(){
+    	SortedSet<String> res = new TreeSet<String>();
+        int searchpath = cmdboot;
+        extDirflag = false;
+        try{
+            if(searchpath == cmdboot){
+                if(bootClassPathString != null){
+                    //search in specified bootclasspath.
+                    classpath = bootClassPathString;
+                    res.addAll(getAllEntries());
+                    searchpath = cmdextdir;
+                }
+                else searchpath = sunboot;
+            }
+
+            if(searchpath == sunboot){
+                if(System.getProperty("sun.boot.class.path") != null){
+                    //search in sun.boot.class.path
+                    classpath = System.getProperty("sun.boot.class.path");
+                    res.addAll(getAllEntries());
+                    searchpath = cmdextdir;
+                }
+                else searchpath = javaclass;
+            }
+
+            if(searchpath == javaclass){
+                if(System.getProperty("java.class.path") != null){
+                    //search in java.class.path
+                    classpath =System.getProperty("java.class.path");
+                    res.addAll(getAllEntries());
+                    searchpath = cmdextdir;
+                }
+                else searchpath = cmdextdir;
+            }
+
+            if(searchpath == cmdextdir){
+                if(extDirsString != null){
+                    //search in specified extdir.
+                    classpath = extDirsString;
+                    extDirflag = true;
+                    res.addAll(getAllEntries());
+                    searchpath = cmdclasspath;
+                    extDirflag = false;
+                }
+                else searchpath = javaext;
+            }
+
+            if(searchpath == javaext){
+                if(System.getProperty("java.ext.dirs") != null){
+                    //search in java.ext.dirs
+                    classpath = System.getProperty("java.ext.dirs");
+                    extDirflag = true;
+                    res.addAll(getAllEntries());
+                    searchpath = cmdclasspath;
+                    extDirflag = false;
+                }
+                else searchpath = cmdclasspath;
+            }
+            if(searchpath == cmdclasspath){
+                if(classPathString != null){
+                    //search in specified classpath.
+                    classpath = classPathString;
+                    res.addAll(getAllEntries());
+                    searchpath = 8;
+                }
+                else searchpath = envclasspath;
+            }
+
+            if(searchpath == envclasspath){
+                if(System.getProperty("env.class.path")!= null){
+                    //search in env.class.path
+                    classpath = System.getProperty("env.class.path");
+                    res.addAll(getAllEntries());
+                    searchpath = javaclasspath;
+                }
+                else searchpath = javaclasspath;
+            }
+
+            if(searchpath == javaclasspath){
+                if(("application.home") == null){
+                    //search in java.class.path
+                    classpath = System.getProperty("java.class.path");
+                    res.addAll(getAllEntries());
+                    searchpath = currentdir;
+                }
+                else searchpath = currentdir;
+            }
+
+            if(searchpath == currentdir){
+                classpath = ".";
+                //search in current dir.
+                res.addAll(getAllEntries());
+            }
+        }catch(SecurityException excsec){
+            excsec.printStackTrace();
+            error("fatal exception");
+        }catch(NullPointerException excnull){
+            excnull.printStackTrace();
+            error("fatal exception");
+        }catch(IllegalArgumentException excill){
+            excill.printStackTrace();
+            error("fatal exception");
+        }
+
+        return res;
+    }
+
+    
+
+    
 }

File diff suppressed because it is too large
+ 530 - 352
utils/javapp/src/fpc/tools/javapp/JavapPrinter.java


+ 4 - 1
utils/javapp/src/fpc/tools/javapp/LineNumData.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;

+ 4 - 1
utils/javapp/src/fpc/tools/javapp/LocVarData.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;

+ 359 - 167
utils/javapp/src/fpc/tools/javapp/Main.java

@@ -22,14 +22,21 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;
 
+import org.jgrapht.alg.CycleDetector;
+import org.jgrapht.graph.*;
+import org.jgrapht.traverse.*;
+
 /**
  * Entry point for javap, class file disassembler.
  *
@@ -37,180 +44,365 @@ import java.io.*;
  */
 public class Main{
 
-    private Vector classList = new Vector();
-    private PrintWriter out;
-    JavapEnvironment env = new JavapEnvironment();
-    private static boolean errorOccurred = false;
-    private static final String progname = "javap";
+	private ArrayList<String> pkgList = new ArrayList<String>();
+	JavapEnvironment env = new JavapEnvironment();
+	private static boolean errorOccurred = false;
+	private static final String progname = "javapp";
 
 
-    public Main(PrintWriter out){
-        this.out = out;
-    }
+	public Main(){
+	}
 
-    public static void main(String argv[]) {
-        entry(argv);
-        if (errorOccurred) {
-            System.exit(1);
-        }
-    }
+	public static void main(String argv[]) {
+		entry(argv);
+		if (errorOccurred) {
+			System.exit(1);
+		}
+	}
 
 
-    /**
-     * Entry point for tool if you don't want System.exit() called.
-     */
-    public static void entry(String argv[]) {
-        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
-        try {
+	/**
+	 * Entry point for tool if you don't want System.exit() called.
+	 */
+	public static void entry(String argv[]) {
+		Main jpmain = new Main();
+		jpmain.perform(argv);
+	}
 
-            Main jpmain = new Main(out);
-            jpmain.perform(argv);
+	/**
+	 * Process the arguments and perform the desired action
+	 */
+	private void perform(String argv[]) {
+		if (parseArguments(argv)) {
+			displayResults();
 
-        } finally {
-            out.close();
-        }
-    }
+		}
+	}
 
-    /**
-     * Process the arguments and perform the desired action
-     */
-    private void perform(String argv[]) {
-        if (parseArguments(argv)) {
-            displayResults();
+	private void error(String msg) {
+		errorOccurred = true;
+		System.err.println(msg);
+		System.err.flush();
+	}
 
+	/**
+	 * Print usage information
+	 */
+	private void usage() {
+		java.io.PrintStream out = System.out;
+		out.println("Usage: " + progname + " <options> [<packages>] [<individual_classes>]");
+		out.println("  Suffix package names with '.'");
+		out.println();
+		out.println("where options include:");
+		out.println("   -a <class_or_pkgename>    Create empty skeleton versions of these classes");
+		out.println("   -classpath <pathlist>     Specify where to find user class files");
+		out.println("   -help                     Print this usage message");
+		out.println("   -J<flag>                  Pass <flag> directly to the runtime system");
+		out.println("   -l                        Print line number and local variable tables");
+		out.println("   -o <output_base_name>     Base name of output unit (default: java");
+		out.println("   -public                   Print only public classes and members");
+		out.println("   -protected                Print protected/public classes and members");
+		out.println("   -private                  Show all classes and members");
+		out.println("   -x <class_or_pkgename>    Do not print a certain classes or package (suffix package names with '.'");
+		out.println("   -s                        Print internal type signatures");
+		out.println("   -bootclasspath <pathlist> Override location of class files loaded");
+		out.println("                             by the bootstrap class loader");
+		out.println("   -verbose                  Print stack size, number of locals and args for methods");
+		out.println("                             If verifying, print reasons for failure");
+		out.println();
+	}
+
+	/**
+	 * Parse the command line arguments.
+	 * Set flags, construct the class list and create environment.
+	 */
+	private boolean parseArguments(String argv[]) {
+		for (int i = 0 ; i < argv.length ; i++) {
+			String arg = argv[i];
+			if (arg.startsWith("-")) {
+				if (arg.equals("-l")) {
+					env.showLineAndLocal = true;
+				} else if (arg.equals("-private") || arg.equals("-p")) {
+					env.showAccess = env.PRIVATE;
+				} else if (arg.equals("-package")) {
+					env.showAccess = env.PACKAGE;
+				} else if (arg.equals("-protected")) {
+					env.showAccess = env.PROTECTED;
+				} else if (arg.equals("-public")) {
+					env.showAccess = env.PUBLIC;
+				} else if (arg.equals("-verbose"))  {
+					env.showVerbose = true;
+				} else if (arg.equals("-v")) {
+					env.showVerbose = true;
+				} else if (arg.equals("-h")) {
+					error("-h is no longer available - use the 'javah' program");
+					return false;
+				} else if (arg.equals("-verify")) {
+					error("-verify is no longer available - use 'java -verify'");
+					return false;
+				} else if (arg.equals("-verify-verbose")) {
+					error("-verify is no longer available - use 'java -verify'");
+					return false;
+				} else if (arg.equals("-help")) {
+					usage();
+					return false;
+				} else if (arg.equals("-classpath")) {
+					if ((i + 1) < argv.length) {
+						env.classPathString = argv[++i];
+					} else {
+						error("-classpath requires argument");
+						usage();
+						return false;
+					}
+				} else if (arg.equals("-bootclasspath")) {
+					if ((i + 1) < argv.length) {
+						env.bootClassPathString = argv[++i];
+					} else {
+						error("-bootclasspath requires argument");
+						usage();
+						return false;
+					}
+				} else if (arg.equals("-extdirs")) {
+					if ((i + 1) < argv.length) {
+						env.extDirsString = argv[++i];
+					} else {
+						error("-extdirs requires argument");
+						usage();
+						return false;
+					}
+				} else if (arg.equals("-o")) {
+					if ((i + 1) < argv.length) {
+						env.outputName = argv[++i];
+					} else {
+						error("-o requires argument");
+						usage();
+						return false;
+					}
+				} else if (arg.equals("-x")) {
+					if ((i + 1) < argv.length) {
+						env.excludePrefixes.add(argv[++i].replace('.','/'));
+					} else {
+						error("-x requires argument");
+						usage();
+						return false;
+					}
+				} else if (arg.equals("-a")) {
+					if ((i + 1) < argv.length) {
+						env.skelPrefixes.add(argv[++i].replace('.','/'));
+					} else {
+						error("-a requires argument");
+						usage();
+						return false;
+					}
+				} else if (arg.equals("-all")) {
+					env.showallAttr = true;
+				} else {
+					error("invalid flag: " + arg);
+					usage();
+					return false;
+				}
+			} else {
+				pkgList.add(arg);
+				env.nothingToDo = false;
+			}
+		}
+		if (env.nothingToDo) {
+			System.out.println("No classes were specified on the command line.  Try -help.");
+			errorOccurred = true;
+			return false;
+		}
+		return true;
+	}
+
+	private PrintWriter createFile(String fname) {
+		PrintWriter res = null;
+		try {
+			res = new PrintWriter(new OutputStreamWriter(new PrintStream(new File(fname))));
+		} catch (FileNotFoundException e) {
+			System.out.println("Unable to create file "+fname+", aborting...");
+			e.printStackTrace();
+			System.exit(1);
+		}
+		return res;
+	}
+
+	/**
+	 * Display results
+	 */
+	private void displayResults() {
+
+		if (pkgList.isEmpty())
+			return;
+
+		// collect all class names in the environment (format: /package/name/classname)
+		SortedSet<String> classes = env.getClassesList();
+		// same for arguments
+		Collections.sort(pkgList);
+		Collections.sort(env.excludePrefixes);
+		// create the unit
+		PrintWriter includeFile;
+		PrintWriter mainUnitFile;
+		PascalUnit thisUnit;
+		String includeName, mainUnitName;
+
+		mainUnitName = env.outputName+".pas";
+		includeName = env.outputName+".inc";
+
+		includeFile = createFile(includeName);
+		mainUnitFile = createFile(mainUnitName);
+		thisUnit = new PascalUnit(mainUnitFile, env, pkgList, includeName);
+		PascalClassData.currentUnit = thisUnit;
+
+		// create unique short names for all classes we may need
+		System.out.println("Determining short Pascal class names...");
+		for (Iterator<String> iter = classes.iterator(); iter.hasNext(); ) {
+			thisUnit.registerClassName(iter.next());
+		}
+
+		// first read all requested classes and build dependency graph
+		Iterator<String> classStepper = classes.iterator();
+		Iterator<String> argStepper = pkgList.iterator();
+		Iterator<String> skipPkgsStepper = env.excludePrefixes.iterator();
+		HashSet<String> classesToPrintList = new HashSet<String>();
+		SimpleDirectedGraph<String,DefaultEdge> classDependencies = new SimpleDirectedGraph<String, DefaultEdge>(DefaultEdge.class);
+
+		try {
+			String currentExcludePkg; 
+			String currentPkgPrefix;
+			if (skipPkgsStepper.hasNext())
+				currentExcludePkg = skipPkgsStepper.next();
+			else
+				currentExcludePkg = ".......";
+			if (argStepper.hasNext())
+				currentPkgPrefix = argStepper.next().replace('.', '/');
+			else
+				currentPkgPrefix = ".......";
+			System.out.println("Indexing classes under "+currentPkgPrefix+"...");
+			do {
+				String currentClass = classStepper.next();
+				// if the current class name is > the current package name, skip packages
+				// until we have a package to which the current class belongs, or the
+				// next in line
+				while (argStepper.hasNext() &&
+						!currentClass.startsWith(currentPkgPrefix) &&
+						(currentClass.compareTo(currentPkgPrefix) > 0)) {
+					String currentArg = argStepper.next();
+					// convention: '.' as package name = no package name, otherwise actual package name
+					if (!currentArg.equals(".")) {
+						currentArg = currentArg.replace('.', '/');
+						currentPkgPrefix = currentArg;
+					} else {
+						currentArg = "./";
+						currentPkgPrefix = currentArg;
+					}
+					System.out.println("Indexing classes under "+currentPkgPrefix+"...");
+					currentPkgPrefix = currentArg;
+				}
+				boolean doPrintClass = false;
+				// should check whether the class is explicitly excluded from being printed
+				if (currentClass.startsWith(currentPkgPrefix)) {
+					while (skipPkgsStepper.hasNext() &&
+							!currentClass.startsWith(currentExcludePkg) &&
+							(currentClass.compareTo(currentExcludePkg) > 0)) {
+						currentExcludePkg = skipPkgsStepper.next();
+					}
+					if (!currentClass.startsWith(currentExcludePkg)) {
+						doPrintClass = true;
+					}
+				}
+				// always construct the class to record the identifiers
+				// (so we can properly rename identifiers in subclasses),
+				// but only collect dependency information if we actually
+				// have to print the class
+				InputStream classin = env.getFileInputStream(currentClass);
+				JavapPrinter printer = new JavapPrinter(classin, includeFile, env, "  ",null,doPrintClass);
+				if (doPrintClass) {
+					if (!classDependencies.containsVertex(currentClass))
+						classDependencies.addVertex(currentClass);
+
+					HashSet<String> dependencies = printer.cls.getDependencies();
+					Iterator<String> depStepper = dependencies.iterator();
+					while (depStepper.hasNext()) {
+						String dep = depStepper.next();
+						thisUnit.registerUsedClass(dep);
+						if (!classDependencies.containsVertex(dep))
+							classDependencies.addVertex(dep);
+						/*								
+								if (currentClass.equals("java/awt/Window"))
+									System.out.println("  java/awt/Window depends on "+dep);
+								if (dep.equals("java/awt/Window"))
+									System.out.println("dep = java/awt/Window for "+currentClass);
+						 */									
+						classDependencies.addEdge(dep, currentClass);
+					}
+
+					classesToPrintList.add(currentClass);
+
+					//    							JavapClassPrinter.PrintClass(env,includeFile,currentClass,"  ");
+				}
+			} while (classStepper.hasNext());
+			// no longer needed
+			classes = null;
+			pkgList = null;
+			System.out.println("Printing classes...");
+			//    		Iterator<String> printerStepper = classesToPrintList.iterator();
+			TopologicalOrderIterator<String,DefaultEdge> printerStepper = new TopologicalOrderIterator<String,DefaultEdge>(classDependencies); 
+			while (printerStepper.hasNext()) {
+				String currentClass = printerStepper.next();
+				// also contains external classes
+				if (!classesToPrintList.remove(currentClass))
+					continue;
+				try {
+					InputStream classin = env.getFileInputStream(currentClass);
+					JavapPrinter printer = new JavapPrinter(classin, includeFile, env, "  ",null, true);
+					printer.print();
+
+					//					JavapClassPrinter.PrintClass(env,includeFile,currentClass,"  ");
+				} catch (IllegalArgumentException exc) {
+					error(exc.getMessage());
+					exc.printStackTrace();
+					System.out.println("Error while processing class "+currentClass+", aborting...");
+					includeFile.close();
+					System.exit(1);
+				}
+			}
+
+			// the iterator
+			if (!classesToPrintList.isEmpty()) {
+				Iterator<String> leftOvers = classesToPrintList.iterator();
+				System.out.println("Classes part of dependency cycles, or related to these classes:");
+				CycleDetector<String, DefaultEdge> cycles = new CycleDetector<String, DefaultEdge>(classDependencies);
+				while (leftOvers.hasNext()) {
+					String currentClass = leftOvers.next();
+					System.out.println("  "+currentClass+" is part of cycle "+cycles.findCyclesContainingVertex(currentClass));
+
+					try {
+						InputStream classin = env.getFileInputStream(currentClass);
+						JavapPrinter printer = new JavapPrinter(classin, includeFile, env, "  ",null,true);
+						printer.print();
+
+						//					JavapClassPrinter.PrintClass(env,includeFile,currentClass,"  ");
+					} catch (IllegalArgumentException exc) {
+						error(exc.getMessage());
+						exc.printStackTrace();
+						System.out.println("Error while processing class "+currentClass+", aborting...");
+						includeFile.close();
+						System.exit(1);
+					}
+				}
+			}
+
+		} finally {
+			includeFile.close();
+			thisUnit.printUnit();
+			mainUnitFile.close();
+		}
+		/*        Class[] classes = ClassListBuilder.getClassesInPackage("fpc.tools.javapp");  
+        for (Class c : classes) {  
+            System.out.println("Found: " + c.getCanonicalName());  
         }
-    }
-
-    private void error(String msg) {
-        errorOccurred = true;
-        System.err.println(msg);
-        System.err.flush();
-    }
-
-    /**
-     * Print usage information
-     */
-    private void usage() {
-        java.io.PrintStream out = System.out;
-        out.println("Usage: " + progname + " <options> <classes>...");
-        out.println();
-        out.println("where options include:");
-        out.println("   -c                        Disassemble the code");
-        out.println("   -classpath <pathlist>     Specify where to find user class files");
-        out.println("   -extdirs <dirs>           Override location of installed extensions");
-        out.println("   -help                     Print this usage message");
-        out.println("   -J<flag>                  Pass <flag> directly to the runtime system");
-        out.println("   -l                        Print line number and local variable tables");
-        out.println("   -public                   Show only public classes and members");
-        out.println("   -protected                Show protected/public classes and members");
-        out.println("   -package                  Show package/protected/public classes");
-        out.println("                             and members (default)");
-        out.println("   -private                  Show all classes and members");
-        out.println("   -s                        Print internal type signatures");
-        out.println("   -bootclasspath <pathlist> Override location of class files loaded");
-        out.println("                             by the bootstrap class loader");
-        out.println("   -verbose                  Print stack size, number of locals and args for methods");
-        out.println("                             If verifying, print reasons for failure");
-        out.println();
-    }
-
-    /**
-     * Parse the command line arguments.
-     * Set flags, construct the class list and create environment.
-     */
-    private boolean parseArguments(String argv[]) {
-        for (int i = 0 ; i < argv.length ; i++) {
-            String arg = argv[i];
-            if (arg.startsWith("-")) {
-                if (arg.equals("-l")) {
-                    env.showLineAndLocal = true;
-                } else if (arg.equals("-private") || arg.equals("-p")) {
-                    env.showAccess = env.PRIVATE;
-                } else if (arg.equals("-package")) {
-                    env.showAccess = env.PACKAGE;
-                } else if (arg.equals("-protected")) {
-                    env.showAccess = env.PROTECTED;
-                } else if (arg.equals("-public")) {
-                    env.showAccess = env.PUBLIC;
-                } else if (arg.equals("-c")) {
-                    env.showDisassembled = true;
-                } else if (arg.equals("-s")) {
-                    env.showInternalSigs = true;
-                } else if (arg.equals("-verbose"))  {
-                    env.showVerbose = true;
-                } else if (arg.equals("-v")) {
-                    env.showVerbose = true;
-                } else if (arg.equals("-h")) {
-                    error("-h is no longer available - use the 'javah' program");
-                    return false;
-                } else if (arg.equals("-verify")) {
-                    error("-verify is no longer available - use 'java -verify'");
-                    return false;
-                } else if (arg.equals("-verify-verbose")) {
-                    error("-verify is no longer available - use 'java -verify'");
-                    return false;
-                } else if (arg.equals("-help")) {
-                    usage();
-                    return false;
-                } else if (arg.equals("-classpath")) {
-                    if ((i + 1) < argv.length) {
-                        env.classPathString = argv[++i];
-                    } else {
-                        error("-classpath requires argument");
-                        usage();
-                        return false;
-                    }
-                } else if (arg.equals("-bootclasspath")) {
-                    if ((i + 1) < argv.length) {
-                        env.bootClassPathString = argv[++i];
-                    } else {
-                        error("-bootclasspath requires argument");
-                        usage();
-                        return false;
-                    }
-                } else if (arg.equals("-extdirs")) {
-                    if ((i + 1) < argv.length) {
-                        env.extDirsString = argv[++i];
-                    } else {
-                        error("-extdirs requires argument");
-                        usage();
-                        return false;
-                    }
-                } else if (arg.equals("-all")) {
-                    env.showallAttr = true;
-                } else {
-                    error("invalid flag: " + arg);
-                    usage();
-                    return false;
-                }
-            } else {
-                classList.addElement(arg);
-                env.nothingToDo = false;
-            }
-        }
-        if (env.nothingToDo) {
-            System.out.println("No classes were specified on the command line.  Try -help.");
-            errorOccurred = true;
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Display results
-     */
-    private void displayResults() {
-        for (int i = 0; i < classList.size() ; i++ ) {
-            String Name = (String)classList.elementAt(i);
-            InputStream classin = env.getFileInputStream(Name);
-
-            try {
-                JavapPrinter printer = new JavapPrinter(classin, out, env);
-                printer.print();                // actual do display
-
-            } catch (IllegalArgumentException exc) {
-                error(exc.getMessage());
-            }
-        }
-    }
+		 */  
+		System.out.println("Done!");
+	}
+
 }

+ 64 - 47
utils/javapp/src/fpc/tools/javapp/MethodData.java

@@ -22,13 +22,16 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;
 
-import static sun.tools.javap.RuntimeConstants.*;
+import static fpc.tools.javapp.RuntimeConstants.*;
 
 /**
  * Strores method data informastion.
@@ -42,16 +45,20 @@ public class MethodData {
     int name_index;
     int descriptor_index;
     int attributes_count;
+/*    
     byte[] code;
     Vector exception_table = new Vector(0);
     Vector lin_num_tb = new Vector(0);
     Vector loc_var_tb = new Vector(0);
     StackMapTableData[] stackMapTable;
     StackMapData[] stackMap;
+*/
     int[] exc_index_table=null;
     Vector attrs=new Vector(0);
+/*    
     Vector code_attrs=new Vector(0);
     int max_stack,  max_locals;
+*/
     boolean isSynthetic=false;
     boolean isDeprecated=false;
 
@@ -116,24 +123,28 @@ public class MethodData {
     public void readCode(DataInputStream in) throws IOException {
 
         int attr_length = in.readInt();
-        max_stack=in.readUnsignedShort();
-        max_locals=in.readUnsignedShort();
+//        max_stack=in.readUnsignedShort();
+//        max_locals=in.readUnsignedShort();
+        int max_stack=in.readUnsignedShort();
+        int max_locals=in.readUnsignedShort();
         int codelen=in.readInt();
 
-        code=new byte[codelen];
+//        code=new byte[codelen];
         int totalread = 0;
         while(totalread < codelen){
-            totalread += in.read(code, totalread, codelen-totalread);
+//            totalread += in.read(code, totalread, codelen-totalread);
+        	totalread += in.skipBytes(codelen-totalread);
         }
         //      in.read(code, 0, codelen);
         int clen = 0;
         readExceptionTable(in);
         int code_attributes_count = in.readUnsignedShort();
 
+        AttrData attr=new AttrData(cls);
         for (int k = 0 ; k < code_attributes_count ; k++) {
             int table_name_index=in.readUnsignedShort();
             int table_name_tag=cls.getTag(table_name_index);
-            AttrData attr=new AttrData(cls);
+//            AttrData attr=new AttrData(cls);
             if (table_name_tag==CONSTANT_UTF8) {
                 String table_name_tstr=cls.getString(table_name_index);
                 if (table_name_tstr.equals("LineNumberTable")) {
@@ -151,12 +162,12 @@ public class MethodData {
                 } else {
                     attr.read(table_name_index, in);
                 }
-                code_attrs.addElement(attr);
+//                code_attrs.addElement(attr);
                 continue;
             }
 
             attr.read(table_name_index, in);
-            code_attrs.addElement(attr);
+//            code_attrs.addElement(attr);
         }
     }
 
@@ -165,7 +176,8 @@ public class MethodData {
      */
     void readExceptionTable (DataInputStream in) throws IOException {
         int exception_table_len=in.readUnsignedShort();
-        exception_table=new Vector(exception_table_len);
+//        exception_table=new Vector(exception_table_len);
+        Vector exception_table=new Vector(exception_table_len);
         for (int l = 0; l < exception_table_len; l++) {
             exception_table.addElement(new TrapData(in, l));
         }
@@ -177,7 +189,8 @@ public class MethodData {
     void readLineNumTable (DataInputStream in) throws IOException {
         int attr_len = in.readInt(); // attr_length
         int lin_num_tb_len = in.readUnsignedShort();
-        lin_num_tb=new Vector(lin_num_tb_len);
+//        lin_num_tb=new Vector(lin_num_tb_len);
+        Vector lin_num_tb=new Vector(lin_num_tb_len);
         for (int l = 0; l < lin_num_tb_len; l++) {
             lin_num_tb.addElement(new LineNumData(in));
         }
@@ -189,7 +202,8 @@ public class MethodData {
     void readLocVarTable (DataInputStream in) throws IOException {
         int attr_len=in.readInt(); // attr_length
         int loc_var_tb_len = in.readUnsignedShort();
-        loc_var_tb = new Vector(loc_var_tb_len);
+//        loc_var_tb = new Vector(loc_var_tb_len);
+        Vector loc_var_tb = new Vector(loc_var_tb_len);
         for (int l = 0; l < loc_var_tb_len; l++) {
             loc_var_tb.addElement(new LocVarData(in));
         }
@@ -202,6 +216,7 @@ public class MethodData {
         int attr_len=in.readInt(); // attr_length in prog
         int num_exceptions = in.readUnsignedShort();
         exc_index_table=new int[num_exceptions];
+        int[] exc_index_table=new int[num_exceptions];
         for (int l = 0; l < num_exceptions; l++) {
             int exc=in.readShort();
             exc_index_table[l]=exc;
@@ -214,7 +229,8 @@ public class MethodData {
     void readStackMapTable(DataInputStream in) throws IOException {
         int attr_len = in.readInt();  //attr_length
         int stack_map_tb_len = in.readUnsignedShort();
-        stackMapTable = new StackMapTableData[stack_map_tb_len];
+//        stackMapTable = new StackMapTableData[stack_map_tb_len];
+        StackMapTableData[] stackMapTable = new StackMapTableData[stack_map_tb_len];
         for (int i=0; i<stack_map_tb_len; i++) {
             stackMapTable[i] = StackMapTableData.getInstance(in, this);
         }
@@ -226,7 +242,8 @@ public class MethodData {
     void readStackMap(DataInputStream in) throws IOException {
         int attr_len = in.readInt();  //attr_length
         int stack_map_len = in.readUnsignedShort();
-        stackMap = new StackMapData[stack_map_len];
+//        stackMap = new StackMapData[stack_map_len];
+        StackMapData[] stackMap = new StackMapData[stack_map_len];
         for (int i = 0; i<stack_map_len; i++) {
             stackMap[i] = new StackMapData(in, this);
         }
@@ -288,52 +305,52 @@ public class MethodData {
     /**
      * Return code attribute data of a method.
      */
-    public byte[] getCode(){
-        return code;
-    }
+//    public byte[] getCode(){
+//        return code;
+//    }
 
     /**
      * Return LineNumberTable size.
      */
-    public int getnumlines(){
-        return lin_num_tb.size();
-    }
+//    public int getnumlines(){
+//        return lin_num_tb.size();
+//    }
 
     /**
      * Return LineNumberTable
      */
-    public Vector getlin_num_tb(){
-        return lin_num_tb;
-    }
+//    public Vector getlin_num_tb(){
+//        return lin_num_tb;
+//    }
 
     /**
      * Return LocalVariableTable size.
      */
-    public int getloc_var_tbsize(){
-        return loc_var_tb.size();
-    }
+//    public int getloc_var_tbsize(){
+//        return loc_var_tb.size();
+//    }
 
 
     /**
      * Return LocalVariableTable.
      */
-    public Vector getloc_var_tb(){
-        return loc_var_tb;
-    }
+//    public Vector getloc_var_tb(){
+//        return loc_var_tb;
+//    }
 
     /**
      * Return StackMap.
      */
-    public StackMapData[] getStackMap() {
-        return stackMap;
-    }
+//    public StackMapData[] getStackMap() {
+//        return stackMap;
+//    }
 
     /**
      * Return StackMapTable.
      */
-    public StackMapTableData[] getStackMapTable() {
-        return stackMapTable;
-    }
+//    public StackMapTableData[] getStackMapTable() {
+//        return stackMapTable;
+//    }
 
     /**
      * Return number of arguments of that method.
@@ -354,17 +371,17 @@ public class MethodData {
     /**
      * Return max depth of operand stack.
      */
-    public int getMaxStack(){
-        return  max_stack;
-    }
+//    public int getMaxStack(){
+//        return  max_stack;
+//    }
 
 
     /**
      * Return number of local variables.
      */
-    public int getMaxLocals(){
-        return max_locals;
-    }
+//    public int getMaxLocals(){
+//        return max_locals;
+//    }
 
 
     /**
@@ -378,9 +395,9 @@ public class MethodData {
     /**
      * Return exception table in code attributre.
      */
-    public Vector getexception_table(){
-        return exception_table;
-    }
+//    public Vector getexception_table(){
+//        return exception_table;
+//    }
 
 
     /**
@@ -394,9 +411,9 @@ public class MethodData {
     /**
      * Return code attributes.
      */
-    public Vector getCodeAttributes(){
-        return code_attrs;
-    }
+//    public Vector getCodeAttributes(){
+//        return code_attrs;
+//    }
 
 
     /**

+ 426 - 0
utils/javapp/src/fpc/tools/javapp/PascalClassData.java

@@ -0,0 +1,426 @@
+package fpc.tools.javapp;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+public class PascalClassData extends ClassData {
+
+	private JavapEnvironment env;
+	public PascalClassData outerClass;
+	private HashSet<String> nestedDependencies;
+	boolean setOuterDependencies; 
+	
+	static public PascalUnit currentUnit; 
+	
+	static final String[] nonNestedDollarClasses;
+	
+
+	
+	public PascalClassData(InputStream infile, PascalClassData outerClass, JavapEnvironment env, boolean doCollectDependencies) {
+		super (infile);
+		this.outerClass = outerClass;
+		this.nestedDependencies = new HashSet<String>();
+		this.env = env;
+		ClassIdentifierInfo.registerClassInfo(getClassName(),getSuperClassName(),getSuperInterfaces());
+		if (doCollectDependencies) {
+			collectDependencies();
+		}
+	}
+
+	/**
+	 * 
+	 */
+	private void collectDependencies() {
+		if (this.outerClass != null) {
+			HashSet<String> myDeps = getDependencies();
+			String mySuperClass = getSuperClassName();
+			boolean foundMatch = false;
+			PascalClassData outerMostClass = this;
+			while (outerMostClass.outerClass != null) {
+				/**
+				 *  adjust dependencies for inner types, e.g.
+				 *  CSNHAuthenticator = class abstract external 'com.sun.net.httpserver' name 'Authenticator' (JLObject)
+				 *  type
+				 *    Retry = class external 'com.sun.net.httpserver' name 'Authenticator$Retry' (Result)
+				 *    ..
+				 *    end;
+				 *    
+				 *    Result = class abstract external 'com.sun.net.httpserver' name 'Authenticator$Result' (JLObject)
+				 *    ..
+				 *    end;
+				 *    
+				 *  end;
+				 *    -> Retry must depend on Result
+				 */
+				if (!foundMatch &&
+						mySuperClass.startsWith(outerMostClass.outerClass.getClassName()) &&
+						!mySuperClass.equals(outerMostClass.outerClass.getClassName())) {
+					foundMatch = true;
+					outerMostClass.addNestedDepdency(mySuperClass);
+				}
+				outerMostClass = outerMostClass.outerClass;
+			}
+			myDeps.remove(outerMostClass.getMasterClassName());
+			outerMostClass.addNestedDepdencies(myDeps);
+		}
+	}
+	
+	public void addNestedDepdencies(HashSet<String> nestedDeps) {
+		this.nestedDependencies.addAll(nestedDeps);
+	}
+	
+	public void addNestedDepdency(String nestedDep) {
+		this.nestedDependencies.add(nestedDep);
+	}
+
+/*	
+	public String getSafeMethodIdentifer(String id) {
+		if (id.charAt(0) == '<')
+			return id;
+		id = PascalKeywords.escapeIfPascalKeyword(id);
+		String testName = id.toUpperCase();
+		while (usedIdentifiers.contains(testName)) {
+			id = id + "_";
+			testName = testName + "_";
+		}
+		if (id.indexOf('$') != -1) {
+			System.out.println("  Warning, cannot represent identifier '"+id+"', hiding");
+			id = id.replace("$","__");
+		}
+		return id;
+	}
+*/
+	public boolean isStatic() {
+		return (access & ACC_STATIC) != 0;
+	}
+
+	public static boolean isInnerClass(String className) {
+		if (className.indexOf('$') == -1)
+			return false;
+		className = className.replace('.', '/');
+		for (String name : nonNestedDollarClasses) {
+			if (className.equals(name))
+				return false;
+		}
+		return true;
+	}
+	
+	public boolean isInnerClass() {
+		return outerClass != null;
+	}
+	
+	public static String getShortClassName(String className) {
+		int index;
+		className = className.replace('-', '_');
+		if (isInnerClass(className)) {
+			index=className.lastIndexOf("$")+1;
+			return "Inner"+className.substring(index);
+		}
+		else
+			className = className.replace("$","__");
+        index=className.lastIndexOf("/")+1;
+        if (index==0) {
+        	index=className.lastIndexOf(".")+1;
+        }
+        if (index!=0) {
+            return className.substring(index);
+        }
+        return className;
+	}
+
+	/**
+	 * For a non-nested class, returns the name of the class itself
+	 * For a nested class, returns the name of the outermost class
+	 * 
+	 */
+	public static String getMasterClassName(String className) {
+		int index;
+//		className = className.replace('-', '_');
+		if (!isInnerClass(className.replace('.','/')))
+			return className;
+        index=className.indexOf('$');
+        if (index!=-1) {
+            return className.substring(0,index);
+        }
+        return className;
+	}
+
+	public static String getShortPascalClassName(String className) {
+		currentUnit.registerUsedClass(className);
+		return currentUnit.getShortPascalName(className);
+
+		/*
+		
+		String shortname = getShortClassName(classname);
+		// inner class -> done (no naming problems)
+		if (classname.indexOf('$') != -1)
+			return shortname;
+
+		// no package?
+		if (shortname.equals(classname))
+			return shortname;
+		// add package component prefixes
+		String pkgname = getClassPackageName(classname);
+		String prefix = Character.toString(classname.charAt(0)).toUpperCase();
+		for (int i = 1; i < pkgname.length(); i++)
+			if ((pkgname.charAt(i) == '.'))
+				prefix = prefix + Character.toString(pkgname.charAt(i+1)).toUpperCase();
+        return prefix+shortname;
+*/
+	}
+	
+	
+	public static String getClassPackageName(String className) {
+		int index;
+      	index=className.lastIndexOf("/");
+        if (index==-1) {
+        	index=className.lastIndexOf(".");
+        }
+        if (index!=-1) {
+            return className.substring(0,index).replace('/', '.');
+        }
+        return null;
+	}
+	
+	public static String getFullPascalClassName(String className) {
+		return getShortPascalClassName(className);
+/*
+		if (isInnerClass(className)) {
+			int nestedIndex = className.indexOf('$');
+			String res = getShortPascalClassName(className.substring(0,nestedIndex));
+			StringTokenizer innerTypes = new StringTokenizer(className.substring(nestedIndex+1), "$");
+			while (innerTypes.hasMoreTokens()) {
+				res = res + "." + PascalKeywords.escapeIfPascalKeyword(innerTypes.nextToken());
+			}
+			return res;
+		} else
+			return getShortPascalClassName(className);
+*/			
+	}
+	
+	public static String getExternalClassName(String className) {
+		int index = className.lastIndexOf('/');
+		if (index != -1) {
+			return className.substring(index+1);
+		}
+		else
+			return className;
+	}
+
+	public String getShortClassName() {
+		return getShortClassName(getClassName());
+    }
+	
+	public String getShortPascalClassName() {
+		return getShortPascalClassName(getClassName());
+	}
+	
+	public String getClassPackageName() {
+		return getClassPackageName(getClassName());
+    }
+	
+	public String getFullPascalClassName() {
+		return getFullPascalClassName(getClassName());
+	}
+
+	public String getMasterClassName() {
+		return getMasterClassName(getClassName());
+	}
+	
+	public String getExternalClassName() {
+		return getExternalClassName(getClassName());
+	}
+	
+	public String[] getPascalSuperInterfaces(){
+		String[] res = super.getSuperInterfaces();
+		for (int i=0; i<res.length; i++)
+			res[i] = getFullPascalClassName(res[i]);
+		return res;
+	}	
+    /**
+     * Returns the visibility of this class or interface.
+     */
+    public String getVisibilitySectionName(){
+    	if (isInnerClass()) {
+    		if (isPublic()) {
+        		return "public";
+        	}
+    		else {
+    			return "strict private";
+    		}
+    	}
+    	else {
+    		return null;
+    	}
+    }
+
+	
+    public String[] getModifiers(){
+        Vector<String> v = new Vector<String>();
+        if ((access & ACC_FINAL)    !=0) v.addElement("sealed");
+        if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
+        String[] accflags = new String[v.size()];
+        v.copyInto(accflags);
+        return accflags;
+    }
+
+    
+    protected void readFields(DataInputStream in) throws IOException {
+        int fields_count = in.readUnsignedShort();
+        fields=new FieldData[fields_count];
+        for (int k = 0; k < fields_count; k++) {
+            FieldData field=new PascalFieldData(this);
+            field.read(in);
+            fields[k]=field;
+        }
+    }
+
+    
+    /**
+     * Reads and stores Method info.
+     */
+    protected void readMethods(DataInputStream in) throws IOException {
+        int methods_count = in.readUnsignedShort();
+        methods=new PascalMethodData[methods_count];
+        for (int k = 0; k < methods_count ; k++) {
+            MethodData method=new PascalMethodData(this);
+            method.read(in);
+            methods[k]=method;
+        }
+    }
+
+    /**
+     * Returns string at that index.
+     */
+    public String StringValue(int cpx) {
+        if (cpx==0) throw new ClassFormatError("Invalid CP index: 0");
+        int tag;
+        Object x;
+        try {
+            tag=tags[cpx];
+            x=cpool[cpx];
+        } catch (IndexOutOfBoundsException e) {
+        	throw new ClassFormatError("<Incorrect CP index:"+cpx+">");
+        }
+
+        if (x==null) return "nil";
+        switch (tag) {
+        case CONSTANT_UTF8: {
+            StringBuffer sb=new StringBuffer();
+            String s=(String)x;
+            sb.append('\'');
+            for (int k=0; k<s.length(); k++) {
+                char c=s.charAt(k);
+                if (c == '\'')
+                	sb.append("''");
+                else if ((c >= ' ') &&
+                		(c <= '~'))
+                	sb.append(c);
+                else
+                	sb.append("'#$"+String.format("%04x",(int)c)+"'");
+            }
+            sb.append('\'');
+            return sb.toString();
+        }
+        case CONSTANT_DOUBLE: {
+            Double d=(Double)x;
+            String sd=d.toString();
+            sd = sd.replace("Infinity", "1.0/0.0").replace("NaN", "0.0/0.0");
+            return "jdouble("+sd+")";
+        }
+        case CONSTANT_FLOAT: {
+            Float f=(Float)x;
+            String sf=(f).toString();
+            sf = sf.replace("Infinity", "1.0/0.0").replace("NaN", "0.0/0.0");
+            return "jfloat("+sf+")";
+        }
+        case CONSTANT_LONG: {
+            Long ln = (Long)x;
+            return "jlong("+ln.toString()+')';
+        }
+        case CONSTANT_INTEGER: {
+            Integer in = (Integer)x;
+            return in.toString();
+        }
+        case CONSTANT_CLASS:
+            return javaName(getClassName(cpx));
+        case CONSTANT_STRING:
+            return StringValue(((CPX)x).cpx);
+        case CONSTANT_FIELD:
+        case CONSTANT_METHOD:
+        case CONSTANT_INTERFACEMETHOD:
+            //return getShortClassName(((CPX2)x).cpx1)+"."+StringValue(((CPX2)x).cpx2);
+             return javaName(getClassName(((CPX2)x).cpx1))+"."+StringValue(((CPX2)x).cpx2);
+
+        case CONSTANT_NAMEANDTYPE:
+        	throw new ClassFormatError("Don't try to print out field/method/interfacemethod constant values");
+        default:
+        	throw new ClassFormatError("Unknown constant tag: "+tag);
+        }
+    }
+    
+
+    protected InnerClassData NewInnerClassData() {
+    	return new PascalInnerClassData(this);
+    }
+    
+        public HashSet<String> getDependencies() {
+    	HashSet<String> res = new HashSet<String>();
+    	// inheritance dependencies (superclass and implemented interfaces)
+    	String superClass = getSuperClassName();
+    	if (superClass != null)
+    		res.add(getMasterClassName(superClass));
+    	String []interfacelist = getSuperInterfaces();
+    	for (String intf : interfacelist)
+    		res.add(getMasterClassName(intf));
+    	/** most dependencies in parameters/result types/field types can be
+    	 *  handled via forward declarations, but there is one exception:
+    	 *  dependencies on nested classes declared in another class
+    	 */
+    	// field types
+    	FieldData[] fields = getFields();
+    	for (FieldData field : fields) {
+    		if (TypeSignature.checkAccess(field.getAccess(),env)) {
+    			String fieldType = ((PascalFieldData)field).getRawBaseType();
+    			if (isInnerClass(fieldType))
+    				res.add(getMasterClassName(fieldType.replace('.', '/')));
+    		}
+    	}
+    	
+    	// method parameter/return types
+    	MethodData[] methods = getMethods();
+    	for (MethodData method : methods) {
+    		if (TypeSignature.checkAccess(method.getAccess(),env)) {
+    			String retType = ((PascalMethodData)method).getRawBaseReturnType();
+    			if (isInnerClass(retType))
+    				res.add(getMasterClassName(retType.replace('.', '/')));
+    			TypeSignature methodSig = new TypeSignature(method.getInternalSig());
+    			Vector<String> paras = methodSig.getParametersList(methodSig.parameterdes);
+    			for (int i = 0; i < paras.size(); i++) {
+    				String paraType = paras.get(i);
+    		        int arrPos = paraType.indexOf('[');
+    		        if (arrPos != -1)
+    		        	paraType = paraType.substring(0,arrPos);
+    				if (isInnerClass(paraType))
+    					res.add(getMasterClassName(paraType.replace('.', '/')));
+    			}
+    		}
+    	}
+    	// dependencies added by nested classes (in case we are a top-level class/interface)
+    	res.addAll(nestedDependencies);
+    	// remove ourselves
+    	res.remove(getClassName());
+    	return res;
+    }
+    
+    
+    static {
+    	nonNestedDollarClasses = new String[1];
+    	nonNestedDollarClasses[0] = "com/sun/org/apache/xalan/internal/xsltc/compiler/CUP$XPathParser$actions";    	
+    }
+}

+ 74 - 0
utils/javapp/src/fpc/tools/javapp/PascalFieldData.java

@@ -0,0 +1,74 @@
+package fpc.tools.javapp;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.Vector;
+
+public class PascalFieldData extends FieldData {
+	
+	private String cachedName;
+
+	public PascalFieldData(ClassData cls){
+       super(cls);
+    }
+	
+    public String getVisibilitySectionName(){
+        if ((access & ACC_PUBLIC)   !=0) return "public";
+        if ((access & ACC_PRIVATE)   !=0) return "strict private";
+        if ((access & ACC_PROTECTED)   !=0) return "strict protected";
+        /* package visibility = visible in this unit */
+        return "private";
+    }
+    
+    public boolean isFormalConst() {
+    	for (int i=0; i < attrs.size(); i++)
+            if(((AttrData)attrs.elementAt(i)).getAttrName().equals("ConstantValue"))
+            	return true;
+    	return false;
+    }
+    
+    public String getModifiers() {
+        Vector<String> v = new Vector<String>();
+        if (isFormalConst()) return "const";
+        else {
+        	if ((access & ACC_FINAL)    !=0) v.addElement("final");
+        	if ((access & ACC_STATIC)   !=0) v.addElement("class var");
+        	else
+        		v.addElement("var");
+        }
+        String res = v.elementAt(0);
+        for (int i=1; i < v.size(); i++)
+        	res=res+" "+v.elementAt(i);
+        return res;
+    }
+
+    /**
+     * Returns Pascal type signature of a field.
+     */
+    public String getType(){
+        return new PascalTypeSignature(getInternalSig(),cls).getFieldType();
+    }
+
+    /**
+     * Returns Java type signature of a field.
+     */
+    public String getRawBaseType(){
+        String res = new TypeSignature(getInternalSig()).getFieldType();
+        int arrIndex = res.indexOf('[');
+        if (arrIndex != -1)
+        	res = res.substring(0,arrIndex);
+        return res;
+    }
+
+    public String getName() {
+    	if (cachedName == null) {
+    		String realName = super.getName();
+    		// we prepend an "f" for fields to prevent name clashes
+    		if (!isFormalConst())
+    			realName = "f" + realName;
+    		cachedName = ClassIdentifierInfo.AddIdentifierNameForClass(cls.getClassName(),realName);    				
+    	}
+    	return cachedName;
+    }
+
+}

+ 12 - 0
utils/javapp/src/fpc/tools/javapp/PascalInnerClassData.java

@@ -0,0 +1,12 @@
+package fpc.tools.javapp;
+
+public class PascalInnerClassData extends InnerClassData {
+
+    public PascalInnerClassData(ClassData cls) {
+        super(cls);
+    }
+    
+	public boolean isStatic() {
+		return (access & ACC_STATIC) != 0;
+	}
+}

+ 95 - 0
utils/javapp/src/fpc/tools/javapp/PascalKeywords.java

@@ -0,0 +1,95 @@
+package fpc.tools.javapp;
+
+import java.util.HashSet;
+
+public class PascalKeywords {
+	static private HashSet<String> pascalKeywords;
+	
+	static public boolean isPascalKeyword(String str) {
+		return pascalKeywords.contains(str.toUpperCase());
+	}
+	
+	static public String escapeIfPascalKeyword(String str) {
+		if (isPascalKeyword(str))
+			return "&"+str;
+		return str;
+	}
+
+	static {
+		pascalKeywords = new HashSet<String>();
+		pascalKeywords.add("AS");
+		pascalKeywords.add("DO");
+		pascalKeywords.add("IF");
+		pascalKeywords.add("IN");
+		pascalKeywords.add("IS");
+		pascalKeywords.add("OF");
+		pascalKeywords.add("ON");
+		pascalKeywords.add("OR");
+		pascalKeywords.add("TO");
+		pascalKeywords.add("AND");
+		pascalKeywords.add("ASM");
+		pascalKeywords.add("DIV");
+		pascalKeywords.add("END");
+		pascalKeywords.add("FOR");
+		pascalKeywords.add("MOD");
+		pascalKeywords.add("NIL");
+		pascalKeywords.add("NOT");
+		pascalKeywords.add("SET");
+		pascalKeywords.add("SHL");
+		pascalKeywords.add("SHR");
+		pascalKeywords.add("TRY");
+		pascalKeywords.add("VAR");
+		pascalKeywords.add("XOR");
+		pascalKeywords.add("CASE");
+		pascalKeywords.add("ELSE");
+		pascalKeywords.add("FILE");
+		pascalKeywords.add("GOTO");
+		pascalKeywords.add("THEN");
+		pascalKeywords.add("TRUE");
+		pascalKeywords.add("TYPE");
+		pascalKeywords.add("UNIT");
+		pascalKeywords.add("USES");
+		pascalKeywords.add("WITH");
+		pascalKeywords.add("ARRAY");
+		pascalKeywords.add("BEGIN");
+		pascalKeywords.add("CLASS");
+		pascalKeywords.add("CONST");
+		pascalKeywords.add("FALSE");
+		pascalKeywords.add("FINAL");
+		pascalKeywords.add("LABEL");
+		pascalKeywords.add("UNTIL");
+		pascalKeywords.add("RAISE");
+		pascalKeywords.add("WHILE");
+		pascalKeywords.add("EXCEPT");
+		pascalKeywords.add("DOWNTO");
+		pascalKeywords.add("OBJECT");
+		pascalKeywords.add("PACKED");
+		pascalKeywords.add("PUBLIC");
+		pascalKeywords.add("RECORD");
+		pascalKeywords.add("REPEAT");
+		pascalKeywords.add("STRING");
+		pascalKeywords.add("STRICT");
+		pascalKeywords.add("EXPORTS");
+		pascalKeywords.add("FINALLY");
+		pascalKeywords.add("LIBRARY");
+		pascalKeywords.add("PROGRAM");
+		pascalKeywords.add("PRIVATE");
+		pascalKeywords.add("ABSTRACT");
+		pascalKeywords.add("CPPCLASS");
+		pascalKeywords.add("FUNCTION");
+		pascalKeywords.add("OPERATOR");
+		pascalKeywords.add("PROPERTY");
+		pascalKeywords.add("BITPACKED");
+		pascalKeywords.add("INHERITED");
+		pascalKeywords.add("INTERFACE");
+		pascalKeywords.add("OTHERWISE");
+		pascalKeywords.add("PROCEDURE");
+		pascalKeywords.add("PROTECTED");
+		pascalKeywords.add("THREADVAR");
+		pascalKeywords.add("DESTRUCTOR");
+		pascalKeywords.add("CONSTRUCTOR");
+		pascalKeywords.add("DISPINTERFACE");
+		pascalKeywords.add("IMPLEMENTATION");
+		pascalKeywords.add("RESOURCESTRING");		
+	}
+}

+ 79 - 0
utils/javapp/src/fpc/tools/javapp/PascalMethodData.java

@@ -0,0 +1,79 @@
+package fpc.tools.javapp;
+
+import fpc.tools.javapp.MethodData;
+import java.util.*;
+import java.io.*;
+
+import static fpc.tools.javapp.RuntimeConstants.*;
+
+public class PascalMethodData extends MethodData {
+	
+	private String cachedName;
+	
+    public PascalMethodData(ClassData cls) {
+		super(cls);
+	}
+
+	public String getVisibilitySectionName(){
+        if ((access & ACC_PUBLIC)   !=0) return "public";
+        if ((access & ACC_PRIVATE)   !=0) return "strict private";
+        if ((access & ACC_PROTECTED)   !=0) return "strict protected";
+        /* package visibility = visible in this unit */
+        return "private";
+    }
+
+    /**
+     * Return modifiers of the method that matter to Pascal import.
+     */
+    public String getModifiers(){
+        if ((access & ACC_FINAL)    !=0) return " final;";
+        if ((access & ACC_ABSTRACT) !=0) return " abstract;";
+        return "";
+    }
+
+    /**
+     * Return java return type signature of method.
+     */
+    public String getReturnType(){
+
+        String rttype = (new PascalTypeSignature(getInternalSig(), cls)).getReturnType();
+        return rttype;
+    }
+
+    /**
+     * Return java return type signature of method.
+     */
+    public String getRawBaseReturnType(){
+
+        String rttype = (new TypeSignature(getInternalSig())).getReturnType();
+        int arrPos = rttype.indexOf('[');
+        if (arrPos != -1)
+        	rttype = rttype.substring(0,arrPos);
+        return rttype;
+    }
+
+    /**
+     * Return java type parameter signature.
+     */
+    public String getParameters(){
+        String ptype = (new PascalTypeSignature(getInternalSig(),cls)).getParameters();
+
+        return ptype;
+    }
+    
+
+    public String getName(){
+    	if (cachedName == null) {
+    		String realName = super.getName();
+    		cachedName = ClassIdentifierInfo.AddIdentifierNameForClass(cls.getClassName(),realName);
+    		// this will require compiler support for remapping field names
+    		// (we also need it for Objective-C and C++ anyway)
+    		if ((cachedName.charAt(0) != '&') &&
+    				!cachedName.equals(realName)) {
+    			System.out.println("  Duplicate identifier conflict in "+cls.getClassName()+" for method '"+realName+"', disabled");
+    		}
+    				
+    	}
+    	return cachedName;
+    }
+}

+ 100 - 0
utils/javapp/src/fpc/tools/javapp/PascalTypeSignature.java

@@ -0,0 +1,100 @@
+package fpc.tools.javapp;
+
+import java.util.Vector;
+
+public class PascalTypeSignature extends TypeSignature {
+
+	public PascalTypeSignature(String JVMSignature, ClassData cls) {
+		init(JVMSignature);
+	}
+
+    /**
+     * Returns Pascal type signature for a base type.
+     */
+    public String getBaseType(String baseType){
+        if(baseType != null){
+            if(baseType.equals("B")) return "jbyte";
+            else if(baseType.equals("C")) return "jchar";
+            else if(baseType.equals("D")) return "jdouble";
+            else if(baseType.equals("F")) return "jfloat";
+            else if(baseType.equals("I")) return "jint";
+            else if(baseType.equals("J")) return "jlong";
+            else if(baseType.equals("S")) return "jshort";
+            else if(baseType.equals("Z")) return "jboolean";
+            else if(baseType.equals("V")) return "";
+        }
+        return null;
+    }
+
+
+    /**
+     * Returns Pascal type signature for a object type.
+     */
+    public String getObjectType(String JVMobjectType) {
+        String objectType = super.getObjectType(JVMobjectType).replace('.','/');
+        if (objectType != null) {
+        	if (!PascalClassData.currentUnit.isExternalInnerClass(objectType)) {
+        		objectType = PascalClassData.getFullPascalClassName(objectType);
+        	} else
+        		objectType = PascalClassData.getShortPascalClassName(objectType);
+        }
+        if (PascalKeywords.isPascalKeyword(objectType))
+        	objectType = "&" + objectType;
+        return objectType;
+    }
+
+    /**
+     * Returns Pascal type signature for array type.
+     */
+    public String getArrayType(String arrayType) {
+        if(arrayType != null){
+        	int dimCount = 0;
+
+            for (int i = 0; i < arrayType.length(); i++) {
+            	if (arrayType.charAt(i) != '[') {
+            		arrayType = arrayType.substring(i);
+            		break;
+            	}
+            	dimCount++;
+            }
+
+            String componentType = "";
+    		String outerClass = "";
+            if(arrayType.startsWith("L")){
+            	String baseType = arrayType.substring(1, arrayType.length()-1);
+            	if (PascalClassData.isInnerClass(baseType) &&
+            			!PascalClassData.currentUnit.isExternalInnerClass(baseType)) {
+            		int index = baseType.lastIndexOf('$');
+            		outerClass = PascalClassData.getShortPascalClassName(baseType.substring(0,index))+".";
+            		componentType = "Inner"+baseType.substring(index+1).replace('$', '.'); 
+            	} else {
+            		outerClass = "";
+                	componentType = PascalClassData.getShortPascalClassName(baseType);
+            	}
+            }else {
+                componentType = getBaseType(arrayType);
+            }
+            return outerClass+"Arr"+dimCount+componentType;
+        }
+        return null;
+    }
+
+    
+    protected String parameterSignatureFromParameters(Vector<String> parameters){
+        /* number of arguments of a method.*/
+        argumentlength =  parameters.size();
+        /* Pascal type signature.*/
+        String parametersignature = "(";
+        int i;
+        
+        for(i = 0; i < argumentlength; i++){
+        	parametersignature += "para"+(i+1)+": "+(String)parameters.elementAt(i);
+            if(i != parameters.size()-1){
+                parametersignature += "; ";
+            }
+        }
+        parametersignature += ")";
+        return parametersignature;
+    }
+    
+}

+ 410 - 0
utils/javapp/src/fpc/tools/javapp/PascalUnit.java

@@ -0,0 +1,410 @@
+package fpc.tools.javapp;
+
+import java.io.PrintWriter;
+import java.util.*;
+
+public class PascalUnit {
+	
+	private static class SkelItem implements Comparable<SkelItem> {
+		String className;
+		String kind;
+		
+		public SkelItem(String className, String kind) {
+			this.className = className;
+			this.kind = kind;
+		}
+
+		public int compareTo(SkelItem o) {
+			return className.compareTo(o.className);
+		}
+		
+		public String toString() {
+			return className;
+		}
+	}
+	
+	private PrintWriter unitFile;
+	private String[] pkgPrefixes;
+	private String[] excludePrefixes;
+	private String[] skelPrefixes;
+	private String includeName;
+	private HashSet<String> registeredExternalClasses, registeredInternalClasses;
+	private SortedSet<SkelItem> registeredSkelObjs;
+	private HashSet<String> registeredExternalInterfaces, registeredInternalInterfaces;
+	// maps full java class names (pkg.classname) to unique "short" Pascal names in the current unit
+	// maps from short to full name
+	private HashMap<String,String> classShortToLong, classLongToShort;
+	private JavapEnvironment env;
+
+	public PascalUnit(PrintWriter unitFile, JavapEnvironment env, ArrayList<String> pkgPrefixes, String includeName) {
+		this.unitFile = unitFile;
+		this.env = env;
+		this.pkgPrefixes = new String[pkgPrefixes.size()];
+		for (int i = 0; i < pkgPrefixes.size(); i++) {
+			this.pkgPrefixes[i] = pkgPrefixes.get(i).replace('.', '/');
+		}
+		this.excludePrefixes = new String[env.excludePrefixes.size()];
+		for (int i = 0; i < env.excludePrefixes.size(); i++) {
+			this.excludePrefixes[i] = env.excludePrefixes.get(i).replace('.', '/');
+		}
+		this.skelPrefixes = new String[env.skelPrefixes.size()];
+		for (int i = 0; i < env.skelPrefixes.size(); i++) {
+			this.skelPrefixes[i] = env.skelPrefixes.get(i).replace('.', '/');
+		}
+		this.includeName = includeName;
+		registeredExternalClasses = new HashSet<String>();
+		registeredInternalClasses = new HashSet<String>();
+		registeredExternalInterfaces = new HashSet<String>();
+		registeredInternalInterfaces = new HashSet<String>();
+		registeredSkelObjs = new TreeSet<SkelItem>();
+		classShortToLong = new HashMap<String,String>();
+		classLongToShort = new HashMap<String,String>();
+	}
+	
+
+	public void registerClassName(String fullName) {
+		String newClassShortName = getDefaultShortPascalName(fullName);
+	    String prevVal = classShortToLong.put(newClassShortName,fullName);
+	    while (prevVal != null) {
+	    	// remove the old shortname item
+	    	classShortToLong.remove(newClassShortName);
+	    	// make the two shortnames unique
+	    	newClassShortName = "";
+	    	String oldClassShortName = "";
+	    	StringTokenizer name1tok = new StringTokenizer(fullName.replace("$", "__").replace('-', '_'), "/.");
+	    	StringTokenizer name2tok = new StringTokenizer(prevVal.replace("$", "__").replace('-', '_'), "/.");
+    		String name1elem = "";
+    		String name2elem = "";
+	    	// create new short names that contain the differing characters in
+	    	// addition to just the first characters
+	    	while (name1tok.hasMoreTokens()) {
+	    		name1elem = name1tok.nextToken();
+	    		name2elem = name2tok.nextToken();
+	    		// ignore class name itself }
+	    		if (!name1tok.hasMoreTokens() ||
+	    				!name2tok.hasMoreTokens())
+	    			break;
+    			newClassShortName = newClassShortName + Character.toUpperCase(name1elem.charAt(0));
+    			oldClassShortName = oldClassShortName + Character.toUpperCase(name2elem.charAt(0));
+    			if (!name1elem.equals(name2elem)) {
+    				int minlen = Math.min(name1elem.length(),name2elem.length());
+    				for (int i = 1; i < minlen; i++) {
+    					if (name1elem.charAt(i) != name2elem.charAt(i)) {
+    						newClassShortName = newClassShortName + name1elem.charAt(i);
+    						oldClassShortName = oldClassShortName + name2elem.charAt(i);
+    					}
+    				}
+    				for (int i = minlen; i < name1elem.length(); i++)
+						newClassShortName = newClassShortName + name1elem.charAt(i);
+    				for (int i = minlen; i < name2elem.length(); i++)
+    					oldClassShortName = oldClassShortName + name2elem.charAt(i);    					
+    			}
+	    	}
+	    	newClassShortName = newClassShortName + name1elem.replace('.','_');
+	    	oldClassShortName = oldClassShortName + name2elem.replace('.', '_');
+	    	assert (!newClassShortName.equals(oldClassShortName));
+	    	// return the previous shortname, ignore
+	    	classLongToShort.put(prevVal,oldClassShortName);
+	    	prevVal = classShortToLong.put(oldClassShortName,prevVal);
+	    	// we don't support a collision for the new shortname of the old class
+	    	assert(prevVal==null);
+	    	prevVal = classShortToLong.put(newClassShortName,fullName);
+	    }
+	    classLongToShort.put(fullName,newClassShortName);
+	}
+	
+	private String getDefaultShortPascalName(String classname) {
+		String shortname = PascalClassData.getShortClassName(classname);
+		// inner class -> done (no naming problems)
+		if (classname.indexOf('$') != -1)
+			return "Inner"+shortname;
+
+		// no package?
+		if (shortname.equals(classname))
+			return shortname;
+		// add package component prefixes
+		String pkgname = PascalClassData.getClassPackageName(classname);
+		String prefix = Character.toString(Character.toUpperCase(classname.charAt(0)));
+		for (int i = 1; i < pkgname.length(); i++)
+			if ((pkgname.charAt(i) == '.'))
+				prefix = prefix + Character.toUpperCase(pkgname.charAt(i+1));
+        return prefix+shortname;
+	}
+	
+	public boolean isExternalInnerClass(String className) {
+		return registeredExternalClasses.contains(className) || registeredExternalInterfaces.contains(className);
+	}
+	
+	public String getShortPascalName(String className) {
+		if (PascalClassData.isInnerClass(className)) {
+			int nestedIndex = className.indexOf('$');
+			// get the abbreviated Pascal name of the top-level class, followed by
+			// "Inner" + the nested class names (to avoid identifier conflicts)
+			String res = getShortPascalName(className.substring(0,nestedIndex));
+			// create valid identifier for inner classes that only exist in external version
+			if (isExternalInnerClass(className)) {
+				res = res + className.substring(nestedIndex);
+				res = res.replace('.', '_').replace("$","__");
+			} else {
+				StringTokenizer innerTypes = new StringTokenizer(className.substring(nestedIndex+1), "$");
+				while (innerTypes.hasMoreTokens()) {
+					res = res + "." + "Inner"+innerTypes.nextToken();
+				}
+			}
+			return res;
+		}
+		else className = className.replace("$", "__");
+		String res = classLongToShort.get(className.replace('.','/'));
+		// happens with one class in classes.jar: com.sun.org.apache.xalan.internal.xsltc.compiler.CUP$XPathParser$actions
+		// unlike what the name suggests, it's not an inner class, and com.sun.org.apache.xalan.internal.xsltc.compiler.CUP
+		// does not exist
+		if (res == null)
+			res = getDefaultShortPascalName(className);
+		return res;
+	}
+	
+	public void registerInnerClassAsExternalClass(String className) {
+		if (!registeredExternalClasses.contains(className)) {
+			registerClassName(className);
+			registeredExternalClasses.add(className);
+		}
+	}
+
+		
+	public void registerUsedClass(String className) {
+		className = className.replace('.','/');
+		PascalClassData classData;
+		boolean isLocal;
+		boolean isSkel;
+		
+		isLocal = false;
+		isSkel = false;
+		// first check for skeleton classes/packages
+		for (int i = 0; i < skelPrefixes.length; i++) {
+			if (className.startsWith(skelPrefixes[i])) {
+				isSkel = true;
+				break;
+			}
+		}
+		if (!isSkel) {
+			// we cannot create forward definitions in the global scope for nested classes
+			if (PascalClassData.isInnerClass(className))
+				return;
+			
+			// check whether we should fully print it; if not,
+			// declare as anonymous external
+			for (int i = 0; i < pkgPrefixes.length; i++) {
+				if (className.startsWith(pkgPrefixes[i])) {
+					boolean excluded = false;
+					// then excluded
+					for (int j = 0; j < excludePrefixes.length; j++) {
+						if (className.startsWith(excludePrefixes[j])) {
+							excluded = true;
+							break;
+						}
+					}
+					if (!excluded) {
+						isLocal = true;
+						break;
+					}
+				}
+			}
+		}
+		StringTokenizer classComponents = new StringTokenizer(className,"$");
+		String completeName = "";
+		
+		if (isSkel) {
+			do {
+				SkelItem item;
+				boolean isClass;
+				completeName += classComponents.nextToken();
+				item = new SkelItem(completeName, "");
+				classData = new PascalClassData(env.getFileInputStream(completeName),null,env,false);
+				if (registeredSkelObjs.contains(item)) {
+					completeName += "$";
+					continue;
+				}
+				isClass = classData.isClass();
+				item.kind = isClass?"class":"interface";
+				registeredSkelObjs.add(item);
+				completeName += "$";
+			} while (classComponents.hasMoreTokens());
+		} else {
+			Set<String> pickedSet = null;
+			do {
+				completeName += classComponents.nextToken();
+				if (isLocal) {
+					if (registeredInternalClasses.contains(completeName) ||
+							registeredInternalInterfaces.contains(completeName))
+						continue;
+					if (pickedSet == null) {
+						classData = new PascalClassData(env.getFileInputStream(completeName),null,env,false);
+						if (classData.isClass()) 
+							pickedSet = registeredInternalClasses;
+						else
+							pickedSet = registeredInternalInterfaces;
+					}
+				} else {
+					if (registeredInternalClasses.contains(completeName) ||
+							registeredInternalInterfaces.contains(completeName))
+						continue;
+					if (pickedSet == null) {
+						classData = new PascalClassData(env.getFileInputStream(completeName),null,env,false);
+						if (classData.isClass())
+							pickedSet= registeredExternalClasses;
+						else
+							pickedSet = registeredExternalInterfaces;
+					}
+				}
+				pickedSet.add(completeName);
+				completeName += "$";
+			} while (classComponents.hasMoreTokens());
+		}
+	}
+	
+	public boolean parentIsKnownInterface(String className) {
+		className = className.substring(0,className.lastIndexOf('$'));
+		className = className.replace('.','/');
+		return
+		  registeredInternalInterfaces.contains(className) ||
+		  registeredExternalInterfaces.contains(className);
+	}
+	
+	public static void printArrayTypes(PrintWriter out, String prefix, String shortName, String shortSafeName) {
+		out.println(prefix+"Arr1"+shortName+" = array of "+shortSafeName+";");
+		out.println(prefix+"Arr2"+shortName+" = array of Arr1"+shortName+";");
+		out.println(prefix+"Arr3"+shortName+" = array of Arr2"+shortName+";");
+	}
+	
+	private void printArrayTypes(String prefix, String shortname) {
+		printArrayTypes(unitFile,prefix,shortname, shortname);
+	}
+	
+	private String RealPkgName(String name) {
+		if (name.equals("./"))
+			return "<nameless package>";
+		else
+			return name.replace('/', '.');
+	}
+	
+	private void printInternalObjs(Enumeration<String> iterator, String kind) {
+		while (iterator.hasMoreElements()) {
+			String curClass = iterator.nextElement();
+			unitFile.println("  "+getShortPascalName(curClass)+" = "+kind+";");
+	    	// create formal array types for array parameters
+			printArrayTypes("  ",getShortPascalName(curClass));
+		}
+	}
+	
+	/**
+	 * @param iterator
+	 */
+	private void printExternalObjs(Enumeration<String> iterator, String kind) {
+		while (iterator.hasMoreElements()) {
+			String curClass = iterator.nextElement();
+			String shortPascalName = getShortPascalName(curClass);
+			String shortExternalName = PascalClassData.getExternalClassName(curClass);
+			String pkgExternalName = PascalClassData.getClassPackageName(curClass).replace('/', '.');
+			unitFile.println("  "+shortPascalName+" = "+kind+" external '"+pkgExternalName+"' name '"+shortExternalName+"';");
+	    	// create formal array types for array parameters
+			printArrayTypes("  ",shortPascalName);
+		}
+	}
+	
+	private void printSkelObjs(Enumeration<SkelItem> iterator) {
+		String prefix="  ";
+		ArrayList<String> nestedClasses = new ArrayList<String>();
+		String curClass = " ";
+		if (!iterator.hasMoreElements())
+			return;
+		while (iterator.hasMoreElements()) {
+			SkelItem curSkelItem = iterator.nextElement();
+			curClass = curSkelItem.className;
+			String shortPascalName;
+			String shortExternalName = PascalClassData.getExternalClassName(curClass);
+			String pkgExternalName = PascalClassData.getClassPackageName(curClass).replace('/', '.');
+
+			// finish earlier nested types if needed
+			if (nestedClasses.size()>0) {
+				while ((nestedClasses.size()>0) &&
+						!curClass.startsWith(nestedClasses.get(nestedClasses.size()-1))) {
+					String finishingName = nestedClasses.get(nestedClasses.size()-1);
+					// remove added '$' again
+					finishingName = finishingName.substring(0,finishingName.length()-1);
+					if (nestedClasses.size()>1) {
+						finishingName = PascalClassData.getShortClassName(finishingName);
+					} else {
+						finishingName = PascalClassData.getShortPascalClassName(finishingName);
+					}
+					unitFile.println(prefix+"end;");
+					printArrayTypes(prefix,finishingName);
+					nestedClasses.remove(nestedClasses.size()-1);
+					if (prefix.length()>4)
+						prefix = prefix.substring(4);
+				}
+			}
+			if (nestedClasses.size()>0) {
+				unitFile.println(prefix+"  type");
+				prefix = prefix + "    ";
+				shortPascalName = PascalClassData.getShortClassName(curClass);
+			} else {
+				shortPascalName = PascalClassData.getShortPascalClassName(curClass);
+			}
+			unitFile.println(prefix+shortPascalName+" = "+curSkelItem.kind+" external '"+pkgExternalName+"' name '"+shortExternalName+"'");
+			// make sure we only match inner classes, not classes that start with the word in the current package
+			nestedClasses.add(curClass+"$");
+		}
+		while (nestedClasses.size()>0) {
+			String finishingName = nestedClasses.get(nestedClasses.size()-1);
+			// remove added '$' again
+			finishingName = finishingName.substring(0,finishingName.length()-1);
+			if (nestedClasses.size()>1) {
+				finishingName = PascalClassData.getShortClassName(finishingName);
+			} else {
+				finishingName = PascalClassData.getShortPascalClassName(finishingName);
+			}
+			unitFile.println(prefix+"end;");
+			printArrayTypes(prefix,finishingName);
+			nestedClasses.remove(nestedClasses.size()-1);
+			if (prefix.length()>4)
+				prefix = prefix.substring(4);
+		}
+	}
+
+	public void printUnit() {
+		Enumeration<String> strIterator;
+		Enumeration<SkelItem> skelIterator;
+		
+		unitFile.print("{ Imports for Java packages: "+RealPkgName(pkgPrefixes[0]));
+		for (int i = 1; i < pkgPrefixes.length; i++) {
+			unitFile.print(", "+RealPkgName(pkgPrefixes[i]));
+		}
+		unitFile.println(" }");
+		unitFile.println("unit "+env.outputName+";");
+		unitFile.println("{$mode objfpc}");
+		unitFile.println();
+		unitFile.println("interface");
+		unitFile.println();
+		unitFile.println("type");
+		// forward declaration for all classes/interfaces in this package
+		strIterator = Collections.enumeration(registeredInternalClasses);
+		printInternalObjs(strIterator,"class");
+		strIterator = Collections.enumeration(registeredInternalInterfaces);
+		printInternalObjs(strIterator,"interface");
+		// anonymous external declaration for all classes/interfaces from other packages 
+		strIterator = Collections.enumeration(registeredExternalClasses);
+		printExternalObjs(strIterator,"class");
+		strIterator = Collections.enumeration(registeredExternalInterfaces);
+		printExternalObjs(strIterator,"interface");
+		skelIterator = Collections.enumeration(registeredSkelObjs);
+		printSkelObjs(skelIterator);
+		unitFile.println();
+		unitFile.println("{$include "+includeName+"}");
+		unitFile.println();
+		unitFile.println("implementation");
+		unitFile.println();
+		unitFile.println("end.");
+	}
+
+
+}

+ 4 - 1
utils/javapp/src/fpc/tools/javapp/RuntimeConstants.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 public interface RuntimeConstants {
 

+ 5 - 2
utils/javapp/src/fpc/tools/javapp/StackMapData.java

@@ -22,14 +22,17 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;
 
-import static sun.tools.javap.RuntimeConstants.*;
+import static fpc.tools.javapp.RuntimeConstants.*;
 
 /* represents one entry of StackMap attribute
  */

+ 5 - 2
utils/javapp/src/fpc/tools/javapp/StackMapTableData.java

@@ -22,14 +22,17 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;
 
-import static sun.tools.javap.RuntimeConstants.*;
+import static fpc.tools.javapp.RuntimeConstants.*;
 
 /* represents one entry of StackMapTable attribute
  */

+ 4 - 1
utils/javapp/src/fpc/tools/javapp/Tables.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.io.IOException;
 import java.io.InputStream;

+ 4 - 1
utils/javapp/src/fpc/tools/javapp/TrapData.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;

+ 67 - 17
utils/javapp/src/fpc/tools/javapp/TypeSignature.java

@@ -22,9 +22,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+/*
+ * Portions Copyright (c) 2011 Jonas Maebe
+ */
 
 
-package sun.tools.javap;
+package fpc.tools.javapp;
 
 import java.util.*;
 import java.io.*;
@@ -37,18 +40,26 @@ import java.io.*;
 public class TypeSignature {
 
     String parameters = null;
+    String parameterdes = null;
     String returntype = null;
     String fieldtype = null;
     int argumentlength = 0;
 
+    protected TypeSignature() {
+    	
+    }
+    
     public TypeSignature(String JVMSignature){
+    	init(JVMSignature);
+    }
+    
+    protected void init(String JVMSignature){
 
         if(JVMSignature != null){
             if(JVMSignature.indexOf("(") == -1){
                 //This is a field type.
                 this.fieldtype = getFieldTypeSignature(JVMSignature);
             }else {
-                String parameterdes = null;
                 if((JVMSignature.indexOf(")")-1) > (JVMSignature.indexOf("("))){
                     //Get parameter signature.
                     parameterdes =
@@ -63,6 +74,30 @@ public class TypeSignature {
         }
     }
 
+    /**
+     * Checks access of class, field or method.
+     */
+    public static boolean checkAccess(String accflags[], JavapEnvironment env){
+
+        boolean ispublic = false;
+        boolean isprotected = false;
+        boolean isprivate = false;
+        boolean ispackage = false;
+
+        for(int i= 0; i < accflags.length; i++){
+            if(accflags[i].equals("public")) ispublic = true;
+            else if (accflags[i].indexOf("protected")!=-1) isprotected = true;
+            else if (accflags[i].indexOf("private")!=-1) isprivate = true;
+        }
+
+        if(!(ispublic || isprotected || isprivate)) ispackage = true;
+
+        if((env.showAccess == JavapEnvironment.PUBLIC) && (isprotected || isprivate || ispackage)) return false;
+        else if((env.showAccess == JavapEnvironment.PROTECTED) && (isprivate || ispackage)) return false;
+        else if((env.showAccess == JavapEnvironment.PACKAGE) && (isprivate)) return false;
+        else return true;
+    }
+
     /**
      * Returns java type signature of a field.
      */
@@ -78,8 +113,8 @@ public class TypeSignature {
     /**
      * Returns java type signature of a parameter.
      */
-    public String getParametersHelper(String parameterdes){
-        Vector parameters = new Vector();
+    public Vector<String> getParametersList(String parameterdes){
+        Vector<String> parameters = new Vector<String>();
         int startindex = -1;
         int endindex = -1;
         String param = "";
@@ -179,20 +214,15 @@ public class TypeSignature {
             }
         }
 
-        /* number of arguments of a method.*/
-        argumentlength =  parameters.size();
-
-        /* java type signature.*/
-        String parametersignature = "(";
-        int i;
+        return parameters;
+    }
 
-        for(i = 0; i < parameters.size(); i++){
-            parametersignature += (String)parameters.elementAt(i);
-            if(i != parameters.size()-1){
-                parametersignature += ", ";
-            }
-        }
-        parametersignature += ")";
+    /**
+     * Returns java type signature of a parameter.
+     */
+    public String getParametersHelper(String parameterdes){
+        Vector<String> parameters = getParametersList(parameterdes);
+        String parametersignature = parameterSignatureFromParameters(parameters);
         return parametersignature;
     }
 
@@ -292,4 +322,24 @@ public class TypeSignature {
     public int getArgumentlength(){
         return argumentlength;
     }
+    
+    
+    
+    protected String parameterSignatureFromParameters(Vector<String> parameters){
+        /* number of arguments of a method.*/
+        argumentlength =  parameters.size();
+        /* java type signature.*/
+        String parametersignature = "(";
+        int i;
+
+        for(i = 0; i < parameters.size(); i++){
+            parametersignature += (String)parameters.elementAt(i);
+            if(i != parameters.size()-1){
+                parametersignature += ", ";
+            }
+        }
+        parametersignature += ")";
+        return parametersignature;
+    }
+    
 }

Some files were not shown because too many files changed in this diff