diff options
author | Michael Bien <[email protected]> | 2009-10-08 18:44:55 +0200 |
---|---|---|
committer | Michael Bien <[email protected]> | 2009-10-08 18:44:55 +0200 |
commit | 03bf321dc0aac6a2bc635093d634e1c8e67f8d43 (patch) | |
tree | e0dddfc255553c39fd9744f79fc1834b338f1555 | |
parent | ce3fceeb101835866224988918b89098157d6e34 (diff) |
defines with constant but more complex expressions are now no longer ignored (e.g #define CL_FP_FMA (1 << 5)).
-rw-r--r-- | src/java/com/sun/gluegen/JavaEmitter.java | 91 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/cgram/StdCParser.g | 21 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/pcpp/PCPP.java | 60 |
3 files changed, 137 insertions, 35 deletions
diff --git a/src/java/com/sun/gluegen/JavaEmitter.java b/src/java/com/sun/gluegen/JavaEmitter.java index 1667ed6..c9a54e3 100644 --- a/src/java/com/sun/gluegen/JavaEmitter.java +++ b/src/java/com/sun/gluegen/JavaEmitter.java @@ -133,14 +133,10 @@ public class JavaEmitter implements GlueEmitter { } } - public void beginEmission(GlueEmitterControls controls) throws IOException - { - try - { + public void beginEmission(GlueEmitterControls controls) throws IOException { + try { openWriters(); - } - catch (Exception e) - { + } catch (Exception e) { throw new RuntimeException( "Unable to open files for writing", e); } @@ -156,30 +152,24 @@ public class JavaEmitter implements GlueEmitter { controls.runSymbolFilter(new ConstantRenamer()); } - public void endEmission() - { + public void endEmission() { emitAllFileFooters(); - try - { + try { closeWriters(); - } - catch (Exception e) - { + } catch (Exception e) { throw new RuntimeException( "Unable to close open files", e); } } - public void beginDefines() throws Exception - { + public void beginDefines() throws Exception { if (cfg.allStatic() || cfg.emitInterface()) { javaWriter().println(); } } - protected static int getJavaRadix(String name, String value) - { + 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. @@ -222,14 +212,59 @@ public class JavaEmitter implements GlueEmitter { } } - protected static Object getJavaValue(String name, String value) - { + protected static Object getJavaValue(String name, String value) { + + // "calculates" the result type of a simple expression + // example: (2+3)-(2.0f-3.0) -> Double + // example: (1 << 2) -> Integer + + Scanner scanner = new Scanner(value).useDelimiter("[+-/*/></(/)]"); + + Object resultType = null; + + while (scanner.hasNext()) { + + String t = scanner.next().trim(); + + if(!t.isEmpty()) { + Object type = getJavaValue2(name, t); + + //fast path + if(type instanceof Double) + return type; + + if(resultType != null) { + + if(resultType instanceof Integer) { + if(type instanceof Long || type instanceof Float || type instanceof Double) + resultType = type; + }else if(resultType instanceof Long) { + if(type instanceof Float || type instanceof Double) + resultType = type; + }else if(resultType instanceof Float) { + if(type instanceof Float) + resultType = type; + } + }else{ + resultType = type; + } + + //fast path + if(resultType instanceof Double) + return type; + } + } + + return resultType; + } + + private static Object getJavaValue2(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; @@ -243,7 +278,7 @@ public class JavaEmitter implements GlueEmitter { } else if (value.startsWith("0") && value.length() > 1) { // TODO: is "0" the prefix in C to indicate octal??? - radix = 8; + radix = 8; parseValue = value.substring(1); } else { @@ -257,7 +292,7 @@ public class JavaEmitter implements GlueEmitter { return new Integer((int)longVal); } return new Long(longVal); - + } catch (NumberFormatException e) { try { // see if it's a double or float @@ -268,7 +303,7 @@ public class JavaEmitter implements GlueEmitter { return new Double(dVal); } return new Float((float) dVal); - } catch (NumberFormatException e2) { + } catch (NumberFormatException e2) { throw new RuntimeException( "Cannot emit define \""+name+"\": value \""+value+ "\" cannot be assigned to a int, long, float, or double", e2); @@ -276,6 +311,7 @@ public class JavaEmitter implements GlueEmitter { } } + protected static String getJavaType(String name, String value) { Object oval = getJavaValue(name, value); return getJavaType(name, oval); @@ -297,8 +333,8 @@ public class JavaEmitter implements GlueEmitter { "\" cannot be assigned to a int, long, float, or double"); } - public void emitDefine(ConstantDefinition def, String optionalComment) throws Exception - { + public void emitDefine(ConstantDefinition def, String optionalComment) throws Exception { + if (cfg.allStatic() || cfg.emitInterface()) { // TODO: Some defines (e.g., GL_DOUBLE_EXT in gl.h) are defined in terms // of other defines -- should we emit them as references to the original @@ -325,8 +361,7 @@ public class JavaEmitter implements GlueEmitter { } } - public void endDefines() throws Exception - { + public void endDefines() throws Exception { } public void beginFunctions(TypeDictionary typedefDictionary, diff --git a/src/java/com/sun/gluegen/cgram/StdCParser.g b/src/java/com/sun/gluegen/cgram/StdCParser.g index e84fbfd..65e7936 100644 --- a/src/java/com/sun/gluegen/cgram/StdCParser.g +++ b/src/java/com/sun/gluegen/cgram/StdCParser.g @@ -1112,22 +1112,33 @@ options { : '#' ( ( "line" || (( ' ' | '\t' | '\014')+ '0'..'9')) => LineDirective - | ( (Space)* "define" (Space)* i:ID (Space)* (n:Number)? + | ( (Space)* "define" (Space)* i:ID (Space)* (n:DefineExpr)? nw:NonWhitespace - ("\r\n" | "\r" | "\n") ) { if (n != null) { + ("\r\n" | "\r" | "\n") ) { + if (n != null) { + //System.out.println("addDefine: #define " + i.getText() + " " + n.getText()); addDefine(i.getText(), n.getText()); } else { - setPreprocessingDirective("#define " + i.getText() + " " + - nw.getText()); + setPreprocessingDirective("#define " + i.getText() + " " + nw.getText()); } } | (~'\n')* { setPreprocessingDirective(getText()); } ) - { + { _ttype = Token.SKIP; } ; +DefineExpr: + ((LPAREN) (Space)* (DefineExpr2) (Space)* (RPAREN)) | (DefineExpr2) +; + +DefineExpr2: + (Number) + ((Space)* (LSHIFT | RSHIFT | PLUS | MINUS | STAR | DIV | MOD) (Space)* (DefineExpr))? +; + + protected Space: ( ' ' | '\t' | '\014') ; diff --git a/src/java/com/sun/gluegen/pcpp/PCPP.java b/src/java/com/sun/gluegen/pcpp/PCPP.java index 7f4fdff..05580a8 100644 --- a/src/java/com/sun/gluegen/pcpp/PCPP.java +++ b/src/java/com/sun/gluegen/pcpp/PCPP.java @@ -456,6 +456,22 @@ public class PCPP { } } } else { + + // find constant expressions like (1 << 3) + // if found just pass them through, they will most likely work in java too + // expressions containing identifiers are currently ignored (casts too) + + boolean containsIdentifier = false; + for (String value : values) { + if(isIdentifier(value)) { + containsIdentifier = true; + break; + } + } + + //TODO more work here e.g casts are currently not handled + if(containsIdentifier) { //skip + // Non-constant define; try to do reasonable textual substitution anyway // (FIXME: should identify some of these, like (-1), as constants) emitDefine = false; @@ -474,14 +490,32 @@ public class PCPP { } defineMap.put(name, val.toString()); nonConstantDefines.add(name); + + }else{ // constant expression -> pass through + + StringBuilder sb = new StringBuilder(); + for (String v : values) { + sb.append(v); } + String value = sb.toString(); + + String oldDef = defineMap.put(name, value); + if (oldDef != null && !oldDef.equals(value)) { + System.err.println("WARNING: \"" + name + "\" redefined from \"" + + oldDef + "\" to \"" + value + "\""); + } + debugPrint(true, "#define " + name + " ["+oldDef+" ] -> "+value + " CONST"); +// System.out.println("#define " + name +" "+value + " CONST EXPRESSION"); + } + + } if (emitDefine) { // Print name and value print("# define "); print(name); + print(" "); for (String v : values) { - print(" "); print(v); } println(); @@ -492,6 +526,28 @@ public class PCPP { //System.err.println("OUT HANDLE_DEFINE: " + name); } + private boolean isIdentifier(String value) { + + boolean identifier = false; + + char[] chars = value.toCharArray(); + + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + if (i == 0) { + if (Character.isJavaIdentifierStart(c)) { + identifier = true; + } + } else { + if (!Character.isJavaIdentifierPart(c)) { + identifier = false; + break; + } + } + } + return identifier; + } + private boolean isConstant(String s) { if (s.startsWith("0x") || s.startsWith("0X")) { return checkHex(s); @@ -832,7 +888,7 @@ public class PCPP { } private boolean enabled() { - return (enabledBits.size() == 0 || enabledBits.get(enabledBits.size() - 1).booleanValue()); + return (enabledBits.size() == 0 || enabledBits.get(enabledBits.size() - 1)); } private void print(String s) { |