aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java')
-rw-r--r--src/java/com/sun/gluegen/JavaEmitter.java180
-rw-r--r--src/java/com/sun/gluegen/opengl/GLEmitter.java263
2 files changed, 384 insertions, 59 deletions
diff --git a/src/java/com/sun/gluegen/JavaEmitter.java b/src/java/com/sun/gluegen/JavaEmitter.java
index 15dff34..9c5e786 100644
--- a/src/java/com/sun/gluegen/JavaEmitter.java
+++ b/src/java/com/sun/gluegen/JavaEmitter.java
@@ -60,7 +60,7 @@ public class JavaEmitter implements GlueEmitter {
private TypeDictionary typedefDictionary;
private TypeDictionary structDictionary;
private Map canonMap;
- private JavaConfiguration cfg;
+ protected JavaConfiguration cfg;
/**
* Style of code emission. Can emit everything into one class
@@ -145,6 +145,125 @@ public class JavaEmitter implements GlueEmitter {
}
}
+ protected static int getJavaRadix(String name, String value)
+ {
+ // FIXME: need to handle when type specifier is in last char (e.g.,
+ // "1.0d or 2759L", because parseXXX() methods don't allow the type
+ // specifier character in the string.
+ //
+ //char lastChar = value.charAt(value.length()-1);
+
+ try {
+ // see if it's a long or int
+ int radix;
+ String parseValue;
+ // FIXME: are you allowed to specify hex/octal constants with
+ // negation, e.g. "-0xFF" or "-056"? If so, need to modify the
+ // following "if(..)" checks and parseValue computation
+ if (value.startsWith("0x") || value.startsWith("0X")) {
+ radix = 16;
+ parseValue = value.substring(2);
+ }
+ else if (value.startsWith("0") && value.length() > 1) {
+ // TODO: is "0" the prefix in C to indicate octal???
+ radix = 8;
+ parseValue = value.substring(1);
+ }
+ else {
+ radix = 10;
+ parseValue = value;
+ }
+ //System.err.println("parsing " + value + " as long w/ radix " + radix);
+ long longVal = Long.parseLong(parseValue, radix);
+ return radix;
+ } catch (NumberFormatException e) {
+ try {
+ // see if it's a double or float
+ double dVal = Double.parseDouble(value);
+ return 10;
+ } catch (NumberFormatException e2) {
+ throw new RuntimeException(
+ "Cannot emit define \""+name+"\": value \""+value+
+ "\" cannot be assigned to a int, long, float, or double", e2);
+ }
+ }
+ }
+
+ protected static Object getJavaValue(String name, String value)
+ {
+ // FIXME: need to handle when type specifier is in last char (e.g.,
+ // "1.0d or 2759L", because parseXXX() methods don't allow the type
+ // specifier character in the string.
+ //
+ //char lastChar = value.charAt(value.length()-1);
+
+ try {
+ // see if it's a long or int
+ int radix;
+ String parseValue;
+ // FIXME: are you allowed to specify hex/octal constants with
+ // negation, e.g. "-0xFF" or "-056"? If so, need to modify the
+ // following "if(..)" checks and parseValue computation
+ if (value.startsWith("0x") || value.startsWith("0X")) {
+ radix = 16;
+ parseValue = value.substring(2);
+ }
+ else if (value.startsWith("0") && value.length() > 1) {
+ // TODO: is "0" the prefix in C to indicate octal???
+ radix = 8;
+ parseValue = value.substring(1);
+ }
+ else {
+ radix = 10;
+ parseValue = value;
+ }
+ //System.err.println("parsing " + value + " as long w/ radix " + radix);
+ long longVal = Long.parseLong(parseValue, radix);
+ // if constant is small enough, store it as an int instead of a long
+ if (longVal > Integer.MIN_VALUE && longVal < Integer.MAX_VALUE) {
+ return new Integer((int)longVal);
+ }
+ return new Long(longVal);
+
+ } catch (NumberFormatException e) {
+ try {
+ // see if it's a double or float
+ double dVal = Double.parseDouble(value);
+ // if constant is small enough, store it as a float instead of a double
+ if (dVal > Float.MIN_VALUE && dVal < Float.MAX_VALUE) {
+ return new Float((float)dVal);
+ }
+ return new Double(dVal);
+
+ } catch (NumberFormatException e2) {
+ throw new RuntimeException(
+ "Cannot emit define \""+name+"\": value \""+value+
+ "\" cannot be assigned to a int, long, float, or double", e2);
+ }
+ }
+ }
+
+ protected static String getJavaType(String name, String value) {
+ Object oval = getJavaValue(name, value);
+ return getJavaType(name, oval);
+ }
+
+ protected static String getJavaType(String name, Object oval) {
+ if(oval instanceof Integer) {
+ return "int";
+ } else if(oval instanceof Long) {
+ return "long";
+ } else if(oval instanceof Float) {
+ return "float";
+ } else if(oval instanceof Double) {
+ return "double";
+ }
+
+ throw new RuntimeException(
+ "Cannot emit define (2) \""+name+"\": value \""+oval+
+ "\" cannot be assigned to a int, long, float, or double");
+ }
+
public void emitDefine(String name, String value, String optionalComment) throws Exception
{
if (cfg.allStatic() || cfg.emitInterface()) {
@@ -158,64 +277,7 @@ public class JavaEmitter implements GlueEmitter {
// objects it would make a bigger difference.
if (!cfg.shouldIgnore(name)) {
- String type = null;
-
- // FIXME: need to handle when type specifier is in last char (e.g.,
- // "1.0d or 2759L", because parseXXX() methods don't allow the type
- // specifier character in the string.
- //
- //char lastChar = value.charAt(value.length()-1);
-
- try {
- // see if it's a long or int
- int radix;
- String parseValue;
- // FIXME: are you allowed to specify hex/octal constants with
- // negation, e.g. "-0xFF" or "-056"? If so, need to modify the
- // following "if(..)" checks and parseValue computation
- if (value.startsWith("0x") || value.startsWith("0X")) {
- radix = 16;
- parseValue = value.substring(2);
- }
- else if (value.startsWith("0") && value.length() > 1) {
- // TODO: is "0" the prefix in C to indicate octal???
- radix = 8;
- parseValue = value.substring(1);
- }
- else {
- radix = 10;
- parseValue = value;
- }
- //System.err.println("parsing " + value + " as long w/ radix " + radix);
- long longVal = Long.parseLong(parseValue, radix);
- type = "long";
- // if constant is small enough, store it as an int instead of a long
- if (longVal > Integer.MIN_VALUE && longVal < Integer.MAX_VALUE) {
- type = "int";
- }
-
- } catch (NumberFormatException e) {
- try {
- // see if it's a double or float
- double dVal = Double.parseDouble(value);
- type = "double";
- // if constant is small enough, store it as a float instead of a double
- if (dVal > Float.MIN_VALUE && dVal < Float.MAX_VALUE) {
- type = "float";
- }
-
- } catch (NumberFormatException e2) {
- throw new RuntimeException(
- "Cannot emit define \""+name+"\": value \""+value+
- "\" cannot be assigned to a int, long, float, or double", e2);
- }
- }
-
- if (type == null) {
- throw new RuntimeException(
- "Cannot emit define (2) \""+name+"\": value \""+value+
- "\" cannot be assigned to a int, long, float, or double");
- }
+ String type = getJavaType(name, value);
if (optionalComment != null && optionalComment.length() != 0) {
javaWriter().println(" /** " + optionalComment + " */");
}
diff --git a/src/java/com/sun/gluegen/opengl/GLEmitter.java b/src/java/com/sun/gluegen/opengl/GLEmitter.java
index 8e7484a..2666aa4 100644
--- a/src/java/com/sun/gluegen/opengl/GLEmitter.java
+++ b/src/java/com/sun/gluegen/opengl/GLEmitter.java
@@ -72,6 +72,269 @@ public class GLEmitter extends ProcAddressEmitter
super.beginEmission(controls);
}
+ static class UnifiedExtensionName implements Cloneable {
+ public UnifiedExtensionName(String name) {
+ this(name, normalizeARB(name));
+ }
+
+ protected UnifiedExtensionName(String orig, String uni) {
+ this.nameOrig=orig;
+ this.nameUni=uni;
+ }
+
+ public void useOriginal() {
+ nameUni=nameOrig;
+ }
+
+ public void addOrig(String name) {
+ if(nameOrig.indexOf(name)<0) {
+ nameOrig = nameOrig.concat(", "+name);
+ }
+ }
+
+ public void normalizeVEN() {
+ nameUni=normalizeVEN(nameUni);
+ }
+
+ public boolean isExtensionVEN() {
+ return isExtensionVEN(nameUni);
+ }
+
+ public boolean equals(Object obj) {
+ if(null==obj || !(obj instanceof UnifiedExtensionName)) return false;
+ UnifiedExtensionName uen = (UnifiedExtensionName) obj;
+ return nameUni.equals(uen.nameUni);
+ }
+
+ public String getCommentString() {
+ if(nameOrig.equals(nameUni)) {
+ return new String();
+ }
+ return " /** " + nameUni + ": Alias of: " + nameOrig + " */";
+ }
+
+ public String toString() {
+ if(nameOrig.equals(nameUni)) {
+ return nameUni;
+ }
+ return nameUni + " /* " + nameOrig + " */";
+ }
+
+ public Object clone() {
+ return new UnifiedExtensionName(nameOrig, nameUni);
+ }
+
+ //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 String[] extensionsARB = { "GL2", "ARB", "OES", "OML" };
+ public static String[] extensionsVEN = { "EXT", "NV", "ATI", "SGI", "SGIS", "SGIX", "HP", "IBM", "WIN" };
+
+ public static boolean isExtension(String[] extensions, String str) {
+ for(int i = extensions.length - 1 ; i>=0 ; i--) {
+ if(str.endsWith("_"+extensions[i])) {
+ return true;
+ }
+ if(str.startsWith("GL_"+extensions[i]+"_")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static String normalize(String[] extensions, String str) {
+ boolean touched = false;
+ for(int i = extensions.length - 1 ; !touched && i>=0 ; i--) {
+ if(str.endsWith("_"+extensions[i])) {
+ str = str.substring(0, str.length()-1-extensions[i].length());
+ touched=true;
+ }
+ if(str.startsWith("GL_"+extensions[i]+"_")) {
+ str = "GL_"+str.substring(4+extensions[i].length());
+ touched=true;
+ }
+ }
+ return str;
+ }
+ public static String normalizeARB(String str) {
+ return normalize(extensionsARB, str);
+ }
+ public static String normalizeVEN(String str) {
+ return normalize(extensionsVEN, str);
+ }
+ public static boolean isExtensionVEN(String str) {
+ return isExtension(extensionsVEN, str);
+ }
+
+ protected String nameOrig;
+ protected String nameUni;
+ }
+
+ static class DefineEntry implements Cloneable {
+ public DefineEntry(String namestr, String valuestr, String optionalComment) {
+ this.name=new UnifiedExtensionName(namestr);
+ this.value=getJavaValue(namestr, valuestr);
+ this.type=getJavaType(namestr, this.value);
+ this.radix=getJavaRadix(namestr, valuestr);
+ this.optionalComment=optionalComment;
+ }
+
+ protected DefineEntry(UnifiedExtensionName name, String type, Object value, int radix, String optionalComment) {
+ this.name=name;
+ this.value=value;
+ this.type=type;
+ this.radix=radix;
+ this.optionalComment=optionalComment;
+ }
+
+ public Object clone() {
+ return new DefineEntry((UnifiedExtensionName)name.clone(), type, value, radix, optionalComment);
+ }
+
+ public boolean equals(Object obj) {
+ if(null==obj || !(obj instanceof DefineEntry)) return false;
+ DefineEntry de = (DefineEntry) obj;
+ return name.equals(de.name) &&
+ type.equals(de.type) &&
+ value.equals(de.value);
+ }
+
+ public String toString() {
+ String res = " public static final " + type + " " + name + " = ";
+ if(16!=radix) {
+ res = res + value;
+ } else {
+ res = res.concat("0x");
+ if(value instanceof Integer) {
+ res = res.concat( Integer.toString( ((Integer)value).intValue(), radix ).toUpperCase() );
+ } else if(value instanceof Long) {
+ res = res.concat( Long.toString( ((Long)value).longValue(), radix ).toUpperCase() );
+ } else {
+ res = res + value;
+ }
+ }
+
+ return res.concat(";");
+ }
+
+ public String getOptCommentString() {
+ if (optionalComment != null && optionalComment.length() > 0) {
+ return " /** " + optionalComment + " */";
+ }
+ return new String();
+ }
+
+ public void addOrigName(String name) {
+ this.name.addOrig(name);
+ }
+ public boolean isExtensionVEN() {
+ return name.isExtensionVEN();
+ }
+ public void normalizeVEN() {
+ name.normalizeVEN();
+ }
+
+ protected UnifiedExtensionName name;
+ protected Object value;
+ protected String type;
+ protected int radix;
+ protected String optionalComment;
+ }
+
+ protected LinkedHashMap/*<String name, DefineEntry entry>*/ defineMap = new LinkedHashMap();
+
+ public void beginDefines() throws Exception
+ {
+ super.beginDefines();
+ }
+
+ /**
+ * Pass-1 Unify ARB extensions with the same value
+ */
+ public void emitDefine(String name, String value, String optionalComment) throws Exception
+ {
+ if (cfg.allStatic() || cfg.emitInterface()) {
+ if (!cfg.shouldIgnore(name)) {
+ DefineEntry deNew = new DefineEntry(name, value, optionalComment);
+ DefineEntry deExist = (DefineEntry) defineMap.get(deNew.name.nameUni);
+ if(deExist!=null) {
+ if(deNew.equals(deExist)) {
+ if(deNew.getOptCommentString().length()>deExist.getOptCommentString().length()) {
+ deExist.optionalComment=deNew.optionalComment;
+ }
+ deExist.addOrigName(deNew.name.nameOrig);
+ return; // done ..
+ }
+ deNew.name.useOriginal();
+ System.err.println("WARNING: Normalized entry with different value exists:"+
+ "\n\tDef: "+deExist+
+ "\n\tNew: "+deNew+
+ "\n\t using original ARB entry");
+ }
+ defineMap.put(deNew.name.nameUni, deNew);
+ }
+ }
+ }
+
+ /**
+ * Pass-2 Unify vendor extensions,
+ * if exist as an ARB extension with the same value.
+ * Pass-3 Emit all ..
+ */
+ public void endDefines() throws Exception
+ {
+ if (cfg.allStatic() || cfg.emitInterface()) {
+ Iterator/*<DefineEntry>*/ deIter = null;
+
+ deIter = defineMap.values().iterator();
+ while( deIter.hasNext() ) {
+ DefineEntry de = (DefineEntry) deIter.next();
+ if(de.isExtensionVEN()) {
+ DefineEntry deUni = (DefineEntry) de.clone();
+ deUni.normalizeVEN();
+ DefineEntry deExist = (DefineEntry) defineMap.get(deUni.name.nameUni);
+ if(null!=deExist) {
+ if(deUni.equals(deExist)) {
+ if(deUni.getOptCommentString().length()>deExist.getOptCommentString().length()) {
+ deExist.optionalComment=deUni.optionalComment;
+ }
+ deIter.remove();
+ deExist.addOrigName(deUni.name.nameOrig);
+ } else {
+ System.err.println("INFO: Normalized entry with different value exists:"+
+ "\n\tDef: "+deExist+
+ "\n\tNew: "+de+
+ "\n\t using original vendor entry");
+ }
+ }
+ }
+ }
+
+ deIter = defineMap.values().iterator();
+ while( deIter.hasNext() ) {
+ DefineEntry de = (DefineEntry) deIter.next();
+ String comment = de.getOptCommentString();
+ if (comment.length() != 0) {
+ javaWriter().println(comment);
+ } else {
+ comment = de.name.getCommentString();
+ if (comment.length() != 0) {
+ javaWriter().println(comment);
+ }
+ }
+ javaWriter().println(de.toString());
+ }
+ }
+ defineMap.clear();
+
+ super.endDefines();
+ }
+
protected JavaConfiguration createConfig() {
return new GLConfiguration(this);
}