Removed string calculation engine, only needed by Tim Mooney's recordtypes.

This commit is contained in:
Andrew Johnson
2003-09-12 19:13:54 +00:00
parent a887ca44d1
commit 35bd1a76d1
6 changed files with 1 additions and 2270 deletions

View File

@@ -30,7 +30,6 @@
#include "gpHash.h"
#include "dbmf.h"
#include "postfix.h"
#include "sCalcPostfix.h"
#include "osiFileName.h"
#define epicsExportSharedSymbols
@@ -1995,14 +1994,9 @@ long epicsShareAPI dbPutString(DBENTRY *pdbentry,const char *pstring)
strncpy((char *)pfield, pstring,pflddes->size);
if((pflddes->special == SPC_CALC) && !stringHasMacro) {
char rpcl[RPCL_LEN];
char *psCalcrpcl = 0;
short error_number;
status = postfix(pstring,rpcl,&error_number);
if(status) {
status = sCalcPostfix(pstring,&psCalcrpcl,&error_number);
free((void *)psCalcrpcl);
}
if(status) status = S_dbLib_badField;
}
if((short)strlen(pstring) >= pflddes->size) status = S_dbLib_strLen;
@@ -2375,15 +2369,10 @@ char * epicsShareAPI dbVerify(DBENTRY *pdbentry,const char *pstring)
}
if((pflddes->special == SPC_CALC) && !stringHasMacro) {
char rpcl[RPCL_LEN];
char *psCalcrpcl = 0;
short error_number;
long status;
status = postfix(pstring,rpcl,&error_number);
if(status) {
status = sCalcPostfix(pstring,&psCalcrpcl,&error_number);
free((void *)psCalcrpcl);
}
if(status) {
sprintf(message,"Illegal Calculation String");
return(message);

View File

@@ -31,13 +31,10 @@ SRCS += epicsRingPointer.cpp
SRCS += epicsRingBytes.c
SRC_DIRS += $(LIBCOM)/calc
#following needed for locating postfixPvt.h and sCalcPostfixPvt.h
#following needed for locating postfixPvt.h
INC += postfix.h
INC += sCalcPostfix.h
SRCS += postfix.c
SRCS += calcPerform.c
SRCS += sCalcPostfix.c
SRCS += sCalcPerform.c
SRC_DIRS += $(LIBCOM)/cvtFast
INC += cvtFast.h

File diff suppressed because it is too large Load Diff

View File

@@ -1,682 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, 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
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* $Id$
* Subroutines used to convert an infix expression to a postfix expression
*
* Author: Bob Dalesio
* Date: 12-12-86
*/
/*
* Subroutines
*
* Public
*
* sCalcPostfix convert an algebraic expression to symbolic postfix
* args
* pinfix the algebraic expression
* pp_postfix address of the symbolic postfix expression
* perror error information
* returns
* 0 successful
* -1 not successful
* Private routines for calcPostfix
*
* find_element finds a symbolic element in the expression element tbl
* args
* pbuffer pointer to the infix expression element
* pelement pointer to the expression element table entry
* pno_bytes pointer to the size of this element
* parg pointer to arg (used for fetch)
* returns
* TRUE element found
* FALSE element not found
*
* get_element finds the next expression element in the infix expr
* args
* pinfix pointer into the infix expression
* pelement pointer to the expression element table
* pno_bytes size of the element in the infix expression
* parg pointer to argument (used for fetch)
* returns
* FINE found an expression element
* VARIABLE found a database reference
* UNKNOWN_ELEMENT unknown element found in the infix expression
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "dbDefs.h"
#define epicsExportSharedSymbols
#include "sCalcPostfix.h"
#include "sCalcPostfixPvt.h"
#define OVERRIDESTDCALC 0
#define DEBUG 0
volatile int sCalcPostfixDebug=0;
/* declarations for postfix */
/* element types */
#define OPERAND 0
#define UNARY_OPERATOR 1
#define BINARY_OPERATOR 2
#define EXPR_TERM 3
#define COND 4
#define CLOSE_PAREN 5
#define CONDITIONAL 6
#define ELSE 7
#define SEPARATOR 8
#define TRASH 9
#define FLOAT_PT_CONST 10
#define MINUS_OPERATOR 11
#define STRING_CONST 12
#define CLOSE_BRACKET 13
#define CLOSE_CURLY 14
#define UNARY_MINUS_I_S_P 7
#define UNARY_MINUS_I_C_P 8
#define UNARY_MINUS_CODE UNARY_NEG
#define BINARY_MINUS_I_S_P 4
#define BINARY_MINUS_I_C_P 4
#define BINARY_MINUS_CODE SUB
/* parsing return values */
#define FINE 0
#define UNKNOWN_ELEMENT -1
#define END -2
/*
* element table
*
* structure of an element
*/
struct expression_element{
char element[10]; /* character representation of an element */
char in_stack_pri; /* priority in translation stack */
char in_coming_pri; /* priority when first checking */
char type; /* element type */
char code; /* postfix representation */
};
/*
* NOTE: DO NOT CHANGE WITHOUT READING THIS NOTICE !!!!!!!!!!!!!!!!!!!!
* Because the routine that looks for a match in this table takes the first
* match it finds, elements whose designations are contained in other elements
* MUST come first in this list. (e.g. ABS will match A if A preceeds ABS and
* then try to find BS therefore ABS must be first in this list
*/
static struct expression_element elements[] = {
/*
element i_s_p i_c_p type_element internal_rep */
{"ABS", 7, 8, UNARY_OPERATOR, ABS_VAL}, /* absolute value */
{"NOT", 7, 8, UNARY_OPERATOR, UNARY_NEG}, /* unary negate */
{"-", 7, 8, MINUS_OPERATOR, UNARY_NEG}, /* unary negate (or binary op) */
{"SQRT", 7, 8, UNARY_OPERATOR, SQU_RT}, /* square root */
{"SQR", 7, 8, UNARY_OPERATOR, SQU_RT}, /* square root */
{"EXP", 7, 8, UNARY_OPERATOR, EXP}, /* exponential function */
{"LOGE", 7, 8, UNARY_OPERATOR, LOG_E}, /* log E */
{"LN", 7, 8, UNARY_OPERATOR, LOG_E}, /* log E */
{"LOG", 7, 8, UNARY_OPERATOR, LOG_10}, /* log 10 */
{"ACOS", 7, 8, UNARY_OPERATOR, ACOS}, /* arc cosine */
{"ASIN", 7, 8, UNARY_OPERATOR, ASIN}, /* arc sine */
{"ATAN2", 7, 8, UNARY_OPERATOR, ATAN2}, /* arc tangent */
{"ATAN", 7, 8, UNARY_OPERATOR, ATAN}, /* arc tangent */
{"MAX", 7, 8, UNARY_OPERATOR, MAX_VAL}, /* maximum of 2 args */
{"MIN", 7, 8, UNARY_OPERATOR, MIN_VAL}, /* minimum of 2 args */
{"CEIL", 7, 8, UNARY_OPERATOR, CEIL}, /* smallest integer >= */
{"FLOOR", 7, 8, UNARY_OPERATOR, FLOOR}, /* largest integer <= */
{"NINT", 7, 8, UNARY_OPERATOR, NINT}, /* nearest integer */
{"INT", 7, 8, UNARY_OPERATOR, NINT}, /* nearest integer */
{"COSH", 7, 8, UNARY_OPERATOR, COSH}, /* hyperbolic cosine */
{"COS", 7, 8, UNARY_OPERATOR, COS}, /* cosine */
{"SINH", 7, 8, UNARY_OPERATOR, SINH}, /* hyperbolic sine */
{"SIN", 7, 8, UNARY_OPERATOR, SIN}, /* sine */
{"TANH", 7, 8, UNARY_OPERATOR, TANH}, /* hyperbolic tangent*/
{"TAN", 7, 8, UNARY_OPERATOR, TAN}, /* tangent */
{"!=", 3, 3, BINARY_OPERATOR,NOT_EQ}, /* not equal */
{"!", 7, 8, UNARY_OPERATOR, REL_NOT}, /* not */
{"~", 7, 8, UNARY_OPERATOR, BIT_NOT}, /* bitwise not */
{"DBL", 7, 8, UNARY_OPERATOR, TO_DOUBLE}, /* convert to double */
{"STR", 7, 8, UNARY_OPERATOR, TO_STRING}, /* convert to string */
{"$P", 7, 8, UNARY_OPERATOR, PRINTF}, /* formatted print to string */
{"PRINTF", 7, 8, UNARY_OPERATOR, PRINTF}, /* formatted print to string */
{"$S", 7, 8, UNARY_OPERATOR, SSCANF}, /* scan string argument */
{"SSCANF", 7, 8, UNARY_OPERATOR, SSCANF}, /* scan string argument */
{"RNDM", 0, 0, OPERAND, RANDOM}, /* Random Number */
{"OR", 1, 1, BINARY_OPERATOR,BIT_OR}, /* or */
{"AND", 2, 2, BINARY_OPERATOR,BIT_AND}, /* and */
{"XOR", 1, 1, BINARY_OPERATOR,BIT_EXCL_OR}, /* exclusive or */
{"PI", 0, 0, OPERAND, CONST_PI}, /* pi */
{"D2R", 0, 0, OPERAND, CONST_D2R}, /* pi/180 */
{"R2D", 0, 0, OPERAND, CONST_R2D}, /* 180/pi */
{"S2R", 0, 0, OPERAND, CONST_S2R}, /* arc-sec to radians: pi/(180*3600) */
{"R2S", 0, 0, OPERAND, CONST_R2S}, /* radians to arc-sec: (180*3600)/pi */
{"0", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"1", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"2", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"3", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"4", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"5", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"6", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"7", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"8", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"9", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{".", 0, 0, FLOAT_PT_CONST, LITERAL}, /* flt pt constant */
{"\"", 0, 0, STRING_CONST, SLITERAL}, /* string constant */
{"'", 0, 0, STRING_CONST, SLITERAL}, /* string constant */
{"?", 0, 0, CONDITIONAL, COND_IF}, /* conditional */
{":", 0, 0, CONDITIONAL, COND_ELSE}, /* else */
{"(", 0, 8, UNARY_OPERATOR, PAREN}, /* open paren */
{"[", 0, 8, BINARY_OPERATOR,SUBRANGE}, /* string subrange */
{"{", 0, 8, BINARY_OPERATOR,REPLACE}, /* string replace */
{"^", 6, 6, BINARY_OPERATOR,EXPON}, /* exponentiation */
{"**", 6, 6, BINARY_OPERATOR,EXPON}, /* exponentiation */
{"+", 4, 4, BINARY_OPERATOR,ADD}, /* addition */
#if 0 /* "-" operator is overloaded; may be unary or binary */
{"-", 4, 4, BINARY_OPERATOR,SUB}, /* subtraction */
#endif
{"*", 5, 5, BINARY_OPERATOR,MULT}, /* multiplication */
{"/", 5, 5, BINARY_OPERATOR,DIV}, /* division */
{"%", 5, 5, BINARY_OPERATOR,MODULO}, /* modulo */
{",", 0, 0, SEPARATOR, COMMA}, /* comma */
{")", 0, 0, CLOSE_PAREN, PAREN}, /* close paren */
{"]", 0, 0, CLOSE_BRACKET, SUBRANGE}, /* close bracket */
{"}", 0, 0, CLOSE_CURLY, REPLACE}, /* close curly bracket */
{"||", 1, 1, BINARY_OPERATOR,REL_OR}, /* logical or */
{"|", 1, 1, BINARY_OPERATOR,BIT_OR}, /* bitwise or */
{"&&", 2, 2, BINARY_OPERATOR,REL_AND}, /* logical and */
{"&", 2, 2, BINARY_OPERATOR,BIT_AND}, /* bitwise and */
{">>", 2, 2, BINARY_OPERATOR,RIGHT_SHIFT}, /* right shift */
{">=", 3, 3, BINARY_OPERATOR,GR_OR_EQ}, /* greater or equal*/
{">", 3, 3, BINARY_OPERATOR,GR_THAN}, /* greater than */
{"<<", 2, 2, BINARY_OPERATOR,LEFT_SHIFT}, /* left shift */
{"<=", 3, 3, BINARY_OPERATOR,LESS_OR_EQ}, /* less or equal to*/
{"<", 3, 3, BINARY_OPERATOR,LESS_THAN}, /* less than */
{"#", 3, 3, BINARY_OPERATOR,NOT_EQ}, /* not equal */
{"==", 3, 3, BINARY_OPERATOR,EQUAL}, /* equal */
{"=", 3, 3, BINARY_OPERATOR,EQUAL}, /* equal */
{""}
};
/*
* Element-table entry for "fetch" operation. This element is used for all
* named variables. Currently, letters A-Z (double) and AA-ZZ (string) are
* allowed. Lower and upper case letters mean the same thing.
*/
static struct expression_element fetch_element = {
"A", 0, 0, OPERAND, FETCH, /* fetch var */
};
static struct expression_element fetch_string_element = {
"AA", 0, 0, OPERAND, SFETCH, /* fetch var */
};
static int strncasecmpPrivate(char *s1, char *s2, size_t n)
{
short i;
for (i=0; i<(short)n && (*s1 || *s2); i++, s1++, s2++) {
if (toupper((int)*s1) > toupper((int)*s2)) return(1);
if (toupper((int)*s1) < toupper((int)*s2)) return(-1);
}
return(0);
}
/*
* FIND_ELEMENT
*
* find the pointer to an entry in the element table
*/
static int find_element(pbuffer, pelement, pno_bytes, parg)
char *pbuffer;
struct expression_element **pelement;
short *pno_bytes, *parg;
{
*parg = 0;
/* compare the string to each element in the element table */
*pelement = &elements[0];
while ((*pelement)->element[0] != NULL){
if (strncasecmpPrivate(pbuffer,(*pelement)->element, strlen((*pelement)->element)) == 0){
*pno_bytes += strlen((*pelement)->element);
return(TRUE);
}
*pelement += 1;
}
/* look for a variable reference */
/* double variables: ["a" - "z"], numbered 1-26 */
if (isalpha((int)*pbuffer)) {
*pelement = &fetch_element; /* fetch means "variable reference" (fetch or store) */
*parg = *pbuffer - (isupper((int)*pbuffer) ? 'A' : 'a');
*pno_bytes += 1;
/* string variables: ["aa" - "zz"], numbered 1-26 */
if (pbuffer[1] == pbuffer[0]) {
*pelement = &fetch_string_element;
*pno_bytes += 1;
}
return(TRUE);
}
if (sCalcPostfixDebug) printf("find_element: can't find '%s'\n", pbuffer);
return(FALSE);
}
/*
* GET_ELEMENT
*
* get an expression element
*/
static int get_element(pinfix, pelement, pno_bytes, parg)
char *pinfix;
struct expression_element **pelement;
short *pno_bytes, *parg;
{
/* get the next expression element from the infix expression */
if (*pinfix == NULL) return(END);
*pno_bytes = 0;
while (*pinfix == 0x20){
*pno_bytes += 1;
pinfix++;
}
if (*pinfix == NULL) return(END);
if (!find_element(pinfix, pelement, pno_bytes, parg))
return(UNKNOWN_ELEMENT);
if (sCalcPostfixDebug > 5) printf("get_element: found element '%s', arg=%d\n", (*pelement)->element, *parg);
return(FINE);
}
#if OVERRIDESTDCALC
/* Override standard EPICS expression evaluator (if we're loaded after it). */
long epicsShareAPI postfix(const char *pinfix,char *ppostfix,short *perror)
{
char *my_ppostfix = NULL, *s, *d;
long retval;
retval = sCalcPostfix(pinfix, &my_ppostfix, perror);
if (*my_ppostfix == BAD_EXPRESSION) {
*ppostfix = BAD_EXPRESSION;
} else {
for (s = my_ppostfix, d = ppostfix; *s != END_STACK; ) {
*d++=*s++;
}
*d = *s;
}
free(my_ppostfix);
return(retval);
}
#endif
/*
* sCalcPostFix
*
* convert an infix expression to a postfix expression
*/
#define MAX_POSTFIX_SIZE 100
long epicsShareAPI sCalcPostfix(const char *pin, char **pp_postfix, short *perror)
{
short no_bytes;
short operand_needed;
short new_expression;
struct expression_element stack[80];
struct expression_element *pelement;
struct expression_element *pstacktop;
double constant;
char c, *pposthold;
char in_stack_pri, in_coming_pri, code;
char *ppostfix, *ppostfixStart;
short arg;
char infix[MAX_POSTFIX_SIZE];
char *pinfix = &infix[0];
int len;
if (sCalcPostfixDebug) printf("sCalcPostfix: entry\n");
len = strlen(pin);
if(len>=MAX_POSTFIX_SIZE) return(-1);
strcpy(infix,pin);
/* Allocate a buffer for the postfix expression. */
if (*pp_postfix) free(*pp_postfix); /* Free old buffer. */
ppostfix = calloc(5*strlen(pinfix)+7, 1);
*pp_postfix = ppostfix;
ppostfixStart = ppostfix++;
*ppostfixStart = BAD_EXPRESSION;
*ppostfix = END_STACK;
/* place the expression elements into postfix */
operand_needed = TRUE;
new_expression = TRUE;
*perror = 0;
if (*pinfix == 0) {
return(0);
}
pstacktop = &stack[0];
while (get_element(pinfix, &pelement, &no_bytes, &arg) != END){
pinfix += no_bytes;
code = pelement->code;
if ((*ppostfixStart != USES_STRING) && ((code == TO_STRING) ||
(code == PRINTF) || (code == SSCANF) || (code == SLITERAL) ||
(code == SUBRANGE) || (code == SFETCH))) {
*ppostfixStart = USES_STRING;
}
switch (pelement->type){
case OPERAND:
if (!operand_needed){
*perror = 5;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add operand to the expression */
*ppostfix++ = pelement->code;
/* if this is a variable reference, append variable number */
if ((pelement->code == (char)FETCH) || (pelement->code == (char)SFETCH)) {
*ppostfix++ = arg;
}
operand_needed = FALSE;
new_expression = FALSE;
break;
case FLOAT_PT_CONST:
if (!operand_needed){
*perror = 5;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add constant to postfix expression */
*ppostfix++ = pelement->code;
pposthold = ppostfix;
pinfix-=no_bytes;
while (*pinfix == ' ') *ppostfix++ = *pinfix++;
while (TRUE) {
if ( ( *pinfix >= '0' && *pinfix <= '9' ) || *pinfix == '.' ) {
*ppostfix++ = *pinfix;
pinfix++;
} else if ( *pinfix == 'E' || *pinfix == 'e' ) {
*ppostfix++ = *pinfix;
pinfix++;
if (*pinfix == '+' || *pinfix == '-' ) {
*ppostfix++ = *pinfix;
pinfix++;
}
} else break;
}
*ppostfix++ = '\0';
ppostfix = pposthold;
if ( sscanf(ppostfix,"%lg",&constant) != 1) {
*ppostfix = '\0';
} else {
memcpy(ppostfix,(void *)&constant,8);
}
ppostfix+=8;
operand_needed = FALSE;
new_expression = FALSE;
break;
case STRING_CONST:
if (!operand_needed){
*perror = 5;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add string literal to the postfix expression */
*ppostfix++ = pelement->code;
c = pinfix[-1];
while (*pinfix != c && *pinfix) *ppostfix++ = *pinfix++;
*ppostfix++ = '\0';
if (*pinfix) pinfix++;
operand_needed = FALSE;
new_expression = FALSE;
break;
case BINARY_OPERATOR:
if (operand_needed){
*perror = 4;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add operators of higher or equal priority to postfix expression */
while ( (pstacktop >= &stack[1]) &&
(pstacktop->in_stack_pri >= pelement->in_coming_pri)) {
*ppostfix++ = pstacktop->code;
pstacktop--;
}
/* add new operator to stack */
pstacktop++;
*pstacktop = *pelement;
operand_needed = TRUE;
break;
case UNARY_OPERATOR:
if (!operand_needed){
*perror = 5;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add operators of higher or equal priority to postfix expression */
while ( (pstacktop >= &stack[1]) &&
(pstacktop->in_stack_pri >= pelement->in_coming_pri)) {
*ppostfix++ = pstacktop->code;
pstacktop--;
}
/* add new operator to stack */
pstacktop++;
*pstacktop = *pelement;
new_expression = FALSE;
break;
case MINUS_OPERATOR:
if (operand_needed) {
/* then assume minus was intended as a unary operator */
in_coming_pri = UNARY_MINUS_I_C_P;
in_stack_pri = UNARY_MINUS_I_S_P;
code = UNARY_MINUS_CODE;
new_expression = FALSE;
} else {
/* then assume minus was intended as a binary operator */
in_coming_pri = BINARY_MINUS_I_C_P;
in_stack_pri = BINARY_MINUS_I_S_P;
code = BINARY_MINUS_CODE;
operand_needed = TRUE;
}
/* add operators of higher or equal priority to postfix expression */
while ( (pstacktop >= &stack[1]) &&
(pstacktop->in_stack_pri >= in_coming_pri)) {
*ppostfix++ = pstacktop->code;
pstacktop--;
}
/* add new operator to stack */
pstacktop++;
*pstacktop = *pelement;
pstacktop->in_stack_pri = in_stack_pri;
pstacktop->code = code;
break;
case SEPARATOR:
if (operand_needed){
*perror = 4;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add operators to postfix until open paren */
while ((pstacktop->element[0] != '(') && (pstacktop->element[0] != '[')
&& (pstacktop->element[0] != '{')) {
if (pstacktop == &stack[1] || pstacktop == &stack[0]){
*perror = 6;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
*ppostfix++ = pstacktop->code;
pstacktop--;
}
operand_needed = TRUE;
break;
case CLOSE_PAREN:
if (operand_needed){
*perror = 4;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add operators to postfix until matching paren */
while (pstacktop->element[0] != '(') {
if (pstacktop == &stack[1] || pstacktop == &stack[0]) {
*perror = 6;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
*ppostfix++ = pstacktop->code;
pstacktop--;
}
pstacktop--; /* remove ( from stack */
break;
case CLOSE_BRACKET:
if (operand_needed){
*perror = 4;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add operators to postfix until matching bracket */
while (pstacktop->element[0] != '[') {
if (pstacktop == &stack[1] || pstacktop == &stack[0]) {
*perror = 6;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
*ppostfix++ = pstacktop->code;
pstacktop--;
}
/* add SUBRANGE operator to postfix */
if (pstacktop == &stack[0]) {
*perror = 6;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
*ppostfix++ = pstacktop->code;
pstacktop--;
break;
case CLOSE_CURLY:
if (operand_needed){
*perror = 4;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add operators to postfix until matching bracket */
while (pstacktop->element[0] != '{') {
if (pstacktop == &stack[1] || pstacktop == &stack[0]) {
*perror = 6;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
*ppostfix++ = pstacktop->code;
pstacktop--;
}
/* add REPLACE operator to postfix */
if (pstacktop == &stack[0]) {
*perror = 6;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
*ppostfix++ = pstacktop->code;
pstacktop--;
break;
case CONDITIONAL:
if (operand_needed){
*perror = 4;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add operators of higher priority to postfix expression */
while ( (pstacktop >= &stack[1]) &&
(pstacktop->in_stack_pri > pelement->in_coming_pri)) {
*ppostfix++ = pstacktop->code;
pstacktop--;
}
/* add new element to the postfix expression */
*ppostfix++ = pelement->code;
/* add : operator with COND_END code to stack */
if (pelement->element[0] == ':'){
pstacktop++;
*pstacktop = *pelement;
pstacktop->code = COND_END;
}
operand_needed = TRUE;
break;
case EXPR_TERM:
if (operand_needed && !new_expression){
*perror = 4;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add all operators on stack to postfix */
while (pstacktop >= &stack[1]){
if (pstacktop->element[0] == '('){
*perror = 6;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
*ppostfix++ = pstacktop->code;
pstacktop--;
}
/* add new element to the postfix expression */
*ppostfix++ = pelement->code;
operand_needed = TRUE;
new_expression = TRUE;
break;
default:
*perror = 8;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
}
if (operand_needed){
*perror = 4;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
/* add all operators on stack to postfix */
while (pstacktop >= &stack[1]){
if (pstacktop->element[0] == '('){
*perror = 6;
*ppostfixStart = BAD_EXPRESSION; return(-1);
}
*ppostfix++ = pstacktop->code;
pstacktop--;
}
*ppostfix++ = END_STACK;
*ppostfix = '\0';
if (ppostfixStart[1] == END_STACK)
*ppostfixStart = BAD_EXPRESSION;
else if (*ppostfixStart != USES_STRING)
*ppostfixStart = NO_STRING;
return(0);
}

View File

@@ -1,40 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, 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
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* sCalcPostfix.h
* Author: Bob Dalesio
* Date: 9-21-88
*/
#ifndef INCsCalcPostfixH
#define INCsCalcPostfixH
#include "shareLib.h"
#define BAD_EXPRESSION 0
#define END_STACK 127
#ifdef __cplusplus
extern "C" {
#endif
epicsShareFunc long epicsShareAPI sCalcPostfix (const char *pinfix,
char **pp_postfix, short *perror);
epicsShareFunc long epicsShareAPI
sCalcPerform (double *parg, int numArgs,
char **psarg, int numSArgs, double *presult,
char *psresult, int lenSresult, char *post);
#ifdef __cplusplus
}
#endif
#endif /* INCsCalcPostfixH */

View File

@@ -1,98 +0,0 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, 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
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* sCalcPostfixPvt.h
* Author: Bob Dalesio
* Date: 9-21-88
*/
#ifndef INCpostfixh
#include <sCalcPostfix.h>
#endif
#ifndef INCpostfixPvth
#define INCpostfixPvth
/* #define BAD_EXPRESSION 0 */
/* defines for element table */
/* elements that define a value */
#define FETCH 1
#define SFETCH 2
#define CONST_PI 3
#define CONST_D2R 4
#define CONST_R2D 5
#define CONST_S2R 6
#define CONST_R2S 7
#define RANDOM 8
#define LITERAL 9
#define SLITERAL 10
#define SSCANF 11
#define VALUE_ELEMENT 11
/* elements that operate on a value */
#define ACOS 12
#define ASIN 13
#define ATAN 14
#define COS 15
#define COSH 16
#define SIN 17
#define RIGHT_SHIFT 18
#define LEFT_SHIFT 19
#define SINH 20
#define TAN 21
#define TANH 22
#define LOG_2 23
#define COND_ELSE 24
#define ABS_VAL 25
#define UNARY_NEG 26
#define SQU_RT 27
#define EXP 28
#define CEIL 29
#define FLOOR 30
#define LOG_10 31
#define LOG_E 32
#define ADD 33
#define SUB 34
#define MULT 35
#define DIV 36
#define EXPON 37
#define MODULO 38
#define BIT_OR 39
#define BIT_AND 40
#define BIT_EXCL_OR 41
#define GR_OR_EQ 42
#define GR_THAN 43
#define LESS_OR_EQ 44
#define LESS_THAN 45
#define NOT_EQ 46
#define EQUAL 47
#define REL_OR 48
#define REL_AND 49
#define REL_NOT 50
#define BIT_NOT 51
#define PAREN 52
#define MAX_VAL 53
#define MIN_VAL 54
#define COMMA 55
#define COND_IF 56
#define COND_END 57
#define NINT 58
#define ATAN2 59
#define STORE 60
#define TO_DOUBLE 61
#define PRINTF 62
#define SUBRANGE 63
#define TO_STRING 64
#define REPLACE 65
/* #define END_STACK 127 */
#define USES_STRING 126
#define NO_STRING 125
#endif /* INCpostfixPvth */