EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: [Merge] lp:~anj/epics-base/expand-calc-size into lp:epics-base
From: Andrew Johnson <[email protected]>
To: [email protected]
Date: Mon, 04 Oct 2010 19:01:20 -0000
Andrew Johnson has proposed merging lp:~anj/epics-base/expand-calc-size into lp:epics-base.

Requested reviews:
  EPICS Core Developers (epics-core)


Expand CALC expression fields to 80 characters.

This branch also includes a revision of the libCom/calc engine that introduces an integer literal op-code that reduces the maximum size of postfix buffer needed for a specific fixed-length infix buffer, and adjusts the estimator macro to match.  The new 80 byte infix buffers only need 280 bytes for the postfix buffer instead of 419 bytes.

Any objections to my merging this into 3.14.12?

-- 
https://code.launchpad.net/~anj/epics-base/expand-calc-size/+merge/37507
Your team EPICS Core Developers is requested to review the proposed merge of lp:~anj/epics-base/expand-calc-size into lp:epics-base.
=== modified file 'src/as/asLibRoutines.c'
--- src/as/asLibRoutines.c	2010-05-04 20:43:20 +0000
+++ src/as/asLibRoutines.c	2010-10-04 19:01:10 +0000
@@ -1323,17 +1323,10 @@
     unsigned long stores;
 
     if (!pasgrule) return 0;
-    insize = strlen(calc);
-    if (insize > MAX_INFIX_SIZE) {
-	pasgrule->calc = NULL;
-	pasgrule->rpcl = NULL;
-	status = S_asLib_badCalc;
-	errlogPrintf("CALC expression too long: '%s'\n", calc);
-	return status;
-    }
-    pasgrule->calc = asCalloc(1, insize+1);
+    insize = strlen(calc) + 1;
+    pasgrule->calc = asCalloc(1, insize);
     strcpy(pasgrule->calc, calc);
-    pasgrule->rpcl = asCalloc(1, MAX_POSTFIX_SIZE);
+    pasgrule->rpcl = asCalloc(1, INFIX_TO_POSTFIX_SIZE(insize));
     status = postfix(pasgrule->calc, pasgrule->rpcl, &err);
     if(status) {
 	free((void *)pasgrule->calc);

=== modified file 'src/libCom/calc/calcPerform.c'
--- src/libCom/calc/calcPerform.c	2009-08-25 18:19:49 +0000
+++ src/libCom/calc/calcPerform.c	2010-10-04 19:01:10 +0000
@@ -1,5 +1,5 @@
 /*************************************************************************\
-* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
+* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
 *     National Laboratory.
 * Copyright (c) 2002 The Regents of the University of California, as
 *     Operator of Los Alamos National Laboratory.
@@ -43,21 +43,26 @@
     double stack[CALCPERFORM_STACK+1];	/* zero'th entry not used */
     double *ptop;			/* stack pointer */
     double top; 			/* value from top of stack */
-    long itop;				/* integer from top of stack */
+    int itop;				/* integer from top of stack */
+    int op;
     int nargs;
 
     /* initialize */
     ptop = stack;
 
     /* RPN evaluation loop */
-    while (*pinst != END_EXPRESSION){
-	switch (*pinst){
-
-	case LITERAL:
-	    ++ptop;
-	    ++pinst;
-	    memcpy((void *)ptop, pinst, sizeof(double));
-	    pinst += sizeof(double) - 1;
+    while ((op = *pinst++) != END_EXPRESSION){
+	switch (op){
+
+	case LITERAL_DOUBLE:
+	    memcpy((void *)++ptop, pinst, sizeof(double));
+	    pinst += sizeof(double);
+	    break;
+
+	case LITERAL_INT:
+	    memcpy(&itop, pinst, sizeof(int));
+	    *++ptop = itop;
+	    pinst += sizeof(int);
 	    break;
 
 	case FETCH_VAL:
@@ -76,7 +81,7 @@
 	case FETCH_J:
 	case FETCH_K:
 	case FETCH_L:
-	    *++ptop = parg[*pinst - FETCH_A];
+	    *++ptop = parg[op - FETCH_A];
 	    break;
 
 	case STORE_A:
@@ -91,7 +96,7 @@
 	case STORE_J:
 	case STORE_K:
 	case STORE_L:
-	    parg[*pinst - STORE_A] = *ptop--;
+	    parg[op - STORE_A] = *ptop--;
 	    break;
 
 	case CONST_PI:
@@ -160,7 +165,7 @@
 	    break;
 
 	case MAX:
-	    nargs = *++pinst;
+	    nargs = *pinst++;
 	    while (--nargs) {
 		top = *ptop--;
 		if (*ptop < top || isnan(top))
@@ -169,7 +174,7 @@
 	    break;
 
 	case MIN:
-	    nargs = *++pinst;
+	    nargs = *pinst++;
 	    while (--nargs) {
 		top = *ptop--;
 		if (*ptop > top || isnan(top))
@@ -231,7 +236,7 @@
 	    break;
 
 	case FINITE:
-	    nargs = *++pinst;
+	    nargs = *pinst++;
 	    top = finite(*ptop);
 	    while (--nargs) {
 		--ptop;
@@ -245,7 +250,7 @@
 	    break;
 
 	case ISNAN:
-	    nargs = *++pinst;
+	    nargs = *pinst++;
 	    top = isnan(*ptop);
 	    while (--nargs) {
 		--ptop;
@@ -350,12 +355,9 @@
 	    break;
 
 	default:
-	    errlogPrintf("calcPerform: Bad Opcode %d at %p\n",*pinst, pinst);
+	    errlogPrintf("calcPerform: Bad Opcode %d at %p\n", op, pinst-1);
 	    return -1;
 	}
-
-	/* Advance to next opcode */
-	++pinst;
     }
 
     /* The stack should now have one item on it, the expression value */
@@ -372,12 +374,21 @@
     unsigned long inputs = 0;
     unsigned long stores = 0;
     char op;
-    while ((op = *pinst) != END_EXPRESSION) {
+    while ((op = *pinst++) != END_EXPRESSION) {
 	switch (op) {
 
-	case LITERAL:
+	case LITERAL_DOUBLE:
 	    pinst += sizeof(double);
 	    break;
+	case LITERAL_INT:
+	    pinst += sizeof(int);
+	    break;
+	case MIN:
+	case MAX:
+	case FINITE:
+	case ISNAN:
+	    pinst++;
+	    break;
 
 	case FETCH_A:
 	case FETCH_B:
@@ -413,7 +424,6 @@
 	default:
 	    break;
 	}
-	pinst++;
     }
     if (pinputs) *pinputs = inputs;
     if (pstores) *pstores = stores;
@@ -439,24 +449,37 @@
 }
 
 /* Search the instruction stream for a matching operator, skipping any
- * other conditional instructions found
+ * other conditional instructions found, and leave *ppinst pointing to
+ * the next instruction to be executed.
  */
 static int cond_search(const char **ppinst, int match)
 {
-    const char *pinst = *ppinst + 1;
+    const char *pinst = *ppinst;
     int count = 1;
     int op;
 
-    while ((op = *pinst) != END_EXPRESSION) {
+    while ((op = *pinst++) != END_EXPRESSION) {
 	if (op == match && --count == 0) {
 	    *ppinst = pinst;
 	    return 0;
-	} else if (op == COND_IF)
+	}
+	switch (op) {
+	case LITERAL_DOUBLE:
+	    pinst += sizeof(double);
+	    break;
+	case LITERAL_INT:
+	    pinst += sizeof(int);
+	    break;
+	case MIN:
+	case MAX:
+	case FINITE:
+	case ISNAN:
+	    pinst++;
+	    break;
+	case COND_IF:
 	    count++;
-	else if (op == LITERAL)
-	    pinst += sizeof(double);
-	pinst++;
+	    break;
+	}
     }
     return 1;
 }
-

=== modified file 'src/libCom/calc/postfix.c'
--- src/libCom/calc/postfix.c	2009-04-23 18:49:40 +0000
+++ src/libCom/calc/postfix.c	2010-10-04 19:01:10 +0000
@@ -1,5 +1,5 @@
 /*************************************************************************\
-* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
+* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
 *     National Laboratory.
 * Copyright (c) 2002 The Regents of the University of California, as
 *     Operator of Los Alamos National Laboratory.
@@ -10,7 +10,7 @@
  *
  * Subroutines used to convert an infix expression to a postfix expression
  *
- *      Author:          Bob Dalesio
+ *      Original Author: Bob Dalesio
  *      Date:            12-12-86
 */
 
@@ -69,17 +69,17 @@
 {"!",		7, 8,	0,	UNARY_OPERATOR, REL_NOT},
 {"(",		0, 8,	0,	UNARY_OPERATOR,	NOT_GENERATED},
 {"-",		7, 8,	0,	UNARY_OPERATOR,	UNARY_NEG},
-{".",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"0",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"1",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"2",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"3",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"4",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"5",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"6",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"7",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"8",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
-{"9",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
+{".",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"0",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"1",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"2",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"3",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"4",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"5",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"6",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"7",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"8",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
+{"9",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
 {"A",		0, 0,	1,	OPERAND,	FETCH_A},
 {"ABS",		7, 8,	0,	UNARY_OPERATOR,	ABS_VAL},
 {"ACOS",	7, 8,	0,	UNARY_OPERATOR,	ACOS},
@@ -101,7 +101,7 @@
 {"G",		0, 0,	1,	OPERAND,	FETCH_G},
 {"H",		0, 0,	1,	OPERAND,	FETCH_H},
 {"I",		0, 0,	1,	OPERAND,	FETCH_I},
-{"INF",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
+{"INF",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
 {"ISINF",	7, 8,	0,	UNARY_OPERATOR,	ISINF},
 {"ISNAN",	7, 8,	0,	VARARG_OPERATOR,ISNAN},
 {"J",		0, 0,	1,	OPERAND,	FETCH_J},
@@ -113,7 +113,7 @@
 {"MAX",		7, 8,	0,	VARARG_OPERATOR,MAX},
 {"MIN",		7, 8,	0,	VARARG_OPERATOR,MIN},
 {"NINT",	7, 8,	0,	UNARY_OPERATOR,	NINT},
-{"NAN",		0, 0,	1,	LITERAL_OPERAND,LITERAL},
+{"NAN",		0, 0,	1,	LITERAL_OPERAND,LITERAL_DOUBLE},
 {"NOT",		7, 8,	0,	UNARY_OPERATOR,	BIT_NOT},
 {"PI",		0, 0,	1,	OPERAND,	CONST_PI},
 {"R2D",		0, 0,	1,	OPERAND,	CONST_R2D},
@@ -214,7 +214,8 @@
     int cond_count = 0;
     char *pout = ppostfix;
     char *pnext;
-    double constant;
+    double lit_d;
+    int lit_i;
 
     if (psrc == NULL || *psrc == '\0' ||
 	pout == NULL || perror == NULL) {
@@ -237,18 +238,25 @@
 	    break;
 
 	case LITERAL_OPERAND:
-	    *pout++ = pel->code;
 	    runtime_depth += pel->runtime_effect;
 
 	    psrc -= strlen(pel->name);
-	    constant = epicsStrtod(psrc, &pnext);
+	    lit_d = epicsStrtod(psrc, &pnext);
 	    if (pnext == psrc) {
 		*perror = CALC_ERR_BAD_LITERAL;
 		goto bad;
 	    }
 	    psrc = pnext;
-	    memcpy(pout, (void *)&constant, sizeof(double));
-	    pout += sizeof(double);
+	    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);
+	    }
 
 	    operand_needed = FALSE;
 	    break;
@@ -500,7 +508,7 @@
     static const char *opcodes[] = {
 	"End Expression",
     /* Operands */
-	"LITERAL", "VAL",
+	"LITERAL_DOUBLE", "LITERAL_INT", "VAL",
 	"FETCH_A", "FETCH_B", "FETCH_C", "FETCH_D", "FETCH_E", "FETCH_F",
 	"FETCH_G", "FETCH_H", "FETCH_I", "FETCH_J", "FETCH_K", "FETCH_L",
     /* Assignment */
@@ -571,15 +579,21 @@
 	"NOT_GENERATED"
     };
     char op;
-    double lit;
+    double lit_d;
+    int lit_i;
     
     while ((op = *pinst) != END_EXPRESSION) {
 	switch (op) {
-	case LITERAL:
-	    memcpy((void *)&lit, ++pinst, sizeof(double));
-	    printf("\tLiteral: %g\n", lit);
+	case LITERAL_DOUBLE:
+	    memcpy((void *)&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);
+	    break;
 	case MIN:
 	case MAX:
 	case FINITE:

=== modified file 'src/libCom/calc/postfix.h'
--- src/libCom/calc/postfix.h	2006-10-03 20:22:23 +0000
+++ src/libCom/calc/postfix.h	2010-10-04 19:01:10 +0000
@@ -1,14 +1,13 @@
 /*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
 *     National Laboratory.
 * Copyright (c) 2002 The Regents of the University of California, as
 *     Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* EPICS BASE is distributed subject to a Software License Agreement found
 * in file LICENSE that is included with this distribution. 
 \*************************************************************************/
 /* postfix.h
- *      Author:          Bob Dalesio
+ *      Original Author: Bob Dalesio
  *      Date:            9-21-88
  */
 
@@ -20,14 +19,11 @@
 #define CALCPERFORM_NARGS 12
 #define CALCPERFORM_STACK 80
 
-#define INFIX_TO_POSTFIX_SIZE(n) (((n-2)>>2)*21 + ((n-2)&2)*5 + 10)
-/* The above is calculated from the following expression fragments:
- *  1?1:  4 chars expand to 21 chars
- *  1+    2 chars expand to 10 chars
- *  1     1 char expands to 9 chars
- * All other infix operators convert by a factor of 1:1 or less.
- * Allow 1 char each for the infix and postfix terminators,
- * and the infix must be a complete expression
+#define INFIX_TO_POSTFIX_SIZE(n) (n*21/6)
+/* The above expression is an estimate of the maximum postfix buffer
+ * size needed for a given infix expression buffer.  The actual size
+ * needed is never larger than this value, although it is actually a
+ * few bytes smaller for some sizes.
  */
 
 /* These are not hard limits, just default sizes for the database */

=== modified file 'src/libCom/calc/postfixPvt.h'
--- src/libCom/calc/postfixPvt.h	2007-05-03 20:03:38 +0000
+++ src/libCom/calc/postfixPvt.h	2010-10-04 19:01:10 +0000
@@ -1,23 +1,25 @@
 /*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
 *     National Laboratory.
 * Copyright (c) 2002 The Regents of the University of California, as
 *     Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* EPICS BASE is distributed subject to a Software License Agreement found
 * in file LICENSE that is included with this distribution. 
 \*************************************************************************/
 /* postfixPvt.h
- *      Author:          Bob Dalesio
+ *      Original Author: Bob Dalesio
  *      Date:            9-21-88
  */
 
 /* Notes:
  *  1. The FETCH_A through FETCH_L and STORE_A through STORE_L opcodes must
  *     be contiguous.
- *  2. The LITERAL opcode is followed by its double value.
- *  3. You can't quite use strlen() on an RPN buffer, since the literal
- *     double value can contain nil bytes.
+ *  2. The LITERAL opcodes are followed by a binary representation of their
+ *     values, but these are not aligned properly.
+ *  3. The var-arg functions MIN, MAX, FINITE and ISNAN are followed by
+ *     a byte giving the number of arguments to process.
+ *  4. You can't use strlen() on an RPN buffer since the literal values
+ *     can contain zero bytes.
  */
 
 #ifndef INCpostfixPvth
@@ -28,7 +30,7 @@
 typedef enum {
 	END_EXPRESSION = 0,
     /* Operands */
-	LITERAL, FETCH_VAL,
+	LITERAL_DOUBLE, LITERAL_INT, FETCH_VAL,
 	FETCH_A, FETCH_B, FETCH_C, FETCH_D, FETCH_E, FETCH_F,
 	FETCH_G, FETCH_H, FETCH_I, FETCH_J, FETCH_K, FETCH_L,
     /* Assignment */

=== modified file 'src/libCom/test/epicsCalcTest.cpp'
--- src/libCom/test/epicsCalcTest.cpp	2009-08-21 14:49:01 +0000
+++ src/libCom/test/epicsCalcTest.cpp	2010-10-04 19:01:10 +0000
@@ -1,5 +1,5 @@
 /*************************************************************************\
-* Copyright (c) 2008 UChicago Argonne LLC, as Operator of Argonne
+* Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
 *     National Laboratory.
 * EPICS BASE is distributed subject to a Software License Agreement found
 * in file LICENSE that is included with this distribution.
@@ -66,13 +66,31 @@
     return;
 }
 
+void testArgs(const char *expr, unsigned long einp, unsigned long eout) {
+    char rpn[MAX_POSTFIX_SIZE];
+    short err = 0;
+    unsigned long vinp, vout;
+
+    if (postfix(expr, rpn, &err)) {
+	testFail("postfix: %s in expression '%s'", calcErrorStr(err), expr);
+	return;
+    }
+    if (calcArgUsage(rpn, &vinp, &vout)) {
+	testFail("calcArgUsage returned error for '%s'", expr);
+	return;
+    }
+    if (!testOk(vinp == einp && vout == eout, "Args for '%s'", expr)) {
+	testDiag("Expected (%lx, %lx) got (%lx, %lx)", einp, eout, vinp, vout);
+    }
+}
+
 void testBadExpr(const char *expr, short expected_err) {
     /* Parse an invalid expression, test against expected error code */
     char rpn[MAX_POSTFIX_SIZE];
     short err = 0;
 
     postfix(expr, rpn, &err);
-    if (!testOk(err == expected_err, "%s (bad expression)", expr)) {
+    if (!testOk(err == expected_err, "Bad expression '%s'", expr)) {
 	testDiag("Expected '%s', actually got '%s'",
 	    calcErrorStr(expected_err), calcErrorStr(err));
 	calcExprDump(rpn);
@@ -83,8 +101,22 @@
 /* Test an expression that is also valid C code */
 #define testExpr(expr) testCalc(#expr, expr);
 
-
-/* Macros to make some expressions into valid C code */
+/* These are the argument bits for testArgs */
+#define A_A 0x001
+#define A_B 0x002
+#define A_C 0x004
+#define A_D 0x008
+#define A_E 0x010
+#define A_F 0x020
+#define A_G 0x040
+#define A_H 0x080
+#define A_I 0x100
+#define A_J 0x200
+#define A_K 0x400
+#define A_L 0x800
+
+
+/* Macros and functions to make some expressions into valid C code */
 
 #ifndef PI
 #define PI 3.14159265358979
@@ -198,7 +230,7 @@
     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(533);
+    testPlan(566);
     
     /* LITERAL_OPERAND elements */
     testExpr(0);
@@ -780,7 +812,39 @@
     testCalc("1+(1|2)**3", 1+pow((double) (1 | 2), 3.));// 8 6
     testExpr(1+(1?(1<2):(1>2))*2);
     
+    testArgs("a", A_A, 0);
+    testArgs("A", A_A, 0);
+    testArgs("B", A_B, 0);
+    testArgs("C", A_C, 0);
+    testArgs("D", A_D, 0);
+    testArgs("E", A_E, 0);
+    testArgs("F", A_F, 0);
+    testArgs("G", A_G, 0);
+    testArgs("H", A_H, 0);
+    testArgs("I", A_I, 0);
+    testArgs("J", A_J, 0);
+    testArgs("K", A_K, 0);
+    testArgs("L", A_L, 0);
+    testArgs("A+B+C+D+E+F+G+H+I+J+K+L",
+	A_A|A_B|A_C|A_D|A_E|A_F|A_G|A_H|A_I|A_J|A_K|A_L, 0);
+    testArgs("0.1;A:=0", 0, A_A);
+    testArgs("1.1;B:=0", 0, A_B);
+    testArgs("2.1;C:=0", 0, A_C);
+    testArgs("3.1;D:=0", 0, A_D);
+    testArgs("4.1;E:=0", 0, A_E);
+    testArgs("5.1;F:=0", 0, A_F);
+    testArgs("6.1;G:=0", 0, A_G);
+    testArgs("7.1;H:=0", 0, A_H);
+    testArgs("8.1;I:=0", 0, A_I);
+    testArgs("9.1;J:=0", 0, A_J);
+    testArgs("10.1;K:=0", 0, A_K);
+    testArgs("11.1;L:=0", 0, A_L);
+    testArgs("12.1;A:=0;B:=A;C:=B;D:=C", 0, A_A|A_B|A_C|A_D);
+    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("1*", CALC_ERR_INCOMPLETE);
+    testBadExpr("*1", CALC_ERR_SYNTAX);
     testBadExpr("MIN", CALC_ERR_INCOMPLETE);
     testBadExpr("MIN()", CALC_ERR_SYNTAX);
     testBadExpr("MIN(A,)", CALC_ERR_SYNTAX);
@@ -789,6 +853,9 @@
     testBadExpr("MAX()", CALC_ERR_SYNTAX);
     testBadExpr("MAX(A,)", CALC_ERR_SYNTAX);
     testBadExpr("MAX(A,B,)", CALC_ERR_SYNTAX);
+    testBadExpr("1?", CALC_ERR_CONDITIONAL);
+    testBadExpr("1?1", CALC_ERR_CONDITIONAL);
+    testBadExpr(":1", CALC_ERR_SYNTAX);
     
     return testDone();
 }

=== modified file 'src/rec/calcRecord.dbd'
--- src/rec/calcRecord.dbd	2007-03-13 16:39:53 +0000
+++ src/rec/calcRecord.dbd	2010-10-04 19:01:10 +0000
@@ -17,7 +17,7 @@
 		promptgroup(GUI_CALC)
 		special(SPC_CALC)
 		pp(TRUE)
-		size(40)
+		size(80)
 		initial("0")
 	}
 	field(INPA,DBF_INLINK) {
@@ -296,6 +296,6 @@
 		prompt("Reverse Polish Calc")
 		special(SPC_NOMOD)
 		interest(4)
-		extra("char	rpcl[INFIX_TO_POSTFIX_SIZE(40)]")
+		extra("char	rpcl[INFIX_TO_POSTFIX_SIZE(80)]")
 	}
 }

=== modified file 'src/rec/calcoutRecord.dbd'
--- src/rec/calcoutRecord.dbd	2009-04-04 23:01:23 +0000
+++ src/rec/calcoutRecord.dbd	2010-10-04 19:01:10 +0000
@@ -45,7 +45,7 @@
 		promptgroup(GUI_CALC)
 		special(SPC_CALC)
 		pp(TRUE)
-		size(40)
+		size(80)
 		initial("0")
 	}
 	field(CLCV,DBF_LONG) {
@@ -248,7 +248,7 @@
 		promptgroup(GUI_CALC)
 		special(SPC_CALC)
 		pp(TRUE)
-		size(40)
+		size(80)
 		initial("0")
 	}
 	field(OCLV,DBF_LONG) {
@@ -495,12 +495,12 @@
 		prompt("Reverse Polish Calc")
 		special(SPC_NOMOD)
 		interest(4)
-		extra("char	rpcl[INFIX_TO_POSTFIX_SIZE(40)]")
+		extra("char	rpcl[INFIX_TO_POSTFIX_SIZE(80)]")
 	}
 	field(ORPC,DBF_NOACCESS) {
 		prompt("Reverse Polish OCalc")
 		special(SPC_NOMOD)
 		interest(4)
-		extra("char	orpc[INFIX_TO_POSTFIX_SIZE(40)]")
+		extra("char	orpc[INFIX_TO_POSTFIX_SIZE(80)]")
 	}
 }


Replies:
Re: [Merge] lp:~anj/epics-base/expand-calc-size into lp:epics-base Ralph Lange

Navigate by Date:
Prev: vxWorks 6.7 tNet0 task crashed with fage fault: help needed from vxWorks guru Matthias Clausen
Next: Launchpad Bugs Re-enabling Auto Expiring Bugs deryck . hodge
Index: 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: vxWorks 6.7 tNet0 task crashed with fage fault: help needed from vxWorks guru Matthias Clausen
Next: Re: [Merge] lp:~anj/epics-base/expand-calc-size into lp:epics-base Ralph Lange
Index: 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·