From a6339fb9242c9c8a7122b7f954422bce1ff46327 Mon Sep 17 00:00:00 2001 From: "Janet B. Anderson" Date: Fri, 22 Mar 1991 15:12:04 +0000 Subject: [PATCH] jba 3/21/91 --- src/db/dbAccess.c | 59 +++-- src/db/dbTest.c | 45 +++- src/libCom/calc/calcPerform.c | 469 +++++++++++++++++++++++++++++++++- src/libCom/calc/postfix.c | 144 +++++++---- src/libCom/calcPerform.c | 469 +++++++++++++++++++++++++++++++++- src/libCom/post.h | 99 ++++++- src/libCom/postfix.c | 144 +++++++---- 7 files changed, 1295 insertions(+), 134 deletions(-) diff --git a/src/db/dbAccess.c b/src/db/dbAccess.c index 2962a2a39..1a5673668 100644 --- a/src/db/dbAccess.c +++ b/src/db/dbAccess.c @@ -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= 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; diff --git a/src/db/dbTest.c b/src/db/dbTest.c index f6a2e4fec..964bdb879 100644 --- a/src/db/dbTest.c +++ b/src/db/dbTest.c @@ -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]); } diff --git a/src/libCom/calc/calcPerform.c b/src/libCom/calc/calcPerform.c index 5c484c2fe..f5ca90cf9 100644 --- a/src/libCom/calc/calcPerform.c +++ b/src/libCom/calc/calcPerform.c @@ -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 +#include +#include +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 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop 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); +} diff --git a/src/libCom/calc/postfix.c b/src/libCom/calc/postfix.c index cac1658df..641a1cc56 100644 --- a/src/libCom/calc/postfix.c +++ b/src/libCom/calc/postfix.c @@ -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 -#include -/* +/* * 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 +#include +#include + +/* 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){ diff --git a/src/libCom/calcPerform.c b/src/libCom/calcPerform.c index 5c484c2fe..f5ca90cf9 100644 --- a/src/libCom/calcPerform.c +++ b/src/libCom/calcPerform.c @@ -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 +#include +#include +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 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop0.0 && *pstacktop 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); +} diff --git a/src/libCom/post.h b/src/libCom/post.h index 8cb7cb989..b19f3c16d 100644 --- a/src/libCom/post.h +++ b/src/libCom/post.h @@ -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 diff --git a/src/libCom/postfix.c b/src/libCom/postfix.c index cac1658df..641a1cc56 100644 --- a/src/libCom/postfix.c +++ b/src/libCom/postfix.c @@ -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 -#include -/* +/* * 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 +#include +#include + +/* 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){