summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2008-07-18 12:18:39 +0000
committerSven Gothel <[email protected]>2008-07-18 12:18:39 +0000
commitc020a396e0cab63fa2b4d283decbea7d20ce3511 (patch)
treeff6b28bf17ed1739ca715ed443795af8f4fe2196
parentaa1a3b6381b79fa1caa43bd6169244f1cff23500 (diff)
- New config feature: 'IgnoreExtendedInterfaceSymbols <java class source file>'
All enums and functions within the specified interface (or abstract class), will not be emitted in the resulting interface. This simplifies the GL profile config's a lot, as well reducing the footprint. - Adding JavaParser 'com.sun.gluegen.jgram.JavaParser', which collects enums and functions. - New config feature 'UnsupportedExceptionType <exception name>', which complements the 'RuntimeExceptionType <exception name>' feature. UnsupportedExceptionType's are thrown in case a function is not available. - Fix: BuildComposablePipeline - Method names are now unique by: - name, return type, modifiers and arguments - Cleanup: - mv: com.sun.gluegen.runtime.opengl.GLUnifiedName -> com.sun.gluegen.opengl.GLUnifiedName - contains only the compile time portion of the former - add: com.sun.gluegen.opengl.runtime.GLExtensionNames - contains the extension name handling - bulletproof GL function and GL enum recognition. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/gluegen/branches/JOGL_2_SANDBOX@101 a78bb65f-1512-4460-ba86-f6dc96a7bf27
-rwxr-xr-xmake/build.xml34
-rw-r--r--src/java/com/sun/gluegen/CMethodBindingEmitter.java2
-rw-r--r--src/java/com/sun/gluegen/FunctionEmitter.java7
-rw-r--r--src/java/com/sun/gluegen/JavaConfiguration.java75
-rw-r--r--src/java/com/sun/gluegen/JavaEmitter.java26
-rw-r--r--src/java/com/sun/gluegen/JavaMethodBindingEmitter.java15
-rw-r--r--src/java/com/sun/gluegen/jgram/JavaParser.g1315
-rw-r--r--src/java/com/sun/gluegen/jgram/Test.java132
-rw-r--r--src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java169
-rwxr-xr-xsrc/java/com/sun/gluegen/opengl/GLConfiguration.java34
-rw-r--r--src/java/com/sun/gluegen/opengl/GLEmitter.java36
-rwxr-xr-xsrc/java/com/sun/gluegen/opengl/GLJavaMethodBindingEmitter.java1
-rw-r--r--src/java/com/sun/gluegen/opengl/GLUnifiedName.java (renamed from src/java/com/sun/gluegen/runtime/opengl/GLUnifiedName.java)153
-rwxr-xr-xsrc/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java4
-rwxr-xr-xsrc/java/com/sun/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java2
-rw-r--r--src/java/com/sun/gluegen/runtime/opengl/GLExtensionNames.java173
-rw-r--r--src/java/com/sun/gluegen/runtime/opengl/GLProcAddressHelper.java4
17 files changed, 1945 insertions, 237 deletions
diff --git a/make/build.xml b/make/build.xml
index 1ff74b8..dd9f147 100755
--- a/make/build.xml
+++ b/make/build.xml
@@ -81,11 +81,13 @@
<!-- The location of the GlueGen source and the C grammar files. -->
<property name="gluegen" value="${src.java}/com/sun/gluegen" />
<property name="c.grammar" value="${gluegen}/cgram" />
+ <property name="j.grammar" value="${gluegen}/jgram" />
<!-- The resulting location of the generated Java files from the
- C grammar via ANTLR. -->
<property name="gluegen.build" value="${src.generated.java}/com/sun/gluegen" />
- <property name="generated.java.from.grammar" value="${gluegen.build}/cgram" />
+ <property name="generated.java.from.c.grammar" value="${gluegen.build}/cgram" />
+ <property name="generated.java.from.j.grammar" value="${gluegen.build}/jgram" />
</target>
<!--
@@ -95,7 +97,7 @@
- @param output.dir the directory to write the generated files to. If
- the directory does not exist, it will be created.
-->
- <target name="generate.c.grammar">
+ <target name="generate.grammar">
<!-- Generate the Java files -->
<antlr target="${output.dir}/${target}" outputdirectory="${output.dir}">
<classpath refid="antlr.classpath" />
@@ -405,37 +407,47 @@
including supergrammars, in one place, so copy all of the
grammars to the output directory up front so we don't put
temporary files into the source tree -->
- <mkdir dir="${generated.java.from.grammar}" />
- <copy todir="${generated.java.from.grammar}">
+ <mkdir dir="${generated.java.from.c.grammar}" />
+ <copy todir="${generated.java.from.c.grammar}">
<fileset dir="${c.grammar}">
<include name="*.g" />
</fileset>
</copy>
+ <mkdir dir="${generated.java.from.j.grammar}" />
+ <copy todir="${generated.java.from.j.grammar}">
+ <fileset dir="${j.grammar}">
+ <include name="*.g" />
+ </fileset>
+ </copy>
<!-- Generate the Java files from the C grammar using ANTLR. -->
- <antcall target="generate.c.grammar">
- <param name="output.dir" value="${generated.java.from.grammar}" />
+ <antcall target="generate.grammar">
+ <param name="output.dir" value="${generated.java.from.c.grammar}" />
<param name="target" value="StdCParser.g" />
</antcall>
<antcall target="generate.c.grammar.glib">
- <param name="output.dir" value="${generated.java.from.grammar}" />
+ <param name="output.dir" value="${generated.java.from.c.grammar}" />
<param name="target" value="GnuCParser.g" />
<param name="glib" value="StdCParser.g" />
</antcall>
- <antcall target="generate.c.grammar">
- <param name="output.dir" value="${generated.java.from.grammar}" />
+ <antcall target="generate.grammar">
+ <param name="output.dir" value="${generated.java.from.c.grammar}" />
<param name="target" value="GnuCTreeParser.g" />
</antcall>
<antcall target="generate.c.grammar.glib">
- <param name="output.dir" value="${generated.java.from.grammar}" />
+ <param name="output.dir" value="${generated.java.from.c.grammar}" />
<param name="target" value="GnuCEmitter.g" />
<param name="glib" value="GnuCTreeParser.g" />
</antcall>
<antcall target="generate.c.grammar.glib">
- <param name="output.dir" value="${generated.java.from.grammar}" />
+ <param name="output.dir" value="${generated.java.from.c.grammar}" />
<param name="target" value="HeaderParser.g" />
<param name="glib" value="GnuCTreeParser.g" />
</antcall>
+ <antcall target="generate.grammar">
+ <param name="output.dir" value="${generated.java.from.j.grammar}" />
+ <param name="target" value="JavaParser.g" />
+ </antcall>
<!-- Build GlueGen using the generated Java files along with the
- original source. -->
diff --git a/src/java/com/sun/gluegen/CMethodBindingEmitter.java b/src/java/com/sun/gluegen/CMethodBindingEmitter.java
index 03b8422..2085477 100644
--- a/src/java/com/sun/gluegen/CMethodBindingEmitter.java
+++ b/src/java/com/sun/gluegen/CMethodBindingEmitter.java
@@ -133,7 +133,7 @@ public class CMethodBindingEmitter extends FunctionEmitter
boolean forIndirectBufferAndArrayImplementation,
MachineDescription machDesc)
{
- super(output);
+ super(output, false);
assert(binding != null);
assert(javaClassName != null);
diff --git a/src/java/com/sun/gluegen/FunctionEmitter.java b/src/java/com/sun/gluegen/FunctionEmitter.java
index 0d0f225..32ac071 100644
--- a/src/java/com/sun/gluegen/FunctionEmitter.java
+++ b/src/java/com/sun/gluegen/FunctionEmitter.java
@@ -47,6 +47,7 @@ public abstract class FunctionEmitter
{
public static final EmissionModifier STATIC = new EmissionModifier("static");
+ private boolean isInterfaceVal;
private ArrayList modifiers = new ArrayList();
private CommentEmitter commentEmitter = null;
private PrintWriter defaultOutput;
@@ -54,10 +55,11 @@ public abstract class FunctionEmitter
/**
* Constructs the FunctionEmitter with a CommentEmitter that emits nothing.
*/
- public FunctionEmitter(PrintWriter defaultOutput)
+ public FunctionEmitter(PrintWriter defaultOutput, boolean isInterface)
{
assert(defaultOutput != null);
this.defaultOutput = defaultOutput;
+ this.isInterfaceVal = isInterface;
}
/**
@@ -67,8 +69,11 @@ public abstract class FunctionEmitter
modifiers = (ArrayList) arg.modifiers.clone();
commentEmitter = arg.commentEmitter;
defaultOutput = arg.defaultOutput;
+ isInterfaceVal = arg.isInterfaceVal;
}
+ public boolean isInterface() { return isInterfaceVal; }
+
public PrintWriter getDefaultOutput() { return defaultOutput; }
public void addModifiers(Iterator/*<EmissionModifier>*/ mi)
diff --git a/src/java/com/sun/gluegen/JavaConfiguration.java b/src/java/com/sun/gluegen/JavaConfiguration.java
index 8cde267..a6ed790 100644
--- a/src/java/com/sun/gluegen/JavaConfiguration.java
+++ b/src/java/com/sun/gluegen/JavaConfiguration.java
@@ -44,6 +44,7 @@ import java.lang.reflect.Array;
import java.util.*;
import java.util.regex.*;
+import com.sun.gluegen.jgram.*;
import com.sun.gluegen.cgram.types.*;
/** Parses and provides access to the contents of .cfg files for the
@@ -100,6 +101,7 @@ public class JavaConfiguration {
* checks fail. Defaults to RuntimeException.
*/
private String runtimeExceptionType = "RuntimeException";
+ private String unsupportedExceptionType = "UnsupportedOperationException";
private Map/*<String,Integer>*/ accessControl = new HashMap();
private Map/*<String,TypeInfo>*/ typeInfoMap = new HashMap();
private Set/*<String>*/ returnsString = new HashSet();
@@ -109,6 +111,7 @@ public class JavaConfiguration {
* converted to String args; value is List of Integer argument indices
*/
private Map/*<String,List<Integer>>*/ argumentsAreString = new HashMap();
+ private Set/*<String>*/ ignoresIf = new HashSet();
private Set/*<Pattern>*/ ignores = new HashSet();
private Map/*<String,Pattern>*/ ignoreMap = new HashMap();
private Set/*<Pattern>*/ ignoreNots = new HashSet();
@@ -262,6 +265,8 @@ public class JavaConfiguration {
public String gluegenRuntimePackage() { return gluegenRuntimePackage; }
/** Returns the kind of exception to raise if run-time checks fail in the generated code. */
public String runtimeExceptionType() { return runtimeExceptionType; }
+ /** Returns the kind of exception to raise if run-time checks fail in the generated code. */
+ public String unsupportedExceptionType() { return unsupportedExceptionType; }
/** Returns the list of imports that should be emitted at the top of each .java file. */
public List/*<String>*/ imports() { return imports; }
@@ -547,7 +552,11 @@ public class JavaConfiguration {
}
public void dumpIgnores() {
- System.err.println("Ignores: ");
+ System.err.println("Ignores (If): ");
+ for (Iterator iter = ignoresIf.iterator(); iter.hasNext(); ) {
+ System.err.println("\t"+(String)iter.next());
+ }
+ System.err.println("Ignores (All): ");
for (Iterator iter = ignores.iterator(); iter.hasNext(); ) {
System.err.println("\t"+(String)iter.next());
}
@@ -555,13 +564,27 @@ public class JavaConfiguration {
/** Returns true if this #define, function, struct, or field within
a struct should be ignored during glue code generation. */
- public boolean shouldIgnore(String symbol) {
+ public boolean shouldIgnoreInInterface(String symbol) {
+ // Simple case; the entire symbol is in the interface ignore table.
+ if (ignoresIf.contains(symbol)) {
+ // System.err.println("Ignore If: "+symbol);
+ // dumpIgnores();
+ return true;
+ }
+ return shouldIgnoreInImpl_Int(symbol);
+ }
+
+ public boolean shouldIgnoreInImpl(String symbol) {
+ return shouldIgnoreInImpl_Int(symbol);
+ }
+
+ private boolean shouldIgnoreInImpl_Int(String symbol) {
// System.err.println("CHECKING IGNORE: " + symbol);
// Simple case; the entire symbol is in the ignore table.
if (ignores.contains(symbol)) {
- // System.err.println("Ignore: "+symbol);
+ // System.err.println("Ignore Impl Simple: "+symbol);
// dumpIgnores();
return true;
}
@@ -572,6 +595,7 @@ public class JavaConfiguration {
Pattern regexp = (Pattern)iter.next();
Matcher matcher = regexp.matcher(symbol);
if (matcher.matches()) {
+ // System.err.println("Ignore Impl RexEx: "+symbol);
return true;
}
}
@@ -586,8 +610,10 @@ public class JavaConfiguration {
if (!matcher.matches()) {
// Special case as this is most often likely to be the case.
// Unignores are not used very often.
- if(unignores.size() == 0)
+ if(unignores.size() == 0) {
+ // System.err.println("Ignore Impl unignores==0: "+symbol);
return true;
+ }
boolean unignoreFound = false;
for (Iterator iter2 = unignores.iterator(); iter2.hasNext(); ) {
@@ -600,6 +626,7 @@ public class JavaConfiguration {
}
if (!unignoreFound)
+ // System.err.println("Ignore Impl !unignore: "+symbol);
return true;
}
}
@@ -754,6 +781,8 @@ public class JavaConfiguration {
// because ReturnedArrayLength changes them.
} else if (cmd.equalsIgnoreCase("ArgumentIsString")) {
readArgumentIsString(tok, filename, lineNo);
+ } else if (cmd.equalsIgnoreCase("IgnoreExtendedInterfaceSymbols")) {
+ readIgnoreExtendedInterfaceSymbols(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("Ignore")) {
readIgnore(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("Unignore")) {
@@ -816,6 +845,8 @@ public class JavaConfiguration {
readRenameJavaMethod(tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("RuntimeExceptionType")) {
runtimeExceptionType = readString("RuntimeExceptionType", tok, filename, lineNo);
+ } else if (cmd.equalsIgnoreCase("UnsupportedExceptionType")) {
+ unsupportedExceptionType = readString("UnsupportedExceptionType", tok, filename, lineNo);
} else if (cmd.equalsIgnoreCase("JavaPrologue")) {
readJavaPrologueOrEpilogue(tok, filename, lineNo, true);
// Warning: make sure delimiters are reset at the top of this loop
@@ -940,6 +971,41 @@ public class JavaConfiguration {
}
}
+ protected void readIgnoreExtendedInterfaceSymbols(StringTokenizer tok, String filename, int lineNo) {
+ File javaFile;
+ BufferedReader javaReader;
+ try {
+ javaFile = new File(tok.nextToken());
+ javaReader = new BufferedReader(new FileReader(javaFile));
+ } catch (FileNotFoundException e) {
+ System.err.println(e);
+ return;
+ }
+
+ JavaLexer lexer = new JavaLexer(javaReader);
+ lexer.setFilename(javaFile.getName());
+
+ JavaParser parser = new JavaParser(lexer);
+ parser.setFilename(javaFile.getName());
+
+ try {
+ parser.compilationUnit();
+ } catch (Exception e) {
+ System.err.println(e);
+ return;
+ }
+
+ Set set = parser.getParsedEnumNames();
+ for(Iterator iter = set.iterator(); iter.hasNext(); ) {
+ ignoresIf.add((String) iter.next());
+ }
+ System.out.println("Functions");
+ set = parser.getParsedFunctionNames();
+ for(Iterator iter = set.iterator(); iter.hasNext(); ) {
+ ignoresIf.add((String) iter.next());
+ }
+ }
+
protected void readIgnore(StringTokenizer tok, String filename, int lineNo) {
try {
String regex = tok.nextToken();
@@ -959,6 +1025,7 @@ public class JavaConfiguration {
Pattern pattern = (Pattern) ignoreMap.get(regex);
ignoreMap.remove(regex);
ignores.remove(pattern);
+ ignoresIf.remove(pattern.toString());
// If the pattern wasn't registered before, then make sure we have a
// valid pattern instance to put into the unignores set.
diff --git a/src/java/com/sun/gluegen/JavaEmitter.java b/src/java/com/sun/gluegen/JavaEmitter.java
index fa0c783..ac9644a 100644
--- a/src/java/com/sun/gluegen/JavaEmitter.java
+++ b/src/java/com/sun/gluegen/JavaEmitter.java
@@ -276,7 +276,7 @@ public class JavaEmitter implements GlueEmitter {
// currently only emits only numeric defines -- if it handled #define'd
// objects it would make a bigger difference.
- if (!cfg.shouldIgnore(name)) {
+ if (!cfg.shouldIgnoreInInterface(name)) {
String type = getJavaType(name, value);
if (optionalComment != null && optionalComment.length() != 0) {
javaWriter().println(" /** " + optionalComment + " */");
@@ -340,7 +340,7 @@ public class JavaEmitter implements GlueEmitter {
for (Iterator iter = funcsToBind.iterator(); iter.hasNext(); ) {
FunctionSymbol cFunc = (FunctionSymbol) iter.next();
// Check to see whether this function should be ignored
- if (cfg.shouldIgnore(cFunc.getName())) {
+ if (cfg.shouldIgnoreInImpl(cFunc.getName())) {
continue; // don't generate bindings for this symbol
}
@@ -352,12 +352,14 @@ public class JavaEmitter implements GlueEmitter {
for (int i = 0; i < methodBindingEmitters.size(); ++i) {
FunctionEmitter emitter = (FunctionEmitter)methodBindingEmitters.get(i);
try {
- emitter.emit();
+ if (!emitter.isInterface() || !cfg.shouldIgnoreInInterface(emitter.getName())) {
+ emitter.emit();
+ emitter.getDefaultOutput().println(); // put newline after method body
+ }
} catch (Exception e) {
throw new RuntimeException(
"Error while emitting binding for \"" + emitter.getName() + "\"", e);
}
- emitter.getDefaultOutput().println(); // put newline after method body
}
// Return the list of FunctionSymbols that we generated gluecode for
@@ -420,6 +422,7 @@ public class JavaEmitter implements GlueEmitter {
new JavaMethodBindingEmitter(binding,
writer,
cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
!signatureOnly && needsBody,
cfg.tagNativeBinding(),
false,
@@ -427,7 +430,8 @@ public class JavaEmitter implements GlueEmitter {
false,
false,
false,
- isUnimplemented);
+ isUnimplemented,
+ signatureOnly);
switch (accessControl) {
case ACC_PUBLIC: emitter.addModifier(JavaMethodBindingEmitter.PUBLIC); break;
case ACC_PROTECTED: emitter.addModifier(JavaMethodBindingEmitter.PROTECTED); break;
@@ -483,6 +487,7 @@ public class JavaEmitter implements GlueEmitter {
new JavaMethodBindingEmitter(binding,
writer,
cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
false,
cfg.tagNativeBinding(),
true,
@@ -490,6 +495,7 @@ public class JavaEmitter implements GlueEmitter {
true,
true,
false,
+ false,
false);
emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
if (cfg.allStatic()) {
@@ -508,6 +514,7 @@ public class JavaEmitter implements GlueEmitter {
new JavaMethodBindingEmitter(binding,
writer,
cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
false,
cfg.tagNativeBinding(),
true,
@@ -515,6 +522,7 @@ public class JavaEmitter implements GlueEmitter {
true,
false,
true,
+ false,
false);
emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
@@ -752,7 +760,7 @@ public class JavaEmitter implements GlueEmitter {
return;
}
- if (cfg.shouldIgnore(name)) {
+ if (cfg.shouldIgnoreInInterface(name)) {
return;
}
@@ -916,7 +924,7 @@ public class JavaEmitter implements GlueEmitter {
for (int i = 0; i < structType.getNumFields(); i++) {
Field field = structType.getField(i);
Type fieldType = field.getType();
- if (!cfg.shouldIgnore(name + " " + field.getName())) {
+ if (!cfg.shouldIgnoreInInterface(name + " " + field.getName())) {
if (fieldType.isFunctionPointer()) {
if (doBaseClass) {
try {
@@ -932,6 +940,7 @@ public class JavaEmitter implements GlueEmitter {
new JavaMethodBindingEmitter(binding,
writer,
cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
true,
cfg.tagNativeBinding(),
false,
@@ -939,6 +948,7 @@ public class JavaEmitter implements GlueEmitter {
false,
false, // FIXME: should unify this with the general emission code
false, // FIXME: should unify this with the general emission code
+ false, // FIXME: should unify this with the general emission code
false);
emitter.addModifier(JavaMethodBindingEmitter.PUBLIC);
emitter.emit();
@@ -948,6 +958,7 @@ public class JavaEmitter implements GlueEmitter {
new JavaMethodBindingEmitter(binding,
writer,
cfg.runtimeExceptionType(),
+ cfg.unsupportedExceptionType(),
false,
cfg.tagNativeBinding(),
true,
@@ -955,6 +966,7 @@ public class JavaEmitter implements GlueEmitter {
true,
true, // FIXME: should unify this with the general emission code
false, // FIXME: should unify this with the general emission code
+ false, // FIXME: should unify this with the general emission code
false);
emitter.addModifier(JavaMethodBindingEmitter.PRIVATE);
emitter.addModifier(JavaMethodBindingEmitter.NATIVE);
diff --git a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java
index 528a0cb..73b12d8 100644
--- a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java
+++ b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java
@@ -65,6 +65,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
// Exception type raised in the generated code if runtime checks fail
private String runtimeExceptionType;
+ private String unsupportedExceptionType;
protected boolean emitBody;
protected boolean eraseBufferAndArrayTypes;
@@ -95,6 +96,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
public JavaMethodBindingEmitter(MethodBinding binding,
PrintWriter output,
String runtimeExceptionType,
+ String unsupportedExceptionType,
boolean emitBody,
boolean tagNativeBinding,
boolean eraseBufferAndArrayTypes,
@@ -102,11 +104,13 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
boolean forImplementingMethodCall,
boolean forDirectBufferImplementation,
boolean forIndirectBufferAndArrayImplementation,
- boolean isUnimplemented)
+ boolean isUnimplemented,
+ boolean isInterface)
{
- super(output);
+ super(output, isInterface);
this.binding = binding;
this.runtimeExceptionType = runtimeExceptionType;
+ this.unsupportedExceptionType = unsupportedExceptionType;
this.emitBody = emitBody;
this.tagNativeBinding = tagNativeBinding;
this.eraseBufferAndArrayTypes = eraseBufferAndArrayTypes;
@@ -126,6 +130,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
super(arg);
binding = arg.binding;
runtimeExceptionType = arg.runtimeExceptionType;
+ unsupportedExceptionType = arg.unsupportedExceptionType;
emitBody = arg.emitBody;
tagNativeBinding = arg.tagNativeBinding;
eraseBufferAndArrayTypes = arg.eraseBufferAndArrayTypes;
@@ -160,6 +165,10 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
return runtimeExceptionType;
}
+ public String getUnsupportedExceptionType() {
+ return unsupportedExceptionType;
+ }
+
/** If the underlying function returns an array (currently only
arrays of compound types are supported) as opposed to a pointer
to an object, this method should be called to provide a
@@ -377,7 +386,7 @@ public class JavaMethodBindingEmitter extends FunctionEmitter
writer.println();
writer.println(" {");
if (isUnimplemented) {
- writer.println(" throw new " + getRuntimeExceptionType() + "(\"Unimplemented\");");
+ writer.println(" throw new " + getUnsupportedExceptionType() + "(\"Unimplemented\");");
} else {
emitPrologueOrEpilogue(prologue, writer);
emitPreCallSetup(binding, writer);
diff --git a/src/java/com/sun/gluegen/jgram/JavaParser.g b/src/java/com/sun/gluegen/jgram/JavaParser.g
new file mode 100644
index 0000000..e3a1962
--- /dev/null
+++ b/src/java/com/sun/gluegen/jgram/JavaParser.g
@@ -0,0 +1,1315 @@
+/* Java 1.3 Recognizer
+ *
+ * Run 'java Main [-showtree] directory-full-of-java-files'
+ *
+ * [The -showtree option pops up a Swing frame that shows
+ * the AST constructed from the parser.]
+ *
+ * Run 'java Main <directory full of java files>'
+ *
+ * Contributing authors:
+ * John Mitchell [email protected]
+ * Terence Parr [email protected]
+ * John Lilley [email protected]
+ * Scott Stanchfield [email protected]
+ * Markus Mohnen [email protected]
+ * Peter Williams [email protected]
+ * Allan Jacobs [email protected]
+ * Steve Messick [email protected]
+ * John Pybus [email protected]
+ *
+ * Version 1.00 December 9, 1997 -- initial release
+ * Version 1.01 December 10, 1997
+ * fixed bug in octal def (0..7 not 0..8)
+ * Version 1.10 August 1998 (parrt)
+ * added tree construction
+ * fixed definition of WS,comments for mac,pc,unix newlines
+ * added unary plus
+ * Version 1.11 (Nov 20, 1998)
+ * Added "shutup" option to turn off last ambig warning.
+ * Fixed inner class def to allow named class defs as statements
+ * synchronized requires compound not simple statement
+ * add [] after builtInType DOT class in primaryExpression
+ * "const" is reserved but not valid..removed from modifiers
+ * Version 1.12 (Feb 2, 1999)
+ * Changed LITERAL_xxx to xxx in tree grammar.
+ * Updated java.g to use tokens {...} now for 2.6.0 (new feature).
+ *
+ * Version 1.13 (Apr 23, 1999)
+ * Didn't have (stat)? for else clause in tree parser.
+ * Didn't gen ASTs for interface extends. Updated tree parser too.
+ * Updated to 2.6.0.
+ * Version 1.14 (Jun 20, 1999)
+ * Allowed final/abstract on local classes.
+ * Removed local interfaces from methods
+ * Put instanceof precedence where it belongs...in relationalExpr
+ * It also had expr not type as arg; fixed it.
+ * Missing ! on SEMI in classBlock
+ * fixed: (expr) + "string" was parsed incorrectly (+ as unary plus).
+ * fixed: didn't like Object[].class in parser or tree parser
+ * Version 1.15 (Jun 26, 1999)
+ * Screwed up rule with instanceof in it. :( Fixed.
+ * Tree parser didn't like (expr).something; fixed.
+ * Allowed multiple inheritance in tree grammar. oops.
+ * Version 1.16 (August 22, 1999)
+ * Extending an interface built a wacky tree: had extra EXTENDS.
+ * Tree grammar didn't allow multiple superinterfaces.
+ * Tree grammar didn't allow empty var initializer: {}
+ * Version 1.17 (October 12, 1999)
+ * ESC lexer rule allowed 399 max not 377 max.
+ * java.tree.g didn't handle the expression of synchronized
+ * statements.
+ * Version 1.18 (August 12, 2001)
+ * Terence updated to Java 2 Version 1.3 by
+ * observing/combining work of Allan Jacobs and Steve
+ * Messick. Handles 1.3 src. Summary:
+ * o primary didn't include boolean.class kind of thing
+ * o constructor calls parsed explicitly now:
+ * see explicitConstructorInvocation
+ * o add strictfp modifier
+ * o missing objBlock after new expression in tree grammar
+ * o merged local class definition alternatives, moved after declaration
+ * o fixed problem with ClassName.super.field
+ * o reordered some alternatives to make things more efficient
+ * o long and double constants were not differentiated from int/float
+ * o whitespace rule was inefficient: matched only one char
+ * o add an examples directory with some nasty 1.3 cases
+ * o made Main.java use buffered IO and a Reader for Unicode support
+ * o supports UNICODE?
+ * Using Unicode charVocabulay makes code file big, but only
+ * in the bitsets at the end. I need to make ANTLR generate
+ * unicode bitsets more efficiently.
+ * Version 1.19 (April 25, 2002)
+ * Terence added in nice fixes by John Pybus concerning floating
+ * constants and problems with super() calls. John did a nice
+ * reorg of the primary/postfix expression stuff to read better
+ * and makes f.g.super() parse properly (it was METHOD_CALL not
+ * a SUPER_CTOR_CALL). Also:
+ *
+ * o "finally" clause was a root...made it a child of "try"
+ * o Added stuff for asserts too for Java 1.4, but *commented out*
+ * as it is not backward compatible.
+ *
+ * Version 1.20 (October 27, 2002)
+ *
+ * Terence ended up reorging John Pybus' stuff to
+ * remove some nondeterminisms and some syntactic predicates.
+ * Note that the grammar is stricter now; e.g., this(...) must
+ * be the first statement.
+ *
+ * Trinary ?: operator wasn't working as array name:
+ * (isBig ? bigDigits : digits)[i];
+ *
+ * Checked parser/tree parser on source for
+ * Resin-2.0.5, jive-2.1.1, jdk 1.3.1, Lucene, antlr 2.7.2a4,
+ * and the 110k-line jGuru server source.
+ *
+ * Version 1.21 (October 17, 2003)
+ * Fixed lots of problems including:
+ * Ray Waldin: add typeDefinition to interfaceBlock in java.tree.g
+ * He found a problem/fix with floating point that start with 0
+ * Ray also fixed problem that (int.class) was not recognized.
+ * Thorsten van Ellen noticed that \n are allowed incorrectly in strings.
+ * TJP fixed CHAR_LITERAL analogously.
+ *
+ * Version 1.22 (April 14, 2004)
+ * Changed vocab to be ..\uFFFE to avoid -1 char. removed dummy VOCAB rule.
+ *
+ * This grammar is in the PUBLIC DOMAIN
+ */
+
+header {
+ package com.sun.gluegen.jgram;
+
+ import java.util.*;
+
+ import antlr.CommonAST;
+}
+
+class JavaParser extends Parser;
+
+options {
+ k = 2; // two token lookahead
+ exportVocab=Java; // Call its vocabulary "Java"
+ codeGenMakeSwitchThreshold = 2; // Some optimizations
+ codeGenBitsetTestThreshold = 3;
+ defaultErrorHandler = false; // Don't generate parser error handlers
+ buildAST = true;
+ //buildAST = false;
+}
+
+tokens {
+ BLOCK; MODIFIERS; OBJBLOCK; SLIST; CTOR_DEF; METHOD_DEF; VARIABLE_DEF;
+ INSTANCE_INIT; STATIC_INIT; TYPE; CLASS_DEF; INTERFACE_DEF;
+ PACKAGE_DEF; ARRAY_DECLARATOR; EXTENDS_CLAUSE; IMPLEMENTS_CLAUSE;
+ PARAMETERS; PARAMETER_DEF; LABELED_STAT; TYPECAST; INDEX_OP;
+ POST_INC; POST_DEC; METHOD_CALL; EXPR; ARRAY_INIT;
+ IMPORT; UNARY_MINUS; UNARY_PLUS; CASE_GROUP; ELIST; FOR_INIT; FOR_CONDITION;
+ FOR_ITERATOR; EMPTY_STAT; FINAL="final"; ABSTRACT="abstract";
+ STRICTFP="strictfp"; SUPER_CTOR_CALL; CTOR_CALL;
+}
+
+{
+ public void clearParsedEnumNames() {
+ enumNames.clear();
+ }
+
+ /** Returns the EnumTypes this HeaderParser processed. */
+ public Set getParsedEnumNames() {
+ return enumNames;
+ }
+
+ /** Clears the list of functions this HeaderParser has parsed.
+ Useful when reusing the same HeaderParser for more than one
+ header file. */
+ public void clearParsedFunctionNames() {
+ functionNames.clear();
+ }
+
+ /** Returns the list of FunctionSymbols this HeaderParser has parsed. */
+ public Set getParsedFunctionNames() {
+ return functionNames;
+ }
+
+ private Set/*<String>*/ functionNames = new HashSet();
+ // hash from name of an enumerated value to the EnumType to which it belongs
+ private Set/*<String>*/ enumNames = new HashSet();
+
+ private int blockDepth = 0;
+}
+
+// Compilation Unit: In Java, this is a single file. This is the start
+// rule for this parser
+compilationUnit
+ : // A compilation unit starts with an optional package definition
+ ( packageDefinition
+ | /* nothing */
+ )
+
+ // Next we have a series of zero or more import statements
+ ( importDefinition )*
+
+ // Wrapping things up with any number of class or interface
+ // definitions
+ ( typeDefinition )*
+
+ EOF!
+ ;
+
+
+// Package statement: "package" followed by an identifier.
+packageDefinition
+ options {defaultErrorHandler = true;} // let ANTLR handle errors
+ : p:"package"^ {#p.setType(PACKAGE_DEF);} identifier SEMI!
+ ;
+
+
+// Import statement: import followed by a package or class name
+importDefinition
+ options {defaultErrorHandler = true;}
+ : i:"import"^ {#i.setType(IMPORT);} identifierStar SEMI!
+ ;
+
+// A type definition in a file is either a class or interface definition.
+typeDefinition
+ options {defaultErrorHandler = true;}
+ : m:modifiers!
+ ( classDefinition[#m]
+ | interfaceDefinition[#m]
+ )
+ | SEMI!
+ ;
+
+/** A declaration is the creation of a reference or primitive-type variable
+ * Create a separate Type/Var tree for each var in the var list.
+ */
+declaration!
+ : m:modifiers t:typeSpec[false] v:variableDefinitions[#m,#t]
+ {#declaration = #v;}
+ ;
+
+// A type specification is a type name with possible brackets afterwards
+// (which would make it an array type).
+typeSpec[boolean addImagNode]
+ : classTypeSpec[addImagNode]
+ | builtInTypeSpec[addImagNode]
+ ;
+
+// A class type specification is a class type with possible brackets afterwards
+// (which would make it an array type).
+classTypeSpec[boolean addImagNode]
+ : identifier (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+ {
+ if ( addImagNode ) {
+ #classTypeSpec = #(#[TYPE,"TYPE"], #classTypeSpec);
+ }
+ }
+ ;
+
+// A builtin type specification is a builtin type with possible brackets
+// afterwards (which would make it an array type).
+builtInTypeSpec[boolean addImagNode]
+ : builtInType (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+ {
+ if ( addImagNode ) {
+ #builtInTypeSpec = #(#[TYPE,"TYPE"], #builtInTypeSpec);
+ }
+ }
+ ;
+
+// A type name. which is either a (possibly qualified) class name or
+// a primitive (builtin) type
+type
+ : identifier
+ | builtInType
+ ;
+
+// The primitive types.
+builtInType
+ : "void"
+ | "boolean"
+ | "byte"
+ | "char"
+ | "short"
+ | "int"
+ | "float"
+ | "long"
+ | "double"
+ ;
+
+// A (possibly-qualified) java identifier. We start with the first IDENT
+// and expand its name by adding dots and following IDENTS
+identifier
+ : IDENT ( DOT^ IDENT )*
+ ;
+
+identifierStar
+ : IDENT
+ ( DOT^ IDENT )*
+ ( DOT^ STAR )?
+ ;
+
+// A list of zero or more modifiers. We could have used (modifier)* in
+// place of a call to modifiers, but I thought it was a good idea to keep
+// this rule separate so they can easily be collected in a Vector if
+// someone so desires
+modifiers
+ : ( modifier )*
+ {#modifiers = #([MODIFIERS, "MODIFIERS"], #modifiers);}
+ ;
+
+// modifiers for Java classes, interfaces, class/instance vars and methods
+modifier
+ : "private"
+ | "public"
+ | "protected"
+ | "static"
+ | "transient"
+ | "final"
+ | "abstract"
+ | "native"
+ | "threadsafe"
+ | "synchronized"
+// | "const" // reserved word, but not valid
+ | "volatile"
+ | "strictfp"
+ ;
+
+// Definition of a Java class
+classDefinition![AST modifiers]
+ : "class" IDENT
+ // it _might_ have a superclass...
+ sc:superClassClause
+ // it might implement some interfaces...
+ ic:implementsClause
+ // now parse the body of the class
+ cb:classBlock
+ {#classDefinition = #(#[CLASS_DEF,"CLASS_DEF"],
+ modifiers,IDENT,sc,ic,cb);}
+ ;
+
+superClassClause!
+ : ( "extends" id:identifier )?
+ {#superClassClause = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],id);}
+ ;
+
+// Definition of a Java Interface
+interfaceDefinition![AST modifiers]
+ : "interface" IDENT
+ // it might extend some other interfaces
+ ie:interfaceExtends
+ // now parse the body of the interface (looks like a class...)
+ cb:classBlock
+ {#interfaceDefinition = #(#[INTERFACE_DEF,"INTERFACE_DEF"],
+ modifiers,IDENT,ie,cb);}
+ ;
+
+
+// This is the body of a class. You can have fields and extra semicolons,
+// That's about it (until you see what a field is...)
+classBlock
+ : LCURLY! { blockDepth++; }
+ ( field | SEMI! )*
+ RCURLY! { blockDepth--; }
+ {#classBlock = #([OBJBLOCK, "OBJBLOCK"], #classBlock);}
+ ;
+
+// An interface can extend several other interfaces...
+interfaceExtends
+ : (
+ e:"extends"!
+ identifier ( COMMA! identifier )*
+ )?
+ {#interfaceExtends = #(#[EXTENDS_CLAUSE,"EXTENDS_CLAUSE"],
+ #interfaceExtends);}
+ ;
+
+// A class can implement several interfaces...
+implementsClause
+ : (
+ i:"implements"! identifier ( COMMA! identifier )*
+ )?
+ {#implementsClause = #(#[IMPLEMENTS_CLAUSE,"IMPLEMENTS_CLAUSE"],
+ #implementsClause);}
+ ;
+
+// Now the various things that can be defined inside a class or interface...
+// Note that not all of these are really valid in an interface (constructors,
+// for example), and if this grammar were used for a compiler there would
+// need to be some semantic checks to make sure we're doing the right thing...
+field!
+ : // method, constructor, or variable declaration
+ mods:modifiers
+ ( h:ctorHead s:constructorBody // constructor
+ {#field = #(#[CTOR_DEF,"CTOR_DEF"], mods, h, s);}
+
+ | cd:classDefinition[#mods] // inner class
+ {#field = #cd;}
+
+ | id:interfaceDefinition[#mods] // inner interface
+ {#field = #id;}
+
+ | t:typeSpec[false] // method or variable declaration(s)
+ ( fn:IDENT // the name of the method
+
+ // parse the formal parameter declarations.
+ LPAREN! param:parameterDeclarationList RPAREN!
+
+ rt:declaratorBrackets[#t]
+
+ // get the list of exceptions that this method is
+ // declared to throw
+ (tc:throwsClause)?
+
+ ( s2:compoundStatement | SEMI )
+ {#field = #(#[METHOD_DEF,"METHOD_DEF"],
+ mods,
+ #(#[TYPE,"TYPE"],rt),
+ fn,
+ param,
+ tc,
+ s2);
+ if(blockDepth==1) {
+ functionNames.add(fn.getText()); } }
+ | v:variableDefinitions[#mods,#t] SEMI
+// {#field = #(#[VARIABLE_DEF,"VARIABLE_DEF"], v);}
+ {#field = #v;}
+ )
+ )
+
+ // "static { ... }" class initializer
+ | "static" s3:compoundStatement
+ {#field = #(#[STATIC_INIT,"STATIC_INIT"], s3);}
+
+ // "{ ... }" instance initializer
+ | s4:compoundStatement
+ {#field = #(#[INSTANCE_INIT,"INSTANCE_INIT"], s4);}
+ ;
+
+constructorBody
+ : lc:LCURLY^ {#lc.setType(SLIST); blockDepth++; }
+ ( options { greedy=true; } : explicitConstructorInvocation)?
+ (statement)*
+ RCURLY! { blockDepth--; }
+ ;
+
+/** Catch obvious constructor calls, but not the expr.super(...) calls */
+explicitConstructorInvocation
+ : "this"! lp1:LPAREN^ argList RPAREN! SEMI!
+ {#lp1.setType(CTOR_CALL);}
+ | "super"! lp2:LPAREN^ argList RPAREN! SEMI!
+ {#lp2.setType(SUPER_CTOR_CALL);}
+ ;
+
+variableDefinitions[AST mods, AST t]
+ : variableDeclarator[getASTFactory().dupTree(mods),
+ getASTFactory().dupTree(t)]
+ ( COMMA!
+ variableDeclarator[getASTFactory().dupTree(mods),
+ getASTFactory().dupTree(t)]
+ )*
+ ;
+
+/** Declaration of a variable. This can be a class/instance variable,
+ * or a local variable in a method
+ * It can also include possible initialization.
+ */
+variableDeclarator![AST mods, AST t]
+ : id:IDENT d:declaratorBrackets[t] v:varInitializer
+ {#variableDeclarator = #(#[VARIABLE_DEF,"VARIABLE_DEF"], mods, #(#[TYPE,"TYPE"],d), id, v);
+ if(blockDepth==1) {
+ enumNames.add(id.getText());
+ }
+ }
+ ;
+
+declaratorBrackets[AST typ]
+ : {#declaratorBrackets=typ;}
+ (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK!)*
+ ;
+
+varInitializer
+ : ( ASSIGN^ initializer )?
+ ;
+
+// This is an initializer used to set up an array.
+arrayInitializer
+ : lc:LCURLY^ {#lc.setType(ARRAY_INIT); blockDepth++; }
+ ( initializer
+ (
+ // CONFLICT: does a COMMA after an initializer start a new
+ // initializer or start the option ',' at end?
+ // ANTLR generates proper code by matching
+ // the comma as soon as possible.
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ :
+ COMMA! initializer
+ )*
+ (COMMA!)?
+ )?
+ RCURLY! { blockDepth--; }
+ ;
+
+
+// The two "things" that can initialize an array element are an expression
+// and another (nested) array initializer.
+initializer
+ : expression
+ | arrayInitializer
+ ;
+
+// This is the header of a method. It includes the name and parameters
+// for the method.
+// This also watches for a list of exception classes in a "throws" clause.
+ctorHead
+ : IDENT // the name of the method
+
+ // parse the formal parameter declarations.
+ LPAREN! parameterDeclarationList RPAREN!
+
+ // get the list of exceptions that this method is declared to throw
+ (throwsClause)?
+ ;
+
+// This is a list of exception classes that the method is declared to throw
+throwsClause
+ : "throws"^ identifier ( COMMA! identifier )*
+ ;
+
+
+// A list of formal parameters
+parameterDeclarationList
+ : ( parameterDeclaration ( COMMA! parameterDeclaration )* )?
+ {#parameterDeclarationList = #(#[PARAMETERS,"PARAMETERS"],
+ #parameterDeclarationList);}
+ ;
+
+// A formal parameter.
+parameterDeclaration!
+ : pm:parameterModifier t:typeSpec[false] id:IDENT
+ pd:declaratorBrackets[#t]
+ {#parameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"],
+ pm, #([TYPE,"TYPE"],pd), id);}
+ ;
+
+parameterModifier
+ : (f:"final")?
+ {#parameterModifier = #(#[MODIFIERS,"MODIFIERS"], f);}
+ ;
+
+// Compound statement. This is used in many contexts:
+// Inside a class definition prefixed with "static":
+// it is a class initializer
+// Inside a class definition without "static":
+// it is an instance initializer
+// As the body of a method
+// As a completely indepdent braced block of code inside a method
+// it starts a new scope for variable definitions
+
+compoundStatement
+ : lc:LCURLY^ {#lc.setType(SLIST); blockDepth++; }
+ // include the (possibly-empty) list of statements
+ (statement)*
+ RCURLY! { blockDepth--; }
+ ;
+
+
+statement
+ // A list of statements in curly braces -- start a new scope!
+ : compoundStatement
+
+ // declarations are ambiguous with "ID DOT" relative to expression
+ // statements. Must backtrack to be sure. Could use a semantic
+ // predicate to test symbol table to see what the type was coming
+ // up, but that's pretty hard without a symbol table ;)
+ | (declaration)=> declaration SEMI!
+
+ // An expression statement. This could be a method call,
+ // assignment statement, or any other expression evaluated for
+ // side-effects.
+ | expression SEMI!
+
+ // class definition
+ | m:modifiers! classDefinition[#m]
+
+ // Attach a label to the front of a statement
+ | IDENT c:COLON^ {#c.setType(LABELED_STAT);} statement
+
+ // If-else statement
+ | "if"^ LPAREN! expression RPAREN! statement
+ (
+ // CONFLICT: the old "dangling-else" problem...
+ // ANTLR generates proper code matching
+ // as soon as possible. Hush warning.
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ :
+ "else"! statement
+ )?
+
+ // For statement
+ | "for"^
+ LPAREN!
+ forInit SEMI! // initializer
+ forCond SEMI! // condition test
+ forIter // updater
+ RPAREN!
+ statement // statement to loop over
+
+ // While statement
+ | "while"^ LPAREN! expression RPAREN! statement
+
+ // do-while statement
+ | "do"^ statement "while"! LPAREN! expression RPAREN! SEMI!
+
+ // get out of a loop (or switch)
+ | "break"^ (IDENT)? SEMI!
+
+ // do next iteration of a loop
+ | "continue"^ (IDENT)? SEMI!
+
+ // Return an expression
+ | "return"^ (expression)? SEMI!
+
+ // switch/case statement
+ | "switch"^ LPAREN! expression RPAREN! LCURLY! { blockDepth++; }
+ ( casesGroup )*
+ RCURLY! { blockDepth--; }
+
+ // exception try-catch block
+ | tryBlock
+
+ // throw an exception
+ | "throw"^ expression SEMI!
+
+ // synchronize a statement
+ | "synchronized"^ LPAREN! expression RPAREN! compoundStatement
+
+ // asserts (uncomment if you want 1.4 compatibility)
+ // | "assert"^ expression ( COLON! expression )? SEMI!
+
+ // empty statement
+ | s:SEMI {#s.setType(EMPTY_STAT);}
+ ;
+
+casesGroup
+ : ( // CONFLICT: to which case group do the statements bind?
+ // ANTLR generates proper code: it groups the
+ // many "case"/"default" labels together then
+ // follows them with the statements
+ options {
+ greedy = true;
+ }
+ :
+ aCase
+ )+
+ caseSList
+ {#casesGroup = #([CASE_GROUP, "CASE_GROUP"], #casesGroup);}
+ ;
+
+aCase
+ : ("case"^ expression | "default") COLON!
+ ;
+
+caseSList
+ : (statement)*
+ {#caseSList = #(#[SLIST,"SLIST"],#caseSList);}
+ ;
+
+// The initializer for a for loop
+forInit
+ // if it looks like a declaration, it is
+ : ( (declaration)=> declaration
+ // otherwise it could be an expression list...
+ | expressionList
+ )?
+ {#forInit = #(#[FOR_INIT,"FOR_INIT"],#forInit);}
+ ;
+
+forCond
+ : (expression)?
+ {#forCond = #(#[FOR_CONDITION,"FOR_CONDITION"],#forCond);}
+ ;
+
+forIter
+ : (expressionList)?
+ {#forIter = #(#[FOR_ITERATOR,"FOR_ITERATOR"],#forIter);}
+ ;
+
+// an exception handler try/catch block
+tryBlock
+ : "try"^ compoundStatement
+ (handler)*
+ ( finallyClause )?
+ ;
+
+finallyClause
+ : "finally"^ compoundStatement
+ ;
+
+// an exception handler
+handler
+ : "catch"^ LPAREN! parameterDeclaration RPAREN! compoundStatement
+ ;
+
+
+// expressions
+// Note that most of these expressions follow the pattern
+// thisLevelExpression :
+// nextHigherPrecedenceExpression
+// (OPERATOR nextHigherPrecedenceExpression)*
+// which is a standard recursive definition for a parsing an expression.
+// The operators in java have the following precedences:
+// lowest (13) = *= /= %= += -= <<= >>= >>>= &= ^= |=
+// (12) ?:
+// (11) ||
+// (10) &&
+// ( 9) |
+// ( 8) ^
+// ( 7) &
+// ( 6) == !=
+// ( 5) < <= > >=
+// ( 4) << >>
+// ( 3) +(binary) -(binary)
+// ( 2) * / %
+// ( 1) ++ -- +(unary) -(unary) ~ ! (type)
+// [] () (method call) . (dot -- identifier qualification)
+// new () (explicit parenthesis)
+//
+// the last two are not usually on a precedence chart; I put them in
+// to point out that new has a higher precedence than '.', so you
+// can validy use
+// new Frame().show()
+//
+// Note that the above precedence levels map to the rules below...
+// Once you have a precedence chart, writing the appropriate rules as below
+// is usually very straightfoward
+
+
+
+// the mother of all expressions
+expression
+ : assignmentExpression
+ {#expression = #(#[EXPR,"EXPR"],#expression);}
+ ;
+
+
+// This is a list of expressions.
+expressionList
+ : expression (COMMA! expression)*
+ {#expressionList = #(#[ELIST,"ELIST"], expressionList);}
+ ;
+
+
+// assignment expression (level 13)
+assignmentExpression
+ : conditionalExpression
+ ( ( ASSIGN^
+ | PLUS_ASSIGN^
+ | MINUS_ASSIGN^
+ | STAR_ASSIGN^
+ | DIV_ASSIGN^
+ | MOD_ASSIGN^
+ | SR_ASSIGN^
+ | BSR_ASSIGN^
+ | SL_ASSIGN^
+ | BAND_ASSIGN^
+ | BXOR_ASSIGN^
+ | BOR_ASSIGN^
+ )
+ assignmentExpression
+ )?
+ ;
+
+
+// conditional test (level 12)
+conditionalExpression
+ : logicalOrExpression
+ ( QUESTION^ assignmentExpression COLON! conditionalExpression )?
+ ;
+
+
+// logical or (||) (level 11)
+logicalOrExpression
+ : logicalAndExpression (LOR^ logicalAndExpression)*
+ ;
+
+
+// logical and (&&) (level 10)
+logicalAndExpression
+ : inclusiveOrExpression (LAND^ inclusiveOrExpression)*
+ ;
+
+
+// bitwise or non-short-circuiting or (|) (level 9)
+inclusiveOrExpression
+ : exclusiveOrExpression (BOR^ exclusiveOrExpression)*
+ ;
+
+
+// exclusive or (^) (level 8)
+exclusiveOrExpression
+ : andExpression (BXOR^ andExpression)*
+ ;
+
+
+// bitwise or non-short-circuiting and (&) (level 7)
+andExpression
+ : equalityExpression (BAND^ equalityExpression)*
+ ;
+
+
+// equality/inequality (==/!=) (level 6)
+equalityExpression
+ : relationalExpression ((NOT_EQUAL^ | EQUAL^) relationalExpression)*
+ ;
+
+
+// boolean relational expressions (level 5)
+relationalExpression
+ : shiftExpression
+ ( ( ( LT^
+ | GT^
+ | LE^
+ | GE^
+ )
+ shiftExpression
+ )*
+ | "instanceof"^ typeSpec[true]
+ )
+ ;
+
+
+// bit shift expressions (level 4)
+shiftExpression
+ : additiveExpression ((SL^ | SR^ | BSR^) additiveExpression)*
+ ;
+
+
+// binary addition/subtraction (level 3)
+additiveExpression
+ : multiplicativeExpression ((PLUS^ | MINUS^) multiplicativeExpression)*
+ ;
+
+
+// multiplication/division/modulo (level 2)
+multiplicativeExpression
+ : unaryExpression ((STAR^ | DIV^ | MOD^ ) unaryExpression)*
+ ;
+
+unaryExpression
+ : INC^ unaryExpression
+ | DEC^ unaryExpression
+ | MINUS^ {#MINUS.setType(UNARY_MINUS);} unaryExpression
+ | PLUS^ {#PLUS.setType(UNARY_PLUS);} unaryExpression
+ | unaryExpressionNotPlusMinus
+ ;
+
+unaryExpressionNotPlusMinus
+ : BNOT^ unaryExpression
+ | LNOT^ unaryExpression
+
+ // use predicate to skip cases like: (int.class)
+ | (LPAREN builtInTypeSpec[true] RPAREN) =>
+ lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN!
+ unaryExpression
+
+ // Have to backtrack to see if operator follows. If no operator
+ // follows, it's a typecast. No semantic checking needed to parse.
+ // if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)"
+ | (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=>
+ lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN!
+ unaryExpressionNotPlusMinus
+
+ | postfixExpression
+ ;
+
+// qualified names, array expressions, method invocation, post inc/dec
+postfixExpression
+ :
+ /*
+ "this"! lp1:LPAREN^ argList RPAREN!
+ {#lp1.setType(CTOR_CALL);}
+
+ | "super"! lp2:LPAREN^ argList RPAREN!
+ {#lp2.setType(SUPER_CTOR_CALL);}
+ |
+ */
+ primaryExpression
+
+ (
+ /*
+ options {
+ // the use of postfixExpression in SUPER_CTOR_CALL adds DOT
+ // to the lookahead set, and gives loads of false non-det
+ // warnings.
+ // shut them off.
+ generateAmbigWarnings=false;
+ }
+ : */
+ DOT^ IDENT
+ ( lp:LPAREN^ {#lp.setType(METHOD_CALL);}
+ argList
+ RPAREN!
+ )?
+ | DOT^ "this"
+
+ | DOT^ "super"
+ ( // (new Outer()).super() (create enclosing instance)
+ lp3:LPAREN^ argList RPAREN!
+ {#lp3.setType(SUPER_CTOR_CALL);}
+ | DOT^ IDENT
+ ( lps:LPAREN^ {#lps.setType(METHOD_CALL);}
+ argList
+ RPAREN!
+ )?
+ )
+ | DOT^ newExpression
+ | lb:LBRACK^ {#lb.setType(INDEX_OP);} expression RBRACK!
+ )*
+
+ ( // possibly add on a post-increment or post-decrement.
+ // allows INC/DEC on too much, but semantics can check
+ in:INC^ {#in.setType(POST_INC);}
+ | de:DEC^ {#de.setType(POST_DEC);}
+ )?
+ ;
+
+// the basic element of an expression
+primaryExpression
+ : identPrimary ( options {greedy=true;} : DOT^ "class" )?
+ | constant
+ | "true"
+ | "false"
+ | "null"
+ | newExpression
+ | "this"
+ | "super"
+ | LPAREN! assignmentExpression RPAREN!
+ // look for int.class and int[].class
+ | builtInType
+ ( lbt:LBRACK^ {#lbt.setType(ARRAY_DECLARATOR);} RBRACK! )*
+ DOT^ "class"
+ ;
+
+/** Match a, a.b.c refs, a.b.c(...) refs, a.b.c[], a.b.c[].class,
+ * and a.b.c.class refs. Also this(...) and super(...). Match
+ * this or super.
+ */
+identPrimary
+ : IDENT
+ (
+ options {
+ // .ident could match here or in postfixExpression.
+ // We do want to match here. Turn off warning.
+ greedy=true;
+ }
+ : DOT^ IDENT
+ )*
+ (
+ options {
+ // ARRAY_DECLARATOR here conflicts with INDEX_OP in
+ // postfixExpression on LBRACK RBRACK.
+ // We want to match [] here, so greedy. This overcomes
+ // limitation of linear approximate lookahead.
+ greedy=true;
+ }
+ : ( lp:LPAREN^ {#lp.setType(METHOD_CALL);} argList RPAREN! )
+ | ( options {greedy=true;} :
+ lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK!
+ )+
+ )?
+ ;
+
+/** object instantiation.
+ * Trees are built as illustrated by the following input/tree pairs:
+ *
+ * new T()
+ *
+ * new
+ * |
+ * T -- ELIST
+ * |
+ * arg1 -- arg2 -- .. -- argn
+ *
+ * new int[]
+ *
+ * new
+ * |
+ * int -- ARRAY_DECLARATOR
+ *
+ * new int[] {1,2}
+ *
+ * new
+ * |
+ * int -- ARRAY_DECLARATOR -- ARRAY_INIT
+ * |
+ * EXPR -- EXPR
+ * | |
+ * 1 2
+ *
+ * new int[3]
+ * new
+ * |
+ * int -- ARRAY_DECLARATOR
+ * |
+ * EXPR
+ * |
+ * 3
+ *
+ * new int[1][2]
+ *
+ * new
+ * |
+ * int -- ARRAY_DECLARATOR
+ * |
+ * ARRAY_DECLARATOR -- EXPR
+ * | |
+ * EXPR 1
+ * |
+ * 2
+ *
+ */
+newExpression
+ : "new"^ type
+ ( LPAREN! argList RPAREN! (classBlock)?
+
+ //java 1.1
+ // Note: This will allow bad constructs like
+ // new int[4][][3] {exp,exp}.
+ // There needs to be a semantic check here...
+ // to make sure:
+ // a) [ expr ] and [ ] are not mixed
+ // b) [ expr ] and an init are not used together
+
+ | newArrayDeclarator (arrayInitializer)?
+ )
+ ;
+
+argList
+ : ( expressionList
+ | /*nothing*/
+ {#argList = #[ELIST,"ELIST"];}
+ )
+ ;
+
+newArrayDeclarator
+ : (
+ // CONFLICT:
+ // newExpression is a primaryExpression which can be
+ // followed by an array index reference. This is ok,
+ // as the generated code will stay in this loop as
+ // long as it sees an LBRACK (proper behavior)
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ :
+ lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);}
+ (expression)?
+ RBRACK!
+ )+
+ ;
+
+constant
+ : NUM_INT
+ | CHAR_LITERAL
+ | STRING_LITERAL
+ | NUM_FLOAT
+ | NUM_LONG
+ | NUM_DOUBLE
+ ;
+
+//----------------------------------------------------------------------------
+// The Java scanner
+//----------------------------------------------------------------------------
+class JavaLexer extends Lexer;
+
+options {
+ exportVocab=Java; // call the vocabulary "Java"
+ testLiterals=false; // don't automatically test for literals
+ k=4; // four characters of lookahead
+ charVocabulary='\u0003'..'\u7FFE';
+ // without inlining some bitset tests, couldn't do unicode;
+ // I need to make ANTLR generate smaller bitsets; see
+ // bottom of JavaLexer.java
+ codeGenBitsetTestThreshold=20;
+}
+
+// OPERATORS
+QUESTION : '?' ;
+LPAREN : '(' ;
+RPAREN : ')' ;
+LBRACK : '[' ;
+RBRACK : ']' ;
+LCURLY : '{' ;
+RCURLY : '}' ;
+COLON : ':' ;
+COMMA : ',' ;
+//DOT : '.' ;
+ASSIGN : '=' ;
+EQUAL : "==" ;
+LNOT : '!' ;
+BNOT : '~' ;
+NOT_EQUAL : "!=" ;
+DIV : '/' ;
+DIV_ASSIGN : "/=" ;
+PLUS : '+' ;
+PLUS_ASSIGN : "+=" ;
+INC : "++" ;
+MINUS : '-' ;
+MINUS_ASSIGN : "-=" ;
+DEC : "--" ;
+STAR : '*' ;
+STAR_ASSIGN : "*=" ;
+MOD : '%' ;
+MOD_ASSIGN : "%=" ;
+SR : ">>" ;
+SR_ASSIGN : ">>=" ;
+BSR : ">>>" ;
+BSR_ASSIGN : ">>>=" ;
+GE : ">=" ;
+GT : ">" ;
+SL : "<<" ;
+SL_ASSIGN : "<<=" ;
+LE : "<=" ;
+LT : '<' ;
+BXOR : '^' ;
+BXOR_ASSIGN : "^=" ;
+BOR : '|' ;
+BOR_ASSIGN : "|=" ;
+LOR : "||" ;
+BAND : '&' ;
+BAND_ASSIGN : "&=" ;
+LAND : "&&" ;
+SEMI : ';' ;
+
+
+// Whitespace -- ignored
+WS : ( ' '
+ | '\t'
+ | '\f'
+ // handle newlines
+ | ( options {generateAmbigWarnings=false;}
+ : "\r\n" // Evil DOS
+ | '\r' // Macintosh
+ | '\n' // Unix (the right way)
+ )
+ { newline(); }
+ )+
+ { _ttype = Token.SKIP; }
+ ;
+
+// Single-line comments
+SL_COMMENT
+ : "//"
+ (~('\n'|'\r'))* ('\n'|'\r'('\n')?)?
+ {$setType(Token.SKIP); newline();}
+ ;
+
+// multiple-line comments
+ML_COMMENT
+ : "/*"
+ ( /* '\r' '\n' can be matched in one alternative or by matching
+ '\r' in one iteration and '\n' in another. I am trying to
+ handle any flavor of newline that comes in, but the language
+ that allows both "\r\n" and "\r" and "\n" to all be valid
+ newline is ambiguous. Consequently, the resulting grammar
+ must be ambiguous. I'm shutting this warning off.
+ */
+ options {
+ generateAmbigWarnings=false;
+ }
+ :
+ { LA(2)!='/' }? '*'
+ | '\r' '\n' {newline();}
+ | '\r' {newline();}
+ | '\n' {newline();}
+ | ~('*'|'\n'|'\r')
+ )*
+ "*/"
+ {$setType(Token.SKIP);}
+ ;
+
+
+// character literals
+CHAR_LITERAL
+ : '\'' ( ESC | ~('\''|'\n'|'\r'|'\\') ) '\''
+ ;
+
+// string literals
+STRING_LITERAL
+ : '"' (ESC|~('"'|'\\'|'\n'|'\r'))* '"'
+ ;
+
+
+// escape sequence -- note that this is protected; it can only be called
+// from another lexer rule -- it will not ever directly return a token to
+// the parser
+// There are various ambiguities hushed in this rule. The optional
+// '0'...'9' digit matches should be matched here rather than letting
+// them go back to STRING_LITERAL to be matched. ANTLR does the
+// right thing by matching immediately; hence, it's ok to shut off
+// the FOLLOW ambig warnings.
+protected
+ESC
+ : '\\'
+ ( 'n'
+ | 'r'
+ | 't'
+ | 'b'
+ | 'f'
+ | '"'
+ | '\''
+ | '\\'
+ | ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
+ | '0'..'3'
+ (
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ : '0'..'7'
+ (
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ : '0'..'7'
+ )?
+ )?
+ | '4'..'7'
+ (
+ options {
+ warnWhenFollowAmbig = false;
+ }
+ : '0'..'7'
+ )?
+ )
+ ;
+
+
+// hexadecimal digit (again, note it's protected!)
+protected
+HEX_DIGIT
+ : ('0'..'9'|'A'..'F'|'a'..'f')
+ ;
+
+
+// an identifier. Note that testLiterals is set to true! This means
+// that after we match the rule, we look in the literals table to see
+// if it's a literal or really an identifer
+IDENT
+ options {testLiterals=true;}
+ : ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|'$')*
+ ;
+
+
+// a numeric literal
+NUM_INT
+ {boolean isDecimal=false; Token t=null;}
+ : '.' {_ttype = DOT;}
+ ( ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})?
+ {
+ if (t != null && t.getText().toUpperCase().indexOf('F')>=0) {
+ _ttype = NUM_FLOAT;
+ }
+ else {
+ _ttype = NUM_DOUBLE; // assume double
+ }
+ }
+ )?
+
+ | ( '0' {isDecimal = true;} // special case for just '0'
+ ( ('x'|'X')
+ ( // hex
+ // the 'e'|'E' and float suffix stuff look
+ // like hex digits, hence the (...)+ doesn't
+ // know when to stop: ambig. ANTLR resolves
+ // it correctly by matching immediately. It
+ // is therefor ok to hush warning.
+ options {
+ warnWhenFollowAmbig=false;
+ }
+ : HEX_DIGIT
+ )+
+
+ | //float or double with leading zero
+ (('0'..'9')+ ('.'|EXPONENT|FLOAT_SUFFIX)) => ('0'..'9')+
+
+ | ('0'..'7')+ // octal
+ )?
+ | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal
+ )
+ ( ('l'|'L') { _ttype = NUM_LONG; }
+
+ // only check to see if it's a float if looks like decimal so far
+ | {isDecimal}?
+ ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})?
+ | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})?
+ | f4:FLOAT_SUFFIX {t=f4;}
+ )
+ {
+ if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0) {
+ _ttype = NUM_FLOAT;
+ }
+ else {
+ _ttype = NUM_DOUBLE; // assume double
+ }
+ }
+ )?
+ ;
+
+
+// a couple protected methods to assist in matching floating point numbers
+protected
+EXPONENT
+ : ('e'|'E') ('+'|'-')? ('0'..'9')+
+ ;
+
+
+protected
+FLOAT_SUFFIX
+ : 'f'|'F'|'d'|'D'
+ ;
+
diff --git a/src/java/com/sun/gluegen/jgram/Test.java b/src/java/com/sun/gluegen/jgram/Test.java
new file mode 100644
index 0000000..996d645
--- /dev/null
+++ b/src/java/com/sun/gluegen/jgram/Test.java
@@ -0,0 +1,132 @@
+package com.sun.gluegen.jgram;
+
+import java.util.*;
+
+import java.io.*;
+// import antlr.collections.AST;
+import antlr.collections.impl.*;
+import antlr.debug.misc.*;
+import antlr.*;
+// import java.awt.event.*;
+
+class Test {
+
+ static boolean showTree = false;
+ public static void main(String[] args) {
+ // Use a try/catch block for parser exceptions
+ try {
+ // if we have at least one command-line argument
+ if (args.length > 0 ) {
+ System.err.println("Parsing...");
+
+ // for each directory/file specified on the command line
+ for(int i=0; i< args.length;i++) {
+ if ( args[i].equals("-showtree") ) {
+ showTree = true;
+ }
+ else {
+ doFile(new File(args[i])); // parse it
+ }
+ } }
+ else
+ System.err.println("Usage: java com.sun.gluegen.jgram.Test [-showtree] "+
+ "<directory or file name>");
+ }
+ catch(Exception e) {
+ System.err.println("exception: "+e);
+ e.printStackTrace(System.err); // so we can get stack trace
+ }
+ }
+
+
+ // This method decides what action to take based on the type of
+ // file we are looking at
+ public static void doFile(File f)
+ throws Exception {
+ // If this is a directory, walk each file/dir in that directory
+ if (f.isDirectory()) {
+ String files[] = f.list();
+ for(int i=0; i < files.length; i++)
+ doFile(new File(f, files[i]));
+ }
+
+ // otherwise, if this is a java file, parse it!
+ else if ((f.getName().length()>5) &&
+ f.getName().substring(f.getName().length()-5).equals(".java")) {
+ System.err.println(" "+f.getAbsolutePath());
+ // parseFile(f.getName(), new FileInputStream(f));
+ parseFile(f.getName(), new BufferedReader(new FileReader(f)));
+ }
+ }
+
+ // Here's where we do the real work...
+ public static void parseFile(String f, Reader r)
+ throws Exception {
+ try {
+ // Create a scanner that reads from the input stream passed to us
+ JavaLexer lexer = new JavaLexer(r);
+ lexer.setFilename(f);
+
+ // Create a parser that reads from the scanner
+ JavaParser parser = new JavaParser(lexer);
+ parser.setFilename(f);
+
+ // start parsing at the compilationUnit rule
+ parser.compilationUnit();
+
+ Set set = parser.getParsedEnumNames();
+ System.out.println("Enums");
+ for(Iterator iter = set.iterator(); iter.hasNext(); ) {
+ String s = (String) iter.next();
+ System.out.println(s);
+ }
+ System.out.println("Functions");
+ set = parser.getParsedFunctionNames();
+ for(Iterator iter = set.iterator(); iter.hasNext(); ) {
+ String s = (String) iter.next();
+ System.out.println(s);
+ }
+
+ // do something with the tree
+ //doTreeAction(f, parser.getAST(), parser.getTokenNames());
+ }
+ catch (Exception e) {
+ System.err.println("parser exception: "+e);
+ e.printStackTrace(); // so we can get stack trace
+ }
+ }
+
+ /*
+ public static void doTreeAction(String f, AST t, String[] tokenNames) {
+ if ( t==null ) return;
+ if ( showTree ) {
+ ((CommonAST)t).setVerboseStringConversion(true, tokenNames);
+ ASTFactory factory = new ASTFactory();
+ AST r = factory.create(0,"AST ROOT");
+ r.setFirstChild(t);
+ final ASTFrame frame = new ASTFrame("Java AST", r);
+ frame.setVisible(true);
+ frame.addWindowListener(
+ new WindowAdapter() {
+ public void windowClosing (WindowEvent e) {
+ frame.setVisible(false); // hide the Frame
+ frame.dispose();
+ System.exit(0);
+ }
+ }
+ );
+ // System.out.println(t.toStringList());
+ }
+ JavaTreeParser tparse = new JavaTreeParser();
+ try {
+ tparse.compilationUnit(t);
+ // System.out.println("successful walk of result AST for "+f);
+ }
+ catch (RecognitionException e) {
+ System.err.println(e.getMessage());
+ e.printStackTrace();
+ }
+
+ } */
+}
+
diff --git a/src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java b/src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java
index cc9175b..6c9f377 100644
--- a/src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java
+++ b/src/java/com/sun/gluegen/opengl/BuildComposablePipeline.java
@@ -65,7 +65,7 @@ public class BuildComposablePipeline
classToComposeAround = Class.forName(nameOfClassToComposeAround);
} catch (Exception e) {
throw new RuntimeException(
- "Could not find class \"" + nameOfClassToComposeAround + "\"", e);
+ "Could not find class \"" + nameOfClassToComposeAround + "\"", e);
}
String outputDir = args[1];
@@ -80,7 +80,7 @@ public class BuildComposablePipeline
catch (IOException e)
{
throw new RuntimeException(
- "Error generating composable pipeline source files", e);
+ "Error generating composable pipeline source files", e);
}
}
@@ -92,7 +92,7 @@ public class BuildComposablePipeline
if (! classToComposeAround.isInterface())
{
throw new IllegalArgumentException(
- classToComposeAround.getName() + " is not an interface class");
+ classToComposeAround.getName() + " is not an interface class");
}
try {
@@ -116,14 +116,59 @@ public class BuildComposablePipeline
{
String pDir = outputDirectory;
String pInterface = classToComposeAround.getName();
- List/*<Method>*/ publicMethods = Arrays.asList(classToComposeAround.getMethods());
+ List/*<Method>*/ publicMethodsRaw = Arrays.asList(classToComposeAround.getMethods());
+ Set/*<Method>*/ publicMethodsPlain = new HashSet();
+ for (Iterator iter=publicMethodsRaw.iterator(); iter.hasNext(); ) {
+ publicMethodsPlain.add(new PlainMethod((Method)iter.next())); }
- (new DebugPipeline(pDir, pInterface)).emit(publicMethods);
- (new TracePipeline(pDir, pInterface)).emit(publicMethods);
+ (new DebugPipeline(pDir, pInterface)).emit(publicMethodsPlain);
+ (new TracePipeline(pDir, pInterface)).emit(publicMethodsPlain);
}
//-------------------------------------------------------
+ protected class PlainMethod
+ {
+ Method m;
+
+ public PlainMethod(Method m) {
+ this.m=m;
+ }
+
+ public Method getWrappedMethod() { return m; }
+
+ public boolean equals(Object obj) {
+ if(obj instanceof PlainMethod) {
+ PlainMethod b = (PlainMethod)obj;
+ boolean res =
+ m.getName().equals(b.m.getName()) &&
+ m.getModifiers() == b.m.getModifiers() &&
+ m.getReturnType().equals(b.m.getReturnType()) &&
+ Arrays.equals( m.getParameterTypes() , b.m.getParameterTypes() ) ;
+ return res;
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ int hash = m.getName().hashCode() ^ m.getModifiers() ^ m.getReturnType().hashCode();
+ Class[] args = m.getParameterTypes();
+ for(int i=0; i<args.length; i++) {
+ hash ^= args[i].hashCode();
+ }
+ return hash;
+ }
+
+ public String toString() {
+ Class[] args = m.getParameterTypes();
+ return m.toString() +
+ "\n\tname: " + m.getName() +
+ "\n\tmods: " + m.getModifiers() +
+ "\n\tretu: " + m.getReturnType() +
+ "\n\targs[" + args.length + "]: "+Arrays.toString(args);
+ }
+ }
+
/**
* Emits a Java source file that represents one element of the composable
* pipeline.
@@ -148,20 +193,20 @@ public class BuildComposablePipeline
int lastDot = baseInterfaceClassName.lastIndexOf('.');
if (lastDot == -1)
{
- // no package, class is at root level
- this.baseName = baseInterfaceClassName;
- this.basePackage = null;
+ // no package, class is at root level
+ this.baseName = baseInterfaceClassName;
+ this.basePackage = null;
}
else
- {
- this.baseName = baseInterfaceClassName.substring(lastDot+1);
- this.basePackage = baseInterfaceClassName.substring(0, lastDot);
+ {
+ this.baseName = baseInterfaceClassName.substring(lastDot+1);
+ this.basePackage = baseInterfaceClassName.substring(0, lastDot);
}
this.outputDir = outputDir;
}
- public void emit(List/*<Method>*/ methodsToWrap) throws IOException
+ public void emit(Iterable/*<Method>*/ methodsToWrap) throws IOException
{
String pipelineClassName = getPipelineName();
this.file = new File(outputDir + File.separatorChar + pipelineClassName + ".java");
@@ -175,29 +220,29 @@ public class BuildComposablePipeline
PrintWriter output = new PrintWriter(new BufferedWriter(new FileWriter(file)));
CodeGenUtils.emitJavaHeaders(output,
- basePackage,
- pipelineClassName,
+ basePackage,
+ pipelineClassName,
"com.sun.gluegen.runtime", // FIXME: should make configurable
- true,
- new String[] { "java.io.*", "javax.media.opengl.*" },
- new String[] { "public" },
- new String[] { baseName },
- null,
- new CodeGenUtils.EmissionCallback() {
- public void emit(PrintWriter w) { emitClassDocComment(w); }
- }
- );
+ true,
+ new String[] { "java.io.*", "javax.media.opengl.*" },
+ new String[] { "public" },
+ new String[] { baseName },
+ null,
+ new CodeGenUtils.EmissionCallback() {
+ public void emit(PrintWriter w) { emitClassDocComment(w); }
+ }
+ );
preMethodEmissionHook(output);
-
+
constructorHook(output);
- for (int i = 0; i < methodsToWrap.size(); ++i)
+ for (Iterator iter=methodsToWrap.iterator(); iter.hasNext(); )
{
- Method m = (Method)methodsToWrap.get(i);
- emitMethodDocComment(output, m);
- emitSignature(output, m);
- emitBody(output, m);
+ Method m = ((PlainMethod)iter.next()).getWrappedMethod();
+ emitMethodDocComment(output, m);
+ emitSignature(output, m);
+ emitBody(output, m);
}
postMethodEmissionHook(output);
@@ -246,8 +291,8 @@ public class BuildComposablePipeline
if (retType != Void.TYPE)
{
- output.print(JavaType.createForClass(retType).getName());
- output.print(" _res = ");
+ output.print(JavaType.createForClass(retType).getName());
+ output.print(" _res = ");
}
output.print(getDownstreamObjectName());
output.print('.');
@@ -260,7 +305,7 @@ public class BuildComposablePipeline
if (retType != Void.TYPE)
{
- output.println(" return _res;");
+ output.println(" return _res;");
}
output.println(" }");
@@ -271,25 +316,25 @@ public class BuildComposablePipeline
StringBuffer buf = new StringBuffer(256);
if (!includeArgNames && !includeArgTypes)
{
- throw new IllegalArgumentException(
- "Cannot generate arglist without both arg types and arg names");
+ throw new IllegalArgumentException(
+ "Cannot generate arglist without both arg types and arg names");
}
Class[] argTypes = m.getParameterTypes();
for (int i = 0; i < argTypes.length; ++i)
{
- if (includeArgTypes)
- {
- buf.append(JavaType.createForClass(argTypes[i]).getName());
- buf.append(' ');
- }
-
- if (includeArgNames)
- {
- buf.append("arg");
- buf.append(i);
- }
- if (i < argTypes.length-1) { buf.append(','); }
+ if (includeArgTypes)
+ {
+ buf.append(JavaType.createForClass(argTypes[i]).getName());
+ buf.append(' ');
+ }
+
+ if (includeArgNames)
+ {
+ buf.append("arg");
+ buf.append(i);
+ }
+ if (i < argTypes.length-1) { buf.append(','); }
}
return buf.toString();
@@ -387,16 +432,16 @@ public class BuildComposablePipeline
}
output.println(" // Debug code to make sure the pipeline is working; leave commented out unless testing this class");
output.println(" //System.err.println(\"Checking for GL errors " +
- "after call to \" + caller + \"()\");");
+ "after call to \" + caller + \"()\");");
output.println();
output.println(" int err = " +
- getDownstreamObjectName() +
- ".glGetError();");
+ getDownstreamObjectName() +
+ ".glGetError();");
output.println(" if (err == GL_NO_ERROR) { return; }");
output.println();
output.println(" StringBuffer buf = new StringBuffer(");
output.println(" \"glGetError() returned the following error codes " +
- "after a call to \" + caller + \"(): \");");
+ "after a call to \" + caller + \"(): \");");
output.println();
output.println(" // Loop repeatedly to allow for distributed GL implementations,");
output.println(" // as detailed in the glGetError() specification");
@@ -415,8 +460,8 @@ public class BuildComposablePipeline
output.println(" default: throw new InternalError(\"Unknown glGetError() return value: \" + err);");
output.println(" }");
output.println(" } while ((--recursionDepth >= 0) && (err = " +
- getDownstreamObjectName() +
- ".glGetError()) != GL_NO_ERROR);");
+ getDownstreamObjectName() +
+ ".glGetError()) != GL_NO_ERROR);");
output.println(" throw new GLException(buf.toString());");
output.println(" }");
if (hasImmediateMode) {
@@ -458,18 +503,18 @@ public class BuildComposablePipeline
{
if (m.getName().equals("glBegin"))
{
- output.println(" insideBeginEndPair = true;");
- output.println(" // NOTE: can't check glGetError(); it's not allowed inside glBegin/glEnd pair");
+ output.println(" insideBeginEndPair = true;");
+ output.println(" // NOTE: can't check glGetError(); it's not allowed inside glBegin/glEnd pair");
}
else
{
- if (m.getName().equals("glEnd"))
- {
- output.println(" insideBeginEndPair = false;");
- }
-
- // calls to glGetError() are only allowed outside of glBegin/glEnd pairs
- output.println(" checkGLGetError(\"" + m.getName() + "\");");
+ if (m.getName().equals("glEnd"))
+ {
+ output.println(" insideBeginEndPair = false;");
+ }
+
+ // calls to glGetError() are only allowed outside of glBegin/glEnd pairs
+ output.println(" checkGLGetError(\"" + m.getName() + "\");");
}
}
diff --git a/src/java/com/sun/gluegen/opengl/GLConfiguration.java b/src/java/com/sun/gluegen/opengl/GLConfiguration.java
index d9f35ba..1d2e08a 100755
--- a/src/java/com/sun/gluegen/opengl/GLConfiguration.java
+++ b/src/java/com/sun/gluegen/opengl/GLConfiguration.java
@@ -186,23 +186,35 @@ public class GLConfiguration extends ProcAddressConfiguration {
}
}
- public boolean shouldIgnore(String symbol) {
- return shouldIgnore(symbol, false);
- }
-
- public boolean shouldIgnore(String symbol, boolean skipExtensionCheck) {
- // Check ignored extensions based on our knowledge of the static GL info
- if (!skipExtensionCheck && glInfo != null) {
+ protected boolean shouldIgnoreExtension(String symbol, boolean criteria) {
+ if (criteria && glInfo != null) {
String extension = glInfo.getExtension(symbol);
if (extension != null &&
ignoredExtensions.contains(extension)) {
- // System.err.println("GL Ignore: "+symbol+" within extension "+extension);
- // dumpIgnores();
- return true;
+ // System.err.println("GL Ignore: "+symbol+" within extension "+extension);
+ // Throwable t = new Throwable("XXX");
+ // t.printStackTrace();
+ // dumpIgnores();
+ return true;
}
}
+ return false;
+ }
+
+ public boolean shouldIgnoreInInterface(String symbol) {
+ return shouldIgnoreInInterface(symbol, true);
+ }
+
+ public boolean shouldIgnoreInInterface(String symbol, boolean checkEXT) {
+ return shouldIgnoreExtension(symbol, checkEXT) || super.shouldIgnoreInInterface(symbol);
+ }
+
+ public boolean shouldIgnoreInImpl(String symbol) {
+ return shouldIgnoreInImpl(symbol, true);
+ }
- return super.shouldIgnore(symbol);
+ public boolean shouldIgnoreInImpl(String symbol, boolean checkEXT) {
+ return shouldIgnoreExtension(symbol, checkEXT) || super.shouldIgnoreInImpl(symbol);
}
/** shall the non unified (uniq) vendor extensions be dropped ? */
diff --git a/src/java/com/sun/gluegen/opengl/GLEmitter.java b/src/java/com/sun/gluegen/opengl/GLEmitter.java
index 0dd4ebf..c5477a0 100644
--- a/src/java/com/sun/gluegen/opengl/GLEmitter.java
+++ b/src/java/com/sun/gluegen/opengl/GLEmitter.java
@@ -46,7 +46,7 @@ import com.sun.gluegen.*;
import com.sun.gluegen.cgram.types.*;
import com.sun.gluegen.procaddress.*;
import com.sun.gluegen.runtime.*;
-import com.sun.gluegen.runtime.opengl.GLUnifiedName;
+import com.sun.gluegen.runtime.opengl.GLExtensionNames;
/**
* A subclass of ProcAddressEmitter with special OpenGL-specific
@@ -139,8 +139,8 @@ public class GLEmitter extends ProcAddressEmitter
public void normalizeVEN() {
name.normalizeVEN();
}
- public boolean shouldIgnore(GLConfiguration cfg) {
- return GLEmitter.shouldIgnore(name, cfg);
+ public boolean shouldIgnoreInInterface(GLConfiguration cfg) {
+ return GLEmitter.shouldIgnoreInInterface(name, cfg);
}
protected GLUnifiedName name;
@@ -150,10 +150,18 @@ public class GLEmitter extends ProcAddressEmitter
protected String optionalComment;
}
- protected static boolean shouldIgnore(GLUnifiedName name, GLConfiguration cfg) {
- boolean res = cfg.shouldIgnore(name.getUni(), false);
+ protected static boolean shouldIgnoreInInterface(GLUnifiedName name, GLConfiguration cfg) {
+ boolean res = cfg.shouldIgnoreInInterface(name.getUni(), name.isUnique());
for (Iterator iter = name.getOrig().iterator(); !res && iter.hasNext(); ) {
- res = cfg.shouldIgnore((String)iter.next(), true);
+ res = cfg.shouldIgnoreInInterface((String)iter.next(), false);
+ }
+ return res;
+ }
+
+ protected static boolean shouldIgnoreInImpl(GLUnifiedName name, GLConfiguration cfg) {
+ boolean res = cfg.shouldIgnoreInImpl(name.getUni(), name.isUnique());
+ for (Iterator iter = name.getOrig().iterator(); !res && iter.hasNext(); ) {
+ res = cfg.shouldIgnoreInImpl((String)iter.next(), false);
}
return res;
}
@@ -203,7 +211,7 @@ public class GLEmitter extends ProcAddressEmitter
while( deIter.hasNext() ) {
DefineEntry de = (DefineEntry) deIter.next();
if(de.isExtensionVEN()) {
- String extSuffix = GLUnifiedName.getExtensionSuffix(de.name.getUni());
+ String extSuffix = GLExtensionNames.getExtensionSuffix(de.name.getUni(), false);
DefineEntry deUni = (DefineEntry) de.clone();
deUni.normalizeVEN();
DefineEntry deExist = (DefineEntry) defineMap.get(deUni.name.getUni());
@@ -234,7 +242,7 @@ public class GLEmitter extends ProcAddressEmitter
deIter = defineMap.values().iterator();
while( deIter.hasNext() ) {
DefineEntry de = (DefineEntry) deIter.next();
- if (de.shouldIgnore((GLConfiguration)cfg)) {
+ if (de.shouldIgnoreInInterface((GLConfiguration)cfg)) {
continue;
}
String comment = de.getOptCommentString();
@@ -350,7 +358,7 @@ public class GLEmitter extends ProcAddressEmitter
FunctionSymbol fsOrig = (FunctionSymbol) iter.next();
origFuncNames.add(fsOrig.getName());
GLUnifiedName uniName = new GLUnifiedName(fsOrig.getName());
- if (GLEmitter.shouldIgnore(uniName, (GLConfiguration)cfg)) {
+ if (GLEmitter.shouldIgnoreInImpl(uniName, (GLConfiguration)cfg)) {
iter.remove(); // remove ignored function
} else {
if( uniName.isExtensionARB() &&
@@ -386,11 +394,11 @@ public class GLEmitter extends ProcAddressEmitter
GLUnifiedName uniName = new GLUnifiedName(fsOrig.getName());
if(uniName.isExtensionVEN()) {
uniName.normalizeVEN();
- if (GLEmitter.shouldIgnore(uniName, (GLConfiguration)cfg)) {
+ if (GLEmitter.shouldIgnoreInImpl(uniName, (GLConfiguration)cfg)) {
System.err.println("INFO: Ignored: Remove Function:"+ uniName);
iter.remove(); // remove ignored function
} else {
- String extSuffix = GLUnifiedName.getExtensionSuffix(fsOrig.getName());
+ String extSuffix = GLExtensionNames.getExtensionSuffix(fsOrig.getName(), true);
FunctionSymbol fsUni = new FunctionSymbol(uniName.getUni(), fsOrig.getType());
if(funcsSet.contains(fsUni)) {
GLUnifiedName uniNameMap = (GLUnifiedName) funcNameMap.get(uniName.getUni());
@@ -460,12 +468,12 @@ public class GLEmitter extends ProcAddressEmitter
w.println(" * it was statically linked.");
w.println(" */");
w.println(" public long getAddressFor(String functionNameUsr) {");
- w.println(" String functionNameBase = com.sun.gluegen.runtime.opengl.GLUnifiedName.normalizeVEN(com.sun.gluegen.runtime.opengl.GLUnifiedName.normalizeARB(functionNameUsr));");
+ w.println(" String functionNameBase = com.sun.gluegen.runtime.opengl.GLExtensionNames.normalizeVEN(com.sun.gluegen.runtime.opengl.GLExtensionNames.normalizeARB(functionNameUsr, true), true);");
w.println(" String addressFieldNameBase = " + getProcAddressConfig().gluegenRuntimePackage() + ".ProcAddressHelper.PROCADDRESS_VAR_PREFIX + functionNameBase;");
w.println(" java.lang.reflect.Field addressField = null;");
- w.println(" int funcNamePermNum = com.sun.gluegen.runtime.opengl.GLUnifiedName.getNamePermutationNumber(functionNameBase);");
+ w.println(" int funcNamePermNum = com.sun.gluegen.runtime.opengl.GLExtensionNames.getFuncNamePermutationNumber(functionNameBase);");
w.println(" for(int i = 0; null==addressField && i < funcNamePermNum; i++) {");
- w.println(" String addressFieldName = com.sun.gluegen.runtime.opengl.GLUnifiedName.getNamePermutation(addressFieldNameBase, i);");
+ w.println(" String addressFieldName = com.sun.gluegen.runtime.opengl.GLExtensionNames.getFuncNamePermutation(addressFieldNameBase, i);");
w.println(" try {");
w.println(" addressField = getClass().getField(addressFieldName);");
w.println(" } catch (Exception e) { }");
diff --git a/src/java/com/sun/gluegen/opengl/GLJavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/opengl/GLJavaMethodBindingEmitter.java
index 3983916..581dff0 100755
--- a/src/java/com/sun/gluegen/opengl/GLJavaMethodBindingEmitter.java
+++ b/src/java/com/sun/gluegen/opengl/GLJavaMethodBindingEmitter.java
@@ -44,7 +44,6 @@ import java.util.*;
import com.sun.gluegen.*;
import com.sun.gluegen.cgram.types.*;
import com.sun.gluegen.procaddress.*;
-import com.sun.gluegen.runtime.opengl.GLUnifiedName;
/** A specialization of the proc address emitter which knows how to
change argument names to take into account Vertex Buffer Object /
diff --git a/src/java/com/sun/gluegen/runtime/opengl/GLUnifiedName.java b/src/java/com/sun/gluegen/opengl/GLUnifiedName.java
index 02545dd..cf99b66 100644
--- a/src/java/com/sun/gluegen/runtime/opengl/GLUnifiedName.java
+++ b/src/java/com/sun/gluegen/opengl/GLUnifiedName.java
@@ -35,132 +35,32 @@
*
*/
-package com.sun.gluegen.runtime.opengl;
+package com.sun.gluegen.opengl;
import java.util.*;
import com.sun.gluegen.runtime.*;
+import com.sun.gluegen.runtime.opengl.GLExtensionNames;
public class GLUnifiedName implements Cloneable {
- //GL_XYZ : GL_XYZ, GL_XYZ_GL2, GL_XYZ_ARB, GL_XYZ_OES, GL_XYZ_OML
- //GL_XYZ : GL_XYZ, GL_GL2_XYZ, GL_ARB_XYZ, GL_OES_XYZ, GL_OML_XYZ
- //
- // Pass-1 Unify ARB extensions with the same value
- // Pass-2 Unify vendor extensions,
- // if exist as an ARB extension with the same value.
- // Pass-3 Emit
-
- public static final String[] extensionsARB = { "ARB", "GL2", "OES", "OML" };
- public static final String[] extensionsVEN = { "AMD",
- "APPLE",
- "ATI",
- "EXT",
- "HP",
- "IBM",
- "MESA",
- "NV",
- "SGI",
- "SGIS",
- "SGIX",
- "SUN",
- "WIN"
- };
-
- public static final int getExtensionIdx(String[] extensions, String str) {
- for(int i = extensions.length - 1 ; i>=0 ; i--) {
- if(str.endsWith(extensions[i])) {
- return i;
- }
- }
- return -1;
- }
-
- public static final boolean isExtension(String[] extensions, String str) {
- return getExtensionIdx(extensions, str)>=0;
- }
-
- public static final String getExtensionSuffix(String str) {
- int idx = getExtensionIdx(extensionsARB, str);
- if(idx>=0) {
- return extensionsARB[idx];
- }
- idx = getExtensionIdx(extensionsVEN, str);
- if(idx>=0) {
- return extensionsVEN[idx];
- }
- return null;
- }
-
- public static final String normalize(String[] extensions, String str) {
- boolean touched = false;
- for(int i = extensions.length - 1 ; !touched && i>=0 ; i--) {
- if(str.endsWith("_"+extensions[i])) {
- // enums
- str = str.substring(0, str.length()-1-extensions[i].length());
- touched=true;
- } else if(str.endsWith(extensions[i])) {
- // functions
- str = str.substring(0, str.length()-extensions[i].length());
- touched=true;
- }
- }
- return str;
- }
- public static final String normalizeARB(String str) {
- return normalize(extensionsARB, str);
- }
- public static final boolean isExtensionARB(String str) {
- return isExtension(extensionsARB, str);
- }
- public static final String normalizeVEN(String str) {
- return normalize(extensionsVEN, str);
- }
- public static final boolean isExtensionVEN(String str) {
- return isExtension(extensionsVEN, str);
- }
-
- public static final int getNamePermutationNumber(String name) {
- if(isExtensionARB(name) || isExtensionVEN(name)) {
- // no name permutation, if it's already a known extension
- return 1;
- }
- return 1 + extensionsARB.length + extensionsVEN.length;
- }
-
- public static final String getNamePermutation(String name, int i) {
- // identity
- if(i==0) {
- return name;
- }
- if(0>i || i>=(1+extensionsARB.length + extensionsVEN.length)) {
- throw new RuntimeException("Index out of range [0.."+(1+extensionsARB.length+extensionsVEN.length-1)+"]: "+i);
- }
- // ARB
- i-=1;
- if(i<extensionsARB.length) {
- return name+extensionsARB[i];
- }
- // VEN
- i-=extensionsARB.length;
- return name+extensionsVEN[i];
- }
-
- /**
- */
public GLUnifiedName(String name) {
- this(name, normalizeARB(name));
- }
-
- protected GLUnifiedName(String orig, String uni) {
+ isGLFunc = GLExtensionNames.isGLFunction(name);
+ isGLEnum = GLExtensionNames.isGLEnumeration(name);
+ if(!isGLFunc && !isGLEnum) {
+ nameUni=name;
+ } else {
+ nameUni=GLExtensionNames.normalizeARB(name, isGLFunc);
+ }
this.nameOrig=new ArrayList();
- this.nameOrig.add(orig);
- this.nameUni=uni;
+ this.nameOrig.add(name);
}
- protected GLUnifiedName(List origs, String uni) {
+ protected GLUnifiedName(List origs, String uni, boolean isGLFunc, boolean isGLEnum) {
this.nameOrig=new ArrayList();
this.nameOrig.addAll(origs);
this.nameUni=uni;
+ this.isGLFunc=isGLFunc;
+ this.isGLEnum=isGLEnum;
}
public void resetUni() {
@@ -177,22 +77,36 @@ public class GLUnifiedName implements Cloneable {
}
}
+ /**
+ * unique in case this name reflects only one
+ * original entry (no extension unification)
+ */
+ public boolean isUnique() {
+ return nameOrig.size()==1;
+ }
+
public boolean isExtensionARB() {
boolean res = false;
- for (Iterator iter = nameOrig.iterator(); !res && iter.hasNext(); ) {
- res = isExtensionARB((String)iter.next());
+ if(isGLFunc||isGLEnum) {
+ for (Iterator iter = nameOrig.iterator(); !res && iter.hasNext(); ) {
+ res = GLExtensionNames.isExtensionARB((String)iter.next(), isGLFunc);
+ }
}
return res;
}
public void normalizeVEN() {
- nameUni=normalizeVEN(nameUni);
+ if(isGLFunc||isGLEnum) {
+ nameUni=GLExtensionNames.normalizeVEN(nameUni, isGLFunc);
+ }
}
public boolean isExtensionVEN() {
boolean res = false;
- for (Iterator iter = nameOrig.iterator(); !res && iter.hasNext(); ) {
- res = isExtensionVEN((String)iter.next());
+ if(isGLFunc||isGLEnum) {
+ for (Iterator iter = nameOrig.iterator(); !res && iter.hasNext(); ) {
+ res = GLExtensionNames.isExtensionVEN((String)iter.next(), isGLFunc);
+ }
}
return res;
}
@@ -249,7 +163,7 @@ public class GLUnifiedName implements Cloneable {
}
public Object clone() {
- return new GLUnifiedName(nameOrig, nameUni);
+ return new GLUnifiedName(nameOrig, nameUni, isGLFunc, isGLEnum);
}
public String getUni() { return nameUni; }
@@ -258,5 +172,6 @@ public class GLUnifiedName implements Cloneable {
private List nameOrig;
private String nameUni;
+ private boolean isGLFunc, isGLEnum;
}
diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
index 98340a9..ea1feb6 100755
--- a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
+++ b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java
@@ -94,6 +94,10 @@ public class ProcAddressEmitter extends JavaEmitter
return getConfig().runtimeExceptionType();
}
+ public String unsupportedExceptionType() {
+ return getConfig().unsupportedExceptionType();
+ }
+
protected JavaConfiguration createConfig() {
return new ProcAddressConfiguration();
}
diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java
index 4b65d84..f6ae58e 100755
--- a/src/java/com/sun/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java
+++ b/src/java/com/sun/gluegen/procaddress/ProcAddressJavaMethodBindingEmitter.java
@@ -126,7 +126,7 @@ public class ProcAddressJavaMethodBindingEmitter extends JavaMethodBindingEmitte
ProcAddressEmitter.PROCADDRESS_VAR_PREFIX + binding.getName();
writer.println(" final long __addr_ = " + getProcAddressTableExpr + "." + procAddressVariable + ";");
writer.println(" if (__addr_ == 0) {");
- writer.println(" throw new " + emitter.runtimeExceptionType() + "(\"Method \\\"" + binding.getName() + "\\\" not available\");");
+ writer.println(" throw new " + emitter.unsupportedExceptionType() + "(\"Method \\\"" + binding.getName() + "\\\" not available\");");
writer.println(" }");
}
}
diff --git a/src/java/com/sun/gluegen/runtime/opengl/GLExtensionNames.java b/src/java/com/sun/gluegen/runtime/opengl/GLExtensionNames.java
new file mode 100644
index 0000000..cc9233d
--- /dev/null
+++ b/src/java/com/sun/gluegen/runtime/opengl/GLExtensionNames.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ */
+
+package com.sun.gluegen.runtime.opengl;
+
+import java.util.*;
+import com.sun.gluegen.runtime.*;
+
+public class GLExtensionNames {
+ //GL_XYZ : GL_XYZ, GL_XYZ_GL2, GL_XYZ_ARB, GL_XYZ_OES, GL_XYZ_OML
+ //GL_XYZ : GL_XYZ, GL_GL2_XYZ, GL_ARB_XYZ, GL_OES_XYZ, GL_OML_XYZ
+ //
+ // Pass-1 Unify ARB extensions with the same value
+ // Pass-2 Unify vendor extensions,
+ // if exist as an ARB extension with the same value.
+ // Pass-3 Emit
+
+ public static final String[] extensionsARB = { "ARB", "GL2", "OES", "OML" };
+ public static final String[] extensionsVEN = { "AMD",
+ "APPLE",
+ "ATI",
+ "EXT",
+ "HP",
+ "IBM",
+ "MESA",
+ "MESAX",
+ "NV",
+ "SGI",
+ "SGIS",
+ "SGIX",
+ "SUN",
+ "WIN"
+ };
+
+
+ public static final boolean isGLFunction(String str) {
+ return str.startsWith("gl") || /* str.startsWith("glu") || str.startsWith("glX") || */
+ str.startsWith("egl") || str.startsWith("wgl") || str.startsWith("agl") ||
+ str.startsWith("cgl") ;
+ }
+
+ public static final boolean isGLEnumeration(String str) {
+ return str.startsWith("GL_") || str.startsWith("GLU_") || str.startsWith("GLX_") ||
+ str.startsWith("EGL_") || str.startsWith("WGL_") || str.startsWith("AGL_") ||
+ str.startsWith("CGL_") ;
+ }
+
+ public static final int getExtensionIdx(String[] extensions, String str, boolean isGLFunc) {
+ if(isGLFunc) {
+ for(int i = extensions.length - 1 ; i>=0 ; i--) {
+ if( str.endsWith(extensions[i]) ) {
+ return i;
+ }
+ }
+ } else {
+ for(int i = extensions.length - 1 ; i>=0 ; i--) {
+ if( str.endsWith("_"+extensions[i]) ) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public static final boolean isExtension(String[] extensions, String str, boolean isGLFunc) {
+ return getExtensionIdx(extensions, str, isGLFunc)>=0;
+ }
+
+ public static final String getExtensionSuffix(String str, boolean isGLFunc) {
+ int idx = getExtensionIdx(extensionsARB, str, isGLFunc);
+ if(idx>=0) {
+ return extensionsARB[idx];
+ }
+ idx = getExtensionIdx(extensionsVEN, str, isGLFunc);
+ if(idx>=0) {
+ return extensionsVEN[idx];
+ }
+ return null;
+ }
+
+ public static final String normalize(String[] extensions, String str, boolean isGLFunc) {
+ boolean touched = false;
+ for(int i = extensions.length - 1 ; !touched && i>=0 ; i--) {
+ if(isGLFunc) {
+ if(str.endsWith(extensions[i])) {
+ // functions
+ str = str.substring(0, str.length()-extensions[i].length());
+ touched=true;
+ }
+ } else {
+ if(str.endsWith("_"+extensions[i])) {
+ // enums
+ str = str.substring(0, str.length()-1-extensions[i].length());
+ touched=true;
+ }
+ }
+ }
+ return str;
+ }
+ public static final String normalizeARB(String str, boolean isGLFunc) {
+ return normalize(extensionsARB, str, isGLFunc);
+ }
+ public static final boolean isExtensionARB(String str, boolean isGLFunc) {
+ return isExtension(extensionsARB, str, isGLFunc);
+ }
+ public static final String normalizeVEN(String str, boolean isGLFunc) {
+ return normalize(extensionsVEN, str, isGLFunc);
+ }
+ public static final boolean isExtensionVEN(String str, boolean isGLFunc) {
+ return isExtension(extensionsVEN, str, isGLFunc);
+ }
+
+ public static final int getFuncNamePermutationNumber(String name) {
+ if(isExtensionARB(name, true) || isExtensionVEN(name, true)) {
+ // no name permutation, if it's already a known extension
+ return 1;
+ }
+ return 1 + extensionsARB.length + extensionsVEN.length;
+ }
+
+ public static final String getFuncNamePermutation(String name, int i) {
+ // identity
+ if(i==0) {
+ return name;
+ }
+ if(0>i || i>=(1+extensionsARB.length + extensionsVEN.length)) {
+ throw new RuntimeException("Index out of range [0.."+(1+extensionsARB.length+extensionsVEN.length-1)+"]: "+i);
+ }
+ // ARB
+ i-=1;
+ if(i<extensionsARB.length) {
+ return name+extensionsARB[i];
+ }
+ // VEN
+ i-=extensionsARB.length;
+ return name+extensionsVEN[i];
+ }
+}
+
diff --git a/src/java/com/sun/gluegen/runtime/opengl/GLProcAddressHelper.java b/src/java/com/sun/gluegen/runtime/opengl/GLProcAddressHelper.java
index f8858d2..3f88261 100644
--- a/src/java/com/sun/gluegen/runtime/opengl/GLProcAddressHelper.java
+++ b/src/java/com/sun/gluegen/runtime/opengl/GLProcAddressHelper.java
@@ -75,9 +75,9 @@ public class GLProcAddressHelper extends ProcAddressHelper {
"\" in class " + tableClass.getName(), e);
}
long newProcAddress = 0;
- int funcNamePermNum = GLUnifiedName.getNamePermutationNumber(funcNameBase);
+ int funcNamePermNum = GLExtensionNames.getFuncNamePermutationNumber(funcNameBase);
for(int j = 0; 0==newProcAddress && j < funcNamePermNum; j++) {
- String funcName = GLUnifiedName.getNamePermutation(funcNameBase, j);
+ String funcName = GLExtensionNames.getFuncNamePermutation(funcNameBase, j);
try {
if (DEBUG) {
dout.println(" try function lookup: " + funcName + " / " + funcNameBase);