libCom: Accept hex literals in CALC expressions

Code back-ported from the 3.15 branch.
This commit is contained in:
Andrew Johnson
2012-12-03 12:58:26 -06:00
parent d622bbad05
commit ef5688f8de
2 changed files with 43 additions and 22 deletions

View File

@@ -71,6 +71,7 @@ static const ELEMENT operands[] = {
{"-", 7, 8, 0, UNARY_OPERATOR, UNARY_NEG},
{".", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE},
{"0", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE},
{"0X", 0, 0, 1, LITERAL_OPERAND,LITERAL_INT},
{"1", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE},
{"2", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE},
{"3", 0, 0, 1, LITERAL_OPERAND,LITERAL_DOUBLE},
@@ -237,29 +238,42 @@ epicsShareFunc long
operand_needed = FALSE;
break;
case LITERAL_OPERAND:
runtime_depth += pel->runtime_effect;
case LITERAL_OPERAND:
runtime_depth += pel->runtime_effect;
psrc -= strlen(pel->name);
lit_d = epicsStrtod(psrc, &pnext);
if (pnext == psrc) {
*perror = CALC_ERR_BAD_LITERAL;
goto bad;
}
psrc = pnext;
lit_i = lit_d;
if (lit_d != (double) lit_i) {
*pout++ = pel->code;
memcpy(pout, (void *)&lit_d, sizeof(double));
pout += sizeof(double);
} else {
*pout++ = LITERAL_INT;
memcpy(pout, (void *)&lit_i, sizeof(int));
pout += sizeof(int);
}
psrc -= strlen(pel->name);
if (pel->code == LITERAL_DOUBLE) {
lit_d = epicsStrtod(psrc, &pnext);
if (pnext == psrc) {
*perror = CALC_ERR_BAD_LITERAL;
goto bad;
}
psrc = pnext;
lit_i = lit_d;
if (lit_d != (double) lit_i) {
*pout++ = pel->code;
memcpy(pout, (void *)&lit_d, sizeof(double));
pout += sizeof(double);
} else {
*pout++ = LITERAL_INT;
memcpy(pout, (void *)&lit_i, sizeof(int));
pout += sizeof(int);
}
}
else {
lit_i = strtoul(psrc, &pnext, 0);
if (pnext == psrc) {
*perror = CALC_ERR_BAD_LITERAL;
goto bad;
}
psrc = pnext;
*pout++ = LITERAL_INT;
memcpy(pout, (void *)&lit_i, sizeof(int));
pout += sizeof(int);
}
operand_needed = FALSE;
break;
operand_needed = FALSE;
break;
case STORE_OPERATOR:
if (pout == ppostfix || pstacktop > stack ||

View File

@@ -238,7 +238,7 @@ MAIN(epicsCalcTest)
const double a=1.0, b=2.0, c=3.0, d=4.0, e=5.0, f=6.0,
g=7.0, h=8.0, i=9.0, j=10.0, k=11.0, l=12.0;
testPlan(570);
testPlan(577);
/* LITERAL_OPERAND elements */
testExpr(0);
@@ -253,6 +253,11 @@ MAIN(epicsCalcTest)
testExpr(9);
testExpr(.1);
testExpr(0.1);
testExpr(0X0);
testExpr(0x10);
testExpr(0x7fffffff);
testCalc("0x80000000", -2147483648.0);
testCalc("0xffffffff", -1);
testExpr(Inf);
testCalc("Infinity", Inf);
testExpr(NaN);
@@ -287,6 +292,7 @@ MAIN(epicsCalcTest)
testExpr(-1);
testExpr(-Inf);
testExpr(- -1);
testCalc("-0x80000000", 2147483648.0);
/* UNARY_OPERATOR elements */
testExpr((1));
@@ -855,6 +861,7 @@ MAIN(epicsCalcTest)
testArgs("13.1;B:=A;A:=B;C:=D;D:=C", A_A|A_D, A_A|A_B|A_C|A_D);
// Malformed expressions
testBadExpr("0x0.1", CALC_ERR_SYNTAX);
testBadExpr("1*", CALC_ERR_INCOMPLETE);
testBadExpr("*1", CALC_ERR_SYNTAX);
testBadExpr("MIN", CALC_ERR_INCOMPLETE);