From fb6f4ce704013d0f52c5032ef65d7b45505dfc98 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Wed, 29 Nov 1995 14:38:52 +0000 Subject: [PATCH] Changes for replacing default.dctsdr by all ascii files --- src/dbStatic/Makefile | 18 + src/dbStatic/Makefile.Unix | 47 + src/dbStatic/Makefile.Vx | 36 + src/dbStatic/dbAsciiLex.l | 70 + src/dbStatic/dbAsciiRoutines.c | 822 +++++++++ src/dbStatic/dbAsciiTest.c | 56 + src/dbStatic/dbAsciiToMenuH.c | 79 + src/dbStatic/dbAsciiToRecordtypeH.c | 207 +++ src/dbStatic/dbAsciiYacc.y | 199 +++ src/dbStatic/dbPvdLib.c | 243 +++ src/dbStatic/dbStaticLib.c | 2580 +++++++++++++++++++++++++++ src/dbStatic/dbStaticNoRun.c | 266 +++ src/dbStatic/dbStaticPvt.h | 64 + src/dbStatic/dbStaticRun.c | 591 ++++++ src/dev/devAiSoft.c | 4 +- src/dev/devAiSoftRaw.c | 2 +- src/dev/devAiTestAsyn.c | 4 +- src/dev/devBiSoft.c | 4 +- src/dev/devBiSoftRaw.c | 2 +- src/dev/devBiTestAsyn.c | 4 +- src/dev/devEventSoft.c | 6 +- src/dev/devHistogramSoft.c | 2 +- src/dev/devHistogramTestAsyn.c | 2 +- src/dev/devLiSoft.c | 4 +- src/dev/devMbbiDirectSoft.c | 4 +- src/dev/devMbbiDirectSoftRaw.c | 2 +- src/dev/devMbbiSoft.c | 4 +- src/dev/devMbbiSoftRaw.c | 2 +- src/dev/devMbbiTestAsyn.c | 4 +- src/dev/devMpc.c | 4 + src/dev/devMz8310.c | 1 - src/dev/devSiSoft.c | 7 +- src/dev/devSiTestAsyn.c | 6 +- src/dev/devSysmon.c | 4 + src/dev/devTimerMz8310.c | 1 - src/dev/devVxiTDM.c | 1 - src/libCom/errInc.c | 3 - src/libCom/freeList/freeListLib.c | 42 +- src/libCom/freeListLib.c | 42 +- src/libCom/gpHash/gpHashLib.c | 101 +- src/libCom/gpHashLib.c | 101 +- 41 files changed, 5522 insertions(+), 119 deletions(-) create mode 100644 src/dbStatic/Makefile create mode 100755 src/dbStatic/Makefile.Unix create mode 100644 src/dbStatic/Makefile.Vx create mode 100644 src/dbStatic/dbAsciiLex.l create mode 100644 src/dbStatic/dbAsciiRoutines.c create mode 100644 src/dbStatic/dbAsciiTest.c create mode 100644 src/dbStatic/dbAsciiToMenuH.c create mode 100644 src/dbStatic/dbAsciiToRecordtypeH.c create mode 100644 src/dbStatic/dbAsciiYacc.y create mode 100644 src/dbStatic/dbPvdLib.c create mode 100644 src/dbStatic/dbStaticLib.c create mode 100644 src/dbStatic/dbStaticNoRun.c create mode 100644 src/dbStatic/dbStaticPvt.h create mode 100644 src/dbStatic/dbStaticRun.c diff --git a/src/dbStatic/Makefile b/src/dbStatic/Makefile new file mode 100644 index 000000000..5ab776fa9 --- /dev/null +++ b/src/dbStatic/Makefile @@ -0,0 +1,18 @@ +# +# $Id$ +# +# Base: Lowest Level Directroy Makefile +# by Janet Anderson +# +# $Log$ +# Revision 1.1 1994/09/07 19:26:01 jba +# New file +# +# + +EPICS=../../.. + +include $(EPICS)/config/CONFIG_BASE + +include $(EPICS)/config/RULES_ARCHS + diff --git a/src/dbStatic/Makefile.Unix b/src/dbStatic/Makefile.Unix new file mode 100755 index 000000000..e720333b3 --- /dev/null +++ b/src/dbStatic/Makefile.Unix @@ -0,0 +1,47 @@ +EPICS = ../../../.. +include Target.include +include $(EPICS)/config/CONFIG_BASE + +USR_LDLIBS = -lDb -lCom -lm + +#USR_CFLAGS = -v -g +#CC = $(PURIFYHOME)/purify $(C_$(CMPLR)) + +LEX = $(ELEX) +YACC = $(EYACC) + +DEPLIBS_BASE = $(EPICS_BASE_LIB) +DEPLIBS = ./libDb.a\ + $(DEPLIBS_BASE)/libCom.a + + +SRCS.c = \ + dbAsciiYacc.c \ + ../dbAsciiTest.c\ + ../dbPvdLib.c\ + ../dbStaticNoRun.c\ + ../dbStaticLib.c\ + ../dbAsciiToMenuH.c\ + ../dbAsciiToRecordtypeH.c + +OBJS = \ + dbAsciiTest.o\ + dbAsciiToMenuH.o\ + dbAsciiToRecordtypeH.o + +LIBOBJS = dbStaticLib.o dbAsciiYacc.o dbPvdLib.o dbStaticNoRun.o +LIBNAME = libDb.a + +PROD = \ + dbAsciiTest\ + dbAsciiToMenuH\ + dbAsciiToRecordtypeH + +include $(EPICS)/config/RULES.Unix + +# Extra rule since dbAsciiRoutines.c is included in dbAsciiYacc.c +dbAsciiYacc.o: dbAsciiLex.c ../dbAsciiRoutines.c + +clean:: + @$(RM) dbAsciiLex.c dbAsciiYacc.c + diff --git a/src/dbStatic/Makefile.Vx b/src/dbStatic/Makefile.Vx new file mode 100644 index 000000000..82ad32cf7 --- /dev/null +++ b/src/dbStatic/Makefile.Vx @@ -0,0 +1,36 @@ +EPICS = ../../../.. +include Target.include +include $(EPICS)/config/CONFIG_BASE + +LEX = $(ELEX) +YACC = $(EYACC) + +USR_CFLAGS = -ansi +VX_WARN_YES = -Wall -pedantic + +SRCS.c = \ + dbAsciiYacc.c \ + ../dbPvdLib.c\ + ../dbStaticRun.c\ + ../dbStaticLib.c + +OBJSdbLib = \ + dbAsciiYacc.o\ + dbPvdLib.o\ + dbStaticRun.o\ + dbStaticLib.o + +PROD = dbStaticLib + +include $(EPICS)/config/RULES.Vx + +# Extra rule since dbAsciiRoutines.c is included in dbAsciiYacc.c +dbAsciiYacc.o: dbAsciiLex.c ../dbAsciiRoutines.c + +clean:: + @$(RM) dbAsciiLex.c dbAsciiYacc.c + +dbStaticLib: $(OBJSdbLib) + $(RM) $@ + $(LINK.c) $@ $(OBJSdbLib) $(LDLIBS) + diff --git a/src/dbStatic/dbAsciiLex.l b/src/dbStatic/dbAsciiLex.l new file mode 100644 index 000000000..366a93c4b --- /dev/null +++ b/src/dbStatic/dbAsciiLex.l @@ -0,0 +1,70 @@ +name [a-zA-Z0-9_\-:\.\[\]<>;] +string [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\t] + +%{ +#undef YY_INPUT +#define YY_INPUT(b,r,ms) (r=(*dbAscii_yyinput)(b,ms)) + +static int yyreset(void) +{ + BEGIN INITIAL; + return(0); +} + +%} + +%% + +"include" {return(tokenINCLUDE);} +"path" {return(tokenPATH);} +"menu" {return(tokenMENU);} +"choice" {return(tokenCHOICE);} +"recordtype" {return(tokenRECORDTYPE);} +"field" {return(tokenFIELD);} +"device" {return(tokenDEVICE);} +"driver" {return(tokenDRIVER);} +"breaktable" {return(tokenBREAKTABLE);} +"record" {return(tokenRECORD);} + +[0-9]+ { /*integer number*/ + yylval.Str = (char *)malloc(strlen(yytext)+1); + strcpy(yylval.Str,yytext); + return(tokenSTRING); + } + +([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { /*real number*/ + yylval.Str = (char *)malloc(strlen(yytext)+1); + strcpy(yylval.Str,yytext); + return(tokenSTRING); +} + + +{name}+ { /*unquoted string*/ + yylval.Str = (char *)malloc(strlen(yytext)+1); + strcpy(yylval.Str,yytext); + return(tokenSTRING); +} + +\"{string}*\" { /*quoted string*/ + yylval.Str = (char *)malloc(strlen(yytext)+1); + strcpy(yylval.Str,yytext+1); + yylval.Str[strlen(yylval.Str)-1] = '\0'; + return(tokenSTRING); +} + +"{" { return(yytext[0]); } +"}" { return(yytext[0]); } +"(" { return(yytext[0]); } +")" { return(yytext[0]); } +"," { return(yytext[0]); } +#.* { ;} +[ \t\r] ; +\n { ;} +. { + char message[20]; + + sprintf(message,"invalid character '%c'",yytext[0]); + yyerror(message); + } + +%% diff --git a/src/dbStatic/dbAsciiRoutines.c b/src/dbStatic/dbAsciiRoutines.c new file mode 100644 index 000000000..3bc6cf377 --- /dev/null +++ b/src/dbStatic/dbAsciiRoutines.c @@ -0,0 +1,822 @@ +/* dbAsciiRoutines.c */ +/* Author: Marty Kraimer Date: 13JUL95*/ +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + +This software was developed under a United States Government license +described on the COPYRIGHT_UniversityOfChicago file included as part +of this distribution. +**********************************************************************/ +/* + * + * Modification Log: + * ----------------- + * .01 13JUL95 mrk Initial Implementation + */ + +/*The routines in this module are serially reusable NOT reentrant*/ + +#ifdef vxWorks +#include +#endif +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*private routines */ +static void yyerrorAbort(char *str); +static void allocTemp(void *pvoid); +static void *popFirstTemp(void); +static void *getLastTemp(void); +static int dbAscii_yyinput(char *buf,int max_size); +static void dbAsciiIncludePrint(FILE *fp); +static void dbAsciiPath(char *path); +static void dbAsciiIncludeNew(char *include_file); +static void dbAsciiMenuHead(char *name); +static void dbAsciiMenuChoice(char *name,char *value); +static void dbAsciiMenuBody(void); + +static void dbAsciiRecordtypeHead(char *name); +static void dbAsciiRecordtypeBody(void); +static void dbAsciiRecordtypeFieldHead(char *name,char *type); +static void dbAsciiRecordtypeFieldItem(char *name,char *value); + +static void dbAsciiDevice(char *recordtype,char *linktype, + char *dsetname,char *choicestring); +static void dbAsciiDriver(char *name); + +static void dbAsciiBreakHead(char *name); +static void dbAsciiBreakItem(char *value); +static void dbAsciiBreakBody(void); + +static void dbAsciiRecordHead(char *rectype,char*name); +static void dbAsciiRecordField(char *name,char *value); +static void dbAsciiRecordBody(void); + +/*private declarations*/ +static int firstTime = TRUE; +#define MY_BUFFER_SIZE 1024 +static char *my_buffer=NULL; +static char *my_buffer_ptr=NULL; +typedef struct inputFile{ + ELLNODE node; + char *path; + char *filename; + FILE *fp; + int line_num; +}inputFile; +static ELLLIST inputFileList; + +static inputFile *pinputFileNow = NULL; +static DBBASE *pdbbase = NULL; + +typedef struct tempListNode { + ELLNODE node; + void *item; +}tempListNode; + +static ELLLIST tempList; +static void *freeListPvt = NULL; +static int duplicate = FALSE; + +static void yyerrorAbort(char *str) +{ + yyerror(str); + free((void *)my_buffer); + exit(-1); +} + +static void allocTemp(void *pvoid) +{ + tempListNode *ptempListNode; + + ptempListNode = freeListCalloc(freeListPvt); + ptempListNode->item = pvoid; + ellAdd(&tempList,&ptempListNode->node); +} + +static void *popFirstTemp(void) +{ + tempListNode *ptempListNode; + void *ptemp; + + ptempListNode = (tempListNode *)ellFirst(&tempList); + ptemp = ptempListNode->item; + ellDelete(&tempList,(ELLNODE *)ptempListNode); + freeListFree(freeListPvt,ptempListNode); + return(ptemp); +} + +static void *getLastTemp(void) +{ + tempListNode *ptempListNode; + + ptempListNode = (tempListNode *)ellLast(&tempList); + return(ptempListNode->item); +} + +static long dbAsciiReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp) +{ + long status; + inputFile *pinputFile; + + my_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char)); + if(firstTime) { + ellInit(&inputFileList); + ellInit(&tempList); + freeListInitPvt(&freeListPvt,sizeof(tempListNode),5); + firstTime = FALSE; + } + pinputFile = (inputFile *)ellLast(&inputFileList); + while(pinputFile) { + fclose(pinputFile->fp); + free((void *)pinputFile->filename); + free((void *)pinputFile->path); + ellDelete(&inputFileList,(ELLNODE *)pinputFile); + free((void *)pinputFile); + pinputFile = (inputFile *)ellLast(&inputFileList); + } + pinputFile = dbCalloc(1,sizeof(inputFile)); + if(filename) { + pinputFile->filename = dbCalloc(strlen(filename)+1,sizeof(char)); + strcpy(pinputFile->filename,filename); + } + if(!fp) { + if(!filename || !(fp = fopen(filename,"r"))) { + errPrintf(0,__FILE__, __LINE__, + "dbAsciiRead opening file %s\n",filename); + free((void *)pinputFile); + free((void *)my_buffer); + return(-1); + } + } + pinputFile->fp = fp; + pinputFile->line_num = 0; + pinputFileNow = pinputFile; + my_buffer[0] = '\0'; + my_buffer_ptr = my_buffer; + if(*ppdbbase) { + pdbbase = *ppdbbase; + } else { + pdbbase = dbAllocBase(); + *ppdbbase = pdbbase; + } + ellAdd(&inputFileList,&pinputFile->node); + status = pvt_yy_parse(); + if(status) { + fprintf(stderr,"db_parse returned %d\n",status); + } + freeListCleanup(freeListPvt); + free((void *)my_buffer); + firstTime = TRUE; + return(0); +} + +long dbAsciiRead(DBBASE **ppdbbase,const char *filename) +{return (dbAsciiReadCOM(ppdbbase,filename,0));} + +long dbAsciiReadFP(DBBASE **ppdbbase,FILE *fp) +{return (dbAsciiReadCOM(ppdbbase,0,fp));} + +static int dbAscii_yyinput(char *buf, int max_size) +{ + int l,n; + + if(*my_buffer_ptr==0) { + while(fgets(my_buffer,MY_BUFFER_SIZE,pinputFileNow->fp)==NULL) { + + if(fclose(pinputFileNow->fp)) + errPrintf(0,__FILE__, __LINE__, + "Closing file %s\n",pinputFileNow->filename); + free((void *)pinputFileNow->filename); + free((void *)pinputFileNow->path); + ellDelete(&inputFileList,(ELLNODE *)pinputFileNow); + free((void *)pinputFileNow); + pinputFileNow = (inputFile *)ellLast(&inputFileList); + if(!pinputFileNow) return(0); + } + if(dbDebug) fprintf(stderr,"%s",my_buffer); + pinputFileNow->line_num++; + my_buffer_ptr = &my_buffer[0]; + } + l = strlen(my_buffer_ptr); + n = (l<=max_size ? l : max_size); + memcpy(buf,my_buffer_ptr,n); + my_buffer_ptr += n; + return(n); +} + +static void dbAsciiIncludePrint(FILE *fp) +{ + inputFile *pinputFile = pinputFileNow; + + fprintf(fp,"input line: %s",my_buffer); + while(pinputFile) { + if(pinputFile->filename) { + fprintf(fp," in file: "); + if(pinputFile->path) + fprintf(fp," path \"%s\"",pinputFile->path); + fprintf(fp,"%s",pinputFile->filename); + } else { + fprintf(fp," stdin:"); + if(pinputFile->path) + fprintf(fp," path \"%s\"",pinputFile->path); + } + fprintf(fp," line %d\n",pinputFile->line_num); + pinputFile = (inputFile *)ellPrevious(&pinputFile->node); + } + fprintf(fp,"\n"); + return; +} + +static void dbAsciiPath(char *path) +{ + pinputFileNow->path = path; +} + +static void dbAsciiIncludeNew(char *filename) +{ + inputFile *newfile; + inputFile *pinputFile; + inputFile *pinputFileFirst; + FILE *fp; + char *currentPath; + int lenPathAndFilename = 0; + int lenstr; + + newfile = dbCalloc(1,sizeof(inputFile)); + newfile->filename = dbCalloc(strlen(filename)+1,sizeof(char)); + strcpy(newfile->filename,filename); + /*search backward for first path starting with / */ + pinputFile = (inputFile *)ellLast(&inputFileList); + while(pinputFile) { + if(pinputFile->path) { + if(pinputFile->path[0]=='/') break; + } + pinputFile = (inputFile *)ellPrevious(&pinputFile->node); + } + if(!pinputFile) pinputFile=(inputFile *)ellFirst(&inputFileList); + pinputFileFirst = pinputFile; + while(pinputFile) { + if(pinputFile->path) { + lenstr = strlen(pinputFile->path); + lenPathAndFilename += lenstr; + if(pinputFile->path[lenstr-1] != '/') lenPathAndFilename++; + } + pinputFile = (inputFile *)ellNext(&pinputFile->node); + } + lenPathAndFilename += strlen(filename) + 1; + currentPath = dbCalloc(lenPathAndFilename,sizeof(char)); + pinputFile = pinputFileFirst; + while(pinputFile) { + if(pinputFile->path) { + strcat(currentPath,pinputFile->path); + lenstr = strlen(pinputFile->path); + if(pinputFile->path[lenstr-1] != '/') strcat(currentPath,"/"); + } + pinputFile = (inputFile *)ellNext(&pinputFile->node); + } + strcat(currentPath,filename); + fp = fopen(currentPath,"r"); + if(!fp) { + errPrintf(0,__FILE__, __LINE__, + "dbAsciiIncludeNew opening file %s\n",currentPath); + yyerror(NULL); + free((void *)filename); + free((void *)newfile); + return; + } + free((void *)currentPath); + free((void *)filename); + newfile->fp = fp; + ellAdd(&inputFileList,&newfile->node); + pinputFileNow = newfile; +} + +static void dbAsciiMenuHead(char *name) +{ + dbMenu *pdbMenu; + GPHENTRY *pgphentry; + + pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->menuList); + if(pgphentry) { + yyerror("Duplicate menu ignored"); + duplicate = TRUE; + } + pdbMenu = dbCalloc(1,sizeof(dbMenu)); + pdbMenu->name = name; + if(ellCount(&tempList)) yyerrorAbort("dbAsciiMenuHead: tempList not empty"); + allocTemp(pdbMenu); +} + +static void dbAsciiMenuChoice(char *name,char *value) +{ + if(duplicate) { + free((void *)name); + free((void *)value); + return; + } + allocTemp(name); + allocTemp(value); +} + +static void dbAsciiMenuBody(void) +{ + dbMenu *pnewMenu; + dbMenu *pMenu; + int nChoice; + int i; + GPHENTRY *pgphentry; + + if(duplicate) { + duplicate = FALSE; + return; + } + pnewMenu = (dbMenu *)popFirstTemp(); + pnewMenu->nChoice = nChoice = ellCount(&tempList)/2; + pnewMenu->papChoiceName = dbCalloc(pnewMenu->nChoice,sizeof(char *)); + pnewMenu->papChoiceValue = dbCalloc(pnewMenu->nChoice,sizeof(char *)); + for(i=0; ipapChoiceName[i] = (char *)popFirstTemp(); + pnewMenu->papChoiceValue[i] = (char *)popFirstTemp(); + } + if(ellCount(&tempList)) yyerrorAbort("dbAsciiMenuBody: tempList not empty"); + /* Add menu in sorted order */ + pMenu = (dbMenu *)ellFirst(&pdbbase->menuList); + while(pMenu && strcmp(pMenu->name,pnewMenu->name) >0 ) + pMenu = (dbMenu *)ellNext(&pMenu->node); + if(pMenu) + ellInsert(&pdbbase->menuList,ellPrevious(&pMenu->node),&pnewMenu->node); + else + ellAdd(&pdbbase->menuList,&pnewMenu->node); + pgphentry = gphAdd(pdbbase->pgpHash,pnewMenu->name,&pdbbase->menuList); + if(!pgphentry) { + yyerrorAbort("gphAdd failed"); + } else { + pgphentry->userPvt = pnewMenu; + } +} + +static void dbAsciiRecordtypeHead(char *name) +{ + dbRecDes *pdbRecDes; + GPHENTRY *pgphentry; + + pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->recDesList); + if(pgphentry) { + yyerror("Duplicate recordtype ignored"); + duplicate = TRUE; + } + pdbRecDes = dbCalloc(1,sizeof(dbRecDes)); + pdbRecDes->name = name; + if(ellCount(&tempList)) + yyerrorAbort("dbAsciiRecordtypeHead tempList not empty"); + allocTemp(pdbRecDes); +} + +static void dbAsciiRecordtypeFieldHead(char *name,char *type) +{ + dbFldDes *pdbFldDes; + int i; + + if(duplicate) { + free((void *)name); + free((void *)type); + return; + } + pdbFldDes = dbCalloc(1,sizeof(dbFldDes)); + allocTemp(pdbFldDes); + pdbFldDes->name = name; + for(i=0; ifield_type = pamapdbfType[i].value; + free((void *)type); + return; + } + } + free((void *)type); + yyerrorAbort("Illegal Field Type"); +} + +static void dbAsciiRecordtypeFieldItem(char *name,char *value) +{ + dbFldDes *pdbFldDes; + + if(duplicate) { + free((void *)name); + free((void *)value); + return; + } + pdbFldDes = (dbFldDes *)getLastTemp(); + if(strcmp(name,"asl")==0) { + if(strcmp(value,"ASL0")==0) { + pdbFldDes->as_level = ASL0; + } else if(strcmp(value,"ASL1")==0) { + pdbFldDes->as_level = ASL1; + } else { + yyerror("Illegal Access Security value: Must be ASL0 or ASL1"); + } + free((void *)name); + free((void *)value); + return; + } + if(strcmp(name,"initial")==0) { + pdbFldDes->initial = value; + free((void *)name); + return; + } + if(strcmp(name,"promptgroup")==0) { + int i; + for(i=0; ipromptgroup = pamapguiGroup[i].value; + free((void *)name); + free((void *)value); + return; + } + } + yyerror("Illegal promptgroup. See guigroup.h for legal values"); + return; + } + if(strcmp(name,"prompt")==0) { + pdbFldDes->prompt = value; + free((void *)name); + return; + } + if(strcmp(name,"special")==0) { + int i; + for(i=0; ispecial = pamapspcType[i].value; + free((void *)name); + free((void *)value); + return; + } + } + if(sscanf(value,"%hd",&pdbFldDes->special)==1) { + free((void *)name); + free((void *)value); + return; + } + yyerror("Illegal promptgroup. See guigroup.h for legal values"); + return; + } + if(strcmp(name,"pp")==0) { + if((strcmp(value,"YES")==0) || (strcmp(value,"TRUE")==0)) { + pdbFldDes->process_passive = TRUE; + } else if((strcmp(value,"NO")==0) || (strcmp(value,"FALSE")==0)) { + pdbFldDes->process_passive = FALSE; + } else { + yyerror("Illegal value. Must be NO or YES"); + } + free((void *)name); + free((void *)value); + return; + } + if(strcmp(name,"interest")==0) { + if(sscanf(value,"%hd",&pdbFldDes->interest)!=1) + yyerror("Illegal value. Must be integer"); + free((void *)name); + free((void *)value); + return; + } + if(strcmp(name,"base")==0) { + if(strcmp(value,"DECIMAL")==0) { + pdbFldDes->base = CT_DECIMAL; + } else if(strcmp(value,"HEX")==0) { + pdbFldDes->base = CT_HEX; + } else { + yyerror("Illegal value. Must be CT_DECIMAL or CT_HEX"); + } + free((void *)name); + free((void *)value); + return; + } + if(strcmp(name,"size")==0) { + if(sscanf(value,"%hd",&pdbFldDes->size)!=1) + yyerror("Illegal value. Must be integer"); + free((void *)name); + free((void *)value); + return; + } + if(strcmp(name,"extra")==0) { + pdbFldDes->extra = value; + free((void *)name); + return; + } + if(strcmp(name,"menu")==0) { + pdbFldDes->ftPvt = (dbMenu *)dbFindMenu(pdbbase,value); + if(!pdbbase->ignoreMissingMenus && !pdbFldDes->ftPvt) + yyerrorAbort("menu not found"); + free((void *)name); + free((void *)value); + return; + } +} + +static void dbAsciiRecordtypeBody(void) +{ + dbRecDes *pdbRecDes; + dbFldDes *pdbFldDes; + int i,j,ilink; + GPHENTRY *pgphentry; + int no_fields,no_prompt,no_links; + dbfType field_type; + char *psortFldNameTemp; + short psortFldIndTemp; + char **papsortFldName; + short *sortFldInd; + + if(duplicate) { + duplicate = FALSE; + return; + } + pdbRecDes= (dbRecDes *)popFirstTemp(); + pdbRecDes->no_fields = no_fields = ellCount(&tempList); + pdbRecDes->papFldDes = dbCalloc(no_fields,sizeof(dbFldDes *)); + pdbRecDes->papsortFldName = dbCalloc(no_fields,sizeof(char *)); + pdbRecDes->sortFldInd = dbCalloc(no_fields,sizeof(short)); + no_prompt = no_links = 0; + for(i=0; ipdbRecDes = pdbRecDes; + pdbFldDes->indRecDes = i; + pdbRecDes->papFldDes[i] = pdbFldDes; + if(pdbFldDes->promptgroup) no_prompt++; + field_type = pdbFldDes->field_type; + if((field_type>=DBF_INLINK) && (field_type<=DBF_FWDLINK))no_links++; + if((field_type==DBF_STRING) && (pdbFldDes->size==0)) + fprintf(stderr,"recordtype(%s).%s size not specified\n", + pdbRecDes->name,pdbFldDes->name); + if((field_type==DBF_NOACCESS) && (pdbFldDes->extra==0)) + fprintf(stderr,"recordtype(%s).%s extra not specified\n", + pdbRecDes->name,pdbFldDes->name); + } + if(ellCount(&tempList)) yyerrorAbort("dbAsciiMenuBody: tempList not empty"); + pdbRecDes->no_prompt = no_prompt; + pdbRecDes->no_links = no_links; + pdbRecDes->link_ind = dbCalloc(no_prompt,sizeof(short)); + ilink = 0; + for(i=0; ipapFldDes[i]; + field_type = pdbFldDes->field_type; + if((field_type>=DBF_INLINK) && (field_type<=DBF_FWDLINK)) + pdbRecDes->link_ind[ilink++] = i; + if(strcmp(pdbFldDes->name,"VAL")==0) { + pdbRecDes->pvalFldDes = pdbRecDes->papFldDes[i]; + pdbRecDes->indvalFlddes = i; + } + pdbRecDes->papsortFldName[i] = pdbFldDes->name; + pdbRecDes->sortFldInd[i] = i; + } + /*Now sort fields. Sorry dumb sort algorithm */ + papsortFldName = pdbRecDes->papsortFldName; + sortFldInd = pdbRecDes->sortFldInd; + for(i=0; irecList); + ellInit(&pdbRecDes->devList); + pgphentry = gphAdd(pdbbase->pgpHash,pdbRecDes->name,&pdbbase->recDesList); + if(!pgphentry) { + yyerrorAbort("gphAdd failed"); + } else { + pgphentry->userPvt = pdbRecDes; + } + ellAdd(&pdbbase->recDesList,&pdbRecDes->node); + dbGetRecordtypeSizeOffset(pdbRecDes); +} + +static void dbAsciiDevice(char *recordtype,char *linktype, + char *dsetname,char *choicestring) +{ + devSup *pdevSup; + dbRecDes *pdbRecDes; + GPHENTRY *pgphentry; + int i,link_type; + + pgphentry = gphFind(pdbbase->pgpHash,recordtype,&pdbbase->recDesList); + if(!pgphentry) { + yyerror(" record type not found"); + return; + } + free(recordtype); + link_type=-1; + for(i=0; iuserPvt; + pgphentry = gphFind(pdbbase->pgpHash,choicestring,&pdbRecDes->devList); + if(pgphentry) { + yyerror("Duplicate Device Support ignored"); + free((void *)dsetname); + free((void *)choicestring); + return; + } + pdevSup = dbCalloc(1,sizeof(devSup)); + pdevSup->name = dsetname; + pdevSup->choice = choicestring; + pdevSup->link_type = link_type; + pgphentry = gphAdd(pdbbase->pgpHash,choicestring,&pdbRecDes->devList); + if(!pgphentry) { + yyerror("gphAdd failed"); + } else { + pgphentry->userPvt = pdevSup; + } + ellAdd(&pdbRecDes->devList,&pdevSup->node); +} + +static void dbAsciiDriver(char *name) +{ + drvSup *pdrvSup; + GPHENTRY *pgphentry; + + pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->drvList); + if(pgphentry) { + yyerror("Duplicate driver ignored"); + return; + } + pdrvSup = dbCalloc(1,sizeof(drvSup)); + pdrvSup->name = name; + pgphentry = gphAdd(pdbbase->pgpHash,name,&pdbbase->drvList); + if(!pgphentry) { + yyerrorAbort("gphAdd failed"); + } + pgphentry->userPvt = pdrvSup; + ellAdd(&pdbbase->drvList,&pdrvSup->node); +} + +static void dbAsciiBreakHead(char *name) +{ + brkTable *pbrkTable; + GPHENTRY *pgphentry; + + pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->bptList); + if(pgphentry) { + yyerror("Duplicate breakpoint table ignored"); + duplicate = TRUE; + } + pbrkTable = dbCalloc(1,sizeof(brkTable)); + pbrkTable->name = name; + if(ellCount(&tempList)) yyerrorAbort("dbAsciiBreakHead:tempList not empty"); allocTemp(pbrkTable); +} + +static void dbAsciiBreakItem(char *value) +{ + if(duplicate) { + free((void *)value); + return; + } + allocTemp(value); +} + +static void dbAsciiBreakBody(void) +{ + brkTable *pnewbrkTable; + brkTable *pbrkTable; + int number; + int i,choice; + GPHENTRY *pgphentry; + + if(duplicate) { + duplicate = FALSE; + return; + } + pnewbrkTable = (brkTable *)popFirstTemp(); + pnewbrkTable->number = number = ellCount(&tempList)/2; + if(number*2 != ellCount(&tempList)) + yyerrorAbort("dbAsciiBreakBody: Odd number of values"); + pnewbrkTable->papBrkInt = dbCalloc(number,sizeof(brkInt)); + for(i=0; ipapBrkInt[i] = dbCalloc(1,sizeof(brkInt)); + pnewbrkTable->papBrkInt[i]->raw = raw; + pnewbrkTable->papBrkInt[i]->eng = eng; + } + /* Compute slopes */ + for(i=0; ipapBrkInt[i]->slope = + (pnewbrkTable->papBrkInt[i+1]->eng - pnewbrkTable->papBrkInt[i]->eng)/ + (pnewbrkTable->papBrkInt[i+1]->raw - pnewbrkTable->papBrkInt[i]->raw); + } + /* Add brkTable in sorted order */ + pbrkTable = (brkTable *)ellFirst(&pdbbase->bptList); + while(pbrkTable) { + choice = strcmp(pbrkTable->name,pnewbrkTable->name); + if(choice==0) { + ellInsert(&pdbbase->bptList,ellPrevious((ELLNODE *)pbrkTable), + (ELLNODE *)pnewbrkTable); + gphDelete(pdbbase->pgpHash,pbrkTable->name,&pdbbase->bptList); + ellDelete(&pdbbase->bptList,(ELLNODE *)pbrkTable); + break; + } else if(choice>0) { + ellInsert(&pdbbase->bptList,ellPrevious((ELLNODE *)pbrkTable), + (ELLNODE *)pnewbrkTable); + break; + } + pbrkTable = (brkTable *)ellNext(&pbrkTable->node); + } + pgphentry = gphAdd(pdbbase->pgpHash,pnewbrkTable->name,&pdbbase->bptList); + if(!pgphentry) { + yyerrorAbort("gphAdd failed"); + } else { + pgphentry->userPvt = pnewbrkTable; + } + if(!pbrkTable) ellAdd(&pdbbase->bptList,&pnewbrkTable->node); +} + +static void dbAsciiRecordHead(char *rectype,char *name) +{ + DBENTRY *pdbentry; + long status; + + pdbentry = dbAllocEntry(pdbbase); + if(ellCount(&tempList)) + yyerrorAbort("dbAsciiRecordHead: tempList not empty"); + allocTemp(pdbentry); + status = dbFindRecdes(pdbentry,rectype); + if(status) { + errMessage(status,""); + yyerrorAbort(NULL); + return; + } + /*Duplicate records ok. Thus dont check return status.*/ + dbCreateRecord(pdbentry,name); +} + +static void dbAsciiRecordField(char *name,char *value) +{ + DBENTRY *pdbentry; + tempListNode *ptempListNode; + long status; + + ptempListNode = (tempListNode *)ellFirst(&tempList); + pdbentry = ptempListNode->item; + status = dbFindField(pdbentry,name); + if(status) { + errMessage(status,""); + yyerror(NULL); + return; + } + status = dbPutString(pdbentry,value); + if(status) { + errMessage(status,""); + yyerror(NULL); + return; + } +} + +static void dbAsciiRecordBody(void) +{ + DBENTRY *pdbentry; + + pdbentry = (DBENTRY *)popFirstTemp(); + if(ellCount(&tempList)) + yyerrorAbort("dbAsciiRecordBody: tempList not empty"); + dbFreeEntry(pdbentry); +} diff --git a/src/dbStatic/dbAsciiTest.c b/src/dbStatic/dbAsciiTest.c new file mode 100644 index 000000000..87a381e77 --- /dev/null +++ b/src/dbStatic/dbAsciiTest.c @@ -0,0 +1,56 @@ +/* asciiTest.c */ +/* Author: Marty Kraimer Date: 13JUL95 */ +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + +This software was developed under a United States Government license +described on the COPYRIGHT_UniversityOfChicago file included as part +of this distribution. +**********************************************************************/ + +/* Modification Log: + * ----------------- + * .01 13JUL95 mrk Initial Implementation +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DBBASE *pdbbase = NULL; + +int main(int argc,char **argv) +{ + long status; + int i; + + if(argc<2) { + printf("usage: dbAsciiTest file1.ascii fi;e2.ascii ...\n"); + exit(0); + } + for(i=1; ipgpHash); + dbDumpMenu(pdbbase,NULL); + dbDumpRecords(pdbbase,NULL,0); +*/ + dbFreeBase(pdbbase); + return(0); +} diff --git a/src/dbStatic/dbAsciiToMenuH.c b/src/dbStatic/dbAsciiToMenuH.c new file mode 100644 index 000000000..a6985d221 --- /dev/null +++ b/src/dbStatic/dbAsciiToMenuH.c @@ -0,0 +1,79 @@ +/* dbAsciiToMenuH.c */ +/* Author: Marty Kraimer Date: 11Sep95 */ +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + +This software was developed under a United States Government license +described on the COPYRIGHT_UniversityOfChicago file included as part +of this distribution. +**********************************************************************/ + +/* Modification Log: + * ----------------- + * .01 11Sep95 mrk Initial Implementation +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DBBASE *pdbbase = NULL; + +int main(int argc,char **argv) +{ + long status; + dbMenu *pdbMenu; + char *outFilename; + char *pext; + FILE *outFile; + int i; + + if(argc!=2) { + fprintf(stderr,"usage: dbAsciiToMenuH file.ascii\n"); + exit(-1); + } + outFilename = dbCalloc(1,strlen(argv[1])+1); + strcpy(outFilename,argv[1]); + pext = strstr(outFilename,".ascii"); + if(!pext) { + fprintf(stderr,"Input file MUST have .ascii extension\n"); + exit(-1); + } + strcpy(pext,".h"); + outFile = fopen(outFilename,"w"); + if(!outFile) { + errPrintf(0,__FILE__,__LINE__,"Error opening %s\n",outFilename); + exit(-1); + } + pdbbase = dbAllocBase(); + pdbbase->ignoreMissingMenus = TRUE; + status = dbAsciiRead(&pdbbase,argv[1]); + if(status) { + epicsPrintf("Terminal error For input file %s\n",argv[1]); + exit(-1); + } + pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList); + while(pdbMenu) { + fprintf(outFile,"#ifndef INC%sH\n",pdbMenu->name); + fprintf(outFile,"#define INC%sH\n",pdbMenu->name); + fprintf(outFile,"typedef enum {\n"); + for(i=0; inChoice; i++) { + fprintf(outFile,"\t%s,\n",pdbMenu->papChoiceName[i]); + } + fprintf(outFile,"}%s;\n",pdbMenu->name); + fprintf(outFile,"#endif /*INC%sH*/\n",pdbMenu->name); + pdbMenu = (dbMenu *)ellNext(&pdbMenu->node); + } + fclose(outFile); + free((void *)outFilename); + return(0); +} diff --git a/src/dbStatic/dbAsciiToRecordtypeH.c b/src/dbStatic/dbAsciiToRecordtypeH.c new file mode 100644 index 000000000..fda4f21c4 --- /dev/null +++ b/src/dbStatic/dbAsciiToRecordtypeH.c @@ -0,0 +1,207 @@ +/* dbAsciiToRecordtypeH.c */ +/* Author: Marty Kraimer Date: 11Sep95 */ +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + +This software was developed under a United States Government license +described on the COPYRIGHT_UniversityOfChicago file included as part +of this distribution. +**********************************************************************/ + +/* Modification Log: + * ----------------- + * .01 11Sep95 mrk Initial Implementation +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DBBASE *pdbbase = NULL; + +int main(int argc,char **argv) +{ + long status; + char *outFilename; + char *pext; + FILE *outFile; + int i; + dbMenu *pdbMenu; + dbRecDes *pdbRecDes; + dbFldDes *pdbFldDes; + int isdbCommonRecord = FALSE; + + if(argc!=2) { + fprintf(stderr,"usage: dbAsciiToMenuH file.ascii\n"); + exit(-1); + } + outFilename = dbCalloc(1,strlen(argv[1])+1); + strcpy(outFilename,argv[1]); + pext = strstr(outFilename,".ascii"); + if(!pext) { + fprintf(stderr,"Input file MUST have .ascii extension\n"); + exit(-1); + } + strcpy(pext,".h"); + if(strcmp(outFilename,"dbCommonRecord.h")==0) { + strcpy(outFilename,"dbCommon.h"); + isdbCommonRecord = TRUE; + } + outFile = fopen(outFilename,"w"); + if(!outFile) { + errPrintf(0,__FILE__,__LINE__,"Error opening %s\n",outFilename); + exit(-1); + } + pdbbase = dbAllocBase(); + pdbbase->ignoreMissingMenus = TRUE; + status = dbAsciiRead(&pdbbase,argv[1]); + if(status) { + epicsPrintf("Terminal error For input file %s\n",argv[1]); + exit(-1); + } + fprintf(outFile,"#include \n"); + fprintf(outFile,"#include \n"); + fprintf(outFile,"#include \"ellLib.h\"\n"); + fprintf(outFile,"#include \"fast_lock.h\"\n"); + fprintf(outFile,"#include \"link.h\"\n"); + fprintf(outFile,"#include \"tsDefs.h\"\n"); + pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList); + while(pdbMenu) { + fprintf(outFile,"\n#ifndef INC%sH\n",pdbMenu->name); + fprintf(outFile,"#define INC%sH\n",pdbMenu->name); + fprintf(outFile,"typedef enum {\n"); + for(i=0; inChoice; i++) { + fprintf(outFile,"\t%s,\n",pdbMenu->papChoiceName[i]); + } + fprintf(outFile,"}%s;\n",pdbMenu->name); + fprintf(outFile,"#endif /*INC%sH*/\n",pdbMenu->name); + pdbMenu = (dbMenu *)ellNext(&pdbMenu->node); + } + pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); + while(pdbRecDes) { + fprintf(outFile,"#ifndef INC%sH\n",pdbRecDes->name); + fprintf(outFile,"#define INC%sH\n",pdbRecDes->name); + fprintf(outFile,"typedef struct %s",pdbRecDes->name); + if(!isdbCommonRecord) fprintf(outFile,"Record"); + fprintf(outFile," {\n"); + for(i=0; ino_fields; i++) { + char name[256]; + int j; + + pdbFldDes = pdbRecDes->papFldDes[i]; + for(j=0; j< (int)strlen(pdbFldDes->name); j++) + name[j] = tolower(pdbFldDes->name[j]); + name[strlen(pdbFldDes->name)] = 0; + switch(pdbFldDes->field_type) { + case DBF_STRING : + fprintf(outFile,"\tchar\t\t%s[%d]; /*%s*/\n", + name,pdbFldDes->size,pdbFldDes->prompt); + break; + case DBF_CHAR : + fprintf(outFile,"\tchar\t\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_UCHAR : + fprintf(outFile,"\tunsigned char\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_SHORT : + fprintf(outFile,"\tshort\t\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_USHORT : + fprintf(outFile,"\tunsigned short\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_LONG : + fprintf(outFile,"\tlong\t\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_ULONG : + fprintf(outFile,"\tunsigned long\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_FLOAT : + fprintf(outFile,"\tfloat\t\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_DOUBLE : + fprintf(outFile,"\tdouble\t\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_ENUM : + case DBF_MENU : + case DBF_DEVICE : + fprintf(outFile,"\tunsigned short\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_INLINK : + case DBF_OUTLINK : + case DBF_FWDLINK : + fprintf(outFile,"\tDBLINK\t\t%s;\t/*%s*/\n", + name,pdbFldDes->prompt); + break; + case DBF_NOACCESS: + fprintf(outFile,"\t%s;\t/*%s*/\n", + pdbFldDes->extra,pdbFldDes->prompt); + break; + default: + fprintf(outFile,"ILLEGAL FIELD TYPE\n"); + } + } + fprintf(outFile,"} %s",pdbRecDes->name); + if(!isdbCommonRecord) fprintf(outFile,"Record"); + fprintf(outFile,";\n"); + if(!isdbCommonRecord) { + for(i=0; ino_fields; i++) { + pdbFldDes = pdbRecDes->papFldDes[i]; + fprintf(outFile,"#define %sRecord%s\t%d\n", + pdbRecDes->name,pdbFldDes->name,pdbFldDes->indRecDes); + } + } + fprintf(outFile,"#endif /*INC%sH*/\n",pdbRecDes->name); + pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node); + if(pdbRecDes) fprintf(outFile,"\n"); + } + if(!isdbCommonRecord) { + fprintf(outFile,"#ifdef GEN_SIZE_OFFSET\n"); + pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); + while(pdbRecDes) { + fprintf(outFile,"int %sRecordSizeOffset(dbRecDes *pdbRecDes)\n{\n", + pdbRecDes->name); + fprintf(outFile," %sRecord *prec = 0;\n",pdbRecDes->name); + for(i=0; ino_fields; i++) { + char name[256]; + int j; + + pdbFldDes = pdbRecDes->papFldDes[i]; + for(j=0; j< (int)strlen(pdbFldDes->name); j++) + name[j] = tolower(pdbFldDes->name[j]); + name[strlen(pdbFldDes->name)] = 0; + fprintf(outFile, + " pdbRecDes->papFldDes[%d]->size=sizeof(prec->%s);\n", + i,name); + fprintf(outFile," pdbRecDes->papFldDes[%d]->offset=",i); + fprintf(outFile, + "(short)((char *)&prec->%s - (char *)prec);\n",name); + } + fprintf(outFile," pdbRecDes->rec_size = sizeof(*prec);\n"); + fprintf(outFile," return(0);\n"); + fprintf(outFile,"}\n"); + pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node); + } + fprintf(outFile,"#endif /*GEN_SIZE_OFFSET*/\n"); + } + fclose(outFile); + free((void *)outFilename); + return(0); +} diff --git a/src/dbStatic/dbAsciiYacc.y b/src/dbStatic/dbAsciiYacc.y new file mode 100644 index 000000000..f8ed5ef57 --- /dev/null +++ b/src/dbStatic/dbAsciiYacc.y @@ -0,0 +1,199 @@ +%{ +static int yyerror(); +static int yy_start; +static long pvt_yy_parse(void); +static int yyFailed = 0; +#include "dbAsciiRoutines.c" +static char *menuString = "menu"; +%} + +%start database + +%token tokenINCLUDE tokenPATH +%token tokenMENU tokenCHOICE tokenRECORDTYPE tokenFIELD +%token tokenDEVICE tokenDRIVER tokenBREAKTABLE +%token tokenRECORD +%token tokenSTRING + +%union +{ + char *Str; +} + +%% + +database: database database_item | database_item; + +database_item: include + | path + | tokenMENU menu_head menu_body + | tokenRECORDTYPE recordtype_head recordtype_body + | device + | driver + | tokenBREAKTABLE break_head break_body + | tokenRECORD record_head record_body + ; + +include: tokenINCLUDE tokenSTRING +{ + if(dbDebug>2) printf("include : %s\n",$2); + dbAsciiIncludeNew($2); +}; + +path: tokenPATH tokenSTRING +{ + if(dbDebug>2) printf("path : %s\n",$2); + dbAsciiPath($2); +}; + +menu_head: '(' tokenSTRING ')' +{ + if(dbDebug>2) printf("menu_head %s\n",$2); + dbAsciiMenuHead($2); +}; + +menu_body: '{' choice_list '}' +{ + if(dbDebug>2) printf("menu_body\n"); + dbAsciiMenuBody(); +} + | include ; + +choice_list: choice_list choice | choice; + +choice: tokenCHOICE '(' tokenSTRING ',' tokenSTRING ')' +{ + if(dbDebug>2) printf("choice %s %s\n",$3,$5); + dbAsciiMenuChoice($3,$5); +} ; + +recordtype_head: '(' tokenSTRING ')' +{ + if(dbDebug>2) printf("recordtype_head %s\n",$2); + dbAsciiRecordtypeHead($2); +}; + +recordtype_body: '{' recordtype_field_list '}' +{ + if(dbDebug>2) printf("recordtype_body\n"); + dbAsciiRecordtypeBody(); +}; + +recordtype_field_list: recordtype_field_list recordtype_field + | recordtype_field; + +recordtype_field: tokenFIELD recordtype_field_head recordtype_field_body + | include ; + +recordtype_field_head: '(' tokenSTRING ',' tokenSTRING ')' +{ + if(dbDebug>2) printf("recordtype_field_head %s %s\n",$2,$4); + dbAsciiRecordtypeFieldHead($2,$4); +}; + +recordtype_field_body: '{' recordtype_field_item_list '}' ; + +recordtype_field_item_list: recordtype_field_item_list recordtype_field_item + | recordtype_field_item; + +recordtype_field_item: tokenSTRING '(' tokenSTRING ')' +{ + if(dbDebug>2) printf("recordtype_field_item %s %s\n",$1,$3); + dbAsciiRecordtypeFieldItem($1,$3); +} + | tokenMENU '(' tokenSTRING ')' +{ + char *pmenu; + + if(dbDebug>2) printf("recordtype_field_item %s (%s)\n",menuString,$3); + pmenu = (char *)malloc(strlen(menuString)+1); + strcpy(pmenu,menuString); + dbAsciiRecordtypeFieldItem(pmenu,$3); +}; + + +device: tokenDEVICE '(' + tokenSTRING ',' tokenSTRING ',' tokenSTRING ',' tokenSTRING ')' +{ + if(dbDebug>2) printf("device %s %s %s %s\n",$3,$5,$7,$9); + dbAsciiDevice($3,$5,$7,$9); +}; + + +driver: tokenDRIVER '(' tokenSTRING ')' +{ + if(dbDebug>2) printf("driver %s\n",$3); + dbAsciiDriver($3); +}; + +break_head: '(' tokenSTRING ')' +{ + if(dbDebug>2) printf("break_head %s\n",$2); + dbAsciiBreakHead($2); +}; + +break_body : '{' break_list '}' +{ + if(dbDebug>2) printf("break_body\n"); + dbAsciiBreakBody(); +}; + +break_list: break_list ',' break_item | break_item; + +break_item: tokenSTRING +{ + if(dbDebug>2) printf("break_item tokenSTRING %s\n",$1); + dbAsciiBreakItem($1); +}; + + +record_head: '(' tokenSTRING ',' tokenSTRING ')' +{ + if(dbDebug>2) printf("record_head %s %s\n",$2,$4); + dbAsciiRecordHead($2,$4); +}; + +record_body: '{' record_field_list '}' +{ + if(dbDebug>2) printf("record_body\n"); + dbAsciiRecordBody(); +}; + +record_field_list: record_field_list record_field + | record_field; + +record_field: tokenFIELD '(' tokenSTRING ',' tokenSTRING ')' +{ + if(dbDebug>2) printf("record_field %s %s\n",$3,$5); + dbAsciiRecordField($3,$5); +} + | include ; + +%% + +#include "dbAsciiLex.c" + + +static int yyerror(char *str) +{ + fprintf(stderr,"Error "); + if(str) fprintf(stderr,"\"%s\"",str); + fprintf(stderr," Last token \"%s\"\n",yytext); + dbAsciiIncludePrint(stderr); + yyFailed = TRUE; + return(0); +} +static long pvt_yy_parse(void) +{ + static int FirstFlag = 1; + long rtnval; + + if (!FirstFlag) { + yyFailed = FALSE; + yyreset(); + yyrestart(NULL); + } + FirstFlag = 0; + rtnval = yyparse(); + if(rtnval!=0 || yyFailed) return(-1); else return(0); +} diff --git a/src/dbStatic/dbPvdLib.c b/src/dbStatic/dbPvdLib.c new file mode 100644 index 000000000..77427a4a8 --- /dev/null +++ b/src/dbStatic/dbPvdLib.c @@ -0,0 +1,243 @@ +/*dbPvdLib.c*/ +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + +This software was developed under a United States Government license +described on the COPYRIGHT_UniversityOfChicago file included as part +of this distribution. +**********************************************************************/ +#ifdef vxWorks +#include +#include +#endif +#include +#include +#include + +#include +#include +#include +#include + +int dbPvdHashTableSize = 512; +static int dbPvdHashTableShift; +#define NTABLESIZES 9 +static struct { + unsigned int tablesize; + int shift; +}hashTableParms[9] = { + {256,0}, + {512,1}, + {1024,2}, + {2048,3}, + {4096,4}, + {8192,5}, + {16384,6}, + {32768,7}, + {65536,8} +}; + +/*The hash algorithm is a modification of the algorithm described in */ +/* Fast Hashing of Variable Length Text Strings, Peter K. Pearson, */ +/* Communications of the ACM, June 1990 */ +/* The modifications were designed by Marty Kraimer */ + +static unsigned char T[256] = { + 39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69, +157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160, +176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77, + 75,107,169,138,195,184, 70, 90, 61,166, 7,244,165,108,219, 51, + 9,139,209, 40, 31,202, 58,179,116, 33,207,146, 76, 60,242,124, +254,197, 80,167,153,145,129,233,132, 48,246, 86,156,177, 36,187, + 45, 1, 96, 18, 19, 62,185,234, 99, 16,218, 95,128,224,123,253, + 42,109, 4,247, 72, 5,151,136, 0,152,148,127,204,133, 17, 14, +182,217, 54,199,119,174, 82, 57,215, 41,114,208,206,110,239, 23, +189, 15, 3, 22,188, 79,113,172, 28, 2,222, 21,251,225,237,105, +102, 32, 56,181,126, 83,230, 53,158, 52, 59,213,118,100, 67,142, +220,170,144,115,205, 26,125,168,249, 66,175, 97,255, 92,229, 91, +214,236,178,243, 46, 44,201,250,135,186,150,221,163,216,162, 43, + 11,101, 34, 37,194, 25, 50, 12, 87,198,173,240,193,171,143,231, +111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238, +134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47 +}; + + +static unsigned short hash( char *pname, int length) +{ + unsigned char h0=0; + unsigned char h1=0; + unsigned short ind0,ind1; + int even = TRUE; + unsigned char c; + int i; + + for(i=0; i=hashTableParms[i].tablesize) + && (dbPvdHashTableSizeppvd = (void *) ppvd; + return; +} + +PVDENTRY *dbPvdFind(dbBase *pdbBase,char *name,int lenName) +{ + unsigned short hashInd; + ELLLIST **ppvd = (ELLLIST **) pdbBase->ppvd; + ELLLIST *pvdlist; + PVDENTRY *ppvdNode; + + hashInd = hash(name, lenName); + if ((pvdlist=ppvd[hashInd]) == NULL) return (NULL); + ppvdNode = (PVDENTRY *) ellFirst(pvdlist); + while(ppvdNode) { + if(strcmp(name,ppvdNode->precnode->recordname) == 0) + return(ppvdNode); + ppvdNode = (PVDENTRY *) ellNext((ELLNODE*)ppvdNode); + } + return (NULL); +} + +PVDENTRY *dbPvdAdd(dbBase *pdbBase,dbRecDes *precdes,dbRecordNode *precnode) +{ + unsigned short hashInd; + ELLLIST **ppvd = (ELLLIST **) pdbBase->ppvd; + ELLLIST *ppvdlist; + PVDENTRY *ppvdNode; + int lenName; + char *name=precnode->recordname; + + lenName=strlen(name); + hashInd = hash(name, lenName); + if (ppvd[hashInd] == NULL) { + ppvd[hashInd] = dbCalloc(1, sizeof(ELLLIST)); + ellInit(ppvd[hashInd]); + } + ppvdlist=ppvd[hashInd]; + ppvdNode = (PVDENTRY *) ellFirst(ppvdlist); + while(ppvdNode) { + if(strcmp(name,(char *)ppvdNode->precnode->precord) == 0) return(NULL); + ppvdNode = (PVDENTRY *) ellNext((ELLNODE*)ppvdNode); + } + ppvdNode = dbCalloc(1, sizeof(PVDENTRY)); + ellAdd(ppvdlist, (ELLNODE*)ppvdNode); + ppvdNode->precdes = precdes; + ppvdNode->precnode = precnode; + return (ppvdNode); +} + +void dbPvdDelete(dbBase *pdbBase,dbRecordNode *precnode) +{ + char *name=precnode->recordname; + unsigned short hashInd; + ELLLIST **ppvd = (ELLLIST **) pdbBase->ppvd; + ELLLIST *ppvdlist; + PVDENTRY *ppvdNode; + int lenName; + + lenName=strlen(name); + hashInd = hash(name, lenName); + if (ppvd[hashInd] == NULL)return; + ppvdlist=ppvd[hashInd]; + ppvdNode = (PVDENTRY *) ellFirst(ppvdlist); + while(ppvdNode) { + if(ppvdNode->precnode && ppvdNode->precnode->precord + && strcmp(name,(char *)ppvdNode->precnode->precord) == 0) { + ellDelete(ppvdlist, (ELLNODE*)ppvdNode); + free((void *)ppvdNode); + return; + } + ppvdNode = (PVDENTRY *) ellNext((ELLNODE*)ppvdNode); + } + return; +} + +void dbPvdFreeMem(dbBase *pdbBase) +{ + unsigned short hashInd; + ELLLIST **ppvd = (ELLLIST **) pdbBase->ppvd; + ELLLIST *ppvdlist; + PVDENTRY *ppvdNode; + PVDENTRY *next; + + if (ppvd == NULL) return; + for (hashInd=0; hashInd<(unsigned short)dbPvdHashTableSize; hashInd++) { + if(ppvd[hashInd] == NULL) continue; + ppvdlist=ppvd[hashInd]; + ppvdNode = (PVDENTRY *) ellFirst(ppvdlist); + while(ppvdNode) { + next = (PVDENTRY *) ellNext((ELLNODE*)ppvdNode); + ellDelete(ppvdlist,(ELLNODE*)ppvdNode); + free((void *)ppvdNode); + ppvdNode = next; + } + free((void *)ppvd[hashInd]); + } + free((void *)ppvd); +} + +void dbPvdDump(dbBase *pdbBase,int verbose) +{ + unsigned short hashInd; + ELLLIST **ppvd = (ELLLIST **) pdbBase->ppvd; + ELLLIST *ppvdlist; + PVDENTRY *ppvdNode; + int number; + + if (ppvd == NULL) return; + printf("Process Variable Directory\n"); + printf("dbPvdHashTableSize %d dbPvdHashTableShift %d\n", + dbPvdHashTableSize,dbPvdHashTableShift); + for (hashInd=0; hashInd<(unsigned short)dbPvdHashTableSize; hashInd++) { + if(ppvd[hashInd] == NULL) continue; + ppvdlist=ppvd[hashInd]; + ppvdNode = (PVDENTRY *) ellFirst(ppvdlist); + printf("\n%3.3hd=%3.3d ",hashInd,ellCount(ppvdlist)); + number=0; + while(ppvdNode && verbose) { + printf(" %s",(char *)ppvdNode->precnode->recordname); + if(number++ ==2) {number=0;printf("\n ");} + ppvdNode = (PVDENTRY *) ellNext((ELLNODE*)ppvdNode); + } + } + printf("\nEnd of Process Variable Directory\n"); +} diff --git a/src/dbStatic/dbStaticLib.c b/src/dbStatic/dbStaticLib.c new file mode 100644 index 000000000..53b2bf74f --- /dev/null +++ b/src/dbStatic/dbStaticLib.c @@ -0,0 +1,2580 @@ +/*dbStaticLib.c*/ +/* share/src/db @(#)dbStaticLib.c 1.21 7/11/94 */ +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + +This software was developed under a United States Government license +described on the COPYRIGHT_UniversityOfChicago file included as part +of this distribution. +**********************************************************************/ + +/* + * Modification Log: + * ----------------- + * .01 02-03-93 mrk Consolidated all databse defs in one place + * .02 09-10-93 mrk dbIsDefault always returns FALSE for DEVCHOICE + * .03 02-23-94 mrk dbPutString to DEV_CHOICE. Ok if no INP or OUT + */ + +#ifdef vxWorks +#include +#include +#endif +#include +#include +#include +#include +#include + +#define DBFLDTYPES_GBLSOURCE +#define GUIGROUPS_GBLSOURCE +#define SPECIAL_GBLSOURCE +#define LINK_GBLSOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int dbDebug = 0; +#define messagesize 100 +#define RPCL_LEN 184 +long postfix(char *pinfix, char *ppostfix,short *perror); + +static char *ppstring[2]={"NPP","PP"}; +static char *msstring[2]={"NMS","MS"}; + +static int mapDBFtoDCT[DBF_NOACCESS+1] = { + DCT_STRING, + DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,DCT_INTEGER,DCT_INTEGER, + DCT_REAL,DCT_REAL, + DCT_INTEGER, + DCT_MENU, + DCT_MENUFORM, + DCT_INLINK,DCT_OUTLINK,DCT_FWDLINK, + DCT_NOACCESS}; + +struct form { + DBLINK *plink; + int nlines; + char **prompt; + char **value; + char **verify; +}; + +static char *promptCONSTANT[] = { + "Constant:"}; +static char *promptPV_LINK[] = { + " PV Name:", + " Process Passive?", + " Maximize Severity?"}; +static char *promptVME_IO[] = { + " card:", + "signal:", + " parm:"}; +static char *promptCAMAC_IO[] = { + " branch:", + " crate:", + " station:", + "subaddress:", + " function:", + " parameter:"}; +static char *promptRF_IO[] = { + " cryo:", + " micro:", + " dataset:", + " element:"}; +static char *promptAB_IO[] = { + " link:", + " adapter:", + " card:", + " signal:", + " parm:"}; +static char *promptGPIB_IO[] = { + "link:", + "addr:", + "parm:"}; +static char *promptBITBUS_IO[] = { + " link:", + " node:", + " port:", + "signal:", + " parm:"}; +static char *promptINST_IO[] = { + "parm:"}; +static char *promptBBGPIB_IO[] = { + " link:", + " bbaddr:", + "gpibaddr:", + " parm:"}; +static char *promptVXI_IO[] = { + " Dynamic?", + "DYN frame:", + "DYN slot:", + "STATIC la:", + " Signal:", + " parm:"}; + +static char **promptAddr[VXI_IO+1]; +static int formlines[VXI_IO+1]; + +/* internal routines*/ +static void initForms(void) +{ + static int firstTime=TRUE; + int i; + + if(!firstTime) return; + firstTime = FALSE; + for(i=0; i<=VXI_IO; i++) { + promptAddr[i] = NULL; + formlines[i] = 0; + } + promptAddr[CONSTANT] = promptCONSTANT; formlines[CONSTANT] = 1; + promptAddr[PV_LINK] = promptPV_LINK; formlines[PV_LINK] = 4; + promptAddr[VME_IO] = promptVME_IO; formlines[VME_IO] = 3; + promptAddr[CAMAC_IO] = promptCAMAC_IO; formlines[CAMAC_IO] = 6; + promptAddr[RF_IO] = promptRF_IO; formlines[RF_IO] = 4; + promptAddr[AB_IO] = promptAB_IO; formlines[AB_IO] = 5; + promptAddr[GPIB_IO] = promptGPIB_IO; formlines[GPIB_IO] = 3; + promptAddr[BITBUS_IO]= promptBITBUS_IO;formlines[BITBUS_IO]= 5; + promptAddr[INST_IO] = promptINST_IO; formlines[INST_IO] = 1; + promptAddr[BBGPIB_IO]= promptBBGPIB_IO;formlines[BBGPIB_IO]= 4; + promptAddr[VXI_IO] = promptVXI_IO; formlines[VXI_IO] = 6; +} + +static void entryErrMessage(DBENTRY *pdbentry,long status,char *mess) +{ + char message[200]; + char *pmessage=&message[0]; + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes = pdbentry->pflddes; + char *pname = NULL; + + *pmessage=0; + if(pdbentry->precdes) pname = pdbentry->precdes->name; + if(pname) { + strcat(pmessage,"RecordType:"); + strcat(pmessage,pname); + } + if(precnode){ + strcat(pmessage," Record:"); + strcat(pmessage,(char *)precnode->precord); + } + if(pflddes) { + char *pstr=pflddes->name; + + strcat(pmessage," Field:"); + strcat(pmessage,pstr); + } + strcat(pmessage,"\n"); + strcat(pmessage,mess); + errMessage(status,pmessage); +} + +static void zeroDbentry(DBENTRY *pdbentry) +{ + /*NOTE that pdbbase, message, and formpvt MUST NOT be set to NULL*/ + pdbentry->precdes=NULL; + pdbentry->pflddes=NULL; + pdbentry->precnode=NULL; + pdbentry->pfield=NULL; + pdbentry->indfield=0; +} + +static char *getpMessage(DBENTRY *pdbentry) +{ + if(!pdbentry->message) pdbentry->message = dbCalloc(1,messagesize); + return(pdbentry->message); +} + +void dbInitDeviceMenu(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + dbFldDes *pflddes = pdbentry->pflddes; + dbDeviceMenu *pdbDeviceMenu; + devSup *pdevSup; + int ind; + + if(!precdes) return; + if(!pflddes) return; + pdbDeviceMenu = dbCalloc(1,sizeof(dbDeviceMenu)); + pflddes->ftPvt = pdbDeviceMenu; + pdbDeviceMenu->nChoice = ellCount(&precdes->devList); + pdbDeviceMenu->papChoice = dbCalloc(pdbDeviceMenu->nChoice,sizeof(char *)); + pdevSup = (devSup *)ellFirst(&precdes->devList); + ind = 0; + while(pdevSup) { + pdbDeviceMenu->papChoice[ind] = pdevSup->choice; + ind++; + pdevSup = (devSup *)ellNext(&pdevSup->node); + } +} + +/* Beginning of Public Routines */ +void *dbCalloc(size_t nobj,size_t size) +{ + void *p; + + p=calloc(nobj,size); + if(p) return(p); + printf("dbCalloc: Can't allocate memory\n"); +#ifdef vxWorks + taskSuspend(0); +#else + abort(); +#endif + return(NULL); +} +void *dbMalloc(size_t size) +{ + void *p; + + p=malloc(size); + if(p) return(p); + printf("dbMalloc: Can't allocate memory\n"); +#ifdef vxWorks + taskSuspend(0); +#else + abort(); +#endif + return(NULL); +} + +dbBase *dbAllocBase(void) +{ + dbBase *pdbbase; + + pdbbase = dbCalloc(1,sizeof(dbBase)); + ellInit(&pdbbase->menuList); + ellInit(&pdbbase->recDesList); + ellInit(&pdbbase->drvList); + ellInit(&pdbbase->bptList); + gphInitPvt(&pdbbase->pgpHash,256); + dbPvdInitPvt(pdbbase); + initForms(); + return (pdbbase); +} + +void dbFreeBase(dbBase *pdbbase) +{ + dbMenu *pdbMenu; + dbMenu *pdbMenuNext; + dbRecDes *pdbRecDes; + dbRecDes *pdbRecDesNext; + dbFldDes *pdbFldDes; + dbRecordNode *pdbRecordNode; + dbRecordNode *pdbRecordNodeNext; + devSup *pdevSup; + devSup *pdevSupNext; + drvSup *pdrvSup; + drvSup *pdrvSupNext; + brkTable *pbrkTable; + brkTable *pbrkTableNext; + int i; + DBENTRY dbentry; + + + dbInitEntry(pdbbase,&dbentry); + pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); + while(pdbRecDes) { + pdbRecordNode = (dbRecordNode *)ellFirst(&pdbRecDes->recList); + while(pdbRecordNode) { + pdbRecordNodeNext = (dbRecordNode *)ellNext(&pdbRecordNode->node); + if(dbFindRecord(&dbentry,pdbRecordNode->recordname)) + dbDeleteRecord(&dbentry); + pdbRecordNode = pdbRecordNodeNext; + } + pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node); + } + dbFinishEntry(&dbentry); + pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); + while(pdbRecDes) { + for(i=0; ino_fields; i++) { + pdbFldDes = pdbRecDes->papFldDes[i]; + free((void *)pdbFldDes->prompt); + free((void *)pdbFldDes->name); + free((void *)pdbFldDes->extra); + free((void *)pdbFldDes->initial); + if(pdbFldDes->field_type==DBF_DEVICE && pdbFldDes->ftPvt) { + dbDeviceMenu *pdbDeviceMenu; + + pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt; + free((void *)pdbDeviceMenu->papChoice); + free((void *)pdbDeviceMenu); + pdbFldDes->ftPvt=0; + } + free((void *)pdbFldDes); + } + pdevSup = (devSup *)ellFirst(&pdbRecDes->devList); + while(pdevSup) { + pdevSupNext = (devSup *)ellNext(&pdevSup->node); + ellDelete(&pdbRecDes->devList,&pdevSup->node); + free((void *)pdevSup->name); + free((void *)pdevSup->choice); + free((void *)pdevSup); + pdevSup = pdevSupNext; + } + pdbRecDesNext = (dbRecDes *)ellNext(&pdbRecDes->node); + gphDelete(pdbbase->pgpHash,pdbRecDes->name,&pdbbase->recDesList); + ellDelete(&pdbbase->recDesList,&pdbRecDes->node); + free((void *)pdbRecDes->name); + free((void *)pdbRecDes->link_ind); + free((void *)pdbRecDes->papsortFldName); + free((void *)pdbRecDes->sortFldInd); + free((void *)pdbRecDes->papFldDes); + free((void *)pdbRecDes); + pdbRecDes = pdbRecDesNext; + } + pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList); + while(pdbMenu) { + pdbMenuNext = (dbMenu *)ellNext(&pdbMenu->node); + gphDelete(pdbbase->pgpHash,pdbMenu->name,&pdbbase->menuList); + ellDelete(&pdbbase->menuList,&pdbMenu->node); + for(i=0; i< pdbMenu->nChoice; i++) { + free((void *)pdbMenu->papChoiceName[i]); + free((void *)pdbMenu->papChoiceValue[i]); + } + free((void *)pdbMenu->papChoiceName); + free((void *)pdbMenu->papChoiceValue); + free((void *)pdbMenu ->name); + free((void *)pdbMenu); + pdbMenu = pdbMenuNext; + } + pdrvSup = (drvSup *)ellFirst(&pdbbase->drvList); + while(pdrvSup) { + pdrvSupNext = (drvSup *)ellNext(&pdrvSup->node); + ellDelete(&pdbbase->drvList,&pdrvSup->node); + free((void *)pdrvSup->name); + free((void *)pdrvSup); + pdrvSup = pdrvSupNext; + } + pbrkTable = (brkTable *)ellFirst(&pdbbase->bptList); + while(pbrkTable) { + pbrkTableNext = (brkTable *)ellNext(&pbrkTable->node); + gphDelete(pdbbase->pgpHash,pbrkTable->name,&pdbbase->bptList); + ellDelete(&pdbbase->bptList,&pbrkTable->node); + free(pbrkTable->name); + for(i=0; inumber; i++) + free((void *)(pbrkTable->papBrkInt[i])); + free((void *)pbrkTable); + pbrkTable = pbrkTableNext; + } + gphFreeMem(pdbbase->pgpHash); + dbPvdFreeMem(pdbbase); + free((void *)pdbbase); + return; +} + +DBENTRY *dbAllocEntry(dbBase *pdbbase) +{ + DBENTRY *pdbentry; + + pdbentry = dbCalloc(1,sizeof(DBENTRY)); + pdbentry->pdbbase = pdbbase; + return(pdbentry); +} + +void dbFreeEntry(DBENTRY *pdbentry) +{ + if(pdbentry->message) free((void *)pdbentry->message); + if(pdbentry->formpvt) dbFreeForm(pdbentry); + free((void *)pdbentry); +} + +void dbInitEntry(dbBase *pdbbase,DBENTRY *pdbentry) +{ + memset((char *)pdbentry,'\0',sizeof(DBENTRY)); + pdbentry->pdbbase = pdbbase; +} + +void dbFinishEntry(DBENTRY *pdbentry) +{ + if(pdbentry->message) free((void *)pdbentry->message); + if(pdbentry->formpvt) dbFreeForm(pdbentry); +} + +DBENTRY *dbCopyEntry(DBENTRY *pdbentry) +{ + DBENTRY *pnew; + + dbFinishEntry(pdbentry); + pnew = dbAllocEntry(pdbentry->pdbbase); + *pnew = *pdbentry; + return(pnew); +} + +long dbRead(DBBASE *pdbbase,FILE *fp) +{ + return(dbAsciiReadFP(&pdbbase,fp)); +} +long dbWrite(DBBASE *pdbbase,FILE *fpdctsdr,FILE *fp) +{ + epicsPrintf("dbWrite obsolete. It does NOTHING\n"); + return(-1); +} + +long dbWriteRecords(DBBASE *pdbbase,FILE *fp,char *precdesname,int level) +{ + DBENTRY dbentry; + DBENTRY *pdbentry=&dbentry; + long status; + int dctonly; + + dctonly = ((level>1) ? FALSE : TRUE); + dbInitEntry(pdbbase,pdbentry); + if(!precdesname) + status = dbFirstRecdes(pdbentry); + else + status = dbFindRecdes(pdbentry,precdesname); + if(status) { + fprintf(stderr,"No record description\n"); + return(status); + } + while(!status) { + status = dbFirstRecord(pdbentry); + while(!status) { + fprintf(fp,"record(%s,%s) {\n", + dbGetRecdesName(pdbentry),dbGetRecordName(pdbentry)); + status = dbFirstFielddes(pdbentry,dctonly); + while(!status) { + if(!dbIsDefaultValue(pdbentry) || level>0) { + fprintf(fp,"\tfield(%s,\"%s\")\n", + dbGetFieldName(pdbentry),dbGetString(pdbentry)); + } + status=dbNextFielddes(pdbentry,dctonly); + } + fprintf(fp,"}\n"); + status = dbNextRecord(pdbentry); + } + if(precdesname) break; + status = dbNextRecdes(pdbentry); + } + dbFinishEntry(pdbentry); + return(0); +} + +long dbFindRecdes(DBENTRY *pdbentry,char *rectype) +{ + dbBase *pdbbase = pdbentry->pdbbase; + GPHENTRY *phash; + + zeroDbentry(pdbentry); + phash = gphFind(pdbbase->pgpHash,rectype,&pdbbase->recDesList); + if(!phash) return(S_dbLib_recdesNotFound); + pdbentry->precdes = phash->userPvt; + return(0); +} + +long dbFirstRecdes(DBENTRY *pdbentry) +{ + dbRecDes *precdes; + + zeroDbentry(pdbentry); + precdes = (dbRecDes *)ellFirst(&pdbentry->pdbbase->recDesList); + if(!precdes) return(S_dbLib_recdesNotFound); + pdbentry->precdes = precdes; + return(0); +} + +long dbNextRecdes(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + + zeroDbentry(pdbentry); + precdes = (dbRecDes *)ellNext(&precdes->node); + if(!precdes) return(S_dbLib_recdesNotFound); + pdbentry->precdes = precdes; + return(0); +} + +char *dbGetRecdesName(DBENTRY *pdbentry) +{ + return(pdbentry->precdes->name); +} + +int dbGetNRecdes(DBENTRY *pdbentry) +{ + return(ellCount(&pdbentry->pdbbase->recDesList)); +} + +long dbCreateRecord(DBENTRY *pdbentry,char *precordName) +{ + dbRecDes *precdes = pdbentry->precdes; + PVDENTRY *ppvd; + ELLLIST *preclist = NULL; + dbRecordNode *precnode = NULL; + dbRecordNode *pNewRecNode = NULL; + long status; + + if(strlen(precordName)>PVNAME_SZ) return(S_dbLib_nameLength); + if(!precdes) return(S_dbLib_recdesNotFound); + /* clear callers entry */ + zeroDbentry(pdbentry); + if(!dbFindRecord(pdbentry,precordName)) return (S_dbLib_recExists); + zeroDbentry(pdbentry); + pdbentry->precdes = precdes; + preclist = &precdes->recList; + /* create a recNode */ + pNewRecNode = dbCalloc(1,sizeof(dbRecordNode)); + /* create a new record of this record type */ + pdbentry->precnode = pNewRecNode; + if(status = dbAllocRecord(pdbentry,precordName)) return(status); + pNewRecNode->recordname = dbRecordName(pdbentry); + /* install record node in list in sorted postion */ + precnode = (dbRecordNode *)ellFirst(preclist); + while(precnode && strcmp(precordName,(char*)precnode->precord) > 0) + precnode = (dbRecordNode *)ellNext(&precnode->node); + if(precnode) + ellInsert(preclist,ellPrevious(&precnode->node),&pNewRecNode->node); + else + ellAdd(preclist,&pNewRecNode->node); + pdbentry->precnode = pNewRecNode; + ppvd = dbPvdAdd(pdbentry->pdbbase,precdes,pNewRecNode); + if(!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);} + return (0); +} + +long dbDeleteRecord(DBENTRY *pdbentry) +{ + dbBase *pdbbase = pdbentry->pdbbase; + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + ELLLIST *preclist; + long status; + + if (!precnode) return (S_dbLib_recNotFound); + if(status = dbFreeRecord(pdbentry)) return(status); + preclist = &precdes->recList; + ellDelete(preclist,&precnode->node); + dbPvdDelete(pdbbase,precnode); + free((void *)precnode); + pdbentry->precnode = NULL; + return (0); +} + +long dbFindRecord(DBENTRY *pdbentry,char *precordName) +{ + dbBase *pdbbase = pdbentry->pdbbase; + int lenName=0; + PVDENTRY *ppvdNode; + char convName[PVNAME_SZ + 1]; + char *pconvName = &convName[0]; + + + zeroDbentry(pdbentry); + /* convert the record name */ + while (*precordName && (*precordName != '.') && (lenName < PVNAME_SZ)) { + *pconvName++ = *precordName++; + lenName++; + } + *pconvName = 0; + pconvName = &convName[0]; + ppvdNode = dbPvdFind(pdbbase,pconvName,lenName); + if(!ppvdNode) return(S_dbLib_recNotFound); + pdbentry->precnode = ppvdNode->precnode; + pdbentry->precdes = ppvdNode->precdes; + if(*precordName++=='.') return(dbFindField(pdbentry, precordName)); + return (0); +} + +long dbFirstRecord(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode; + + zeroDbentry(pdbentry); + if(!precdes) return(S_dbLib_recdesNotFound); + pdbentry->precdes = precdes; + precnode = (dbRecordNode *)ellFirst(&precdes->recList); + if(!precnode) return(S_dbLib_recNotFound); + pdbentry->precnode = precnode; + return(0); +} + +long dbNextRecord(DBENTRY *pdbentry) +{ + dbRecordNode *precnode=pdbentry->precnode; + long status=0; + + if(!precnode) return(S_dbLib_recNotFound); + precnode = (dbRecordNode *)ellNext(&precnode->node); + if(!precnode) status = S_dbLib_recNotFound; + pdbentry->precnode = precnode; + pdbentry->pfield = NULL; + return(status); +} + +int dbGetNRecords(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + + if(!precdes) return(0); + return(ellCount(&precdes->recList)); +} + +char *dbGetRecordName(DBENTRY *pdbentry) +{ + return(dbRecordName(pdbentry)); +} + + +long dbRenameRecord(DBENTRY *pdbentry,char *newName) +{ + dbBase *pdbbase = pdbentry->pdbbase; + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + PVDENTRY *ppvd; + ELLLIST *preclist; + dbRecordNode *plistnode; + long status; + DBENTRY dbentry; + + if(strlen(newName)>PVNAME_SZ) return(S_dbLib_nameLength); + if(!precnode) return(S_dbLib_recNotFound); + dbInitEntry(pdbentry->pdbbase,&dbentry); + status = dbFindRecord(&dbentry,newName); + dbFinishEntry(&dbentry); + if(!status) return(S_dbLib_recExists); + dbPvdDelete(pdbbase,precnode); + pdbentry->pflddes = precdes->papFldDes[0]; + if(status = dbGetFieldAddress(pdbentry)) return(status); + strcpy(pdbentry->pfield,newName); + ppvd = dbPvdAdd(pdbbase,precdes,precnode); + if(!ppvd) {errMessage(-1,"Logic Err: Could not add to PVD");return(-1);} + /*remove from record list and reinstall in sorted order*/ + preclist = &precdes->recList; + ellDelete(preclist,&precnode->node); + plistnode = (dbRecordNode *)ellFirst(preclist); + while(plistnode) { + pdbentry->precnode = plistnode; + if(strcmp(newName,dbRecordName(pdbentry)) >=0) break; + plistnode = (dbRecordNode *)ellNext(&plistnode->node); + } + if(plistnode) + ellInsert(preclist,ellPrevious(&plistnode->node),&precnode->node); + else + ellAdd(preclist,&precnode->node); + return(0); +} + +long dbFindField(DBENTRY *pdbentry,char *pfieldName) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + char *precord; + dbFldDes *pflddes; + short top, bottom, test; + char **papsortFldName; + short *sortFldInd; + long status; + int compare; + + if(!precdes) return(S_dbLib_recdesNotFound); + if(!precnode) return(S_dbLib_recNotFound); + precord = precnode->precord; + papsortFldName = precdes->papsortFldName; + sortFldInd = precdes->sortFldInd; + /* check for default field name or VAL to be supplied */ + if((*pfieldName==0) || (strcmp(pfieldName,"VAL")==0)) { + if(!(pflddes=precdes->pvalFldDes)) + return(S_dbLib_recdesNotFound); + pdbentry->pflddes = pflddes; + pdbentry->indfield = precdes->indvalFlddes; + status = dbGetFieldAddress(pdbentry); + return (status); + } + /* binary search through ordered field names */ + top = precdes->no_fields - 1; + bottom = 0; + test = (top + bottom) / 2; + while (1) { + /* check the field name */ + compare = strcmp(papsortFldName[test],pfieldName); + if (compare == 0) { + if(!(pflddes=precdes->papFldDes[sortFldInd[test]])) + return(S_dbLib_recdesNotFound); + pdbentry->pflddes = pflddes; + pdbentry->indfield = sortFldInd[test]; + status = dbGetFieldAddress(pdbentry); + return (status); + } else if (compare > 0) { + top = test - 1; + if (top < bottom) return (S_dbLib_fieldNotFound); + test = (top + bottom) / 2; + } else { + bottom = test + 1; + if (top < bottom) return (S_dbLib_fieldNotFound); + test = (top + bottom) / 2; + } + } +} + +long dbFirstFielddes(DBENTRY *pdbentry,int dctonly) +{ + + pdbentry->indfield = -1; + return(dbNextFielddes(pdbentry,dctonly)); +} + +long dbNextFielddes(DBENTRY *pdbentry,int dctonly) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes; + short indfield = pdbentry->indfield; + long status; + + if(!precdes) return(S_dbLib_recdesNotFound); + indfield++; + while(TRUE) { + if(indfield>=precdes->no_fields) { + pdbentry->indfield = 0; + pdbentry->pflddes = NULL; + pdbentry->pfield = NULL; + return(S_dbLib_fieldNotFound); + } + pflddes = precdes->papFldDes[indfield]; + if(!dctonly || pflddes->promptgroup) { + pdbentry->indfield = indfield; + pdbentry->pflddes = pflddes; + pdbentry->indfield = indfield; + if(precnode) { + status = dbGetFieldAddress(pdbentry); + }else { + pdbentry->pfield = NULL; + } + return(0); + } + indfield++; + } +} + +int dbGetFieldType(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + long status; + + if(!pflddes){ + status = S_dbLib_flddesNotFound; + entryErrMessage(pdbentry,status,"dbGetFieldType"); + return(status); + } + return(mapDBFtoDCT[pflddes->field_type]); +} + +int dbGetNFields(DBENTRY *pdbentry,int dctonly) +{ + dbRecDes *precdes = pdbentry->precdes; + dbFldDes *pflddes; + int indfield,n; + + if(!precdes) return(S_dbLib_recdesNotFound); + n = 0; + for(indfield=0; indfieldno_fields; indfield++) { + pflddes = precdes->papFldDes[indfield]; + if(!dctonly || pflddes->promptgroup) n++; + } + return(n); +} + +char *dbGetFieldName(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + + if(!pflddes) return(NULL); + return(pflddes->name); +} + +char *dbGetPrompt(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + + if(!pflddes) return(NULL); + return(&pflddes->prompt[0]); +} + +int dbGetPromptGroup(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + + if(!pflddes) return(NULL); + return(pflddes->promptgroup); +} + +char *dbGetString(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + char *message; + unsigned char cvttype; + + message = getpMessage(pdbentry); + *message = 0; + if(!pflddes) {strcpy(message,"fldDes not found"); return(message);} + cvttype = pflddes->base; + switch (pflddes->field_type) { + case DBF_STRING: + if(!pfield) {strcpy(message,"Field not found"); return(message);} + strcpy(message, (char *)pfield); + break; + case DBF_CHAR: + case DBF_UCHAR: + case DBF_SHORT: + case DBF_USHORT: + case DBF_ENUM: + case DBF_LONG: + case DBF_ULONG: + case DBF_FLOAT: + case DBF_DOUBLE: + return(dbGetStringNum(pdbentry)); + case DBF_MENU: { + dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; + short choice_ind; + char *pchoice; + + if(!pfield) {strcpy(message,"Field not found"); return(message);} + choice_ind = *((short *) pdbentry->pfield); + if(!pdbMenu || choice_ind<0 || choice_ind>=pdbMenu->nChoice) + return(NULL); + pchoice = pdbMenu->papChoiceValue[choice_ind]; + strcpy(message, pchoice); + } + break; + case DBF_DEVICE: { + dbDeviceMenu *pdbDeviceMenu; + char *pchoice; + short choice_ind; + + if(!pfield) {strcpy(message,"Field not found"); return(message);} + if(!pflddes->ftPvt) dbInitDeviceMenu(pdbentry); + pdbDeviceMenu = (dbDeviceMenu *)pflddes->ftPvt; + if(!pdbDeviceMenu) return(NULL); + choice_ind = *((short *) pdbentry->pfield); + if(choice_ind<0 || choice_ind>=pdbDeviceMenu->nChoice) + return(NULL); + pchoice = pdbDeviceMenu->papChoice[choice_ind]; + strcpy(message, pchoice); + } + break; + case DBF_INLINK: + case DBF_OUTLINK: { + DBLINK *plink=(DBLINK *)pfield; + + if(!pfield) {strcpy(message,"Field not found"); return(message);} + switch(plink->type) { + case CONSTANT: + if(plink->value.constantStr) { + strcpy(message,plink->value.constantStr); + } else { + strcpy(message,"0"); + } + break; + case PV_LINK: + if(plink->value.pv_link.process_passive<0 + ||plink->value.pv_link.process_passive>1) + plink->value.pv_link.process_passive=0; + if(plink->value.pv_link.maximize_sevr<0 + ||plink->value.pv_link.maximize_sevr>1) + plink->value.pv_link.maximize_sevr=0; + sprintf(message,"%s %s %s", + plink->value.pv_link.pvname, + ppstring[plink->value.pv_link.process_passive], + msstring[plink->value.pv_link.maximize_sevr]); + break; + case VME_IO: + sprintf(message,"#C%d S%d @%s", + plink->value.vmeio.card,plink->value.vmeio.signal, + plink->value.vmeio.parm); + break; + case CAMAC_IO: + sprintf(message,"#B%d C%d N%d A%d F%d @%s", + plink->value.camacio.b,plink->value.camacio.c, + plink->value.camacio.n,plink->value.camacio.a, + plink->value.camacio.f,plink->value.camacio.parm); + break; + case RF_IO: + sprintf(message,"#R%d M%d D%d E%d", + plink->value.rfio.cryo, + plink->value.rfio.micro, + plink->value.rfio.dataset, + plink->value.rfio.element); + break; + case AB_IO: + sprintf(message,"#L%d A%d C%d S%d @%s", + plink->value.abio.link,plink->value.abio.adapter, + plink->value.abio.card,plink->value.abio.signal, + plink->value.abio.parm); + break; + case GPIB_IO: + sprintf(message,"#L%d A%d @%s", + plink->value.gpibio.link,plink->value.gpibio.addr, + plink->value.gpibio.parm); + break; + case BITBUS_IO: + sprintf(message,"#L%u N%u P%u S%u @%s", + plink->value.bitbusio.link,plink->value.bitbusio.node, + plink->value.bitbusio.port,plink->value.bitbusio.signal, + plink->value.bitbusio.parm); + break; + case BBGPIB_IO: + sprintf(message,"#L%u B%u G%u @%s", + plink->value.bbgpibio.link,plink->value.bbgpibio.bbaddr, + plink->value.bbgpibio.gpibaddr,plink->value.bbgpibio.parm); + break; + case INST_IO: + sprintf(message,"@%s", plink->value.instio.string); + break; + case VXI_IO : + if (plink->value.vxiio.flag == VXIDYNAMIC) + sprintf(message,"#V%d C%d S%d @%s", + plink->value.vxiio.frame,plink->value.vxiio.slot, + plink->value.vxiio.signal,plink->value.vxiio.parm); + else + sprintf(message,"#V%d S%d @%s", + plink->value.vxiio.la,plink->value.vxiio.signal, + plink->value.vxiio.parm); + break; + default : + return(NULL); + } + } + break; + case DBF_FWDLINK: { + DBLINK *plink=(DBLINK *)pfield; + + if(!pfield) {strcpy(message,"Field not found"); return(message);} + switch(plink->type) { + case CONSTANT: + strcpy(message,"0"); + break; + case PV_LINK: + sprintf(message,"%s", + plink->value.pv_link.pvname); + break; + default : + return(NULL); + } + } + break; + default: + return(NULL); + } + return (message); +} + +/* utility routines used by dbPutString */ +static long checkDevChoice(DBENTRY *pdbentry, long link_type) +{ + dbFldDes *savepflddes = pdbentry->pflddes; + void *savepfield = pdbentry->pfield; + short saveindfield = pdbentry->indfield; + dbFldDes *pflddes; + DBLINK *plink; + long status=0; + + status = dbFindField(pdbentry,"INP"); + if(status) status = dbFindField(pdbentry,"OUT"); + if(!status) { + pflddes = pdbentry->pflddes; + plink = (DBLINK *)(pdbentry->pfield); + if(plink->type == link_type) goto clean_up; + if(link_type==CONSTANT && plink->type==PV_LINK)goto clean_up; + if(link_type!=CONSTANT && plink->type==PV_LINK) { + status = S_dbLib_badField; + goto clean_up; + } + if(plink->type==CONSTANT) free((void *)plink->value.constantStr); + memset((char *)plink,0,sizeof(struct link)); + plink->type = link_type; + } else { + if(link_type==CONSTANT) status = 0; + else status = S_dbLib_badField; + } +clean_up: + pdbentry->pflddes = savepflddes; + pdbentry->pfield = savepfield; + pdbentry->indfield = saveindfield; + return(status); +} + +long dbPutString(DBENTRY *pdbentry,char *pstring) +{ + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + long status=0; + + if(!pflddes) return(S_dbLib_flddesNotFound); + switch (pflddes->field_type) { + case DBF_STRING: + if(!pfield) return(S_dbLib_fieldNotFound); + strncpy((char *)pfield, pstring,pflddes->size); + if(pflddes->special == SPC_CALC) { + char rpcl[RPCL_LEN]; + short error_number; + + status = postfix(pstring,rpcl,&error_number); + if(status) status = S_dbLib_badField; + } + break; + case DBF_CHAR : + case DBF_SHORT : + case DBF_LONG: + case DBF_UCHAR: + case DBF_USHORT: + case DBF_ULONG: + case DBF_ENUM: + case DBF_FLOAT: + case DBF_DOUBLE: + return(dbPutStringNum(pdbentry,pstring)); + case DBF_MENU: { + dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; + char *pchoice; + int i; + + if(!pfield) return(S_dbLib_fieldNotFound); + if(!pdbMenu) return(S_dbLib_menuNotFound); + for (i = 0; i < pdbMenu->nChoice; i++) { + if(!(pchoice = pdbMenu->papChoiceValue[i])) continue; + if(strcmp(pchoice, pstring) == 0) { + *(unsigned short *)pfield = i; + return(0); + } + } + } + return (S_dbLib_badField); + case DBF_DEVICE: { + dbDeviceMenu *pdbDeviceMenu; + char *pchoice; + int i; + + if(!pfield) return(S_dbLib_fieldNotFound); + if(!pflddes->ftPvt) dbInitDeviceMenu(pdbentry); + pdbDeviceMenu = (dbDeviceMenu *)pflddes->ftPvt; + if(!pdbDeviceMenu) return(S_dbLib_menuNotFound); + for (i = 0; i < pdbDeviceMenu->nChoice; i++) { + if (!(pchoice = pdbDeviceMenu->papChoice[i])) + continue; + if (strcmp(pchoice, pstring) == 0) { + long link_type; + devSup *pdevSup; + + pdevSup = (devSup *)ellNth(&pdbentry->precdes->devList,i+1); + link_type = pdevSup->link_type; + /*If no INP or OUT OK */ + checkDevChoice(pdbentry,link_type); + *(unsigned short *)pfield = i; + return(0); + } + } + } + return(S_dbLib_badField); + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: { + DBLINK *plink=(DBLINK *)pfield; + char string[80]; + char *pstr=&string[0]; + int ind; + + if(!pfield) return(S_dbLib_fieldNotFound); + if(strlen(pstring)>=sizeof(string)) { + status = S_dbLib_badField; + errMessage(status,"dbPutString received a LONG string"); + return(status); + } + strcpy(pstr,pstring); + /*strip off leading blanks and tabs*/ + while(*pstr && (*pstr==' ' || *pstr=='\t')) pstr++; + /*strip off trailing blanks and tabs*/ + if(pstr) for(ind = strlen(pstr)-1; ind>=0; ind--) { + if(pstr[ind]!=' ' && pstr[ind]!='\t') break; + pstr[ind] = '\0'; + } + if(!pstr || strlen(pstr)<=0 ) { + if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry); + if(plink->type!=CONSTANT) return(S_dbLib_badField); + return(0); + } + switch(plink->type) { + case CONSTANT: + case PV_LINK: { + int pp=0; + int ms=0; + char *end; + double tempval; + + /* Check first to see if string is a constant*/ + /*It is a double if strtod eats entire string*/ + /*leading and trailing blanks have already been stripped*/ + tempval = strtod(pstr,&end); + if(*end == 0) { + if(plink->type==PV_LINK) dbCvtLinkToConstant(pdbentry); + if((!plink->value.constantStr) + || (strlen(plink->value.constantStr)value.constantStr); + plink->value.constantStr = + dbCalloc(strlen(pstr)+1,sizeof(char)); + } + strcpy(plink->value.constantStr,pstr); + return(0); + } + if(plink->type==CONSTANT) dbCvtLinkToPvlink(pdbentry); + end = strchr(pstr,' '); + if(end) { + if(strstr(end," PP")) pp = TRUE; + if(strstr(end,".PP")) pp = TRUE; + if(strstr(end," MS")) ms = TRUE; + if(strstr(end,".MS")) ms = TRUE; + *end = 0; + } + status = dbPutPvlink(pdbentry,pp,ms,pstr); + return(0); + } + case VME_IO: { + char *end; + + if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField); + pstr = end + 1; + if(!(end = strchr(pstr,'C'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.vmeio.card); + if(!(end = strchr(pstr,'S'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.vmeio.signal); + plink->value.vmeio.parm[0] = 0; + if(end = strchr(pstr,'@')) { + pstr = end + 1; + strcpy(&plink->value.vmeio.parm[0],pstr); + } + } + break; + case CAMAC_IO: { + char *end; + + if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField); + pstr = end + 1; + if(!(end = strchr(pstr,'B'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.camacio.b); + if(!(end = strchr(pstr,'C'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.camacio.c); + if(!(end = strchr(pstr,'N'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.camacio.n); + if(!(end = strchr(pstr,'A'))) { + plink->value.camacio.a = 0; + } else { + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.camacio.a); + } + if(!(end = strchr(pstr,'F'))) { + plink->value.camacio.f = 0; + } else { + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.camacio.f); + } + plink->value.camacio.parm[0] = 0; + if(end = strchr(pstr,'@')) { + pstr = end + 1; + strcpy(&plink->value.camacio.parm[0],pstr); + } + } + break; + case RF_IO: { + char *end; + + if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField); + pstr = end + 1; + if(!(end = strchr(pstr,'R'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.rfio.cryo); + if(!(end = strchr(pstr,'M'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.rfio.micro); + if(!(end = strchr(pstr,'D'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.rfio.dataset); + if(!(end = strchr(pstr,'E'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.rfio.element); + } + break; + case AB_IO: { + char *end; + + if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField); + pstr = end + 1; + if(!(end = strchr(pstr,'L'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.abio.link); + if(!(end = strchr(pstr,'A'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.abio.adapter); + if(!(end = strchr(pstr,'C'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.abio.card); + if(!(end = strchr(pstr,'S'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.abio.signal); + plink->value.abio.parm[0] = 0; + if(end = strchr(pstr,'@')) { + pstr = end + 1; + strcpy(&plink->value.abio.parm[0],pstr); + } + } + break; + case GPIB_IO: { + char *end; + + if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField); + pstr = end + 1; + if(!(end = strchr(pstr,'L'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.gpibio.link); + if(!(end = strchr(pstr,'A'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.gpibio.addr); + plink->value.gpibio.parm[0] = 0; + if(end = strchr(pstr,'@')) { + pstr = end + 1; + strcpy(&plink->value.gpibio.parm[0],pstr); + } + } + break; + case BITBUS_IO: { + /* jbk - the bbgpib struct uses unsigned char's instead + of short, so read values into short and then convert */ + + char *end; + short tmp_val; + + if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField); + pstr = end + 1; + if(!(end = strchr(pstr,'L'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&tmp_val); + plink->value.bitbusio.link=(unsigned char)tmp_val; + if(!(end = strchr(pstr,'N'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&tmp_val); + plink->value.bitbusio.node=(unsigned char)tmp_val; + if(!(end = strchr(pstr,'P'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&tmp_val); + plink->value.bitbusio.port=(unsigned char)tmp_val; + if(!(end = strchr(pstr,'S'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&tmp_val); + plink->value.bitbusio.signal=(unsigned char)tmp_val; + plink->value.bitbusio.parm[0] = 0; + if(end = strchr(pstr,'@')) { + pstr = end + 1; + strcpy(&plink->value.bitbusio.parm[0],pstr); + } + } + break; + case BBGPIB_IO: { + /* jbk - the bbgpib struct uses unsigned char's instead + of short, so read values into short and then convert */ + + char *end; + short tmp_val; + + if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField); + pstr = end + 1; + if(!(end = strchr(pstr,'L'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&tmp_val); + plink->value.bbgpibio.link=(unsigned char)tmp_val; + if(!(end = strchr(pstr,'B'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&tmp_val); + plink->value.bbgpibio.bbaddr=(unsigned char)tmp_val; + if(!(end = strchr(pstr,'G'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&tmp_val); + plink->value.bbgpibio.gpibaddr=tmp_val; + plink->value.bbgpibio.parm[0] = 0; + if(end = strchr(pstr,'@')) { + pstr = end + 1; + strcpy(&plink->value.bbgpibio.parm[0],pstr); + } + } + break; + case VXI_IO: { + char *end; + + if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField); + pstr = end + 1; + memset((char *)&plink->value.vxiio,0,sizeof(struct vxiio)); + if(!(end = strchr(pstr,'C'))) { + plink->value.vxiio.flag = VXISTATIC; + if(!(end = strchr(pstr,'V'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.vxiio.la); + } else { + plink->value.vxiio.flag = VXIDYNAMIC; + if(!(end = strchr(pstr,'V'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.vxiio.frame); + if(!(end = strchr(pstr,'C'))) return (S_dbLib_badField); + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.vxiio.slot); + } + if(end = strchr(pstr,'S')) { + pstr = end + 1; + sscanf(pstr,"%hd",&plink->value.vxiio.signal); + } else { + plink->value.vxiio.signal = 0; + } + plink->value.vxiio.parm[0] = 0; + if(end = strchr(pstr,'@')) { + pstr = end + 1; + strcpy(&plink->value.vxiio.parm[0],pstr); + } + } + break; + case INST_IO: { + char *end; + + plink->value.instio.string[0] = 0; + if(end = strchr(pstr,'@')) { + pstr = end + 1; + strcpy(&plink->value.instio.string[0],pstr); + } + } + break; + } + } + break; + default: + return (S_dbLib_badField); + } + return(status); +} + +char *dbVerify(DBENTRY *pdbentry,char *pstring) +{ + dbFldDes *pflddes = pdbentry->pflddes; + char *message; + + message = getpMessage(pdbentry); + *message = 0; + if(!pflddes) {strcpy(message,"fldDes not found"); return(message);} + switch (pflddes->field_type) { + case DBF_STRING: { + unsigned int length; + + length=strlen(pstring); + if(length>=pflddes->size) { + sprintf(message,"string to big. max=%hd",pflddes->size); + return(message); + } + if(pflddes->special == SPC_CALC) { + char rpcl[RPCL_LEN]; + short error_number; + long status; + + status = postfix(pstring,rpcl,&error_number); + if(status) { + sprintf(message,"Illegal Calculation String"); + return(message); + } + } + } + return(NULL); + case DBF_CHAR : + case DBF_SHORT : + case DBF_LONG:{ + long value; + char *endp; + + value = strtol(pstring,&endp,0); + if(*endp!=0) { + strcpy(message,"not an integer number"); + return(message); + } + switch (pflddes->field_type) { + case DBF_CHAR : + if(value<-128 || value>127) { + strcpy(message,"must have -128<=value<=127"); + return(message); + } + return(NULL); + case DBF_SHORT : + if(value<-32768 || value>32767) { + strcpy(message,"must have -32768<=value<=32767"); + return(message); + } + return(NULL); + case DBF_LONG : return(NULL); + default: + errPrintf(-1,__FILE__, __LINE__,"Logic Error\n"); + return(NULL); + } + } + case DBF_UCHAR: + case DBF_USHORT: + case DBF_ULONG: + case DBF_ENUM:{ + unsigned long value; + char *endp; + + value = strtoul(pstring,&endp,0); + if(*endp!=0) { + strcpy(message,"not an integer number"); + return(message); + } + switch (pflddes->field_type) { + case DBF_UCHAR : + if(value>255) { + strcpy(message,"must have 0<=value<=255"); + return(message); + } + return(NULL); + case DBF_ENUM: + case DBF_USHORT : + if(value>65535) { + strcpy(message,"must have 0<=value<=65535"); + return(message); + } + return(NULL); + case DBF_ULONG : return(NULL); + default: + errPrintf(-1,__FILE__, __LINE__,"Logic Error\n"); + return(NULL); + } + } + case DBF_FLOAT: + case DBF_DOUBLE: { + double value; + char *endp; + + value = strtod(pstring,&endp); + if(*endp!=0) { + strcpy(message,"not a number"); + return(message); + } + return(NULL); + } + case DBF_MENU: { + dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; + char *pchoice; + int i; + + if(!pdbMenu) return(NULL); + for (i = 0; i < pdbMenu->nChoice; i++) { + if(!(pchoice = pdbMenu->papChoiceValue[i])) continue; + if(strcmp(pchoice, pstring) == 0) { + return(NULL); + } + } + } + strcpy(message,"Not a valid menu choice"); + return (message); + case DBF_DEVICE: { + dbDeviceMenu *pdbDeviceMenu; + char *pchoice; + int i; + + if(!pflddes->ftPvt) dbInitDeviceMenu(pdbentry); + pdbDeviceMenu = (dbDeviceMenu *)pflddes->ftPvt; + if(!pdbDeviceMenu) return(NULL); + for (i = 0; i < pdbDeviceMenu->nChoice; i++) { + if (!(pchoice = pdbDeviceMenu->papChoice[i])) + continue; + if (strcmp(pchoice, pstring) == 0) { + return(NULL); + } + } + } + strcpy(message,"Not a valid menu choice"); + return (message); + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: + return(NULL); + default: break; + } + strcpy(message,"Not a valid field type"); + return (message); +} + +char *dbGetRange(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + char *message; + + message = getpMessage(pdbentry); + *message = 0; + if(!pflddes) {strcpy(message,"fldDes not found"); return(message);} + switch (pflddes->field_type) { + case DBF_STRING: {strcpy(message,"string"); return(message);} + case DBF_CHAR : {strcpy(message,"-128<->127"); return(message);} + case DBF_SHORT : {strcpy(message,"-32768<->32767");return(message);} + case DBF_LONG: {strcpy(message,"integer"); return(message);} + case DBF_UCHAR: {strcpy(message,"0<->255");return(message);} + case DBF_USHORT:{strcpy(message,"0<->65535");return(message);} + case DBF_ULONG:{strcpy(message,"unsigned integer");return(message);} + case DBF_ENUM: return(NULL); + case DBF_FLOAT: + case DBF_DOUBLE: {strcpy(message,"float");return(message);} + case (DBF_MENU): + case (DBF_DEVICE): + {strcpy(message,"menu");return(message);} + case DBF_INLINK: {strcpy(message,"inlink");return(message);} + case DBF_OUTLINK: {strcpy(message,"outlink");return(message);} + case DBF_FWDLINK: {strcpy(message,"fwdlink");return(message);} + default: + errPrintf(-1,__FILE__, __LINE__,"Logic Error\n"); + } + strcpy(message,"Not a valid field type"); + return (message); +} + +brkTable *dbFindBrkTable(dbBase *pdbBase,char *name) +{ + GPHENTRY *pgph; + + pgph = gphFind(pdbBase->pgpHash,name,(void *)&pdbBase->bptList); + if(!pgph) return(NULL); + return((brkTable *)pgph->userPvt); +} + +dbMenu *dbFindMenu(dbBase *pdbBase,char *name) +{ + GPHENTRY *pgph; + + pgph = gphFind(pdbBase->pgpHash,name,(void *)&pdbBase->menuList); + if(!pgph) return(NULL); + return((dbMenu *)pgph->userPvt); +} + +char **dbGetChoices(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + + if(!pflddes) return(NULL); + if(!pfield) return(NULL); + switch (pflddes->field_type) { + case DBF_MENU: { + dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; + + if(!pdbMenu) return(NULL); + return(pdbMenu->papChoiceValue); + } + case DBF_DEVICE: { + dbDeviceMenu *pdbDeviceMenu; + + if(!pflddes->ftPvt) dbInitDeviceMenu(pdbentry); + pdbDeviceMenu = (dbDeviceMenu *)pflddes->ftPvt; + if(!pdbDeviceMenu) return(NULL); + return(pdbDeviceMenu->papChoice); + } + default: + return(NULL); + } +} + +int dbGetMenuIndex(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + + if(!pflddes) return(-1); + if(!pfield) return(-1); + switch (pflddes->field_type) { + case (DBF_MENU): + case (DBF_DEVICE): + return((int)(*(unsigned short *)pfield)); + default: + errPrintf(-1,__FILE__, __LINE__,"Logic Error\n"); + } + return(-1); +} + +long dbPutMenuIndex(DBENTRY *pdbentry,int index) +{ + dbFldDes *pflddes = pdbentry->pflddes; + unsigned short *pfield = pdbentry->pfield; + + if(!pflddes) return(S_dbLib_flddesNotFound); + if(!pfield) return(S_dbLib_fieldNotFound); + switch (pflddes->field_type) { + case DBF_MENU: { + dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; + + if(!pdbMenu) return(S_dbLib_menuNotFound); + if(index<0 | index>=pdbMenu->nChoice) return(S_dbLib_badField); + *pfield = (unsigned short)index; + return(0); + } + case DBF_DEVICE: { + dbDeviceMenu *pdbDeviceMenu; + + if(!pflddes->ftPvt) dbInitDeviceMenu(pdbentry); + pdbDeviceMenu = (dbDeviceMenu *)pflddes->ftPvt; + if(!pdbDeviceMenu) return(S_dbLib_menuNotFound); + if(index<0 | index>=pdbDeviceMenu->nChoice) + return(S_dbLib_badField); + *pfield = (unsigned short)index; + return(0); + } + default: + break; + } + return (S_dbLib_badField); +} + +int dbGetNMenuChoices(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + + if(!pflddes) return(-1); + switch (pflddes->field_type) { + case DBF_MENU: { + dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; + + if(!pdbMenu) return(NULL); + return(pdbMenu->nChoice); + } + case DBF_DEVICE: { + dbDeviceMenu *pdbDeviceMenu; + + if(!pflddes->ftPvt) dbInitDeviceMenu(pdbentry); + pdbDeviceMenu = (dbDeviceMenu *)pflddes->ftPvt; + if(!pdbDeviceMenu) return(NULL); + return(pdbDeviceMenu->nChoice); + } + default: + break; + } + return (-1); +} + +int dbAllocForm(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + short indfield = pdbentry->indfield; + dbFldDes *plinkflddes; + DBLINK *plink; + int nlines=0; + char *pstr; + struct form *pform; + long status; + int nbytes,i; + + if(pflddes->field_type != DBF_DEVICE) return(0); + status = dbFindField(pdbentry,"INP"); + if(status) status = dbFindField(pdbentry,"OUT"); + if(!status) { + plinkflddes = pdbentry->pflddes; + plink = (DBLINK *)(pdbentry->pfield); + nlines = formlines[plink->type]; + nbytes = sizeof(struct form) + + 2*nlines*(sizeof(char *) + MAX_STRING_SIZE); + pform = dbCalloc(1,nbytes); + pdbentry->formpvt = pform; + pform->plink = plink ; + pform->prompt = promptAddr[plink->type]; + pform->value = (char **)((char *)pform + sizeof(struct form)); + pform->verify = (char **)((char *)(pform->value)+nlines*sizeof(char *)); + pstr = (char *)(pform->verify) + nlines*sizeof(char *); + for(i=0; ivalue[i] = pstr; + pstr += MAX_STRING_SIZE; + } + for(i=0; iverify[i] = pstr; + pstr += MAX_STRING_SIZE; + } + + } + pdbentry->pflddes = pflddes; + pdbentry->pfield = pfield; + pdbentry->indfield = indfield; + return(nlines); +} + +long dbFreeForm(DBENTRY *pdbentry) +{ + if(pdbentry->formpvt) free(pdbentry->formpvt); + return(0); +} + +char **dbGetFormPrompt(DBENTRY *pdbentry) +{ + struct form *pform = pdbentry->formpvt; + + if(!pform) return(NULL); + return(pform->prompt); +} + +char **dbGetFormValue(DBENTRY *pdbentry) +{ + struct form *pform = pdbentry->formpvt; + DBLINK *plink; + char **value; + + if(!pform) return(NULL); + plink = pform->plink; + if(!plink) return(NULL); + value = pform->value; + switch(plink->type) { + case CONSTANT: + if(plink->value.constantStr) { + strcpy(*value,plink->value.constantStr); + } else { + *value = 0; + } + break; + case PV_LINK: + strcpy(*value,plink->value.pv_link.pvname); + value++; + strcpy(*value, (plink->value.pv_link.process_passive ? "Yes" : "No")); + value++; + strcpy(*value, (plink->value.pv_link.maximize_sevr ? "Yes" : "No")); + break; + case VME_IO: + cvtShortToString(plink->value.vmeio.card,*value); + value++; + cvtShortToString(plink->value.vmeio.signal,*value); + value++; + strcpy(*value,plink->value.vmeio.parm); + break; + case CAMAC_IO: + cvtShortToString(plink->value.camacio.b,*value); + value++; + cvtShortToString(plink->value.camacio.c,*value); + value++; + cvtShortToString(plink->value.camacio.n,*value); + value++; + cvtShortToString(plink->value.camacio.a,*value); + value++; + cvtShortToString(plink->value.camacio.f,*value); + value++; + strcpy(*value,plink->value.camacio.parm); + break; + case RF_IO: + cvtShortToString(plink->value.rfio.cryo,*value); + value++; + cvtShortToString(plink->value.rfio.micro,*value); + value++; + cvtShortToString(plink->value.rfio.dataset,*value); + value++; + cvtShortToString(plink->value.rfio.element,*value); + break; + case AB_IO: + cvtShortToString(plink->value.abio.link,*value); + value++; + cvtShortToString(plink->value.abio.adapter,*value); + value++; + cvtShortToString(plink->value.abio.card,*value); + value++; + cvtShortToString(plink->value.abio.signal,*value); + value++; + strcpy(*value,plink->value.abio.parm); + break; + case GPIB_IO: + cvtShortToString(plink->value.gpibio.link,*value); + value++; + cvtShortToString(plink->value.gpibio.addr,*value); + value++; + strcpy(*value,plink->value.gpibio.parm); + break; + case BITBUS_IO: + cvtCharToString(plink->value.bitbusio.link,*value); + value++; + cvtCharToString(plink->value.bitbusio.node,*value); + value++; + cvtCharToString(plink->value.bitbusio.port,*value); + value++; + cvtCharToString(plink->value.bitbusio.signal,*value); + value++; + strcpy(*value,plink->value.bitbusio.parm); + break; + case INST_IO: + strcpy(*value,plink->value.instio.string); + break; + case BBGPIB_IO: + cvtCharToString(plink->value.bbgpibio.link,*value); + value++; + cvtCharToString(plink->value.bbgpibio.bbaddr,*value); + value++; + cvtCharToString(plink->value.bbgpibio.gpibaddr,*value); + value++; + strcpy(*value,plink->value.bbgpibio.parm); + break; + case VXI_IO: + strcpy(*value,(plink->value.vxiio.flag == VXIDYNAMIC ? "Yes" : "No")); + value++; + if(plink->value.vxiio.flag == VXIDYNAMIC) + cvtShortToString(plink->value.vxiio.frame,*value); + else + **value = 0; + value++; + if(plink->value.vxiio.flag == VXIDYNAMIC) + cvtShortToString(plink->value.vxiio.slot,*value); + else + **value = 0; + value++; + if(plink->value.vxiio.flag == VXISTATIC) + cvtShortToString(plink->value.vxiio.la,*value); + else + **value = 0; + value++; + cvtShortToString(plink->value.vxiio.signal,*value); + value++; + strcpy(*value,plink->value.vxiio.parm); + break; + default : + return(NULL); + } + return(pform->value); +} + +long dbPutForm(DBENTRY *pdbentry,char **value) +{ + struct form *pform = pdbentry->formpvt; + DBLINK *plink; + char **verify; + long lvalue; + double dvalue; + char *endp; + + if(!pform) return(S_dbLib_badLink); + plink = pform->plink; + if(!plink) return(S_dbLib_badLink); + verify = pform->verify; + switch(plink->type) { + case CONSTANT: + **verify = 0; /*Initialize to no error*/ + if(**value == '\0') break; + dvalue = strtod(*value,&endp); + if(*endp!=0) { + strcpy(*verify,"Illegal. Must be number"); + break; + } + if((!plink->value.constantStr) + || (strlen(plink->value.constantStr)value.constantStr); + plink->value.constantStr = dbCalloc(strlen(*value)+1,sizeof(char)); + } + strcpy(plink->value.constantStr,*value); + break; + case PV_LINK: { + int pp=0; + int ms=0; + char *pstr; + + pstr = *value; + **verify = 0; + value++; verify++; + pp = ((strchr(*value,'Y') || strchr(*value,'y') ? TRUE : FALSE)); + value++; verify++; + ms = ((strchr(*value,'Y') || strchr(*value,'y') ? TRUE : FALSE)); + dbPutPvlink(pdbentry,pp,ms,pstr); + } + break; + case VME_IO: + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.vmeio.card = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.vmeio.signal = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + strncpy(plink->value.vmeio.parm,*value,VME_PARAM_SZ-1); + break; + case CAMAC_IO: + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.camacio.b = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.camacio.c = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.camacio.n = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.camacio.a = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.camacio.f = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + strncpy(plink->value.camacio.parm,*value,CAMAC_PARAM_SZ-1); + break; + case RF_IO: + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.rfio.cryo = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.rfio.micro = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.rfio.dataset = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.rfio.element = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + break; + case AB_IO: + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.abio.link = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.abio.adapter = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.abio.card = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.abio.signal = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + strncpy(plink->value.abio.parm,*value,AB_PARAM_SZ-1); + break; + case GPIB_IO: + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.gpibio.link = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.gpibio.addr = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + strncpy(plink->value.gpibio.parm,*value,LINK_PARAM_SZ-1); + **verify = 0; + break; + case BITBUS_IO: + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.bitbusio.link = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.bitbusio.node = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.bitbusio.port = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.bitbusio.signal = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + strncpy(plink->value.bitbusio.parm,*value,LINK_PARAM_SZ-1); + **verify = 0; + break; + case INST_IO: + strncpy(plink->value.instio.string,*value,INSTIO_FLD_SZ-1); + **verify = 0; + break; + case BBGPIB_IO: + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.bbgpibio.link = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.bbgpibio.bbaddr = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.bbgpibio.gpibaddr = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + strncpy(plink->value.bbgpibio.parm,*value,LINK_PARAM_SZ-1); + **verify = 0; + break; + case VXI_IO: + plink->value.vxiio.flag = + ((strchr(*value,'Y')||strchr(*value,'y') ? VXIDYNAMIC : VXISTATIC)); + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.vxiio.frame = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.vxiio.slot = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.vxiio.la = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + lvalue = strtol(*value,&endp,0); + if(*endp==0) { + plink->value.vxiio.signal = lvalue; **verify = 0; + } else { + strcpy(*verify,"Illegal. Must be number"); + } + value++; verify++; + strncpy(plink->value.vxiio.parm,*value,VXI_PARAM_SZ-1); + **verify = 0; + break; + default : + return(S_dbLib_badLink); + } + return(0); +} + +char **dbVerifyForm(DBENTRY *pdbentry,char **value) +{ + struct form *pform = pdbentry->formpvt; + DBLINK *plink; + DBLINK templink; + int nlines,i; + + if(!pform) return(NULL); + plink = pform->plink; + if(!plink) return(NULL); + templink = *plink; + if(plink->type==CONSTANT) templink.value.constantStr = NULL; + if(plink->type==PV_LINK) templink.value.pv_link.pvname = NULL; + pform->plink = &templink; + dbPutForm(pdbentry,value); + if(plink->type==CONSTANT) free((void *)templink.value.constantStr); + if(plink->type==PV_LINK) free((void *)templink.value.pv_link.pvname); + pform->plink = plink; + nlines = pform->nlines; + for(i=0; iverify[i]) return(pform->verify); + return(NULL); +} + +int dbGetNLinks(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + + if(!precdes) return(S_dbLib_recdesNotFound); + return((int)precdes->no_links); +} + +long dbGetLinkField(DBENTRY *pdbentry,int index) +{ + dbRecDes *precdes = pdbentry->precdes; + dbFldDes *pflddes; + + if(!precdes) return(S_dbLib_recdesNotFound); + if(index<0 || index>=precdes->no_links) return(S_dbLib_badLink); + pdbentry->indfield = precdes->link_ind[index]; + pdbentry->pflddes = pflddes = precdes->papFldDes[pdbentry->indfield]; + dbGetFieldAddress(pdbentry); + return(0); +} + +int dbGetLinkType(DBENTRY *pdbentry) +{ + dbFldDes *pflddes; + DBLINK *plink; + int field_type; + int INPorOUT=FALSE; + + dbGetFieldAddress(pdbentry); + pflddes = pdbentry->pflddes; + if(!pflddes) return(-1); + plink = (DBLINK *)pdbentry->pfield; + if(!plink) return(-1); + if(strcmp(pflddes->name,"INP")==0 + || strcmp(pflddes->name,"OUT")==0) INPorOUT = TRUE; + field_type = pflddes->field_type; + switch (field_type) { + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: + switch(plink->type) { + case CONSTANT: + if(INPorOUT) return(DCT_LINK_FORM); + else return(DCT_LINK_CONSTANT); + case PV_LINK: + return(DCT_LINK_PV); + default: + return(DCT_LINK_DEVICE); + } + } + return(-1); +} + +long dbCvtLinkToConstant(DBENTRY *pdbentry) +{ + dbFldDes *pflddes; + DBLINK *plink; + + dbGetFieldAddress(pdbentry); + pflddes = pdbentry->pflddes; + if(!pflddes) return(-1); + plink = (DBLINK *)pdbentry->pfield; + if(!plink) return(-1); + switch (pflddes->field_type) { + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: + if(plink->type == CONSTANT) return(0); + if(plink->type != PV_LINK) return(S_dbLib_badLink); + free((void *)plink->value.pv_link.pvname); + plink->type = CONSTANT; + if(pflddes->initial) { + plink->value.constantStr = + dbCalloc(strlen(pflddes->initial)+1,sizeof(char)); + strcpy(plink->value.constantStr,pflddes->initial); + } + return(0); + default: + errPrintf(-1,__FILE__, __LINE__,"Logic Error\n"); + } + return(S_dbLib_badLink); +} + +long dbCvtLinkToPvlink(DBENTRY *pdbentry) +{ + dbFldDes *pflddes; + DBLINK *plink; + + dbGetFieldAddress(pdbentry); + pflddes = pdbentry->pflddes; + if(!pflddes) return(-1); + plink = (DBLINK *)pdbentry->pfield; + if(!plink) return(-1); + switch (pflddes->field_type) { + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: + if(plink->type == PV_LINK) return(0); + if(plink->type != CONSTANT) return(S_dbLib_badLink); + free(plink->value.constantStr); + plink->type = PV_LINK; + plink->value.pv_link.process_passive = 0; + plink->value.pv_link.maximize_sevr = 0; + plink->value.pv_link.pvname = 0; + return(0); + default: + errPrintf(-1,__FILE__, __LINE__,"Logic Error\n"); + } + return(S_dbLib_badLink); +} + +long dbPutPvlink(DBENTRY *pdbentry,int pp,int ms,char *pvname) +{ + dbFldDes *pflddes; + DBLINK *plink; + char *pname; + + dbGetFieldAddress(pdbentry); + pflddes = pdbentry->pflddes; + if(!pflddes) return(-1); + plink = (DBLINK *)pdbentry->pfield; + if(!plink) return(-1); + switch (pflddes->field_type) { + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: + if(plink->type != PV_LINK) return(S_dbLib_badLink); + pname = plink->value.pv_link.pvname; + if(pname) free((void **)pname); + pname = dbCalloc(strlen(pvname)+1,sizeof(char)); + plink->value.pv_link.pvname = pname; + strcpy(pname,pvname); + plink->value.pv_link.process_passive = pp; + plink->value.pv_link.maximize_sevr = ms; + return(0); + default: + errPrintf(-1,__FILE__, __LINE__,"Logic Error\n"); + } + return(S_dbLib_badLink); +} + +long dbGetPvlink(DBENTRY *pdbentry,int *pp,int *ms,char *pvname) +{ + dbFldDes *pflddes; + DBLINK *plink; + + dbGetFieldAddress(pdbentry); + pflddes = pdbentry->pflddes; + if(!pflddes) return(-1); + plink = (DBLINK *)pdbentry->pfield; + if(!plink) return(-1); + switch (pflddes->field_type) { + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: + if(plink->type != PV_LINK) return(S_dbLib_badLink); + if(plink->value.pv_link.pvname) { + strcpy(pvname,plink->value.pv_link.pvname); + } else { + strcpy(pvname,"0"); + } + *pp = plink->value.pv_link.process_passive; + *ms = plink->value.pv_link.maximize_sevr; + return(0); + default: + errPrintf(-1,__FILE__, __LINE__,"Logic Error\n"); + return(NULL); + } +} + +void dbDumpMenu(DBBASE *pdbbase,char *menuName) +{ + dbMenu *pdbMenu; + int gotMatch; + int i; + + if(!pdbbase) { + printf("pdbBase not specified\n"); + return; + } + pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList); + while(pdbMenu) { + if(menuName) { + gotMatch = (strcmp(menuName,pdbMenu->name)==0) ? TRUE : FALSE; + }else { + gotMatch=TRUE; + } + if(gotMatch) { + printf("menu(%s) {\n",pdbMenu->name); + for(i=0; inChoice; i++) { + printf("\tchoice(%s,%s)\n",pdbMenu->papChoiceName[i], + pdbMenu->papChoiceValue[i]); + } + printf("}\n"); + if(menuName) break; + } + pdbMenu = (dbMenu *)ellNext(&pdbMenu->node); + } +} + +void dbDumpRecDes(DBBASE *pdbbase,char *recdesName) +{ + dbRecDes *pdbRecDes; + dbFldDes *pdbFldDes; + int gotMatch; + int i; + + if(!pdbbase) { + printf("pdbBase not specified\n"); + return; + } + for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); + pdbRecDes; pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) { + if(recdesName) { + gotMatch = (strcmp(recdesName,pdbRecDes->name)==0) ? TRUE : FALSE; + }else { + gotMatch=TRUE; + } + if(!gotMatch) continue; + printf("name(%s) no_fields(%hd) no_prompt(%hd) no_links(%hd)\n", + pdbRecDes->name,pdbRecDes->no_fields, + pdbRecDes->no_prompt,pdbRecDes->no_links); + printf("index name\tsortind sortname\n"); + for(i=0; ino_fields; i++) { + pdbFldDes = pdbRecDes->papFldDes[i]; + printf("%5d %s\t%7d %s\n", + i,pdbFldDes->name, + pdbRecDes->sortFldInd[i],pdbRecDes->papsortFldName[i]); + } + printf("link_ind "); + for(i=0; ino_links; i++) + printf(" %hd",pdbRecDes->link_ind[i]); + printf("\n"); + printf("indvalFlddes %d name %s\n",pdbRecDes->indvalFlddes, + pdbRecDes->pvalFldDes->name); + printf("struct rset * %p rec_size %d\n", + pdbRecDes->prset,pdbRecDes->rec_size); + if(recdesName) break; + } +} + +void dbDumpFldDes(DBBASE *pdbbase,char *recdesName,char *fname) +{ + dbRecDes *pdbRecDes; + dbFldDes *pdbFldDes; + int gotMatch; + int i; + + if(!pdbbase) { + printf("pdbBase not specified\n"); + return; + } + for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); + pdbRecDes; pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) { + if(recdesName) { + gotMatch = (strcmp(recdesName,pdbRecDes->name)==0) ? TRUE : FALSE; + }else { + gotMatch=TRUE; + } + if(!gotMatch) continue; + printf("recordtype(%s) \n",pdbRecDes->name); + for(i=0; ino_fields; i++) { + int j; + + pdbFldDes = pdbRecDes->papFldDes[i]; + if(fname && strcmp(fname,pdbFldDes->name)!=0) continue; + printf(" %s\n", pdbFldDes->name); + printf("\t prompt: %s\n",pdbFldDes->prompt); + printf("\t extra: %s\n",pdbFldDes->extra); + printf("\t indRecDes: %hd\n",pdbFldDes->indRecDes); + printf("\t special: %hd ",pdbFldDes->special); + if(pdbFldDes->special) { + for(j=0; jspecial) { + printf("%s",pamapspcType[j].strvalue); + break; + } + } + } + printf("\n"); + for(j=0; jfield_type) break; + } + if(j>=DBF_NTYPES) + printf("\t field_type: %d\n", pdbFldDes->field_type); + else + printf("\t field_type: %s\n", pamapdbfType[j].strvalue); + printf("\tprocess_passive: %hd\n",pdbFldDes->process_passive); + printf("\t base: %hd\n",pdbFldDes->base); + if(!pdbFldDes->promptgroup) { + printf("\t promptgroup: %d\n",pdbFldDes->promptgroup); + } else { + for(j=0; jpromptgroup) { + printf("\t promptgroup: %s\n", + pamapguiGroup[j].strvalue); + break; + } + } + } + printf("\t interest: %hd\n", pdbFldDes->interest); + printf("\t as_level: %hd\n",pdbFldDes->as_level); + printf("\t initial: %s\n",pdbFldDes->initial); + if(pdbFldDes->field_type==DBF_MENU) { + if(pdbFldDes->ftPvt) + printf("\t\t menu: %s\n", + ((dbMenu *)pdbFldDes->ftPvt)->name); + else + printf("\t\t menu: NOT FOUND\n"); + } + if(pdbFldDes->field_type==DBF_DEVICE) { + printf("\t ftPvt: %p\n",pdbFldDes->ftPvt); + } + printf("\t size: %hd\n",pdbFldDes->size); + printf("\t offset: %hd\n",pdbFldDes->offset); + } + if(recdesName) break; + } +} + +void dbDumpDevice(DBBASE *pdbbase,char *recdesName) +{ + dbRecDes *pdbRecDes; + devSup *pdevSup; + int gotMatch; + + if(!pdbbase) { + printf("pdbBase not specified\n"); + return; + } + for(pdbRecDes = (dbRecDes *)ellFirst(&pdbbase->recDesList); + pdbRecDes; pdbRecDes = (dbRecDes *)ellNext(&pdbRecDes->node)) { + if(recdesName) { + gotMatch = (strcmp(recdesName,pdbRecDes->name)==0) ? TRUE : FALSE; + }else { + gotMatch=TRUE; + } + if(!gotMatch) continue; + printf("recordtype(%s) \n",pdbRecDes->name); + for(pdevSup = (devSup *)ellFirst(&pdbRecDes->devList); + pdevSup; pdevSup = (devSup *)ellNext(&pdevSup->node)) { + printf("\t name: %s\n",pdevSup->name); + printf("\t choice: %s\n",pdevSup->choice); + printf("\tlink_type: %d\n",pdevSup->link_type); + printf("\t pdset: %p\n",pdevSup->pdset); + } + if(recdesName) break; + } +} + +void dbDumpDriver(DBBASE *pdbbase) +{ + drvSup *pdrvSup; + + if(!pdbbase) { + printf("pdbBase not specified\n"); + return; + } + for(pdrvSup = (drvSup *)ellFirst(&pdbbase->drvList); + pdrvSup; pdrvSup = (drvSup *)ellNext(&pdrvSup->node)) { + printf("%s(%p)\n",pdrvSup->name,pdrvSup->pdrvet); + } +} + +void dbDumpRecords(dbBase *pdbbase,char *precdesname,int levl) +{ + if(!pdbbase) { + printf("pdbBase not specified\n"); + return; + } + dbWriteRecords(pdbbase,stdout,precdesname,levl); +} + +static char *bus[VXI_IO+1] = {"","","VME","CAMAC","AB", + "GPIB","BITBUS","","","","","","INST","BBGPIB","VXI"}; +void dbReportDeviceConfig(dbBase *pdbbase,FILE *report) +{ + DBENTRY dbentry; + DBENTRY *pdbentry=&dbentry; + long status; + char busName[40]; + char linkValue[40]; + char dtypValue[40]; + char cvtValue[40]; + int ilink,nlinks; + struct link *plink; + + dbInitEntry(pdbbase,pdbentry); + status = dbFirstRecdes(pdbentry); + while(!status) { + status = dbFirstRecord(pdbentry); + while(!status) { + nlinks = dbGetNLinks(pdbentry); + for(ilink=0; ilinkpfield; + strcpy(busName,bus[plink->type]); + if(strlen(busName)==0) continue; + strcpy(linkValue,dbGetString(pdbentry)); + status = dbFindField(pdbentry,"DTYP"); + if(status) break; + strcpy(dtypValue,dbGetString(pdbentry)); + status = dbFindField(pdbentry,"LINR"); + if(status || *((short *)pdbentry->pfield) <=1 ) { + cvtValue[0] = 0; + } else { + strcpy(cvtValue,"cvt("); + status = dbFindField(pdbentry,"EGUL"); + if(!status) strcat(cvtValue,dbGetString(pdbentry)); + status = dbFindField(pdbentry,"EGUH"); + if(!status) strcat(cvtValue,dbGetString(pdbentry)); + strcat(cvtValue,")"); + } + fprintf(report,"%-8s %-20s %-20s %-20s %-s\n", + busName,linkValue,dtypValue, + dbGetRecordName(pdbentry),cvtValue); + break; + } + status = dbNextRecord(pdbentry); + } + status = dbNextRecdes(pdbentry); + } + dbFinishEntry(pdbentry); + return; +} diff --git a/src/dbStatic/dbStaticNoRun.c b/src/dbStatic/dbStaticNoRun.c new file mode 100644 index 000000000..1382bf3d8 --- /dev/null +++ b/src/dbStatic/dbStaticNoRun.c @@ -0,0 +1,266 @@ +/*dbStaticNoRun.c*/ +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + +This software was developed under a United States Government license +described on the COPYRIGHT_UniversityOfChicago file included as part +of this distribution. +**********************************************************************/ + +/* + * Modification Log: + * ----------------- + * .01 06-JUN-95 mrk Initial Version + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +long dbAllocRecord(DBENTRY *pdbentry,char *precordName) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes; + void **papField; + int i; + char *pstr; + + if(!precdes) return(S_dbLib_recdesNotFound); + if(!precnode) return(S_dbLib_recNotFound); + precnode->precord = dbCalloc(precdes->no_fields,sizeof(void *)); + papField = (void **)precnode->precord; + for(i=0; ino_fields; i++) { + pflddes = precdes->papFldDes[i]; + if(!pflddes) continue; + switch(pflddes->field_type) { + case DBF_STRING: + if(pflddes->size <= 0) { + epicsPrintf("size=0 for %s.%s\n",precdes->name,pflddes->name); + pflddes->size = 1; + } + papField[i] = dbCalloc(pflddes->size,sizeof(char)); + if(pflddes->initial) { + if(strlen(pflddes->initial) >= pflddes->size) { + epicsPrintf("initial size > size for %s.%s\n", + precdes->name,pflddes->name); + } else { + strcpy((char *)papField[i],pflddes->initial); + } + } + break; + case DBF_CHAR: + case DBF_UCHAR: + case DBF_SHORT: + case DBF_USHORT: + case DBF_LONG: + case DBF_ULONG: + case DBF_FLOAT: + case DBF_DOUBLE: + case DBF_ENUM: + if(pflddes->initial) { + papField[i] = + dbCalloc(strlen(pflddes->initial)+1,sizeof(char)); + strcpy((char *)papField[i],pflddes->initial); + } + break; + case DBF_MENU: + case DBF_DEVICE: + papField[i] = dbCalloc(1,sizeof(unsigned short)); + if(pflddes->initial) sscanf(pflddes->initial,"%hu",papField[i]); + break; + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: { + struct link *plink; + + papField[i] = plink = dbCalloc(1,sizeof(struct link)); + if(pflddes->initial) { + plink->value.constantStr = + dbCalloc(strlen(pflddes->initial)+1,sizeof(char)); + strcpy(plink->value.constantStr,pflddes->initial); + } + } + break; + case DBF_NOACCESS: + break; + default: + epicsPrintf("dbAllocRecord: Illegal field type\n"); + } + } + pstr = (char *)papField[0]; + strcpy(pstr,precordName); + return(0); +} + +long dbFreeRecord(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes = pdbentry->pflddes; + void **pap; + int i,field_type; + + if(!precdes) return(S_dbLib_recdesNotFound); + if(!precnode) return(S_dbLib_recNotFound); + if(!precnode->precord) return(S_dbLib_recNotFound); + pap = (void **)precnode->precord; + precnode->precord = NULL; + for(i=0; ino_fields; i++) { + pflddes = precdes->papFldDes[i]; + field_type = pflddes->field_type; + if(field_type==DBF_INLINK + || field_type==DBF_OUTLINK + || field_type==DBF_FWDLINK) { + struct link *plink = (struct link *)pap[i]; + + if(plink->type== CONSTANT) + free((void *)plink->value.constantStr); + if(plink->type==PV_LINK) + free((void *)plink->value.pv_link.pvname); + } + free(pap[i]); + } + free((void *)pap); + return(0); +} + +long dbGetFieldAddress(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes = pdbentry->pflddes; + void **pap; + + if(!precdes) return(S_dbLib_recdesNotFound); + if(!precnode) return(S_dbLib_recNotFound); + if(!pflddes) return(S_dbLib_flddesNotFound); + if(!precnode->precord) return(0); + pap = (void **)precnode->precord; + pdbentry->pfield = pap[pflddes->indRecDes]; + return(0); +} + +char *dbRecordName(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + void **pap; + + if(!precdes) return(0); + if(!precnode) return(0); + if(!precnode->precord) return(0); + pap = (void **)precnode->precord; + return((char *)pap[0]); +} + +int dbIsDefaultValue(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + + if(!pflddes) return(FALSE); + switch (pflddes->field_type) { + case DBF_STRING: + if(!pfield) return(FALSE); + if(!pflddes->initial) + return((*(char *)pfield =='\0') ? TRUE : FALSE); + return(strcmp((char *)pfield,(char *)pflddes->initial)==0); + case DBF_CHAR: + case DBF_UCHAR: + case DBF_SHORT: + case DBF_USHORT: + case DBF_LONG: + case DBF_ULONG: + case DBF_FLOAT: + case DBF_DOUBLE: + case DBF_ENUM: + if(!pfield) return(TRUE); + if(!pflddes->initial) return(FALSE); + return(strcmp((char *)pfield,(char *)pflddes->initial)==0); + case DBF_MENU: + case DBF_DEVICE: { + unsigned short val,ival; + + if(!pfield) return(FALSE); + val = *(unsigned short *)pfield; + if(pflddes->initial == 0) return((val==0)?TRUE:FALSE); + sscanf(pflddes->initial,"%hu",&ival); + return((val==ival)?TRUE:FALSE); + } + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: { + struct link *plink = (struct link *)pfield; + + if(!plink) return(FALSE); + if(plink->type!=CONSTANT) return(FALSE); + if(plink->value.constantStr == 0) return(TRUE); + if(strcmp(plink->value.constantStr,pflddes->initial)==0) + return(TRUE); + return(FALSE); + } + } + return(FALSE); +} + +char *dbGetStringNum(DBENTRY *pdbentry) +{ + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + void **pap; + static char zero[] = "0"; + + if(!precnode) return(0); + if(!precnode->precord) return(0); + if(!pflddes) return(0); + pap = (void **)precnode->precord; + if(!pfield) return(zero); + return((char *)pap[pflddes->indRecDes]); +} + +long dbPutStringNum(DBENTRY *pdbentry,char *pstring) +{ + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes = pdbentry->pflddes; + char *pfield = (char *)pdbentry->pfield; + void **pap; + + if(!precnode) return(S_dbLib_recNotFound); + if(!precnode->precord) return(S_dbLib_recNotFound); + if(!pflddes) return(S_dbLib_flddesNotFound); + if(pfield) { + if(strlen(pfield) < strlen(pstring)) { + free((void *)pfield); + pfield = NULL; + } + } + if(!pfield) { + pfield = dbCalloc(strlen(pstring)+1,sizeof(char)); + strcpy(pfield,pstring); + pdbentry->pfield = pfield; + pap = (void **)precnode->precord; + pap[pflddes->indRecDes] = pfield; + } + strcpy(pfield,pstring); + return(0); +} + +void dbGetRecordtypeSizeOffset(dbRecDes *pdbRecDes) +{ + /*For no run cant and dont need to set size and offset*/ + return; +} diff --git a/src/dbStatic/dbStaticPvt.h b/src/dbStatic/dbStaticPvt.h new file mode 100644 index 000000000..df0a93eb7 --- /dev/null +++ b/src/dbStatic/dbStaticPvt.h @@ -0,0 +1,64 @@ +/* dbStaticPvt.h */ +/* + * Author: Marty Kraimer + * Date: 06Jun95 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * .01 06JUN95 mrk Initial version + */ + +#ifndef INCdbStaticPvth +#define INCdbStaticPvth 1 + +/*Following are not intended for client code */ +void dbInitDeviceMenu(DBENTRY *pdbentry); + +/*The following routines have different versions for run-time no-run-time*/ +long dbAllocRecord(DBENTRY *pdbentry,char *precordName); +long dbFreeRecord(DBENTRY *pdbentry); + +long dbGetFieldAddress(DBENTRY *pdbentry); +char *dbRecordName(DBENTRY *pdbentry); + +char *dbGetStringNum(DBENTRY *pdbentry); +long dbPutStringNum(DBENTRY *pdbentry,char *pstring); + +void dbGetRecordtypeSizeOffset(dbRecDes *pdbRecDes); + +/*The following are in dbPvdLib.c*/ +/*directory*/ +typedef struct{ + ELLNODE node; + dbRecDes *precdes; + dbRecordNode *precnode; +}PVDENTRY; +int dbPvdTableSize(DBBASE *pdbBase,int size); +void dbPvdInitPvt(DBBASE *pdbBase); +PVDENTRY *dbPvdFind(DBBASE *pdbBase,char *name,int lenname); +PVDENTRY *dbPvdAdd(DBBASE *pdbBase,dbRecDes *precdes,dbRecordNode *precnode); +void dbPvdDelete(DBBASE *pdbBase,dbRecordNode *precnode); +void dbPvdFreeMem(DBBASE *pdbBase); +void dbPvdDump(DBBASE *pdbBase,int verbose); +#endif /*INCdbStaticPvth*/ diff --git a/src/dbStatic/dbStaticRun.c b/src/dbStatic/dbStaticRun.c new file mode 100644 index 000000000..7d27aa17e --- /dev/null +++ b/src/dbStatic/dbStaticRun.c @@ -0,0 +1,591 @@ +/*dbStaticLibRun.c*/ +/***************************************************************** + COPYRIGHT NOTIFICATION +***************************************************************** + +(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO + +This software was developed under a United States Government license +described on the COPYRIGHT_UniversityOfChicago file included as part +of this distribution. +**********************************************************************/ + +/* Modification Log: + * ----------------- + * .01 06-12-95 mrk Initial + */ + +#ifdef vxWorks +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include /* for sysSymTbl*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char hex_digit_to_ascii[16]={'0','1','2','3','4','5','6','7','8','9', + 'a','b','c','d','e','f'}; + +static void ulongToHexString(unsigned long source,char *pdest) +{ + unsigned long val,temp; + char digit[10]; + int i,j; + + if(source==0) { + strcpy(pdest,"0x0"); + return; + } + *pdest++ = '0'; *pdest++ = 'x'; + val = source; + for(i=0; val!=0; i++) { + temp = val/16; + digit[i] = hex_digit_to_ascii[val - temp*16]; + val = temp; + } + for(j=i-1; j>=0; j--) { + *pdest++ = digit[j]; + } + *pdest = 0; + return; +} + +static double delta[2]={1e-6,1e-15}; +static int precision[2]={6,14}; +static void realToString(double value,char *preturn,int isdouble) +{ + long intval; + double diff,absvalue; + int logval,prec,end; + char tstr[30]; + char *ptstr=&tstr[0]; + int round; + int ise=FALSE; + char *loce=NULL; + + if(value==0.0) {strcpy(preturn,"0"); return;}; + intval=value; + diff = value - intval; + if(diff<0.0) diff =-diff; + absvalue = (value<0.0? -value: value); + if(diff < absvalue*delta[isdouble]) { + cvtLongToString(intval,preturn); + return; + } + /*Now starts the hard cases*/ + if(value<0.0) {*preturn++ = '-'; value = -value;} + logval = (int)log10(value); + if(logval>6 || logval<-2 ) { + ise=TRUE; + prec = precision[isdouble]; + sprintf(ptstr,"%.*e",prec,value); + loce = strchr(ptstr,'e'); + if(!loce) {errMessage(-1,"logic error in real to string"); return;} + *loce++ = 0; + } else { + prec = precision[isdouble]-logval; + if(prec<0)prec=0; + sprintf(ptstr,"%.*f",prec,value); + } + if(prec>0) { + end = strlen(ptstr) -1; + round=FALSE; + while(TRUE) { + if(end<=0)break; + if(tstr[end]=='.'){end--; break;} + if(tstr[end]=='0'){end--; continue;} + if(!round && endprecdes; + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes; + int i; + char *precord; + char *pfield; + + if(!precdes) return(S_dbLib_recdesNotFound); + if(!precnode) return(S_dbLib_recNotFound); + precnode->precord = dbCalloc(1,precdes->rec_size); + precord = (char *)precnode->precord; + if(precdes->rec_size == 0) { + epicsPrintf("dbAllocRecord(%s) record_size =0\n", + precdes->name); + return(S_dbLib_noRecSup); + } + pflddes = precdes->papFldDes[0]; + if(!pflddes) { + epicsPrintf("dbAllocRecord pflddes for NAME not found\n"); + return(S_dbLib_flddesNotFound); + } + if(strlen(precordName)>=pflddes->size) { + epicsPrintf("dbAllocRecord: NAME(%s) too long\n",precordName); + return(S_dbLib_nameLength); + } + pfield = precord + pflddes->offset; + strcpy(pfield,precordName); + for(i=1; ino_fields; i++) { + + pflddes = precdes->papFldDes[i]; + if(!pflddes) continue; + pfield = precord + pflddes->offset; + pdbentry->pfield = (void *)pfield; + pdbentry->pflddes = pflddes; + pdbentry->indfield = i; + switch(pflddes->field_type) { + case DBF_STRING: + if(pflddes->initial) { + if(strlen(pflddes->initial) >= pflddes->size) { + epicsPrintf("initial size > size for %s.%s\n", + precdes->name,pflddes->name); + } else { + strcpy(pfield,pflddes->initial); + } + } + break; + case DBF_CHAR: + case DBF_UCHAR: + case DBF_SHORT: + case DBF_USHORT: + case DBF_LONG: + case DBF_ULONG: + case DBF_FLOAT: + case DBF_DOUBLE: + case DBF_ENUM: + case DBF_DEVICE: + if(!pflddes->ftPvt) dbInitDeviceMenu(pdbentry); + case DBF_MENU: + if(pflddes->initial) { + long status; + + status = dbPutStringNum(pdbentry,pflddes->initial); + if(status) + epicsPrintf("Error initializing %s.%s initial %s\n", + precdes->name,pflddes->name,pflddes->initial); + } + break; + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: { + DBLINK *plink = (DBLINK *)pfield; + + if(pflddes->initial) { + plink->value.constantStr = + dbCalloc(strlen(pflddes->initial)+1,sizeof(char)); + strcpy(plink->value.constantStr,pflddes->initial); + } + } + break; + case DBF_NOACCESS: + break; + default: + epicsPrintf("dbAllocRecord: Illegal field type\n"); + } + } + return(0); +} + +long dbFreeRecord(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + + if(!precdes) return(S_dbLib_recdesNotFound); + if(!precnode) return(S_dbLib_recNotFound); + if(!precnode->precord) return(S_dbLib_recNotFound); + free(precnode->precord); + precnode->precord = NULL; + return(0); +} + +long dbGetFieldAddress(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes = pdbentry->pflddes; + + if(!precdes) return(S_dbLib_recdesNotFound); + if(!precnode) return(S_dbLib_recNotFound); + if(!pflddes) return(S_dbLib_flddesNotFound); + if(!precnode->precord) return(0); + pdbentry->pfield = ((char *)precnode->precord) + pflddes->offset; + return(0); +} + +char *dbRecordName(DBENTRY *pdbentry) +{ + dbRecDes *precdes = pdbentry->precdes; + dbRecordNode *precnode = pdbentry->precnode; + dbFldDes *pflddes; + char *precord; + + if(!precdes) return(0); + if(!precnode) return(0); + if(!precnode->precord) return(0); + precord = (char *)precnode->precord; + pflddes = precdes->papFldDes[0]; + if(!pflddes) return(NULL); + return(precord + pflddes->offset); +} + +int dbIsDefaultValue(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + + if(!pflddes) return(FALSE); + if(!pfield) return(FALSE); + switch (pflddes->field_type) { + case (DBF_STRING) : { + char *p = (char *)pfield; + + if(!pflddes->initial) return((strlen(p)==0) ? TRUE : FALSE); + return((strcmp(pflddes->initial,p)==0) ? TRUE : FALSE); + } + case DBF_CHAR: { + char field = *(char *)pfield; + long ltemp; + if(pflddes->initial) { + ltemp = strtol(pflddes->initial,NULL,0); + return((field==ltemp)); + } + return((field==0)); + } + case DBF_UCHAR: { + unsigned char field = *(unsigned char *)pfield; + unsigned long ltemp; + + if(pflddes->initial) { + ltemp = strtoul(pflddes->initial,NULL,0); + return((field==ltemp)); + } + return((field==0)); + } + case DBF_SHORT: { + short field = *(short *)pfield; + long ltemp; + + if(pflddes->initial) { + ltemp = strtol(pflddes->initial,NULL,0); + return((field==ltemp)); + } + return((field==0)); + } + case DBF_USHORT: { + unsigned short field = *(unsigned short *)pfield; + unsigned long ltemp; + + if(pflddes->initial) { + ltemp = strtoul(pflddes->initial,NULL,0); + return((field==ltemp)); + } + return((field==0)); + } + case DBF_LONG: { + long field = *(long *)pfield; + long ltemp; + + if(pflddes->initial) { + ltemp = strtol(pflddes->initial,NULL,0); + return((field==ltemp)); + } + return((field==0)); + } + case DBF_ULONG: { + unsigned long field = *(unsigned long *)pfield; + unsigned long ltemp; + + if(pflddes->initial) { + ltemp = strtoul(pflddes->initial,NULL,0); + return((field==ltemp)); + } + return((field==0)); + } + case DBF_FLOAT: { + float field = *(float *)pfield; + double dtemp; + + if(pflddes->initial) { + dtemp = strtod(pflddes->initial,NULL); + return((field==dtemp)); + } + return((field==0.0)); + } + case DBF_DOUBLE: { + double field = *(double *)pfield; + double dtemp; + + if(pflddes->initial) { + dtemp = strtod(pflddes->initial,NULL); + return((field==dtemp)); + } + return((field==0.0)); + } + case DBF_ENUM: + case DBF_MENU: + case DBF_DEVICE: { + unsigned short field = *(unsigned short *)pfield; + unsigned long ltemp; + + if(pflddes->initial) { + ltemp = strtoul(pflddes->initial,NULL,0); + return((field==ltemp)); + } + return((field==0)); + } + case DBF_INLINK: + case DBF_OUTLINK: + case DBF_FWDLINK: + return(TRUE); /*Dont know what to do with this!!*/ + default: + return(TRUE); + } + return(FALSE); +} + +char *dbGetStringNum(DBENTRY *pdbentry) +{ + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + char *message; + unsigned char cvttype; + + if(!pdbentry->message) pdbentry->message = dbCalloc(1,50); + message = pdbentry->message; + cvttype = pflddes->base; + switch (pflddes->field_type) { + case DBF_CHAR: + if(cvttype==CT_DECIMAL) + cvtCharToString(*(char*)pfield, message); + else + ulongToHexString((unsigned long)(*(char*)pfield),message); + break; + case DBF_UCHAR: + if(cvttype==CT_DECIMAL) + cvtUcharToString(*(unsigned char*)pfield, message); + else + ulongToHexString((unsigned long)(*(unsigned char*)pfield),message); + break; + case DBF_SHORT: + if(cvttype==CT_DECIMAL) + cvtShortToString(*(short*)pfield, message); + else + ulongToHexString((unsigned long)(*(short*)pfield),message); + break; + case DBF_USHORT: + case DBF_ENUM: + if(cvttype==CT_DECIMAL) + cvtUshortToString(*(unsigned short*)pfield, message); + else + ulongToHexString((unsigned long)(*(unsigned short*)pfield),message); + break; + case DBF_LONG: + if(cvttype==CT_DECIMAL) + cvtLongToString(*(long*)pfield, message); + else + ulongToHexString((unsigned long)(*(long*)pfield), message); + break; + case DBF_ULONG: + if(cvttype==CT_DECIMAL) + cvtUlongToString(*(unsigned long *)pfield, message); + else + ulongToHexString(*(unsigned long*)pfield, message); + break; + case DBF_FLOAT: + floatToString(*(float *)pfield,message); + break; + case DBF_DOUBLE: + doubleToString(*(double *)pfield,message); + break; + default: + return(NULL); + } + return (message); +} + +long dbPutStringNum(DBENTRY *pdbentry,char *pstring) +{ + dbFldDes *pflddes = pdbentry->pflddes; + void *pfield = pdbentry->pfield; + long status=0; + + switch (pflddes->field_type) { + case DBF_CHAR : + case DBF_SHORT : + case DBF_LONG:{ + long value; + char *endp; + + value = strtol(pstring,&endp,0); + if(*endp!=0) status = S_dbLib_badField; + switch (pflddes->field_type) { + case DBF_CHAR : *(char *)pfield = value; break; + case DBF_SHORT : *(short *)pfield = value; break; + case DBF_LONG : *(long *)pfield = value; break; + default: epicsPrintf("Logic error in dbPutStringNum\n"); + } + } + break; + case DBF_UCHAR: + case DBF_USHORT: + case DBF_ULONG: + case DBF_ENUM:{ + unsigned long value; + char *endp; + + value = strtoul(pstring,&endp,0); + if(*endp!=0) status = S_dbLib_badField; + switch (pflddes->field_type) { + case DBF_UCHAR : *(unsigned char *)pfield = value; break; + case DBF_USHORT: + case DBF_ENUM: *(unsigned short *)pfield=value; break; + case DBF_ULONG : *(unsigned long *)pfield = value; break; + default: epicsPrintf("Logic error in dbPutStringNum\n"); + } + } + break; + case DBF_FLOAT: + case DBF_DOUBLE: { + double value; + char *endp; + + value = strtod(pstring,&endp); + if(*endp!=0) status = S_dbLib_badField; + if(pflddes->field_type==DBF_FLOAT) + *(float *)pfield = value; + else + *(double *)pfield = value; + } + break; + case DBF_MENU: { + dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt; + char **papChoiceValue; + char *pchoice; + unsigned short *field= (unsigned short*)pfield; + unsigned int nChoice,ind; + int nargs,nchars; + + if( pdbMenu && (papChoiceValue = pdbMenu->papChoiceValue)) { + nChoice = pdbMenu->nChoice; + for(ind=0; indftPvt; + char **papChoice; + char *pchoice; + unsigned short *field= (unsigned short*)pfield; + unsigned int nChoice,ind; + int nargs,nchars; + + if( pdbDeviceMenu && (papChoice = pdbDeviceMenu->papChoice)) { + nChoice = pdbDeviceMenu->nChoice; + for(ind=0; indname); + strcat(name,"RecordSizeOffset"); + vxstatus = symFindByName(sysSymTbl, name, + (void *)&sizeOffset, &type); + if (vxstatus != OK) { + status = S_rec_noSizeOffset; + errPrintf(status,__FILE__,__LINE__,"%s",pdbRecDes->name); + return; + } + sizeOffset(pdbRecDes); +} diff --git a/src/dev/devAiSoft.c b/src/dev/devAiSoft.c index 6aa1b505e..d97a1aa7b 100644 --- a/src/dev/devAiSoft.c +++ b/src/dev/devAiSoft.c @@ -84,8 +84,8 @@ static long init_record(pai) /* ai.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ switch (pai->inp.type) { case (CONSTANT) : - pai->val = pai->inp.value.value; - pai->udf = FALSE; + if(recGblInitConstantLink(&pai->inp,DBF_DOUBLE,&pai->val)) + pai->udf = FALSE; break; case (PV_LINK) : diff --git a/src/dev/devAiSoftRaw.c b/src/dev/devAiSoftRaw.c index d68436765..8beea2a02 100644 --- a/src/dev/devAiSoftRaw.c +++ b/src/dev/devAiSoftRaw.c @@ -85,7 +85,7 @@ static long init_record(pai) /* ai.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ switch (pai->inp.type) { case (CONSTANT) : - pai->rval = pai->inp.value.value; + recGblInitConstantLink(&pai->inp,DBF_LONG,&pai->rval); break; case (PV_LINK) : case (DB_LINK) : diff --git a/src/dev/devAiTestAsyn.c b/src/dev/devAiTestAsyn.c index 53a4f1850..5bdfa5416 100644 --- a/src/dev/devAiTestAsyn.c +++ b/src/dev/devAiTestAsyn.c @@ -108,8 +108,8 @@ static long init_record(pai) callbackSetCallback(myCallback,&pcallback->callback); pcallback->precord = (struct dbCommon *)pai; pcallback->wd_id = wdCreate(); - pai->val = pai->inp.value.value; - pai->udf = FALSE; + if(recGblInitConstantLink(&pai->inp,DBF_DOUBLE,&pai->val)) + pai->udf = FALSE; break; default : recGblRecordError(S_db_badField,(void *)pai, diff --git a/src/dev/devBiSoft.c b/src/dev/devBiSoft.c index ceeac5200..6a8d402c2 100644 --- a/src/dev/devBiSoft.c +++ b/src/dev/devBiSoft.c @@ -81,8 +81,8 @@ static long init_record(pbi) /* bi.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK */ switch (pbi->inp.type) { case (CONSTANT) : - pbi->val = pbi->inp.value.value; - pbi->udf = FALSE; + if(recGblInitConstantLink(&pbi->inp,DBF_ENUM,&pbi->val)) + pbi->udf = FALSE; break; case (DB_LINK) : case (PV_LINK) : diff --git a/src/dev/devBiSoftRaw.c b/src/dev/devBiSoftRaw.c index 72e3088ab..ef13eeb1a 100644 --- a/src/dev/devBiSoftRaw.c +++ b/src/dev/devBiSoftRaw.c @@ -82,7 +82,7 @@ static long init_record(pbi) /* bi.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ switch (pbi->inp.type) { case (CONSTANT) : - pbi->rval = pbi->inp.value.value; + recGblInitConstantLink(&pbi->inp,DBF_ULONG,&pbi->rval); break; case (DB_LINK) : case (PV_LINK) : diff --git a/src/dev/devBiTestAsyn.c b/src/dev/devBiTestAsyn.c index 2a4951b78..dc536eb74 100644 --- a/src/dev/devBiTestAsyn.c +++ b/src/dev/devBiTestAsyn.c @@ -110,8 +110,8 @@ static long init_record(pbi) callbackSetCallback(myCallback,&pcallback->callback); pcallback->precord = (struct dbCommon *)pbi; pcallback->wd_id = wdCreate(); - pbi->val = pbi->inp.value.value; - pbi->udf = FALSE; + if(recGblInitConstantLink(&pbi->inp,DBF_ENUM,&pbi->val)) + pbi->udf = FALSE; break; default : recGblRecordError(S_db_badField,(void *)pbi, diff --git a/src/dev/devEventSoft.c b/src/dev/devEventSoft.c index a0a720320..6969a6699 100644 --- a/src/dev/devEventSoft.c +++ b/src/dev/devEventSoft.c @@ -79,10 +79,8 @@ static long init_record(pevent) /* event.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ switch (pevent->inp.type) { case (CONSTANT) : - if(pevent->inp.value.value!=0.0 && pevent->val == 0.0){ - pevent->val=pevent->inp.value.value; - } - pevent->udf= FALSE; + if(recGblInitConstantLink(&pevent->inp,DBF_USHORT,&pevent->val)) + pevent->udf = FALSE; break; case (PV_LINK) : status = dbCaAddInlink(&(pevent->inp), (void *) pevent, "VAL"); diff --git a/src/dev/devHistogramSoft.c b/src/dev/devHistogramSoft.c index 505abc2ca..d70a99f19 100644 --- a/src/dev/devHistogramSoft.c +++ b/src/dev/devHistogramSoft.c @@ -80,7 +80,7 @@ static long init_record(phistogram) /* histogram.svl must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ switch (phistogram->svl.type) { case (CONSTANT) : - phistogram->sgnl = phistogram->svl.value.value; + recGblInitConstantLink(&phistogram->svl,DBF_DOUBLE,&phistogram->sgnl); break; case (PV_LINK) : case (DB_LINK) : diff --git a/src/dev/devHistogramTestAsyn.c b/src/dev/devHistogramTestAsyn.c index bbaa236bf..5b3ef3bbe 100644 --- a/src/dev/devHistogramTestAsyn.c +++ b/src/dev/devHistogramTestAsyn.c @@ -107,7 +107,7 @@ static long init_record(phistogram) callbackSetCallback(myCallback,&pcallback->callback); pcallback->precord = (struct dbCommon *)phistogram; pcallback->wd_id = wdCreate(); - phistogram->sgnl = phistogram->svl.value.value; + recGblInitConstantLink(&phistogram->svl,DBF_DOUBLE,&phistogram->sgnl); break; default : recGblRecordError(S_db_badField,(void *)phistogram, diff --git a/src/dev/devLiSoft.c b/src/dev/devLiSoft.c index 93f1d8b4b..7e69955b8 100644 --- a/src/dev/devLiSoft.c +++ b/src/dev/devLiSoft.c @@ -78,8 +78,8 @@ static long init_record(plongin) /* longin.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ switch (plongin->inp.type) { case (CONSTANT) : - plongin->val = plongin->inp.value.value; - plongin->udf = FALSE; + if(recGblInitConstantLink(&plongin->inp,DBF_LONG,&plongin->val)) + plongin->udf = FALSE; break; case (PV_LINK) : case (DB_LINK) : diff --git a/src/dev/devMbbiDirectSoft.c b/src/dev/devMbbiDirectSoft.c index 620f392b6..5ec9c330c 100644 --- a/src/dev/devMbbiDirectSoft.c +++ b/src/dev/devMbbiDirectSoft.c @@ -81,8 +81,8 @@ static long init_record(pmbbi) /* mbbi.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ switch (pmbbi->inp.type) { case (CONSTANT) : - pmbbi->val = pmbbi->inp.value.value; - pmbbi->udf = FALSE; + if(recGblInitConstantLink(&pmbbi->inp,DBF_ENUM,&pmbbi->val)) + pmbbi->udf = FALSE; break; case (DB_LINK) : case (PV_LINK) : diff --git a/src/dev/devMbbiDirectSoftRaw.c b/src/dev/devMbbiDirectSoftRaw.c index 6a0dfa601..4226b2c67 100644 --- a/src/dev/devMbbiDirectSoftRaw.c +++ b/src/dev/devMbbiDirectSoftRaw.c @@ -80,7 +80,7 @@ static long init_record(pmbbi) /* mbbi.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ switch (pmbbi->inp.type) { case (CONSTANT) : - pmbbi->rval = pmbbi->inp.value.value; + recGblInitConstantLink(&pmbbi->inp,DBF_ULONG,&pmbbi->rval); break; case (DB_LINK) : case (PV_LINK) : diff --git a/src/dev/devMbbiSoft.c b/src/dev/devMbbiSoft.c index a90e795a7..94572242b 100644 --- a/src/dev/devMbbiSoft.c +++ b/src/dev/devMbbiSoft.c @@ -80,8 +80,8 @@ static long init_record(pmbbi) long status; if (pmbbi->inp.type == CONSTANT) { - pmbbi->val = pmbbi->inp.value.value; - pmbbi->udf = FALSE; + if(recGblInitConstantLink(&pmbbi->inp,DBF_ENUM,&pmbbi->val)) + pmbbi->udf = FALSE; } else { status = recGblInitFastInLink(&(pmbbi->inp), (void *) pmbbi, DBR_USHORT, "VAL"); diff --git a/src/dev/devMbbiSoftRaw.c b/src/dev/devMbbiSoftRaw.c index 5e499519c..0172d0c96 100644 --- a/src/dev/devMbbiSoftRaw.c +++ b/src/dev/devMbbiSoftRaw.c @@ -81,7 +81,7 @@ static long init_record(pmbbi) long status; if (pmbbi->inp.type == CONSTANT) { - pmbbi->rval = pmbbi->inp.value.value; + recGblInitConstantLink(&pmbbi->inp,DBF_ULONG,&pmbbi->rval); } else { status = recGblInitFastInLink(&(pmbbi->inp), (void *) pmbbi, DBR_ULONG, "RVAL"); diff --git a/src/dev/devMbbiTestAsyn.c b/src/dev/devMbbiTestAsyn.c index a44feba50..d94db7f6f 100644 --- a/src/dev/devMbbiTestAsyn.c +++ b/src/dev/devMbbiTestAsyn.c @@ -109,8 +109,8 @@ static long init_record(pmbbi) callbackSetCallback(myCallback,&pcallback->callback); pcallback->precord = (struct dbCommon *)pmbbi; pcallback->wd_id = wdCreate(); - pmbbi->val = pmbbi->inp.value.value; - pmbbi->udf = FALSE; + if(recGblInitConstantLink(&pmbbi->inp,DBF_ENUM,&pmbbi->val)) + pmbbi->udf = FALSE; break; default : recGblRecordError(S_db_badField,(void *)pmbbi, diff --git a/src/dev/devMpc.c b/src/dev/devMpc.c index af5af7e81..ca6495ef1 100644 --- a/src/dev/devMpc.c +++ b/src/dev/devMpc.c @@ -53,6 +53,9 @@ ***************************************************************** * * $Log$ + * Revision 1.2 1995/04/05 14:13:43 winans + * Only do a sysIntEnable() for those cards that are found with the probe. + * * Revision 1.1 1995/03/31 15:03:32 winans * Machine protection system interface card * @@ -151,6 +154,7 @@ #include "devSup.h" #include "link.h" +#include "dbCommon.h" #include "aiRecord.h" #include "boRecord.h" #include "biRecord.h" diff --git a/src/dev/devMz8310.c b/src/dev/devMz8310.c index 82f2f10bd..71dcad5cb 100644 --- a/src/dev/devMz8310.c +++ b/src/dev/devMz8310.c @@ -57,7 +57,6 @@ #include #include -#include #include #include #include diff --git a/src/dev/devSiSoft.c b/src/dev/devSiSoft.c index 4b5d6439c..1dd19bf64 100644 --- a/src/dev/devSiSoft.c +++ b/src/dev/devSiSoft.c @@ -79,11 +79,8 @@ static long init_record(pstringin) /* stringin.inp must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ switch (pstringin->inp.type) { case (CONSTANT) : - if(pstringin->inp.value.value!=0.0){ - sprintf(pstringin->val,"%-14.7g",pstringin->inp.value.value); - pstringin->udf= FALSE; - } - pstringin->udf= FALSE; + if(recGblInitConstantLink(&pstringin->inp,DBF_STRING,pstringin->val)) + pstringin->udf = FALSE; break; case (PV_LINK) : status = dbCaAddInlink(&(pstringin->inp), (void *) pstringin, "VAL"); diff --git a/src/dev/devSiTestAsyn.c b/src/dev/devSiTestAsyn.c index 3ab207df9..fcd3cfb77 100644 --- a/src/dev/devSiTestAsyn.c +++ b/src/dev/devSiTestAsyn.c @@ -108,10 +108,8 @@ static long init_record(pstringin) callbackSetCallback(myCallback,&pcallback->callback); pcallback->precord = (struct dbCommon *)pstringin; pcallback->wd_id = wdCreate(); - if (pstringin->inp.value.value!=0.0) { - sprintf(pstringin->val,"%-14.7g",pstringin->inp.value.value); - pstringin->udf = FALSE; - } + if(recGblInitConstantLink(&pstringin->inp,DBF_STRING,pstringin->val)) + pstringin->udf = FALSE; break; default : recGblRecordError(S_db_badField,(void *)pstringin, diff --git a/src/dev/devSysmon.c b/src/dev/devSysmon.c index b2bf8426a..1064d42d3 100644 --- a/src/dev/devSysmon.c +++ b/src/dev/devSysmon.c @@ -58,6 +58,9 @@ * ... * * $Log$ + * Revision 1.9 1995/01/18 16:38:03 winans + * added the '0x' in front of the hex input and outputs in the report function. + * * Revision 1.8 1995/01/09 20:52:02 winans * Added analog input support for temperature * @@ -95,6 +98,7 @@ #include #include +#include #include #include #include diff --git a/src/dev/devTimerMz8310.c b/src/dev/devTimerMz8310.c index dce6c9396..89479eb48 100644 --- a/src/dev/devTimerMz8310.c +++ b/src/dev/devTimerMz8310.c @@ -39,7 +39,6 @@ #include #include -#include #include #include #include diff --git a/src/dev/devVxiTDM.c b/src/dev/devVxiTDM.c index 85957c338..f9fdaadde 100644 --- a/src/dev/devVxiTDM.c +++ b/src/dev/devVxiTDM.c @@ -79,7 +79,6 @@ #include #include -#include #include #include #include diff --git a/src/libCom/errInc.c b/src/libCom/errInc.c index bbd567128..cb8c9bf68 100644 --- a/src/libCom/errInc.c +++ b/src/libCom/errInc.c @@ -5,12 +5,9 @@ /* common to epics Unix and vxWorks */ #include "dbAccess.h" #include "asLib.h" -#include "sdrHeader.h" #include "drvSup.h" #include "devSup.h" #include "recSup.h" -#include "dbRecType.h" -#include "dbRecords.h" #include "tsDefs.h" #include "drvGpibErr.h" #include "drvBitBusErr.h" diff --git a/src/libCom/freeList/freeListLib.c b/src/libCom/freeList/freeListLib.c index e0b686fba..b8d1c7b22 100644 --- a/src/libCom/freeList/freeListLib.c +++ b/src/libCom/freeList/freeListLib.c @@ -53,6 +53,7 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000). #ifdef vxWorks #include +#include #endif #include @@ -60,6 +61,20 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000). #include #include +typedef struct allocMem { + struct allocMem *next; + void *memory; +}allocMem; +typedef struct { + int size; + int nmalloc; + void *head; + allocMem *mallochead; +#ifdef vxWorks + FAST_LOCK lock; +#endif +}FREELISTPVT; + void freeListInitPvt(void **ppvt,int size,int nmalloc) { FREELISTPVT *pfl; @@ -74,6 +89,7 @@ void freeListInitPvt(void **ppvt,int size,int nmalloc) pfl->size = size; pfl->nmalloc = nmalloc; pfl->head = NULL; + pfl->mallochead = NULL; #ifdef vxWorks FASTLOCKINIT(&pfl->lock); #endif @@ -96,6 +112,7 @@ void *freeListMalloc(void *pvt) FREELISTPVT *pfl = pvt; void *ptemp; void **ppnext; + allocMem *pallocmem; int i; #ifdef vxWorks @@ -103,13 +120,18 @@ void *freeListMalloc(void *pvt) #endif ptemp = pfl->head; if(!ptemp) { - ptemp = (void *)malloc(pfl->nmalloc*pfl->size); - if(!ptemp) { + ptemp = (void *)malloc((pfl->nmalloc*pfl->size)+sizeof(void *)); + pallocmem = (allocMem *)calloc(1,sizeof(allocMem)); + if(!ptemp || !pallocmem) { #ifdef vxWorks FASTUNLOCK(&pfl->lock); #endif return(ptemp); } + pallocmem->memory = ptemp; + if(pfl->mallochead) + pallocmem->next = pfl->mallochead; + pfl->mallochead = pallocmem; for(i=0; inmalloc; i++) { ppnext = ptemp; *ppnext = pfl->head; @@ -141,3 +163,19 @@ void freeListFree(void *pvt,void*pmem) FASTUNLOCK(&pfl->lock); #endif } + +void freeListCleanup(void *pvt) +{ + FREELISTPVT *pfl = pvt; + allocMem *phead; + allocMem *pnext; + + phead = pfl->mallochead; + while(phead) { + pnext = phead->next; + free(phead->memory); + free(phead); + phead = pnext; + } + free(pvt); +} diff --git a/src/libCom/freeListLib.c b/src/libCom/freeListLib.c index e0b686fba..b8d1c7b22 100644 --- a/src/libCom/freeListLib.c +++ b/src/libCom/freeListLib.c @@ -53,6 +53,7 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000). #ifdef vxWorks #include +#include #endif #include @@ -60,6 +61,20 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000). #include #include +typedef struct allocMem { + struct allocMem *next; + void *memory; +}allocMem; +typedef struct { + int size; + int nmalloc; + void *head; + allocMem *mallochead; +#ifdef vxWorks + FAST_LOCK lock; +#endif +}FREELISTPVT; + void freeListInitPvt(void **ppvt,int size,int nmalloc) { FREELISTPVT *pfl; @@ -74,6 +89,7 @@ void freeListInitPvt(void **ppvt,int size,int nmalloc) pfl->size = size; pfl->nmalloc = nmalloc; pfl->head = NULL; + pfl->mallochead = NULL; #ifdef vxWorks FASTLOCKINIT(&pfl->lock); #endif @@ -96,6 +112,7 @@ void *freeListMalloc(void *pvt) FREELISTPVT *pfl = pvt; void *ptemp; void **ppnext; + allocMem *pallocmem; int i; #ifdef vxWorks @@ -103,13 +120,18 @@ void *freeListMalloc(void *pvt) #endif ptemp = pfl->head; if(!ptemp) { - ptemp = (void *)malloc(pfl->nmalloc*pfl->size); - if(!ptemp) { + ptemp = (void *)malloc((pfl->nmalloc*pfl->size)+sizeof(void *)); + pallocmem = (allocMem *)calloc(1,sizeof(allocMem)); + if(!ptemp || !pallocmem) { #ifdef vxWorks FASTUNLOCK(&pfl->lock); #endif return(ptemp); } + pallocmem->memory = ptemp; + if(pfl->mallochead) + pallocmem->next = pfl->mallochead; + pfl->mallochead = pallocmem; for(i=0; inmalloc; i++) { ppnext = ptemp; *ppnext = pfl->head; @@ -141,3 +163,19 @@ void freeListFree(void *pvt,void*pmem) FASTUNLOCK(&pfl->lock); #endif } + +void freeListCleanup(void *pvt) +{ + FREELISTPVT *pfl = pvt; + allocMem *phead; + allocMem *pnext; + + phead = pfl->mallochead; + while(phead) { + pnext = phead->next; + free(phead->memory); + free(phead); + phead = pnext; + } + free(pvt); +} diff --git a/src/libCom/gpHash/gpHashLib.c b/src/libCom/gpHash/gpHashLib.c index 2a8146856..faea9e2b0 100644 --- a/src/libCom/gpHash/gpHashLib.c +++ b/src/libCom/gpHash/gpHashLib.c @@ -62,10 +62,11 @@ DEVELOPMENT CENTER AT ARGONNE NATIONAL LABORATORY (708-252-2000). #include #include #include +#include -/*Algorithm depends on HASH_NO=256*/ -#define HASH_NO 256 /*DO NOT CHANGE: number of hash table entries */ +static int tableSize=0; +static int nShift=0; #ifdef vxWorks static FAST_LOCK lock; #endif @@ -75,7 +76,7 @@ static FAST_LOCK lock; /* Fast Hashing of Variable Length Text Strings, Peter K. Pearson, */ /* Communications of the ACM, June 1990 */ -static unsigned char T0[256] = { +static unsigned char T[256] = { 39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69, 157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160, 176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77, @@ -93,6 +94,9 @@ static unsigned char T0[256] = { 111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238, 134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47 }; + +#define NSIZES 9 +static int allowSize[NSIZES] = {256,512,1024,2048,4096,8192,16384,32768,65636}; static void *myCalloc(size_t nobj,size_t size) { @@ -108,21 +112,41 @@ static void *myCalloc(size_t nobj,size_t size) return(NULL); } -static unsigned char hash( char *pname) +static int hash( char *pname) { - unsigned char h=0; + unsigned char h0=0; + unsigned char h1=0; + unsigned short ind0,ind1; + int even = TRUE; + unsigned char c; while(*pname) { - h = T0[h^*pname]; + c = *pname; + if(even) {h0 = T[h0^c]; even = FALSE;} + else {h1 = T[h1^c]; even = TRUE;} pname++; } - return(h); + ind0 = (unsigned short)h0; + ind1 = (unsigned short)h1; + return((ind1< #include #include +#include -/*Algorithm depends on HASH_NO=256*/ -#define HASH_NO 256 /*DO NOT CHANGE: number of hash table entries */ +static int tableSize=0; +static int nShift=0; #ifdef vxWorks static FAST_LOCK lock; #endif @@ -75,7 +76,7 @@ static FAST_LOCK lock; /* Fast Hashing of Variable Length Text Strings, Peter K. Pearson, */ /* Communications of the ACM, June 1990 */ -static unsigned char T0[256] = { +static unsigned char T[256] = { 39,159,180,252, 71, 6, 13,164,232, 35,226,155, 98,120,154, 69, 157, 24,137, 29,147, 78,121, 85,112, 8,248,130, 55,117,190,160, 176,131,228, 64,211,106, 38, 27,140, 30, 88,210,227,104, 84, 77, @@ -93,6 +94,9 @@ static unsigned char T0[256] = { 111,141,191,103, 74,245,223, 20,161,235,122, 63, 89,149, 73,238, 134, 68, 93,183,241, 81,196, 49,192, 65,212, 94,203, 10,200, 47 }; + +#define NSIZES 9 +static int allowSize[NSIZES] = {256,512,1024,2048,4096,8192,16384,32768,65636}; static void *myCalloc(size_t nobj,size_t size) { @@ -108,21 +112,41 @@ static void *myCalloc(size_t nobj,size_t size) return(NULL); } -static unsigned char hash( char *pname) +static int hash( char *pname) { - unsigned char h=0; + unsigned char h0=0; + unsigned char h1=0; + unsigned short ind0,ind1; + int even = TRUE; + unsigned char c; while(*pname) { - h = T0[h^*pname]; + c = *pname; + if(even) {h0 = T[h0^c]; even = FALSE;} + else {h1 = T[h1^c]; even = TRUE;} pname++; } - return(h); + ind0 = (unsigned short)h0; + ind1 = (unsigned short)h1; + return((ind1<