Files
pcas/src/dbStatic/dbStaticNoRun.c
2001-02-06 15:19:53 +00:00

346 lines
9.2 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*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 <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <math.h>
#include "dbDefs.h"
#include "dbFldTypes.h"
#include "epicsPrint.h"
#include "errMdef.h"
#define epicsExportSharedSymbols
#include "dbStaticLib.h"
#include "dbStaticPvt.h"
long dbAllocRecord(DBENTRY *pdbentry,const char *precordName)
{
dbRecordType *pdbRecordType = pdbentry->precordType;
dbRecordNode *precnode = pdbentry->precnode;
dbFldDes *pflddes;
void **papField;
int i;
char *pstr;
if(!pdbRecordType) return(S_dbLib_recordTypeNotFound);
if(!precnode) return(S_dbLib_recNotFound);
precnode->precord = dbCalloc(pdbRecordType->no_fields,sizeof(void *));
papField = (void **)precnode->precord;
for(i=0; i<pdbRecordType->no_fields; i++) {
pflddes = pdbRecordType->papFldDes[i];
if(!pflddes) continue;
pdbentry->pflddes = pflddes;
switch(pflddes->field_type) {
case DBF_STRING:
if(pflddes->size <= 0) {
fprintf(stderr,"size=0 for %s.%s\n",
pdbRecordType->name,pflddes->name);
pflddes->size = 1;
}
papField[i] = dbCalloc(pflddes->size,sizeof(char));
if(pflddes->initial) {
if(strlen(pflddes->initial) >= (unsigned)(pflddes->size)) {
fprintf(stderr,"initial size > size for %s.%s\n",
pdbRecordType->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: {/*Must allow initial value that is choice or index*/
long value;
char *endp;
char *pchoice = NULL;
if(!pflddes->initial) break;
if(dbGetMenuIndexFromString(pdbentry,pflddes->initial)!=-1) {
pchoice=pflddes->initial;
} else {
value = strtol(pflddes->initial,&endp,0);
if(*endp=='\0') pchoice =
dbGetMenuStringFromIndex(pdbentry,(int)value);
}
if(!pchoice) {
epicsPrintf("%s.%s dbAllocRecord. Bad initial value\n",
precordName,pflddes->name);
break;
}
papField[i] = dbCalloc(strlen(pchoice)+1,sizeof(char));
strcpy(papField[i],pchoice);
}
break;
case DBF_INLINK:
case DBF_OUTLINK:
case DBF_FWDLINK: {
struct link *plink;
papField[i] = plink = dbCalloc(1,sizeof(struct link));
plink->type = CONSTANT;
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:
fprintf(stderr,"dbAllocRecord: Illegal field type\n");
}
}
pstr = (char *)papField[0];
strcpy(pstr,precordName);
return(0);
}
long dbFreeRecord(DBENTRY *pdbentry)
{
dbRecordType *pdbRecordType = pdbentry->precordType;
dbRecordNode *precnode = pdbentry->precnode;
dbFldDes *pflddes = pdbentry->pflddes;
void **pap;
int i,field_type;
if(!pdbRecordType) return(S_dbLib_recordTypeNotFound);
if(!precnode) return(S_dbLib_recNotFound);
if(!precnode->precord) return(S_dbLib_recNotFound);
pap = (void **)precnode->precord;
precnode->precord = NULL;
for(i=0; i<pdbRecordType->no_fields; i++) {
pflddes = pdbRecordType->papFldDes[i];
field_type = pflddes->field_type;
if(field_type==DBF_INLINK
|| field_type==DBF_OUTLINK
|| field_type==DBF_FWDLINK)
dbFreeLinkContents((struct link *)pap[i]);
free(pap[i]);
}
free((void *)pap);
return(0);
}
long dbGetFieldAddress(DBENTRY *pdbentry)
{
dbRecordType *pdbRecordType = pdbentry->precordType;
dbRecordNode *precnode = pdbentry->precnode;
dbFldDes *pflddes = pdbentry->pflddes;
void **pap;
if(!pdbRecordType) return(S_dbLib_recordTypeNotFound);
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->indRecordType];
return(0);
}
char *dbRecordName(DBENTRY *pdbentry)
{
dbRecordType *pdbRecordType = pdbentry->precordType;
dbRecordNode *precnode = pdbentry->precnode;
void **pap;
if(!pdbRecordType) return(0);
if(!precnode) return(0);
if(!precnode->precord) return(0);
pap = (void **)precnode->precord;
return((char *)pap[0]);
}
int dbIsMacroOk(DBENTRY *pdbentry) { return(TRUE);}
epicsShareFunc int epicsShareAPI dbIsDefaultValue(DBENTRY *pdbentry)
{
dbFldDes *pflddes = pdbentry->pflddes;
void *pfield = pdbentry->pfield;
if(!pflddes) return(FALSE);
if(pflddes->field_type==DBF_DEVICE) return(FALSE);
if(!pfield) return(TRUE);
switch (pflddes->field_type) {
case DBF_STRING:
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(!pflddes->initial) {
return((strlen((char *)pfield)==0)?TRUE:FALSE);
}
return(strcmp((char *)pfield,(char *)pflddes->initial)==0);
case DBF_MENU: {
long value;
char *endp;
char *pinitial = NULL;
if(pflddes->initial) {
if(dbGetMenuIndexFromString(pdbentry,pflddes->initial)!=-1){
pinitial=pflddes->initial;
} else {
value = strtol(pflddes->initial,&endp,0);
if(*endp=='\0') pinitial =
dbGetMenuStringFromIndex(pdbentry,(int)value);
}
} else {
pinitial = dbGetMenuStringFromIndex(pdbentry,0);
}
if(!pinitial) return(FALSE);
return(strcmp(pinitial,pfield)==0);
}
case DBF_DEVICE: /*Should never reach this state*/
return(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) return(TRUE);
if(!pflddes->initial)
return((strlen((char *)plink->value.constantStr)==0)?TRUE:FALSE);
if(strcmp(plink->value.constantStr,pflddes->initial)==0)
return(TRUE);
return(FALSE);
}
case DBF_NOACCESS:
return(TRUE);
}
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);
if(!pfield) switch(pflddes->field_type) {
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:
return(zero);
case DBF_MENU:
case DBF_DEVICE:
return(dbGetMenuStringFromIndex(pdbentry,0));
default:
epicsPrintf("dbGetStringNum. Illegal Field Type\n");
return(NULL);
}
pap = (void **)precnode->precord;
return((char *)pap[pflddes->indRecordType]);
}
long dbPutStringNum(DBENTRY *pdbentry,const 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((unsigned)strlen(pfield) < (unsigned)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->indRecordType] = pfield;
}
strcpy(pfield,pstring);
return(0);
}
epicsShareFunc int epicsShareAPI dbGetMenuIndex(DBENTRY *pdbentry)
{
dbFldDes *pflddes = pdbentry->pflddes;
int nChoices,choice;
char **menuChoices;
char *pfield;
if(!pflddes) return(-1);
pfield = dbGetStringNum(pdbentry);
if(!pfield) return(-1);
nChoices = dbGetNMenuChoices(pdbentry);
menuChoices = dbGetMenuChoices(pdbentry);
if(nChoices<=0 || !menuChoices) return(-1);
for(choice=0; choice<nChoices; choice++) {
if(strcmp(menuChoices[choice],pfield)==0) return(choice);
}
return(-1);
}
epicsShareFunc long epicsShareAPI dbPutMenuIndex(DBENTRY *pdbentry,int index)
{
int nChoices;
char **menuChoices;
nChoices = dbGetNMenuChoices(pdbentry);
menuChoices = dbGetMenuChoices(pdbentry);
if(index<0 || index>=nChoices) return(S_dbLib_badField);
dbPutStringNum(pdbentry,menuChoices[index]);
return(0);
}