aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/java/com/sun/gluegen/JavaEmitter.java91
-rw-r--r--src/java/com/sun/gluegen/cgram/StdCParser.g21
-rw-r--r--src/java/com/sun/gluegen/pcpp/PCPP.java60
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) {