28package com.jogamp.gluegen;
30import java.math.BigInteger;
32import java.util.regex.Matcher;
33import java.util.regex.Pattern;
35import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider;
36import com.jogamp.gluegen.cgram.types.AliasedSymbol.AliasedSymbolImpl;
37import com.jogamp.gluegen.cgram.types.TypeComparator.AliasedSemanticSymbol;
38import com.jogamp.gluegen.cgram.types.TypeComparator.SemanticEqualityOp;
78 public final double f;
82 this.isInteger =
true;
86 this.isDouble =
false;
91 this.isInteger =
false;
93 this.isUnsigned =
false;
100 return isInteger ? Long.valueOf(
i).hashCode() : Double.valueOf(
f).hashCode();
103 public boolean equals(
final Object arg) {
106 }
else if ( !(arg instanceof
CNumber) ) {
117 return "0x"+Long.toHexString(
i)+
"L";
119 return "0x"+Integer.toHexString((
int)
i);
123 return String.valueOf(
i)+
"L";
125 return String.valueOf((
int)
i);
129 return String.valueOf(
f) + ( !
isDouble ?
"f" :
"");
134 final StringBuilder sb =
new StringBuilder();
138 sb.append(
"unsigned ");
148 sb.append(
"double: ");
150 sb.append(
"float: ");
155 return sb.toString();
192 final Map<String, ConstantDefinition.JavaExpr> constMap) {
193 final boolean debug =
GlueGen.debug();
195 System.err.println(
"ConstJavaExpr.create: "+constDef);
200 System.err.printf(
"V %s (isCNumber)%n", constDef);
204 final StringBuilder javaExpr =
new StringBuilder();
214 while ( matcher.find() ) {
215 final int opStartIdx = matcher.start();
216 if( opStartIdx > preStartIdx ) {
217 final String sValue = nativeExpr.substring(preStartIdx, opStartIdx).trim();
218 if( sValue.length() > 0 ) {
220 System.err.printf(
"V %03d-%03d: %s%n", preStartIdx, opStartIdx, sValue);
223 javaExpr.append(
" ");
226 opEndIdx = matcher.end();
227 final String op = nativeExpr.substring(opStartIdx, opEndIdx);
229 System.err.printf(
"O %03d-%03d: %s%n", opStartIdx, opEndIdx, op);
231 javaExpr.append(op).append(
" ");
232 preStartIdx = opEndIdx;
234 if( opEndIdx < nativeExpr.length() ) {
236 final String sValue = nativeExpr.substring(opEndIdx).trim();
237 if( sValue.length() > 0 ) {
239 System.err.printf(
"V %03d %03d-%03d: %s (tail)%n", preStartIdx, opEndIdx, nativeExpr.length(), sValue);
244 final String javaExprS = javaExpr.toString().trim();
247 "\", parsed \""+javaExprS+
"\" does not contain a constant number", constDef.
getASTLocusTag());
253 final Map<String, ConstantDefinition.JavaExpr> constMap,
255 final StringBuilder javaExpr) {
256 final CNumber nValue = getANumber(constDef, sValue);
257 if(
null != nValue ) {
262 final JavaExpr cje = constMap.get(sValue);
266 javaExpr.append(sValue);
270 private static CNumber getANumber(
final ConstantDefinition constDef,
final String value) {
273 if(
null != number ) {
276 }
catch(
final Throwable _t ) {
277 final String msg =
"Cannot emit const \""+constDef.getName()+
"\": value \""+value+
278 "\" cannot be assigned to a int, long, float, or double";
279 throw new GlueGenException(msg, constDef.getASTLocusTag(), _t);
283 private static CNumber evalType(
final CNumber
resultType,
final CNumber type) {
285 if( type.isDouble ) {
292 if( !type.isInteger ) {
296 }
else if( type.isLong || !type.isInteger ) {
301 if( type.isDouble ) {
313 private final boolean relaxedEqSem;
314 private final String nativeExpr;
315 private final CNumber number;
316 private final boolean isEnum;
317 private final String enumName;
318 private final ASTLocusTag astLocus;
330 final String nativeExpr,
333 this(name, nativeExpr, number,
false,
null, astLocus);
346 final String nativeExpr,
348 final String enumName,
final ASTLocusTag astLocus) {
349 this(name, nativeExpr, number,
true, enumName, astLocus);
362 final String nativeExpr,
363 final CNumber number,
364 final boolean isEnum,
final String enumName,
final ASTLocusTag astLocus) {
366 this.nativeExpr = nativeExpr;
367 this.relaxedEqSem =
TypeConfig.relaxedEqualSemanticsTest();
368 if(
null != number ) {
369 this.number = number;
384 this.isEnum = isEnum;
385 this.enumName = enumName;
386 this.astLocus = astLocus;
404 public final boolean equals(
final Object arg) {
419 hash = ((hash << 5) - hash) + ( isEnum ? 1 : 0 );
420 hash = ((hash << 5) - hash) + (
null != enumName ? enumName.hashCode() : 0 );
421 hash = ((hash << 5) - hash) + (
null != number ? number.hashCode() : 0 );
422 return ((hash << 5) - hash) + ( !relaxedEqSem &&
null != nativeExpr ? nativeExpr.hashCode() : 0 );
434 isEnum != t.isEnum ||
435 !
equals(enumName, t.enumName) ) {
438 if(
null != number ) {
439 if( number.isInteger ) {
440 return number.i == t.number.
i;
442 return number.f == t.number.
f;
446 return relaxedEqSem ||
equals(nativeExpr, t.nativeExpr);
473 return "ConstantDefinition [name \"" +
getName()
474 +
"\", expression \"" + nativeExpr
475 +
"\", number "+number
476 +
"], enum[is " + isEnum +
", name \"" + enumName +
"\"]]";
479 private static boolean equals(
final String s1,
final String s2) {
480 if (s1 ==
null || s2 ==
null) {
481 if (s1 ==
null && s2 ==
null) {
487 return s1.equals(s2);
503 if(
null != value && value.length() > 0 ) {
512 final String[] values = value.split(
"[\\s\\+\\-\\*\\/\\|\\&\\(\\)]|(\\<\\<)|(\\>\\>)|(\\~)");
514 for (
final String s : values) {
515 if( s.length() > 0 ) {
526 final boolean res = numberCount > 0;
533 boolean identifier =
false;
535 final char[] chars = value.toCharArray();
537 for (
int i = 0; i < chars.length; i++) {
538 final char c = chars[i];
540 if (Character.isJavaIdentifierStart(c)) {
544 if (!Character.isJavaIdentifierPart(c)) {
560 if(
null != iNumber ) {
581 String s0 = v.trim();
582 if( 0 == s0.length() ) {
585 if (s0.startsWith(
"+")) {
586 s0 = s0.substring(1, s0.length()).trim();
587 if( 0 == s0.length() ) {
592 if (s0.startsWith(
"-")) {
593 s0 = s0.substring(1, s0.length()).trim();
594 if( 0 == s0.length() ) {
603 boolean isUnsigned =
false;
604 boolean isLong =
false;
605 final int j = s0.length() - 2;
606 for(
int i = s0.length() - 1; i >= 0 && i >= j; i--) {
607 final char lastChar = s0.charAt(s0.length()-1);
608 if( lastChar ==
'u' || lastChar ==
'U' ) {
609 s0 = s0.substring(0, s0.length()-1);
611 }
else if( lastChar ==
'l' || lastChar ==
'L' ) {
612 s0 = s0.substring(0, s0.length()-1);
619 if( 0 == s0.length() ) {
623 if( isLong && isUnsigned ) {
624 res = decodeULong(s0, neg);
629 res = Long.decode(s0).longValue();
631 final boolean isLong2 = isLong ||
632 ( !isUnsigned && ( Integer.MIN_VALUE > res || res > Integer.MAX_VALUE ) ) ||
634 return new CNumber(isLong2, isUnsigned, res);
636 private static long decodeULong(
final String v,
final boolean neg)
throws NumberFormatException {
639 if (v.startsWith(
"0x") || v.startsWith(
"0X")) {
642 }
else if (v.startsWith(
"#")) {
645 }
else if (v.startsWith(
"0") && v.length() > 1) {
652 final String s0 = ( neg ?
"-" :
"" ) + v.substring(idx);
653 final BigInteger res =
new BigInteger(s0, radix);
655 throw new NumberFormatException(
"Value \""+v+
"\" is > UNSIGNED_LONG_MAX");
657 return res.longValue();
674 final String s0 = v.trim();
675 if( 0 == s0.length() ) {
678 boolean _isDouble =
false;
679 final char lastChar = s0.charAt(s0.length()-1);
680 if( lastChar ==
'd' || lastChar ==
'D' ) {
683 final double res = Double.valueOf(s0).doubleValue();
684 final double ares = Math.abs(res);
685 return new CNumber(_isDouble || Float.MIN_VALUE > ares || ares > Float.MAX_VALUE, res);
773 final String WhiteSpace =
"[\\x00-\\x20]*";
774 final String Digits =
"(\\p{Digit}+)";
775 final String HexDigits =
"(\\p{XDigit}+)";
776 final String IntTypeSuffix =
784 final String hexRegex =
788 "0[xX]" + HexDigits + IntTypeSuffix +
"?" +
793 final String intRegex =
797 Digits + IntTypeSuffix +
"?" +
804 final String Exp =
"[eE][+-]?"+Digits;
805 final String fpRegex =
825 "("+Digits+
"(\\.)?("+Digits+
"?)("+Exp+
")?)|"+
828 "(\\.("+Digits+
")("+Exp+
")?)|"+
835 "(0[xX]" + HexDigits +
"(\\.)?)|" +
838 "(0[xX]" + HexDigits +
"?(\\.)" + HexDigits +
")" +
842 "[pP][+-]?" + Digits +
852 final String fpOrIntRegex =
862 "(" + Digits + IntTypeSuffix +
")|" +
877 "(" + Digits +
"(\\.)?(" + Digits +
"?)(" + Exp +
")?)|" +
880 "(\\.(" + Digits +
")(" + Exp +
")?)|" +
887 "(0[xX]" + HexDigits +
"(\\.)?)|" +
890 "(0[xX]" + HexDigits +
"?(\\.)" + HexDigits +
")" +
894 "[pP][+-]?" + Digits +
904 final String fpOrIntRegex2 =
914 "(" + Digits + IntTypeSuffix +
")|" +
929 "(" + Digits +
"(\\.)?(" + Digits +
"?)(" + Exp +
")?)|" +
932 "(\\.(" + Digits +
")(" + Exp +
")?)|" +
939 "(0[xX]" + HexDigits +
"(\\.)?)|" +
942 "(0[xX]" + HexDigits +
"?(\\.)" + HexDigits +
")" +
946 "[pP][+-]?" + Digits +
954 patternCPPOperand = Pattern.compile(
"(?!"+fpOrIntRegex2+
")[\\+\\-\\*\\/\\|\\&\\(\\)]|(\\<\\<)|(\\>\\>)|(\\~)");
A Number, either integer, optionally [long, unsigned], or floating point, optionally [double].
final boolean isInteger
true if number is integer and value stored in i, otherwise false for floating point and value stored ...
final boolean isDouble
true if number is a double precision floating point, i.e.
final boolean isUnsigned
true if number is an unsigned isInteger.
final long i
The value if isInteger.
final double f
The value if !isInteger.
final boolean isLong
true if number is a long isInteger.
CNumber(final boolean isLong, final boolean isUnsigned, final long value)
ctor for integer number
CNumber(final boolean isDouble, final double value)
ctor for floating point number
final String toJavaString()
boolean equals(final Object arg)
A valid java expression, including its result type, usually generated from a native [C] expression,...
final String javaExpression
final String resultJavaTypeName
final Number resultJavaType
JavaExpr(final String javaExpression, final CNumber resultType)
static JavaExpr compute(final ConstantDefinition constDef, final Map< String, ConstantDefinition.JavaExpr > constMap)
Computes a valid java expression based on the given ConstantDefinition, which may either be a single ...
Represents a [native] constant expression, comprises the [native] expression, see getNativeExpr() and...
static boolean isDecimalNumber(final String s)
Matches pattern for floating point number, compatible and described in Double#valueOf(String).
static boolean isHexNumber(final String s)
Matches patternHexNumber.
String getNativeExpr()
Returns the original [native] expression.
ConstantDefinition(final String name, final String nativeExpr, final CNumber number, final String enumName, final ASTLocusTag astLocus)
Constructor for enumerates.
static boolean isNumber(final String s)
Matches isHexNumber(String) or isDecimalOrIntNumber(String).
static Pattern patternCPPOperand
One of: + - * / | & ( ) << >> ~ @endiliteral.
ASTLocusTag getASTLocusTag()
Returns this instance's ASTLocusTag, if available, otherwise returns null.
static boolean isDecimalOrIntNumber(final String s)
Complete pattern for floating point and integer number, covering patternDecimalNumber and patternInte...
static final Pattern patternDecimalNumber
Complete pattern for floating point number, compatible and described in Double#valueOf(String).
final boolean equalSemantics(final SemanticEqualityOp arg)
Semantic equality test for Types exclusive its given name.
static CNumber decodeIntegerNumber(final String v)
If the given string isIntegerNumber(String), return the decoded integer value, represented as a ANumb...
static boolean isIdentifier(final String value)
boolean hasNumber()
Returns true if this instance represents has a number, otherwise false.
static final Pattern patternDecimalOrIntNumber
Complete pattern for floating point and integer number, covering patternDecimalNumber and patternInte...
static CNumber decodeANumber(final String v)
Returns either decodeIntegerNumber(String), decodeDecimalNumber(String) or null.
static final Pattern patternIntegerNumber
Complete pattern for integer number, including an optional sign [+-] and optional suffixes [uUlL].
CNumber getNumber()
Returns the parsed CNumber of the native expression, or null if the latter does not comprise a single...
static Pattern patternHexNumber
Complete pattern for hexadecimal number, including an optional sign [+-] and optional suffixes [uUlL]...
static boolean isConstantExpression(final String value)
String getEnumName()
Returns null if this definition was not part of an enumeration, or if the enumeration is anonymous.
ConstantDefinition(final String name, final String nativeExpr, final CNumber number, final ASTLocusTag astLocus)
Constructor for plain const-values, non-enumerates.
final int hashCodeSemantics()
Semantic hashcode for Types exclusive its given name.
static boolean isIntegerNumber(final String s)
Matches isHexNumber(String) or patternIntegerNumber.
final JavaExpr computeJavaExpr(final Map< String, ConstantDefinition.JavaExpr > constMap)
Computes the java expression based on this instance, see JavaExpr#create(ConstantDefinition).
static CNumber decodeDecimalNumber(final String v)
If the given string isDecimalNumber(String), return the decoded floating-point value,...
final boolean equals(final Object arg)
Equality test by its given name.
final int hashCode()
Hash by its given name.
static final long UNSIGNED_INT_MAX_VALUE
static boolean isCPPOperand(final String s)
Matches pattern for valid CPP operands, see patternCPPOperand.
static final BigInteger UNSIGNED_LONG_MAX_VALUE
A generic exception for Jogamp errors used throughout the binding as a substitute for RuntimeExceptio...
Glue code generator for C functions and data structures.
Static Type config helper binding JavaConfiguration#relaxedEqualSemanticsTest() system wide.
String getName()
Return the current-name, which is the last renamed-name if issued, or the original-name.
Interface tag for ASTLocusTag provider.
Supports common interface for SemanticEqualityOp and AliasedSymbol.
Supports semantic equality and hash functions for types.