jba 3/21/91

This commit is contained in:
Janet B. Anderson
1991-03-22 15:12:04 +00:00
parent b2bb80a895
commit a6339fb924
7 changed files with 1295 additions and 134 deletions

View File

@@ -376,7 +376,8 @@ long dbGetLink(pdblink,pdest,dbrType,pbuffer,options,nRequest)
}
}
return(dbGetField(paddr,dbrType,pbuffer,options,nRequest));
status= dbGetField(paddr,dbrType,pbuffer,options,nRequest);
if(status) recGblRecordError(status,pdest,"dbGetLink");
}
long dbPutLink(pdblink,psource,dbrType,pbuffer,nRequest)
@@ -400,6 +401,7 @@ long dbPutLink(pdblink,psource,dbrType,pbuffer,nRequest)
}
if(!RTN_SUCCESS(status)) return(status);
if(pdblink->process_passive) status=dbScanPassive(paddr);
if(status) recGblRecordError(status,psource,"dbPutLink");
return(status);
}
@@ -414,6 +416,7 @@ long dbPutField(paddr,dbrType,pbuffer,nRequest)
dbScanLock(paddr->precord);
status=dbPut(paddr,dbrType,pbuffer,nRequest);
if(status) recGblDbaddrError(status,paddr,"dbPutField");
if(RTN_SUCCESS(status) && pfldDes->process_passive) status=dbScanPassive(paddr);
dbScanUnlock(paddr->precord);
return(status);
@@ -456,7 +459,7 @@ long dbBufferSize(dbr_type,options,no_elements)
* greater than or equal to 10,000,000.00
*
*/
static long f_to_str(flt_value,pstr_value,precision)
static void f_to_str(flt_value,pstr_value,precision)
double flt_value;
char *pstr_value;
int precision;
@@ -466,6 +469,10 @@ int precision;
short number;
char *pfirst_digit;
if(flt_value>0e0 && flt_value<udfFtest) {
strcpy(pstr_value,"undefined");
return;
}
pfirst_digit = pstr_value;
if (flt_value < 0){
*pstr_value = '-';
@@ -475,8 +482,8 @@ int precision;
}
if (flt_value >= 10000000 ){
gcvt(flt_value,10,pstr_value);
return(0);
gcvt(flt_value,20,pstr_value);
return;
}
/* whole numbers */
@@ -531,7 +538,7 @@ int precision;
*pstr_value += 1;
}
}
return(0);
return;
}
/* Convert various integer types to ascii */
@@ -571,7 +578,7 @@ static void char_to_str(source,pdest)
*pdest = 0;
return;
}
static void uchar_to_str(source,pdest)
unsigned char source;
char *pdest;
@@ -611,6 +618,10 @@ static void short_to_str(source,pdest)
*pdest = 0;
return;
}
if(source==udfShort) {
strcpy(pdest,"undefined");
return;
}
if(source<0) {
*pdest++ = '-';
if(source == -32768) {
@@ -631,7 +642,7 @@ static void short_to_str(source,pdest)
*pdest = 0;
return;
}
static void ushort_to_str(source,pdest)
unsigned short source;
char *pdest;
@@ -645,6 +656,10 @@ static void ushort_to_str(source,pdest)
*pdest = 0;
return;
}
if(source==udfUshort) {
strcpy(pdest,"undefined");
return;
}
val = source;
for(i=0; val!=0; i++) {
temp = val/10;
@@ -671,6 +686,10 @@ static void long_to_str(source,pdest)
*pdest = 0;
return;
}
if(source==udfLong) {
strcpy(pdest,"undefined");
return;
}
if(source<0) {
*pdest++ = '-';
if(source == -2147483648) {
@@ -691,7 +710,7 @@ static void long_to_str(source,pdest)
*pdest = 0;
return;
}
static void ulong_to_str(source,pdest)
unsigned long source;
char *pdest;
@@ -705,6 +724,10 @@ static void ulong_to_str(source,pdest)
*pdest = 0;
return;
}
if(source==udfUlong) {
strcpy(pdest,"undefined");
return;
}
val = source;
for(i=0; val!=0; i++) {
temp = val/10;
@@ -2112,12 +2135,12 @@ long offset;
}
if(nRequest==1 && offset==0) {
return(f_to_str((double)(*psrc),pbuffer,precision));
f_to_str((double)(*psrc),pbuffer,precision);
return(0);
}
psrc += offset;
while (nRequest) {
status=f_to_str((double)(*psrc),pbuffer,precision);
if(!RTN_SUCCESS(status)) return(status);
f_to_str((double)(*psrc),pbuffer,precision);
pbuffer += MAX_STRING_SIZE;
if(++offset==no_elements)
psrc=(float *)paddr->pfield;
@@ -2352,12 +2375,12 @@ long offset;
}
if(nRequest==1 && offset==0) {
return(f_to_str(*psrc,pbuffer,precision));
f_to_str(*psrc,pbuffer,precision);
return(0);
}
psrc += offset;
while (nRequest) {
status=f_to_str(*psrc,pbuffer,precision);
if(!RTN_SUCCESS(status)) return(status);
f_to_str(*psrc,pbuffer,precision);
pbuffer += MAX_STRING_SIZE;
if(++offset==no_elements)
psrc=(double *)paddr->pfield;
@@ -5031,12 +5054,12 @@ long offset;
}
if(nRequest==1 && offset==0) {
status = f_to_str((double)(*pbuffer),pdest,precision);
f_to_str((double)(*pbuffer),pdest,precision);
return(0);
}
pdest += (size*offset);
while (nRequest) {
status = f_to_str((double)(*pbuffer),pdest,precision);
f_to_str((double)(*pbuffer),pdest,precision);
pbuffer++;
if(++offset==no_elements)
pdest=(char *)paddr->pfield;
@@ -5272,12 +5295,12 @@ long offset;
}
if(nRequest==1 && offset==0) {
status = f_to_str(*pbuffer,pdest,precision);
f_to_str(*pbuffer,pdest,precision);
return(0);
}
pdest += (size*offset);
while (nRequest) {
status = f_to_str(*pbuffer,pdest,precision);
f_to_str(*pbuffer,pdest,precision);
pbuffer++;
if(++offset==no_elements)
pdest=(char *)paddr->pfield;

View File

@@ -35,6 +35,9 @@
*/
/* Global Database Test Routines - All can be invoked via vxWorks shell
*
* dba(pname) Print dbAddr info
* char *pname Pvname
*
* dbl(ptypeName) list record names.
* char *ptypeName; Record type. If null all record types
@@ -115,6 +118,17 @@ void dbprReportDevChoice();
struct fldDes *dbprGetFldRec();
struct recTypDes *dbprGetRecTypDes();
long dba(pname) /* get and print dbAddr info */
char *pname;
{
struct dbAddr addr;
long status;
status=dbNameToAddr(pname,&addr);
printDbAddr(status,&addr);
if(status) return(1); else return(0);
}
long dbl(ptypeName) /* list process variables for specified record type*/
char *ptypeName;
@@ -172,7 +186,6 @@ long dbgf(pname) /* get field value*/
tab_size = 10;
status=dbNameToAddr(pname,&addr);
printDbAddr(status,&addr);
if(status) return(1);
no_elements=MIN(addr.no_elements,((sizeof(buffer)*4)/addr.field_size));
options=0;
@@ -262,7 +275,6 @@ long dbpr(pname, interest_level) /* print record */
tab_size = 20;
status = dbNameToAddr(pname, &addr);
printDbAddr(status, &addr);
if (status) return (1);
if (dbpr_report(pname, &addr, interest_level, pMsgBuff, tab_size))
@@ -318,7 +330,6 @@ long dbtgf(pname) /* test all options for dbGetField */
tab_size = 10;
status=dbNameToAddr(pname,&addr);
printDbAddr(status,&addr);
if(status)return(1);
/* try all options first */
req_options=0xffffffff;
@@ -399,7 +410,6 @@ long dbtpf(pname,pvalue)/* test all options for dbPutField */
tab_size = 10;
status=dbNameToAddr(pname,&addr);
printDbAddr(status,&addr);
if(status) return(1);
/* DBR_STRING */
status=dbPutField(&addr,DBR_STRING,pvalue,1L);
@@ -618,11 +628,22 @@ got_it:
return(0);
}
static char *dbf[DBF_NTYPES]={
"STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG",
"FLOAT","DOUBLE","ENUM","GBLCHOICE","CVTCHOICE","RECCHOICE",
"DEVCHOICE","INLINK","OUTLINK","FWDLINK","NOACCESS"};
static char *dbr[DBR_ENUM+2]={
"STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG",
"FLOAT","DOUBLE","ENUM","NOACCESS"};
static void printDbAddr(status,paddr)
long status;
struct dbAddr *paddr;
{
char *pstr;
char *pstr;
short field_type;
short dbr_field_type;
if(status!=0) {
errMessage(status,"dbNameToAddr error");
@@ -635,11 +656,23 @@ static void printDbAddr(status,paddr)
printf(" Record Type: %d\n",paddr->record_type);
else
printf(" Record Type: %s\n",pstr);
printf(" FieldType: DBF_");
field_type = paddr->field_type;
if(field_type<0 || field_type>DBR_NOACCESS)
printf(" Illegal = %d\n",field_type);
else
printf("%s\n",dbf[field_type]);
printf(" Field Type: %d\n",paddr->field_type);
printf(" Field Size: %d\n",paddr->field_size);
printf(" Special: %d\n",paddr->special);
printf(" Choice Set: %d\n",paddr->choice_set);
printf("DBR Field Type: %d\n",paddr->dbr_field_type);
printf("DBR Field Type: DBR_");
dbr_field_type = paddr->dbr_field_type;
if(dbr_field_type==DBR_NOACCESS)dbr_field_type=DBR_ENUM + 1;
if(dbr_field_type<0 || dbr_field_type>(DBR_ENUM+1))
printf(" Illegal = %d\n",dbr_field_type);
else
printf("%s\n",dbr[dbr_field_type]);
}

View File

@@ -1,2 +1,469 @@
/* share/src/libCom/calcPerform $Id$ */
/*
* Author: Julie Sander and Bob Dalesio
* Date: 7-27-87
*
* Control System Software for the GTA Project
*
* Copyright 1988, 1989, the Regents of the University of California.
*
* This software was produced under a U.S. Government contract
* (W-7405-ENG-36) at the Los Alamos National Laboratory, which is
* operated by the University of California for the U.S. Department
* of Energy.
*
* Developed by the Controls and Automation Group (AT-8)
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Direct inqueries to:
* Bob Dalesio, AT-8, Mail Stop H820
* Los Alamos National Laboratory
* Los Alamos, New Mexico 87545
* Phone: (505) 667-3414
* E-mail: dalesio@luke.lanl.gov
*
* Modification Log:
* -----------------
* .01 5-18-88 lrd modified modulo and power to avoid math library
* .02 5-19-88 lrd modified absolute value to avoid math library
* defined unary math lib routines as doubles
* removed include math.h
* stopped loading dinglers math routines (ml)
* wrote a random number generator to return a
* double between 0 and 1
* .03 12-09-88 lrd fixed modulo not to perform zero division
* .04 12-12-88 lrd lock the record while processing
* .05 12-13-88 lrd made an alarm for math error
* .06 12-15-88 lrd Process the forward scan link
* .07 12-23-88 lrd Alarm on locked MAX_LOCKED times
* .08 01-11-89 lrd Add Right and Left Shift
* .09 02-01-89 lrd Add Trig functions
* .10 03-14-89 lrd fix true on C question mark operator
* .11 03-29-89 lrd make hardware errors MAJOR
* remove hw severity spec from database
* .12 04-06-89 lrd add monitor detection
* .13 05-03-89 lrd removed process mask from arg list
* .14 06-05-89 lrd check for negative square root
* .15 08-01-89 lrd full range of exponentiation using pow(x,y)
* .16 04-04-90 lrd fix post events for read and calc alarms
* fix neg base raised to integer exponent
* .17 04-06-90 lrd change conditional to check for 0 and non-zero
* instead of 0 and 1 (more 'C' like)
* .18 09-10-90 lrd add time stamps
* .19 11-26-90 lrd add bit not and relational not - fix RNDM
* .20 11-29-90 lrd conditionally process soft channels
* .21 12-14-90 lrd fixed post events for the variables
* .22 03-15-91 mrk moved code from calcRecord to here
*/
/* This module contains the code for processing the arithmetic
* expressions defined in calculation records. postfix must be called
* to convert a valid infix expression to postfix. CalcPerform
* calculates the postfix expression.
*
* Subroutines
*
* Public
*
* calcPerform perform the calculation
* args
* double *pargs address of arguments (12)
* double *presult address of result
* char *rpcl address of reverse polish buffer
* returns
* 0 fetched successfully
* -1 fetch failed
*
* Private routine for calcPerform
* random random number generator
* returns
* double value between 0.00 and 1.00
*/
#include <stdio.h>
#include <dbDefs.h>
#include <post.h>
double random();
/* the floating point math routines need to be declared as doubles */
double sqrt(),log(),log10();
double acos(),asin(),atan();
double cos(),sin(),tan();
double cosh(),sinh(),tanh();
double srand(),rand();
#define NOT_SET 0
#define TRUE_COND 1
#define FALSE_COND 2
long calcPerform(parg,presult,post)
double *parg;
double *presult;
char *post;
{
register double *pstacktop; /* stack of values */
double stack[80];
register double temp;
short temp1;
register short i;
double *top;
int itop; /* integer top value */
int inexttop; /* ineteger next to top value */
short cond_flag; /* conditional else flag */
/* initialize flag */
cond_flag = NOT_SET;
pstacktop = &stack[0];
/* set post to postfix expression in calc structure */
top = pstacktop;
/* polish calculator loop */
while (*post != END_STACK){
switch (*post){
case FETCH_A:
++pstacktop;
*pstacktop = parg[0];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_B:
++pstacktop;
*pstacktop = parg[1];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_C:
++pstacktop;
*pstacktop = parg[2];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_D:
++pstacktop;
*pstacktop = parg[3];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_E:
++pstacktop;
*pstacktop = parg[4];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_F:
++pstacktop;
*pstacktop = parg[5];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_G:
++pstacktop;
*pstacktop = parg[6];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_H:
++pstacktop;
*pstacktop = parg[7];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_I:
++pstacktop;
*pstacktop = parg[8];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_J:
++pstacktop;
*pstacktop = parg[9];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_K:
++pstacktop;
*pstacktop = parg[10];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_L:
++pstacktop;
*pstacktop = parg[11];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case ADD:
--pstacktop;
*pstacktop = *pstacktop + *(pstacktop+1);
break;
case SUB:
--pstacktop;
*pstacktop = *pstacktop - *(pstacktop+1);
break;
case MULT:
--pstacktop;
*pstacktop = *pstacktop * *(pstacktop+1);
break;
case DIV:
--pstacktop;
if (*(pstacktop+1) == 0) /* can't divide by zero */
return(-1);
*pstacktop = *pstacktop / *(pstacktop+1);
break;
case COND_ELSE:
/* first conditional set cond_flag */
/* true */
if ((*pstacktop != 0.0) && (cond_flag == NOT_SET)){
cond_flag = TRUE_COND;
--pstacktop; /* remove condition */
/* false */
}else if ((*pstacktop==0.0) && (cond_flag==NOT_SET)){
cond_flag = FALSE_COND;
--pstacktop; /* remove condition */
/* check for else condition */
i = 1;
while (*(post+i) != COND_ELSE){
/* no else value */
if (*(post+i) == END_STACK){
/* skip to end of expression */
while (*(post+1) != END_STACK)
++post;
/* use last value as result */
++pstacktop;
*pstacktop = *presult;
}
i++;
}
}else if (cond_flag == TRUE_COND){
/* skip expression - result is on stack */
while ((*(post+1) != COND_ELSE)
&& (*(post+1) != END_STACK))
++post;
}else if (cond_flag == FALSE_COND){
/* remove true answer from stack top */
--pstacktop;
}
break;
case ABS_VAL:
if (*pstacktop < 0) *pstacktop = -*pstacktop;
break;
case UNARY_NEG:
*pstacktop = -1* (*pstacktop);
break;
case SQU_RT:
if (*pstacktop < 0) return(-1); /* undefined */
*pstacktop = sqrt(*pstacktop);
break;
case LOG_10:
*pstacktop = log10(*pstacktop);
break;
case LOG_E:
*pstacktop = log(*pstacktop);
break;
case RANDOM:
++pstacktop;
*pstacktop = random();
break;
case EXPON:
--pstacktop;
if (*pstacktop < 0){
temp1 = (int) *(pstacktop+1);
/* is exponent an integer */
if ((*(pstacktop+1) - (double)temp1) != 0) return (-1);
*pstacktop = exp(*(pstacktop+1) * log(-*pstacktop));
/* is value negative */
if ((temp1 % 2) > 0) *pstacktop = -*pstacktop;
}else{
*pstacktop = exp(*(pstacktop+1) * log(*pstacktop));
}
break;
case MODULO:
--pstacktop;
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop+1);
if (inexttop == 0)
return(-1);
i = itop % inexttop;
*pstacktop = i;
break;
case REL_OR:
--pstacktop;
*pstacktop = (*pstacktop || *(pstacktop+1));
break;
case REL_AND:
--pstacktop;
*pstacktop = (*pstacktop && *(pstacktop+1));
break;
case BIT_OR:
/* force double values into integers and or them */
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop | itop);
break;
case BIT_AND:
/* force double values into integers and and them */
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop & itop);
break;
case BIT_EXCL_OR:
/*force double values to integers to exclusive or them*/
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop ^ itop);
break;
case GR_OR_EQ:
--pstacktop;
*pstacktop = *pstacktop >= *(pstacktop+1);
break;
case GR_THAN:
--pstacktop;
*pstacktop = *pstacktop > *(pstacktop+1);
break;
case LESS_OR_EQ:
--pstacktop;
*pstacktop = *pstacktop <= *(pstacktop+1);
break;
case LESS_THAN:
--pstacktop;
*pstacktop = *pstacktop < *(pstacktop+1);
break;
case NOT_EQ:
--pstacktop;
*pstacktop = *pstacktop != *(pstacktop+1);
break;
case EQUAL:
--pstacktop;
*pstacktop = (*pstacktop == *(pstacktop+1));
break;
case RIGHT_SHIFT:
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop >> itop);
break;
case LEFT_SHIFT:
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop << itop);
break;
case ACOS:
*pstacktop = acos(*pstacktop);
break;
case ASIN:
*pstacktop = asin(*pstacktop);
break;
case ATAN:
*pstacktop = atan(*pstacktop);
break;
case COS:
*pstacktop = cos(*pstacktop);
break;
case SIN:
*pstacktop = sin(*pstacktop);
break;
case TAN:
*pstacktop = tan(*pstacktop);
break;
case COSH:
*pstacktop = cosh(*pstacktop);
break;
case SINH:
*pstacktop = sinh(*pstacktop);
break;
case TANH:
*pstacktop = tanh(*pstacktop);
break;
case REL_NOT:
*pstacktop = ((*pstacktop)?0:1);
break;
case BIT_NOT:
itop = (int)*pstacktop;
*pstacktop = ~itop;
break;
default:
printf("%d bad expression element\n",*post);
break;
}
/* move ahead in postfix expression */
++post;
}
/* if everything is peachy,the stack should end at its first position */
if (++top == pstacktop)
*presult = *pstacktop;
else
return(-1);
return(0);
}
/*
* RAND
*
* generates a random number between 0 and 1 using the
* seed = (multy * seed) + addy Random Number Generator by Knuth
* SemiNumerical Algorithms
* Chapter 1
* randy = 1.0 / (seed & 0xff) To normalize the number between 0 - 1
*/
static unsigned short seed = 0xa3bf;
static unsigned short multy = 191 * 8 + 5; /* 191 % 8 == 5 */
static unsigned short addy = 0x3141;
static double random()
{
double randy;
/* random number */
seed = (seed * multy) + addy;
randy = 1.0 / (seed & 0xffff);
/* between 0 - 1 */
return(randy);
}

View File

@@ -1,47 +1,56 @@
/* share/src/libCom/postfix.c $Id$ */
/*
* POSTFIX.C
*
* Subroutines used to convert an infix expression to a postfix expression
*
* Author: Bob Dalesio
* Date: 12-12-86
* $Id$
* Author: Bob Dalesio
* Date: 12-12-86
* @(#)postfix.c 1.3 12/6/90
*
* Control System Software for the GTA Project
* Control System Software for the GTA Project
*
* Copyright 1988, 1989, the Regents of the University of California.
* Copyright 1988, 1989, the Regents of the University of California.
*
* This software was produced under a U.S. Government contract
* (W-7405-ENG-36) at the Los Alamos National Laboratory, which is
* operated by the University of California for the U.S. Department
* of Energy.
* This software was produced under a U.S. Government contract
* (W-7405-ENG-36) at the Los Alamos National Laboratory, which is
* operated by the University of California for the U.S. Department
* of Energy.
*
* Developed by the Controls and Automation Group (AT-8)
* Accelerator Technology Division
* Los Alamos National Laboratory
* Developed by the Controls and Automation Group (AT-8)
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Direct inqueries to:
* Andy Kozubal, AT-8, Mail Stop H820
* Los Alamos National Laboratory
* Los Alamos, New Mexico 87545
* Phone: (505) 667-6508
* E-mail: kozubal@k2.lanl.gov
* Direct inqueries to:
* Andy Kozubal, AT-8, Mail Stop H820
* Los Alamos National Laboratory
* Los Alamos, New Mexico 87545
* Phone: (505) 667-6508
* E-mail: kozubal@k2.lanl.gov
*
* Modification Log:
* -----------------
* .01 01-11-89 lrd added right shift and left shift operations
* .02 01-13-89 lrd modified to load into IOCs
* .03 02-01-89 lrd added trigonometric functions
* .04 04-05-89 lrd fixed the order of some operations in the
* element table and added a warning label
* .01 01-11-89 lrd added right shift and left shift operations
* .02 01-13-89 lrd modified to load into IOCs
* .03 02-01-89 lrd added trigonometric functions
* .04 04-05-89 lrd fixed the order of some operations in the
* element table and added a warning label
* .05 11-26-90 lrd fix SINH, COSH, TANH
*/
#include <curses.h>
#include <post.h>
/*
/*
* Subroutines
*
* Public
*
* postfix convert an algebraic expression to symbolic postfix
* args
* pinfix the algebraic expression
* ppostfix the symbolic postfix expression
* returns
* 0 successful
* -1 not successful
* Private routines for postfix
*
* find_element finds a symbolic element in the expression element tbl
* args
* pbuffer pointer to the infox expression element
@@ -55,19 +64,25 @@
* pinfix pointer into the infix expression
* pelement pointer to the expression element table
* pno_bytes size of the element in the infix expression
* plink pointer to a resolved database reference (N/A)
* returns
* FINE found an expression element
* VARIABLE found a database reference
* UNKNOWN_ELEMENT unknown element found in the infix expression
* postfix convert an algebraic expression to symbolic postfix
* match_element finds an alpha element in the expression table
* args
* pinfix the algebraic expression
* ppostfix the symbolic postfix expression
* pbuffer pointer to an alpha expression element
* pelement pointer to the expression element table
* returns
* 0 successful
* -1 not successful
* TRUE found the element in the element table
* FLASE expression element not found
*/
#include <stdio.h>
#include <dbDefs.h>
#include <post.h>
/* declarations for postfix */
/* element types */
#define OPERAND 0
#define UNARY_OPERATOR 1
@@ -86,7 +101,12 @@
#define FINE 0
#define UNKNOWN_ELEMENT -1
#define END -2
struct link{
short field1;
short field2;
};
/*
* element table
*
@@ -117,12 +137,14 @@ static struct expression_element elements[] = {
"ACOS", 7, 8, UNARY_OPERATOR, ACOS, /* arc cosine */
"ASIN", 7, 8, UNARY_OPERATOR, ASIN, /* arc sine */
"ATAN", 7, 8, UNARY_OPERATOR, ATAN, /* arc tangent */
"COS", 7, 8, UNARY_OPERATOR, COS, /* cosine */
"COSH", 7, 8, UNARY_OPERATOR, COSH, /* hyperbolic cosine */
"SIN", 7, 8, UNARY_OPERATOR, SIN, /* sine */
"COS", 7, 8, UNARY_OPERATOR, COS, /* cosine */
"SINH", 7, 8, UNARY_OPERATOR, SINH, /* hyperbolic sine */
"TAN", 7, 8, UNARY_OPERATOR, TAN, /* tangent */
"SIN", 7, 8, UNARY_OPERATOR, SIN, /* sine */
"TANH", 7, 8, UNARY_OPERATOR, TANH, /* hyperbolic tangent*/
"TAN", 7, 8, UNARY_OPERATOR, TAN, /* tangent */
"!", 7, 8, UNARY_OPERATOR, REL_NOT, /* not */
"~", 7, 8, UNARY_OPERATOR, BIT_NOT, /* and */
"RNDM", 0, 0, OPERAND, RANDOM, /* Random Number */
"OR", 1, 1, BINARY_OPERATOR,BIT_OR, /* or */
"AND", 2, 2, BINARY_OPERATOR,BIT_AND, /* and */
@@ -133,12 +155,24 @@ static struct expression_element elements[] = {
"D", 0, 0, OPERAND, FETCH_D, /* fetch var D */
"E", 0, 0, OPERAND, FETCH_E, /* fetch var E */
"F", 0, 0, OPERAND, FETCH_F, /* fetch var F */
"G", 0, 0, OPERAND, FETCH_G, /* fetch var G */
"H", 0, 0, OPERAND, FETCH_H, /* fetch var H */
"I", 0, 0, OPERAND, FETCH_I, /* fetch var I */
"J", 0, 0, OPERAND, FETCH_J, /* fetch var J */
"K", 0, 0, OPERAND, FETCH_K, /* fetch var K */
"L", 0, 0, OPERAND, FETCH_L, /* fetch var L */
"a", 0, 0, OPERAND, FETCH_A, /* fetch var A */
"b", 0, 0, OPERAND, FETCH_B, /* fetch var B */
"c", 0, 0, OPERAND, FETCH_C, /* fetch var C */
"d", 0, 0, OPERAND, FETCH_D, /* fetch var D */
"e", 0, 0, OPERAND, FETCH_E, /* fetch var E */
"f", 0, 0, OPERAND, FETCH_F, /* fetch var F */
"g", 0, 0, OPERAND, FETCH_G, /* fetch var G */
"h", 0, 0, OPERAND, FETCH_H, /* fetch var H */
"i", 0, 0, OPERAND, FETCH_I, /* fetch var I */
"j", 0, 0, OPERAND, FETCH_J, /* fetch var J */
"k", 0, 0, OPERAND, FETCH_K, /* fetch var K */
"l", 0, 0, OPERAND, FETCH_L, /* fetch var L */
"?", 0, 0, CONDITIONAL, COND_ELSE, /* conditional */
":", 0, 0, ELSE, COND_ELSE, /* else */
"(", 0, 8, UNARY_OPERATOR, PAREN, /* open paren */
@@ -170,18 +204,17 @@ static struct expression_element elements[] = {
*
* find the pointer to an entry in the element table
*/
static find_element(pbuffer,pelement,pno_bytes)
#define SAME 0
char *pbuffer;
struct expression_element **pelement;
short *pno_bytes;
static find_element(pbuffer,pelement,pno_bytes)
register char *pbuffer;
register struct expression_element **pelement;
register short *pno_bytes;
{
/* compare the string to each element in the element table */
*pelement = &elements[0];
while ((*pelement)->element[0] != NULL){
if (strncmp(pbuffer,(*pelement)->element,
strlen((*pelement)->element)) == SAME){
strlen((*pelement)->element)) == 0){
*pno_bytes += strlen((*pelement)->element);
return(TRUE);
}
@@ -195,11 +228,14 @@ static find_element(pbuffer,pelement,pno_bytes)
*
* get an expression element
*/
static get_element(pinfix,pelement,pno_bytes)
char *pinfix;
struct expression_element **pelement;
short *pno_bytes;
static get_element(pinfix,pelement,pno_bytes,plink)
register char *pinfix;
register struct expression_element **pelement;
register short *pno_bytes;
struct link *plink;
{
char buffer[40];
register short i;
/* get the next expression element from the infix expression */
if (*pinfix == NULL) return(END);
@@ -221,18 +257,20 @@ short *pno_bytes;
* convert an infix expression to a postfix expression
*/
long postfix(pinfix,ppostfix,perror)
char *pinfix;
char *ppostfix;
register char *pinfix;
register char *ppostfix;
short *perror;
{
short got_if;
short got_else;
short no_bytes;
short operand_needed;
short new_expression;
register short operand_needed;
register short new_expression;
register short link_inx; /* index into variable table */
struct link new_link;
struct expression_element stack[80];
struct expression_element *pelement;
struct expression_element *pstacktop;
register struct expression_element *pstacktop;
/* place the expression elements into postfix */
got_if = FALSE;
@@ -240,7 +278,7 @@ short *perror;
operand_needed = TRUE;
new_expression = TRUE;
pstacktop = &stack[0];
while (get_element(pinfix,&pelement,&no_bytes) != END){
while (get_element(pinfix,&pelement,&no_bytes,&new_link) != END){
pinfix += no_bytes;
switch (pelement->type){

View File

@@ -1,2 +1,469 @@
/* share/src/libCom/calcPerform $Id$ */
/*
* Author: Julie Sander and Bob Dalesio
* Date: 7-27-87
*
* Control System Software for the GTA Project
*
* Copyright 1988, 1989, the Regents of the University of California.
*
* This software was produced under a U.S. Government contract
* (W-7405-ENG-36) at the Los Alamos National Laboratory, which is
* operated by the University of California for the U.S. Department
* of Energy.
*
* Developed by the Controls and Automation Group (AT-8)
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Direct inqueries to:
* Bob Dalesio, AT-8, Mail Stop H820
* Los Alamos National Laboratory
* Los Alamos, New Mexico 87545
* Phone: (505) 667-3414
* E-mail: dalesio@luke.lanl.gov
*
* Modification Log:
* -----------------
* .01 5-18-88 lrd modified modulo and power to avoid math library
* .02 5-19-88 lrd modified absolute value to avoid math library
* defined unary math lib routines as doubles
* removed include math.h
* stopped loading dinglers math routines (ml)
* wrote a random number generator to return a
* double between 0 and 1
* .03 12-09-88 lrd fixed modulo not to perform zero division
* .04 12-12-88 lrd lock the record while processing
* .05 12-13-88 lrd made an alarm for math error
* .06 12-15-88 lrd Process the forward scan link
* .07 12-23-88 lrd Alarm on locked MAX_LOCKED times
* .08 01-11-89 lrd Add Right and Left Shift
* .09 02-01-89 lrd Add Trig functions
* .10 03-14-89 lrd fix true on C question mark operator
* .11 03-29-89 lrd make hardware errors MAJOR
* remove hw severity spec from database
* .12 04-06-89 lrd add monitor detection
* .13 05-03-89 lrd removed process mask from arg list
* .14 06-05-89 lrd check for negative square root
* .15 08-01-89 lrd full range of exponentiation using pow(x,y)
* .16 04-04-90 lrd fix post events for read and calc alarms
* fix neg base raised to integer exponent
* .17 04-06-90 lrd change conditional to check for 0 and non-zero
* instead of 0 and 1 (more 'C' like)
* .18 09-10-90 lrd add time stamps
* .19 11-26-90 lrd add bit not and relational not - fix RNDM
* .20 11-29-90 lrd conditionally process soft channels
* .21 12-14-90 lrd fixed post events for the variables
* .22 03-15-91 mrk moved code from calcRecord to here
*/
/* This module contains the code for processing the arithmetic
* expressions defined in calculation records. postfix must be called
* to convert a valid infix expression to postfix. CalcPerform
* calculates the postfix expression.
*
* Subroutines
*
* Public
*
* calcPerform perform the calculation
* args
* double *pargs address of arguments (12)
* double *presult address of result
* char *rpcl address of reverse polish buffer
* returns
* 0 fetched successfully
* -1 fetch failed
*
* Private routine for calcPerform
* random random number generator
* returns
* double value between 0.00 and 1.00
*/
#include <stdio.h>
#include <dbDefs.h>
#include <post.h>
double random();
/* the floating point math routines need to be declared as doubles */
double sqrt(),log(),log10();
double acos(),asin(),atan();
double cos(),sin(),tan();
double cosh(),sinh(),tanh();
double srand(),rand();
#define NOT_SET 0
#define TRUE_COND 1
#define FALSE_COND 2
long calcPerform(parg,presult,post)
double *parg;
double *presult;
char *post;
{
register double *pstacktop; /* stack of values */
double stack[80];
register double temp;
short temp1;
register short i;
double *top;
int itop; /* integer top value */
int inexttop; /* ineteger next to top value */
short cond_flag; /* conditional else flag */
/* initialize flag */
cond_flag = NOT_SET;
pstacktop = &stack[0];
/* set post to postfix expression in calc structure */
top = pstacktop;
/* polish calculator loop */
while (*post != END_STACK){
switch (*post){
case FETCH_A:
++pstacktop;
*pstacktop = parg[0];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_B:
++pstacktop;
*pstacktop = parg[1];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_C:
++pstacktop;
*pstacktop = parg[2];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_D:
++pstacktop;
*pstacktop = parg[3];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_E:
++pstacktop;
*pstacktop = parg[4];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_F:
++pstacktop;
*pstacktop = parg[5];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_G:
++pstacktop;
*pstacktop = parg[6];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_H:
++pstacktop;
*pstacktop = parg[7];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_I:
++pstacktop;
*pstacktop = parg[8];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_J:
++pstacktop;
*pstacktop = parg[9];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_K:
++pstacktop;
*pstacktop = parg[10];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case FETCH_L:
++pstacktop;
*pstacktop = parg[11];
if(*pstacktop>0.0 && *pstacktop<udfDtest) return(-1);
break;
case ADD:
--pstacktop;
*pstacktop = *pstacktop + *(pstacktop+1);
break;
case SUB:
--pstacktop;
*pstacktop = *pstacktop - *(pstacktop+1);
break;
case MULT:
--pstacktop;
*pstacktop = *pstacktop * *(pstacktop+1);
break;
case DIV:
--pstacktop;
if (*(pstacktop+1) == 0) /* can't divide by zero */
return(-1);
*pstacktop = *pstacktop / *(pstacktop+1);
break;
case COND_ELSE:
/* first conditional set cond_flag */
/* true */
if ((*pstacktop != 0.0) && (cond_flag == NOT_SET)){
cond_flag = TRUE_COND;
--pstacktop; /* remove condition */
/* false */
}else if ((*pstacktop==0.0) && (cond_flag==NOT_SET)){
cond_flag = FALSE_COND;
--pstacktop; /* remove condition */
/* check for else condition */
i = 1;
while (*(post+i) != COND_ELSE){
/* no else value */
if (*(post+i) == END_STACK){
/* skip to end of expression */
while (*(post+1) != END_STACK)
++post;
/* use last value as result */
++pstacktop;
*pstacktop = *presult;
}
i++;
}
}else if (cond_flag == TRUE_COND){
/* skip expression - result is on stack */
while ((*(post+1) != COND_ELSE)
&& (*(post+1) != END_STACK))
++post;
}else if (cond_flag == FALSE_COND){
/* remove true answer from stack top */
--pstacktop;
}
break;
case ABS_VAL:
if (*pstacktop < 0) *pstacktop = -*pstacktop;
break;
case UNARY_NEG:
*pstacktop = -1* (*pstacktop);
break;
case SQU_RT:
if (*pstacktop < 0) return(-1); /* undefined */
*pstacktop = sqrt(*pstacktop);
break;
case LOG_10:
*pstacktop = log10(*pstacktop);
break;
case LOG_E:
*pstacktop = log(*pstacktop);
break;
case RANDOM:
++pstacktop;
*pstacktop = random();
break;
case EXPON:
--pstacktop;
if (*pstacktop < 0){
temp1 = (int) *(pstacktop+1);
/* is exponent an integer */
if ((*(pstacktop+1) - (double)temp1) != 0) return (-1);
*pstacktop = exp(*(pstacktop+1) * log(-*pstacktop));
/* is value negative */
if ((temp1 % 2) > 0) *pstacktop = -*pstacktop;
}else{
*pstacktop = exp(*(pstacktop+1) * log(*pstacktop));
}
break;
case MODULO:
--pstacktop;
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop+1);
if (inexttop == 0)
return(-1);
i = itop % inexttop;
*pstacktop = i;
break;
case REL_OR:
--pstacktop;
*pstacktop = (*pstacktop || *(pstacktop+1));
break;
case REL_AND:
--pstacktop;
*pstacktop = (*pstacktop && *(pstacktop+1));
break;
case BIT_OR:
/* force double values into integers and or them */
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop | itop);
break;
case BIT_AND:
/* force double values into integers and and them */
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop & itop);
break;
case BIT_EXCL_OR:
/*force double values to integers to exclusive or them*/
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop ^ itop);
break;
case GR_OR_EQ:
--pstacktop;
*pstacktop = *pstacktop >= *(pstacktop+1);
break;
case GR_THAN:
--pstacktop;
*pstacktop = *pstacktop > *(pstacktop+1);
break;
case LESS_OR_EQ:
--pstacktop;
*pstacktop = *pstacktop <= *(pstacktop+1);
break;
case LESS_THAN:
--pstacktop;
*pstacktop = *pstacktop < *(pstacktop+1);
break;
case NOT_EQ:
--pstacktop;
*pstacktop = *pstacktop != *(pstacktop+1);
break;
case EQUAL:
--pstacktop;
*pstacktop = (*pstacktop == *(pstacktop+1));
break;
case RIGHT_SHIFT:
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop >> itop);
break;
case LEFT_SHIFT:
itop = (int)*pstacktop;
inexttop = (int)*(pstacktop-1);
--pstacktop;
*pstacktop = (inexttop << itop);
break;
case ACOS:
*pstacktop = acos(*pstacktop);
break;
case ASIN:
*pstacktop = asin(*pstacktop);
break;
case ATAN:
*pstacktop = atan(*pstacktop);
break;
case COS:
*pstacktop = cos(*pstacktop);
break;
case SIN:
*pstacktop = sin(*pstacktop);
break;
case TAN:
*pstacktop = tan(*pstacktop);
break;
case COSH:
*pstacktop = cosh(*pstacktop);
break;
case SINH:
*pstacktop = sinh(*pstacktop);
break;
case TANH:
*pstacktop = tanh(*pstacktop);
break;
case REL_NOT:
*pstacktop = ((*pstacktop)?0:1);
break;
case BIT_NOT:
itop = (int)*pstacktop;
*pstacktop = ~itop;
break;
default:
printf("%d bad expression element\n",*post);
break;
}
/* move ahead in postfix expression */
++post;
}
/* if everything is peachy,the stack should end at its first position */
if (++top == pstacktop)
*presult = *pstacktop;
else
return(-1);
return(0);
}
/*
* RAND
*
* generates a random number between 0 and 1 using the
* seed = (multy * seed) + addy Random Number Generator by Knuth
* SemiNumerical Algorithms
* Chapter 1
* randy = 1.0 / (seed & 0xff) To normalize the number between 0 - 1
*/
static unsigned short seed = 0xa3bf;
static unsigned short multy = 191 * 8 + 5; /* 191 % 8 == 5 */
static unsigned short addy = 0x3141;
static double random()
{
double randy;
/* random number */
seed = (seed * multy) + addy;
randy = 1.0 / (seed & 0xffff);
/* between 0 - 1 */
return(randy);
}

View File

@@ -1,2 +1,97 @@
/* share/src/libCom/post.h $Id$ */
/*
* Author: Bob Dalesio
* Date: 9-21-88
* @(#)post.h @(#)post.h 1.1 12/6/90
*
* Control System Software for the GTA Project
*
* Copyright 1988, 1989, the Regents of the University of California.
*
* This software was produced under a U.S. Government contract
* (W-7405-ENG-36) at the Los Alamos National Laboratory, which is
* operated by the University of California for the U.S. Department
* of Energy.
*
* Developed by the Controls and Automation Group (AT-8)
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Direct inqueries to:
* Andy Kozubal, AT-8, Mail Stop H820
* Los Alamos National Laboratory
* Los Alamos, New Mexico 87545
* Phone: (505) 667-6508
* E-mail: kozubal@k2.lanl.gov
*
* Modifcation Log
* ---------------
* .01 01-11-89 lrd add right and left shift
* .02 02-01-89 lrd add trig functions
*/
/* defines for element table */
#define FETCH_A 0
#define FETCH_B 1
#define FETCH_C 2
#define FETCH_D 3
#define FETCH_E 4
#define FETCH_F 5
#define FETCH_G 6
#define FETCH_H 7
#define FETCH_I 8
#define FETCH_J 9
#define FETCH_K 10
#define FETCH_L 11
#define ACOS 12
#define ASIN 13
#define ATAN 14
#define COS 15
#define COSH 16
#define SIN 17
#define STORE_A 18
#define STORE_B 19
#define STORE_C 20
#define STORE_D 21
#define STORE_E 22
#define STORE_F 23
#define STORE_G 24
#define STORE_H 25
#define STORE_I 26
#define STORE_J 27
#define STORE_K 28
#define STORE_L 29
#define RIGHT_SHIFT 30
#define LEFT_SHIFT 31
#define SINH 32
#define TAN 33
#define TANH 34
#define LOG_2 35
#define COND_ELSE 36
#define ABS_VAL 37
#define UNARY_NEG 38
#define SQU_RT 39
#define LOG_10 40
#define LOG_E 41
#define RANDOM 42
#define ADD 43
#define SUB 44
#define MULT 45
#define DIV 46
#define EXPON 47
#define MODULO 48
#define BIT_OR 49
#define BIT_AND 50
#define BIT_EXCL_OR 51
#define GR_OR_EQ 52
#define GR_THAN 53
#define LESS_OR_EQ 54
#define LESS_THAN 55
#define NOT_EQ 56
#define EQUAL 57
#define REL_OR 58
#define REL_AND 59
#define REL_NOT 60
#define BIT_NOT 61
#define PAREN 62
#define END_STACK -1

View File

@@ -1,47 +1,56 @@
/* share/src/libCom/postfix.c $Id$ */
/*
* POSTFIX.C
*
* Subroutines used to convert an infix expression to a postfix expression
*
* Author: Bob Dalesio
* Date: 12-12-86
* $Id$
* Author: Bob Dalesio
* Date: 12-12-86
* @(#)postfix.c 1.3 12/6/90
*
* Control System Software for the GTA Project
* Control System Software for the GTA Project
*
* Copyright 1988, 1989, the Regents of the University of California.
* Copyright 1988, 1989, the Regents of the University of California.
*
* This software was produced under a U.S. Government contract
* (W-7405-ENG-36) at the Los Alamos National Laboratory, which is
* operated by the University of California for the U.S. Department
* of Energy.
* This software was produced under a U.S. Government contract
* (W-7405-ENG-36) at the Los Alamos National Laboratory, which is
* operated by the University of California for the U.S. Department
* of Energy.
*
* Developed by the Controls and Automation Group (AT-8)
* Accelerator Technology Division
* Los Alamos National Laboratory
* Developed by the Controls and Automation Group (AT-8)
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Direct inqueries to:
* Andy Kozubal, AT-8, Mail Stop H820
* Los Alamos National Laboratory
* Los Alamos, New Mexico 87545
* Phone: (505) 667-6508
* E-mail: kozubal@k2.lanl.gov
* Direct inqueries to:
* Andy Kozubal, AT-8, Mail Stop H820
* Los Alamos National Laboratory
* Los Alamos, New Mexico 87545
* Phone: (505) 667-6508
* E-mail: kozubal@k2.lanl.gov
*
* Modification Log:
* -----------------
* .01 01-11-89 lrd added right shift and left shift operations
* .02 01-13-89 lrd modified to load into IOCs
* .03 02-01-89 lrd added trigonometric functions
* .04 04-05-89 lrd fixed the order of some operations in the
* element table and added a warning label
* .01 01-11-89 lrd added right shift and left shift operations
* .02 01-13-89 lrd modified to load into IOCs
* .03 02-01-89 lrd added trigonometric functions
* .04 04-05-89 lrd fixed the order of some operations in the
* element table and added a warning label
* .05 11-26-90 lrd fix SINH, COSH, TANH
*/
#include <curses.h>
#include <post.h>
/*
/*
* Subroutines
*
* Public
*
* postfix convert an algebraic expression to symbolic postfix
* args
* pinfix the algebraic expression
* ppostfix the symbolic postfix expression
* returns
* 0 successful
* -1 not successful
* Private routines for postfix
*
* find_element finds a symbolic element in the expression element tbl
* args
* pbuffer pointer to the infox expression element
@@ -55,19 +64,25 @@
* pinfix pointer into the infix expression
* pelement pointer to the expression element table
* pno_bytes size of the element in the infix expression
* plink pointer to a resolved database reference (N/A)
* returns
* FINE found an expression element
* VARIABLE found a database reference
* UNKNOWN_ELEMENT unknown element found in the infix expression
* postfix convert an algebraic expression to symbolic postfix
* match_element finds an alpha element in the expression table
* args
* pinfix the algebraic expression
* ppostfix the symbolic postfix expression
* pbuffer pointer to an alpha expression element
* pelement pointer to the expression element table
* returns
* 0 successful
* -1 not successful
* TRUE found the element in the element table
* FLASE expression element not found
*/
#include <stdio.h>
#include <dbDefs.h>
#include <post.h>
/* declarations for postfix */
/* element types */
#define OPERAND 0
#define UNARY_OPERATOR 1
@@ -86,7 +101,12 @@
#define FINE 0
#define UNKNOWN_ELEMENT -1
#define END -2
struct link{
short field1;
short field2;
};
/*
* element table
*
@@ -117,12 +137,14 @@ static struct expression_element elements[] = {
"ACOS", 7, 8, UNARY_OPERATOR, ACOS, /* arc cosine */
"ASIN", 7, 8, UNARY_OPERATOR, ASIN, /* arc sine */
"ATAN", 7, 8, UNARY_OPERATOR, ATAN, /* arc tangent */
"COS", 7, 8, UNARY_OPERATOR, COS, /* cosine */
"COSH", 7, 8, UNARY_OPERATOR, COSH, /* hyperbolic cosine */
"SIN", 7, 8, UNARY_OPERATOR, SIN, /* sine */
"COS", 7, 8, UNARY_OPERATOR, COS, /* cosine */
"SINH", 7, 8, UNARY_OPERATOR, SINH, /* hyperbolic sine */
"TAN", 7, 8, UNARY_OPERATOR, TAN, /* tangent */
"SIN", 7, 8, UNARY_OPERATOR, SIN, /* sine */
"TANH", 7, 8, UNARY_OPERATOR, TANH, /* hyperbolic tangent*/
"TAN", 7, 8, UNARY_OPERATOR, TAN, /* tangent */
"!", 7, 8, UNARY_OPERATOR, REL_NOT, /* not */
"~", 7, 8, UNARY_OPERATOR, BIT_NOT, /* and */
"RNDM", 0, 0, OPERAND, RANDOM, /* Random Number */
"OR", 1, 1, BINARY_OPERATOR,BIT_OR, /* or */
"AND", 2, 2, BINARY_OPERATOR,BIT_AND, /* and */
@@ -133,12 +155,24 @@ static struct expression_element elements[] = {
"D", 0, 0, OPERAND, FETCH_D, /* fetch var D */
"E", 0, 0, OPERAND, FETCH_E, /* fetch var E */
"F", 0, 0, OPERAND, FETCH_F, /* fetch var F */
"G", 0, 0, OPERAND, FETCH_G, /* fetch var G */
"H", 0, 0, OPERAND, FETCH_H, /* fetch var H */
"I", 0, 0, OPERAND, FETCH_I, /* fetch var I */
"J", 0, 0, OPERAND, FETCH_J, /* fetch var J */
"K", 0, 0, OPERAND, FETCH_K, /* fetch var K */
"L", 0, 0, OPERAND, FETCH_L, /* fetch var L */
"a", 0, 0, OPERAND, FETCH_A, /* fetch var A */
"b", 0, 0, OPERAND, FETCH_B, /* fetch var B */
"c", 0, 0, OPERAND, FETCH_C, /* fetch var C */
"d", 0, 0, OPERAND, FETCH_D, /* fetch var D */
"e", 0, 0, OPERAND, FETCH_E, /* fetch var E */
"f", 0, 0, OPERAND, FETCH_F, /* fetch var F */
"g", 0, 0, OPERAND, FETCH_G, /* fetch var G */
"h", 0, 0, OPERAND, FETCH_H, /* fetch var H */
"i", 0, 0, OPERAND, FETCH_I, /* fetch var I */
"j", 0, 0, OPERAND, FETCH_J, /* fetch var J */
"k", 0, 0, OPERAND, FETCH_K, /* fetch var K */
"l", 0, 0, OPERAND, FETCH_L, /* fetch var L */
"?", 0, 0, CONDITIONAL, COND_ELSE, /* conditional */
":", 0, 0, ELSE, COND_ELSE, /* else */
"(", 0, 8, UNARY_OPERATOR, PAREN, /* open paren */
@@ -170,18 +204,17 @@ static struct expression_element elements[] = {
*
* find the pointer to an entry in the element table
*/
static find_element(pbuffer,pelement,pno_bytes)
#define SAME 0
char *pbuffer;
struct expression_element **pelement;
short *pno_bytes;
static find_element(pbuffer,pelement,pno_bytes)
register char *pbuffer;
register struct expression_element **pelement;
register short *pno_bytes;
{
/* compare the string to each element in the element table */
*pelement = &elements[0];
while ((*pelement)->element[0] != NULL){
if (strncmp(pbuffer,(*pelement)->element,
strlen((*pelement)->element)) == SAME){
strlen((*pelement)->element)) == 0){
*pno_bytes += strlen((*pelement)->element);
return(TRUE);
}
@@ -195,11 +228,14 @@ static find_element(pbuffer,pelement,pno_bytes)
*
* get an expression element
*/
static get_element(pinfix,pelement,pno_bytes)
char *pinfix;
struct expression_element **pelement;
short *pno_bytes;
static get_element(pinfix,pelement,pno_bytes,plink)
register char *pinfix;
register struct expression_element **pelement;
register short *pno_bytes;
struct link *plink;
{
char buffer[40];
register short i;
/* get the next expression element from the infix expression */
if (*pinfix == NULL) return(END);
@@ -221,18 +257,20 @@ short *pno_bytes;
* convert an infix expression to a postfix expression
*/
long postfix(pinfix,ppostfix,perror)
char *pinfix;
char *ppostfix;
register char *pinfix;
register char *ppostfix;
short *perror;
{
short got_if;
short got_else;
short no_bytes;
short operand_needed;
short new_expression;
register short operand_needed;
register short new_expression;
register short link_inx; /* index into variable table */
struct link new_link;
struct expression_element stack[80];
struct expression_element *pelement;
struct expression_element *pstacktop;
register struct expression_element *pstacktop;
/* place the expression elements into postfix */
got_if = FALSE;
@@ -240,7 +278,7 @@ short *perror;
operand_needed = TRUE;
new_expression = TRUE;
pstacktop = &stack[0];
while (get_element(pinfix,&pelement,&no_bytes) != END){
while (get_element(pinfix,&pelement,&no_bytes,&new_link) != END){
pinfix += no_bytes;
switch (pelement->type){