diff --git a/src/ioc/db/dbLink.c b/src/ioc/db/dbLink.c index 870183136..72929f878 100644 --- a/src/ioc/db/dbLink.c +++ b/src/ioc/db/dbLink.c @@ -76,6 +76,19 @@ static void inherit_severity(const struct pv_link *ppv_link, dbCommon *pdest, /***************************** Constant Links *****************************/ +static long dbConstLoadLink(struct link *plink, short dbrType, void *pbuffer) +{ + if (!plink->value.constantStr) + return S_db_badField; + + /* Constant strings are always numeric */ + if (dbrType== DBF_MENU || dbrType == DBF_ENUM || dbrType == DBF_DEVICE) + dbrType = DBF_USHORT; + + return dbFastPutConvertRoutine[DBR_STRING][dbrType] + (plink->value.constantStr, pbuffer, NULL); +} + static long dbConstGetNelements(const struct link *plink, long *nelements) { *nelements = 0; @@ -358,7 +371,7 @@ static void dbDbScanFwdLink(struct link *plink) dbScanPassive(precord, paddr->precord); } -lset dbDb_lset = { dbDbInitLink, dbDbAddLink, dbDbRemoveLink, +lset dbDb_lset = { dbDbInitLink, dbDbAddLink, NULL, dbDbRemoveLink, dbDbIsLinkConnected, dbDbGetDBFtype, dbDbGetElements, dbDbGetValue, dbDbGetControlLimits, dbDbGetGraphicLimits, dbDbGetAlarmLimits, dbDbGetPrecision, dbDbGetUnits, dbDbGetAlarm, dbDbGetTimeStamp, @@ -404,7 +417,7 @@ void dbAddLink(struct dbCommon *precord, struct link *plink, short dbfType) recGblTSELwasModified(plink); if (!(plink->value.pv_link.pvlMask & (pvlOptCA | pvlOptCP | pvlOptCPP))) { - /* Make it a DB link if possible */ + /* Can we make it a DB link? */ if (!dbDbAddLink(plink, dbfType)) return; } @@ -422,6 +435,15 @@ void dbAddLink(struct dbCommon *precord, struct link *plink, short dbfType) } } +long dbLoadLink(struct link *plink, short dbrType, void *pbuffer) +{ + switch (plink->type) { + case CONSTANT: + return dbConstLoadLink(plink, dbrType, pbuffer); + } + return S_db_notFound; +} + void dbRemoveLink(struct link *plink) { switch (plink->type) { @@ -497,7 +519,8 @@ long dbGetLinkValue(struct link *plink, short dbrType, void *pbuffer, status = dbCaGetLink(plink, dbrType, pbuffer, &stat, &sevr, pnRequest); break; default: - cantProceed("dbGetLinkValue: Illegal link type"); + cantProceed("dbGetLinkValue: Illegal link type %d\n", plink->type); + status = -1; } if (status) { recGblSetSevr(precord, LINK_ALARM, INVALID_ALARM); @@ -599,7 +622,8 @@ long dbPutLinkValue(struct link *plink, short dbrType, const void *pbuffer, status = dbCaPutLink(plink, dbrType, pbuffer, nRequest); break; default: - cantProceed("dbPutLinkValue: Illegal link type %d", plink->type); + cantProceed("dbPutLinkValue: Illegal link type %d\n", plink->type); + status = -1; } if (status) { struct dbCommon *precord = plink->value.pv_link.precord; diff --git a/src/ioc/db/dbLink.h b/src/ioc/db/dbLink.h index 0f2e14da8..55aa0098f 100644 --- a/src/ioc/db/dbLink.h +++ b/src/ioc/db/dbLink.h @@ -22,6 +22,7 @@ typedef struct lset { long (*initLink)(struct link *plink, short dbfType); long (*addLink)(struct link *plink, short dbfType); + long (*loadLink)(struct link *plink, short dbrType, void *pbuffer); void (*removeLink)(struct link *plink); int (*isLinkConnected)(const struct link *plink); int (*getDBFtype)(const struct link *plink); @@ -58,8 +59,12 @@ typedef struct lset { #define dbGetSevr(PLINK, PSEVERITY) \ dbGetAlarm((PLINK), NULL, (PSEVERITY)); -epicsShareFunc void dbInitLink(struct dbCommon *precord, struct link *plink, short dbfType); -epicsShareFunc void dbAddLink(struct dbCommon *precord, struct link *plink, short dbfType); +epicsShareFunc void dbInitLink(struct dbCommon *precord, struct link *plink, + short dbfType); +epicsShareFunc void dbAddLink(struct dbCommon *precord, struct link *plink, + short dbfType); +epicsShareFunc long dbLoadLink(struct link *plink, short dbrType, + void *pbuffer); epicsShareFunc void dbRemoveLink(struct link *plink); epicsShareFunc long dbGetNelements(const struct link *plink, long *nelements); epicsShareFunc int dbIsLinkConnected(const struct link *plink); diff --git a/src/ioc/db/recGbl.c b/src/ioc/db/recGbl.c index 828126e63..2ccac3a07 100644 --- a/src/ioc/db/recGbl.c +++ b/src/ioc/db/recGbl.c @@ -167,60 +167,17 @@ void epicsShareAPI recGblGetControlDouble( return; } - + int epicsShareAPI recGblInitConstantLink( struct link *plink,short dbftype,void *pdest) { - if(plink->type != CONSTANT) return(FALSE); - if(!plink->value.constantStr) return(FALSE); - switch(dbftype) { - case DBF_STRING: - strcpy((char *)pdest,plink->value.constantStr); - break; - case DBF_CHAR : { - epicsInt16 value; - epicsInt8 *pvalue = (epicsInt8 *)pdest; + long status = dbLoadLink(plink, dbftype, pdest); - sscanf(plink->value.constantStr,"%hi",&value); - *pvalue = value; - } - break; - case DBF_UCHAR : { - epicsUInt16 value; - epicsUInt8 *pvalue = (epicsUInt8 *)pdest; - - sscanf(plink->value.constantStr,"%hu",&value); - *pvalue = value; - } - break; - case DBF_SHORT : - sscanf(plink->value.constantStr,"%hi",(epicsInt16 *)pdest); - break; - case DBF_USHORT : - case DBF_ENUM : - case DBF_MENU : - case DBF_DEVICE : - sscanf(plink->value.constantStr,"%hu",(epicsUInt16 *)pdest); - break; - case DBF_LONG : - *(epicsInt32 *)pdest = strtol(plink->value.constantStr, NULL, 0); - break; - case DBF_ULONG : - *(epicsUInt32 *)pdest = strtoul(plink->value.constantStr, NULL, 10); - break; - case DBF_FLOAT : - epicsScanFloat(plink->value.constantStr, (epicsFloat32 *)pdest); - break; - case DBF_DOUBLE : - epicsScanDouble(plink->value.constantStr, (epicsFloat64 *)pdest); - break; - default: - epicsPrintf("Error in recGblInitConstantLink: Illegal DBF type\n"); - return(FALSE); - } - return(TRUE); + if (status) + return FALSE; + return TRUE; } - + unsigned short epicsShareAPI recGblResetAlarms(void *precord) { dbCommon *pdbc = precord;