diff options
Diffstat (limited to 'src/java/com/sun/gluegen')
-rw-r--r-- | src/java/com/sun/gluegen/JavaEmitter.java | 180 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/opengl/GLEmitter.java | 263 |
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); } |