From a942295eadf713ac851e67316dbf14aa7f6587e7 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 6 Jul 2012 14:17:51 -0500 Subject: [PATCH] libCom/calc: Support 0x literals as epicsUInt32 Also use epicsInt32 for all integer calculations. --- src/libCom/calc/calcPerform.c | 43 +++++++++--------- src/libCom/calc/postfix.c | 73 +++++++++++++++++++------------ src/libCom/test/epicsCalcTest.cpp | 9 +++- 3 files changed, 75 insertions(+), 50 deletions(-) diff --git a/src/libCom/calc/calcPerform.c b/src/libCom/calc/calcPerform.c index 6de3f9dc6..0e8fcd5e9 100644 --- a/src/libCom/calc/calcPerform.c +++ b/src/libCom/calc/calcPerform.c @@ -21,6 +21,7 @@ #include "osiUnistd.h" #include "dbDefs.h" #include "epicsMath.h" +#include "epicsTypes.h" #include "errlog.h" #include "postfix.h" #include "postfixPvt.h" @@ -43,7 +44,7 @@ epicsShareFunc long double stack[CALCPERFORM_STACK+1]; /* zero'th entry not used */ double *ptop; /* stack pointer */ double top; /* value from top of stack */ - int itop; /* integer from top of stack */ + epicsInt32 itop; /* integer from top of stack */ int op; int nargs; @@ -55,14 +56,14 @@ epicsShareFunc long switch (op){ case LITERAL_DOUBLE: - memcpy((void *)++ptop, pinst, sizeof(double)); + memcpy(++ptop, pinst, sizeof(double)); pinst += sizeof(double); break; case LITERAL_INT: - memcpy(&itop, pinst, sizeof(int)); + memcpy(&itop, pinst, sizeof(epicsInt32)); *++ptop = itop; - pinst += sizeof(int); + pinst += sizeof(epicsInt32); break; case FETCH_VAL: @@ -136,11 +137,11 @@ epicsShareFunc long break; case MODULO: - itop = (long) *ptop--; + itop = (epicsInt32) *ptop--; if (itop) - *ptop = (long) *ptop % itop; + *ptop = (epicsInt32) *ptop % itop; else - *ptop = epicsNAN; /* NaN */ + *ptop = epicsNAN; break; case POWER: @@ -261,7 +262,7 @@ epicsShareFunc long case NINT: top = *ptop; - *ptop = (double)(long)(top >= 0 ? top + 0.5 : top - 0.5); + *ptop = (double)(epicsInt32)(top >= 0 ? top + 0.5 : top - 0.5); break; case RANDOM: @@ -283,33 +284,33 @@ epicsShareFunc long break; case BIT_OR: - itop = (long) *ptop--; - *ptop = (long) *ptop | itop; + itop = (epicsInt32) *ptop--; + *ptop = (epicsInt32) *ptop | itop; break; case BIT_AND: - itop = (long) *ptop--; - *ptop = (long) *ptop & itop; + itop = (epicsInt32) *ptop--; + *ptop = (epicsInt32) *ptop & itop; break; case BIT_EXCL_OR: - itop = (long) *ptop--; - *ptop = (long) *ptop ^ itop; + itop = (epicsInt32) *ptop--; + *ptop = (epicsInt32) *ptop ^ itop; break; case BIT_NOT: - itop = (long) *ptop; + itop = (epicsInt32) *ptop; *ptop = ~itop; break; case RIGHT_SHIFT: - itop = (long) *ptop--; - *ptop = (long) *ptop >> itop; + itop = (epicsInt32) *ptop--; + *ptop = (epicsInt32) *ptop >> itop; break; case LEFT_SHIFT: - itop = (long) *ptop--; - *ptop = (long) *ptop << itop; + itop = (epicsInt32) *ptop--; + *ptop = (epicsInt32) *ptop << itop; break; case NOT_EQ: @@ -381,7 +382,7 @@ calcArgUsage(const char *pinst, unsigned long *pinputs, unsigned long *pstores) pinst += sizeof(double); break; case LITERAL_INT: - pinst += sizeof(int); + pinst += sizeof(epicsInt32); break; case MIN: case MAX: @@ -468,7 +469,7 @@ static int cond_search(const char **ppinst, int match) pinst += sizeof(double); break; case LITERAL_INT: - pinst += sizeof(int); + pinst += sizeof(epicsInt32); break; case MIN: case MAX: diff --git a/src/libCom/calc/postfix.c b/src/libCom/calc/postfix.c index 20d040b05..e55e2b3fd 100644 --- a/src/libCom/calc/postfix.c +++ b/src/libCom/calc/postfix.c @@ -20,8 +20,10 @@ #define epicsExportSharedSymbols #include "dbDefs.h" +#include "epicsAssert.h" #include "epicsStdlib.h" #include "epicsString.h" +#include "epicsTypes.h" #include "postfix.h" #include "postfixPvt.h" #include "shareLib.h" @@ -71,6 +73,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}, @@ -214,8 +217,6 @@ epicsShareFunc long int cond_count = 0; char *pout = ppostfix; char *pnext; - double lit_d; - int lit_i; if (psrc == NULL || *psrc == '\0' || pout == NULL || perror == NULL) { @@ -237,29 +238,45 @@ 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); + if (pel->code == LITERAL_DOUBLE) { + double lit_d; + epicsInt32 lit_i; - 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); - } + if (epicsParseDouble(psrc, &lit_d, &pnext)) { + *perror = CALC_ERR_BAD_LITERAL; + goto bad; + } + psrc = pnext; + lit_i = lit_d; + if (lit_d != (double) lit_i) { + *pout++ = pel->code; + memcpy(pout, &lit_d, sizeof(double)); + pout += sizeof(double); + } else { + *pout++ = LITERAL_INT; + memcpy(pout, &lit_i, sizeof(epicsInt32)); + pout += sizeof(epicsInt32); + } + } + else { + epicsUInt32 lit_ui; - operand_needed = FALSE; - break; + assert(pel->code == LITERAL_INT); + if (epicsParseUInt32(psrc, &lit_ui, 0, &pnext)) { + *perror = CALC_ERR_BAD_LITERAL; + goto bad; + } + psrc = pnext; + *pout++ = LITERAL_INT; + memcpy(pout, &lit_ui, sizeof(epicsInt32)); + pout += sizeof(epicsInt32); + } + + operand_needed = FALSE; + break; case STORE_OPERATOR: if (pout == ppostfix || pstacktop > stack || @@ -580,19 +597,19 @@ epicsShareFunc void }; char op; double lit_d; - int lit_i; + epicsInt32 lit_i; while ((op = *pinst) != END_EXPRESSION) { switch (op) { case LITERAL_DOUBLE: - memcpy((void *)&lit_d, ++pinst, sizeof(double)); + memcpy(&lit_d, ++pinst, sizeof(double)); printf("\tDouble %g\n", lit_d); pinst += sizeof(double); break; case LITERAL_INT: - memcpy((void *)&lit_i, ++pinst, sizeof(int)); - printf("\tInteger %d\n", lit_i); - pinst += sizeof(int); + memcpy(&lit_i, ++pinst, sizeof(epicsInt32)); + printf("\tInteger %d (0x%x)\n", lit_i, lit_i); + pinst += sizeof(epicsInt32); break; case MIN: case MAX: diff --git a/src/libCom/test/epicsCalcTest.cpp b/src/libCom/test/epicsCalcTest.cpp index f5492e749..12bc585f0 100644 --- a/src/libCom/test/epicsCalcTest.cpp +++ b/src/libCom/test/epicsCalcTest.cpp @@ -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);