}
});
- // public static final Function VAL = registerStringFunc(new Func1NullIsNull("Val") {
- // @Override
- // protected Value eval1(EvalContext ctx, Value param1) {
- // String str = param1.getAsString(ctx).trim();
-
- // if(str.length() == 0) {
- // return ValueSupport.ZERO_VAL;
- // }
-
- // Matcher m = null;
-
- // if(str.charAt(0) == ValueSupport.NUMBER_BASE_PREFIX) {
- // // see if we can parse as a radix format
- // if((m = ValueSupport.HEX_PAT.matcher(str)).find()) {
- // BigInteger bi = ValueSupport.parseIntegerString(m.group(), 16);
- // // FIXME, what to do with large numbers? to double or decimal?
- // return ValueSupport.toValue(bi.intValue());
- // } else if((m = ValueSupport.OCTAL_PAT.matcher(str)).find()) {
- // BigInteger bi = ValueSupport.parseIntegerString(m.group(), 8);
- // // FIXME, what to do with large numbers? to double or decimal?
- // return ValueSupport.toValue(bi.intValue());
- // }
-
- // return ValueSupport.ZERO_VAL;
- // }
-
- // // parse ase normal "decimal" number.
- // // FIXME - leading '+'? exponent?
- // if((m = ValueSupport.NUMBER_PAT.matcher(str)).find()) {
-
- // }
-
- // // return ValueSupport.toValue(Integer.toHexString(lv).toUpperCase());
- // return null;
- // }
- // });
-
+ public static final Function VAL = registerStringFunc(new Func1NullIsNull("Val") {
+ @Override
+ protected Value eval1(EvalContext ctx, Value param1) {
+
+ // strip all whitespace from string
+ String str = ValueSupport.WHITESPACE_PAT.matcher(param1.getAsString(ctx))
+ .replaceAll("");
+
+ if(str.length() == 0) {
+ return ValueSupport.ZERO_D_VAL;
+ }
+
+ Matcher m = null;
+
+ if(str.charAt(0) == ValueSupport.NUMBER_BASE_PREFIX) {
+
+ // see if we can parse as a radix format
+ BigInteger bi = null;
+ if((m = ValueSupport.HEX_PAT.matcher(str)).find()) {
+ bi = ValueSupport.parseIntegerString(m.group(), 16);
+ } else if((m = ValueSupport.OCTAL_PAT.matcher(str)).find()) {
+ bi = ValueSupport.parseIntegerString(m.group(), 8);
+ }
+
+ if(bi != null) {
+ // this function works differently than normal string to number
+ // conversion. it seems to coerce these values to a short/long int
+ // depending on the size of the number (which creates
+ // positive/negative values dependent on the value length)
+ int iVal = ((bi.bitLength() <= 16) ? bi.shortValue() : bi.intValue());
+ return ValueSupport.toValue((double)iVal);
+ }
+
+ } else {
+
+ // parse as normal "decimal" number.
+ if((m = ValueSupport.NUMBER_PAT.matcher(str)).find()) {
+ BigDecimal bd = new BigDecimal(m.group());
+ return ValueSupport.toValue(bd.doubleValue());
+ }
+ }
+
+ return ValueSupport.ZERO_D_VAL;
+ }
+ });
+
private static boolean stringIsNumeric(EvalContext ctx, Value param) {
try {
param.getAsBigDecimal(ctx);
public static final Value ZERO_VAL = FALSE_VAL;
public static final Value NEG_ONE_VAL = TRUE_VAL;
public static final Value ONE_VAL = new LongValue(1);
+ public static final Value ZERO_D_VAL = new DoubleValue(0d);
static final char NUMBER_BASE_PREFIX = '&';
static final Pattern OCTAL_PAT =
static final Pattern HEX_PAT =
Pattern.compile("^" + NUMBER_BASE_PREFIX + "[hH]\\p{XDigit}+");
static final char CANON_DEC_SEP = '.';
- static final Pattern NUMBER_PAT = Pattern.compile("^[-+]?[0-9]*[.]?[0-9]*");
-
+ static final Pattern NUMBER_PAT =
+ Pattern.compile("^[+-]?(([0-9]+[.]?[0-9]*)|([.][0-9]+))([eE][+-]?[0-9]+)?");
+ static final Pattern WHITESPACE_PAT = Pattern.compile("[ \\t\\r\\n]+");
+
private ValueSupport() {}
public static Value toValue(boolean b) {
} catch(EvalException e) {
assertTrue(e.getMessage().contains("Invalid function call"));
}
+
+ assertEquals(1615198d, eval("=Val(' 1615 198th Street N.E.')"));
+ assertEquals(-1d, eval("=Val(' &HFFFFwhatever')"));
+ assertEquals(131071d, eval("=Val(' &H1FFFFwhatever')"));
+ assertEquals(-1d, eval("=Val(' &HFFFFFFFFwhatever')"));
+ assertEquals(291d, eval("=Val(' &H123whatever')"));
+ assertEquals(83d, eval("=Val(' &O123whatever')"));
+ assertEquals(1.23d, eval("=Val(' 1 2 3 e -2 whatever')"));
+ assertEquals(0d, eval("=Val(' whatever123 ')"));
+ assertEquals(0d, eval("=Val('')"));
}
public void testNumberFuncs() throws Exception