Ben Franksen has proposed merging ~bfrk/epics-base:write-filters into epics-base:7.0 with ~dirk.zimoch/epics-base:dbChannelForDBLinks as a prerequisite.
Requested reviews:
EPICS Core Developers (epics-core)
For more details, see:
https://code.launchpad.net/~bfrk/epics-base/+git/epics-base/+merge/381149
This is just the initial refactor, no new features yet.
--
Your team EPICS Core Developers is requested to review the proposed merge of ~bfrk/epics-base:write-filters into epics-base:7.0.
diff --git a/modules/database/src/ioc/db/dbAccess.c b/modules/database/src/ioc/db/dbAccess.c
index 9b149dd..a6c31f2 100644
--- a/modules/database/src/ioc/db/dbAccess.c
+++ b/modules/database/src/ioc/db/dbAccess.c
@@ -34,7 +34,7 @@
#include "errlog.h"
#include "errMdef.h"
-#include "epicsExport.h" /* #define epicsExportSharedSymbols */
+#include "epicsExport.h" /* #define epicsExportSharedSymbols */
#include "caeventmask.h"
#include "callback.h"
#include "dbAccessDefs.h"
@@ -63,7 +63,7 @@
#include "special.h"
epicsShareDef struct dbBase *pdbbase = 0;
-epicsShareDef volatile int interruptAccept=FALSE;
+epicsShareDef volatile int interruptAccept = FALSE;
epicsShareDef int dbAccessDebugPUTF = 0;
epicsExportAddress(int, dbAccessDebugPUTF);
@@ -73,24 +73,24 @@ epicsExportAddress(int, dbAccessDebugPUTF);
epicsShareDef DB_LOAD_RECORDS_HOOK_ROUTINE dbLoadRecordsHook = NULL;
static short mapDBFToDBR[DBF_NTYPES] = {
- /* DBF_STRING => */ DBR_STRING,
- /* DBF_CHAR => */ DBR_CHAR,
- /* DBF_UCHAR => */ DBR_UCHAR,
- /* DBF_SHORT => */ DBR_SHORT,
- /* DBF_USHORT => */ DBR_USHORT,
- /* DBF_LONG => */ DBR_LONG,
- /* DBF_ULONG => */ DBR_ULONG,
- /* DBF_INT64 => */ DBR_INT64,
- /* DBF_UINT64 => */ DBR_UINT64,
- /* DBF_FLOAT => */ DBR_FLOAT,
- /* DBF_DOUBLE => */ DBR_DOUBLE,
- /* DBF_ENUM, => */ DBR_ENUM,
- /* DBF_MENU, => */ DBR_ENUM,
- /* DBF_DEVICE => */ DBR_ENUM,
- /* DBF_INLINK => */ DBR_STRING,
- /* DBF_OUTLINK => */ DBR_STRING,
- /* DBF_FWDLINK => */ DBR_STRING,
- /* DBF_NOACCESS => */ DBR_NOACCESS
+ /* DBF_STRING => */ DBR_STRING,
+ /* DBF_CHAR => */ DBR_CHAR,
+ /* DBF_UCHAR => */ DBR_UCHAR,
+ /* DBF_SHORT => */ DBR_SHORT,
+ /* DBF_USHORT => */ DBR_USHORT,
+ /* DBF_LONG => */ DBR_LONG,
+ /* DBF_ULONG => */ DBR_ULONG,
+ /* DBF_INT64 => */ DBR_INT64,
+ /* DBF_UINT64 => */ DBR_UINT64,
+ /* DBF_FLOAT => */ DBR_FLOAT,
+ /* DBF_DOUBLE => */ DBR_DOUBLE,
+ /* DBF_ENUM, => */ DBR_ENUM,
+ /* DBF_MENU, => */ DBR_ENUM,
+ /* DBF_DEVICE => */ DBR_ENUM,
+ /* DBF_INLINK => */ DBR_STRING,
+ /* DBF_OUTLINK => */ DBR_STRING,
+ /* DBF_FWDLINK => */ DBR_STRING,
+ /* DBF_NOACCESS => */ DBR_NOACCESS
};
/*
@@ -109,217 +109,219 @@ void dbSpcAsRegisterCallback(SPC_ASCALLBACK func)
spcAsCallback = func;
}
-long dbPutSpecial(DBADDR *paddr,int pass)
+long dbPutSpecial(DBADDR *paddr, int pass)
{
- long int (*pspecial)()=NULL;
- rset *prset;
- dbCommon *precord = paddr->precord;
- long status=0;
- long special=paddr->special;
+ long int (*pspecial) () = NULL;
+ rset *prset;
+ dbCommon *precord = paddr->precord;
+ long status = 0;
+ long special = paddr->special;
prset = dbGetRset(paddr);
- if(special<100) { /*global processing*/
- if((special==SPC_NOMOD) && (pass==0)) {
- status = S_db_noMod;
- recGblDbaddrError(status,paddr,"dbPut");
- return(status);
- }else if(special==SPC_SCAN){
- if(pass==0)
- scanDelete(precord);
- else
- scanAdd(precord);
- }else if((special==SPC_AS) && (pass==1)) {
- if(spcAsCallback) (*spcAsCallback)(precord);
- }
- }else {
- if( prset && (pspecial = (prset->special))) {
- status=(*pspecial)(paddr,pass);
- if(status) return(status);
- } else if(pass==0){
- recGblRecSupError(S_db_noSupport,paddr,"dbPut", "special");
- return(S_db_noSupport);
- }
+ if (special < 100) { /*global processing */
+ if ((special == SPC_NOMOD) && (pass == 0)) {
+ status = S_db_noMod;
+ recGblDbaddrError(status, paddr, "dbPut");
+ return (status);
+ } else if (special == SPC_SCAN) {
+ if (pass == 0)
+ scanDelete(precord);
+ else
+ scanAdd(precord);
+ } else if ((special == SPC_AS) && (pass == 1)) {
+ if (spcAsCallback)
+ (*spcAsCallback) (precord);
+ }
+ } else {
+ if (prset && (pspecial = (prset->special))) {
+ status = (*pspecial) (paddr, pass);
+ if (status)
+ return (status);
+ } else if (pass == 0) {
+ recGblRecSupError(S_db_noSupport, paddr, "dbPut", "special");
+ return (S_db_noSupport);
+ }
}
- return(0);
+ return (0);
}
static void get_enum_strs(DBADDR *paddr, char **ppbuffer,
- rset *prset,long *options)
+ rset * prset, long *options)
{
- short field_type=paddr->field_type;
- dbFldDes *pdbFldDes = paddr->pfldDes;
- dbMenu *pdbMenu;
- dbDeviceMenu *pdbDeviceMenu;
- char **papChoice;
- unsigned long no_str;
- char *ptemp;
- struct dbr_enumStrs *pdbr_enumStrs=(struct dbr_enumStrs*)(*ppbuffer);
+ short field_type = paddr->field_type;
+ dbFldDes *pdbFldDes = paddr->pfldDes;
+ dbMenu *pdbMenu;
+ dbDeviceMenu *pdbDeviceMenu;
+ char **papChoice;
+ unsigned long no_str;
+ char *ptemp;
+ struct dbr_enumStrs *pdbr_enumStrs = (struct dbr_enumStrs *)(*ppbuffer);
unsigned int i;
- memset(pdbr_enumStrs,'\0',dbr_enumStrs_size);
- switch(field_type) {
- case DBF_ENUM:
- if( prset && prset->get_enum_strs ) {
- (*prset->get_enum_strs)(paddr,pdbr_enumStrs);
- } else {
- *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/
- }
- break;
- case DBF_MENU:
- pdbMenu = (dbMenu *)pdbFldDes->ftPvt;
- no_str = pdbMenu->nChoice;
- papChoice= pdbMenu->papChoiceValue;
- goto choice_common;
- case DBF_DEVICE:
- pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt;
- if(!pdbDeviceMenu) {
- *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/
- break;
- }
- no_str = pdbDeviceMenu->nChoice;
- papChoice = pdbDeviceMenu->papChoice;
- goto choice_common;
-choice_common:
- i = sizeof(pdbr_enumStrs->strs)/
- sizeof(pdbr_enumStrs->strs[0]);
- if(i<no_str) no_str = i;
- pdbr_enumStrs->no_str = no_str;
- ptemp = &(pdbr_enumStrs->strs[0][0]);
- for (i=0; i<no_str; i++) {
- if(papChoice[i]==NULL) *ptemp=0;
- else {
- strncpy(ptemp,papChoice[i],
- sizeof(pdbr_enumStrs->strs[0]));
- *(ptemp+sizeof(pdbr_enumStrs->strs[0])-1) = 0;
- }
- ptemp += sizeof(pdbr_enumStrs->strs[0]);
- }
- break;
- default:
- *options = (*options)^DBR_ENUM_STRS;/*Turn off option*/
- break;
- }
- *ppbuffer = ((char *)*ppbuffer) + dbr_enumStrs_size;
- return;
+ memset(pdbr_enumStrs, '\0', dbr_enumStrs_size);
+ switch (field_type) {
+ case DBF_ENUM:
+ if (prset && prset->get_enum_strs) {
+ (*prset->get_enum_strs) (paddr, pdbr_enumStrs);
+ } else {
+ *options = (*options) ^ DBR_ENUM_STRS; /*Turn off option */
+ }
+ break;
+ case DBF_MENU:
+ pdbMenu = (dbMenu *) pdbFldDes->ftPvt;
+ no_str = pdbMenu->nChoice;
+ papChoice = pdbMenu->papChoiceValue;
+ goto choice_common;
+ case DBF_DEVICE:
+ pdbDeviceMenu = (dbDeviceMenu *) pdbFldDes->ftPvt;
+ if (!pdbDeviceMenu) {
+ *options = (*options) ^ DBR_ENUM_STRS; /*Turn off option */
+ break;
+ }
+ no_str = pdbDeviceMenu->nChoice;
+ papChoice = pdbDeviceMenu->papChoice;
+ goto choice_common;
+ choice_common:
+ i = sizeof(pdbr_enumStrs->strs) / sizeof(pdbr_enumStrs->strs[0]);
+ if (i < no_str)
+ no_str = i;
+ pdbr_enumStrs->no_str = no_str;
+ ptemp = &(pdbr_enumStrs->strs[0][0]);
+ for (i = 0; i < no_str; i++) {
+ if (papChoice[i] == NULL)
+ *ptemp = 0;
+ else {
+ strncpy(ptemp, papChoice[i], sizeof(pdbr_enumStrs->strs[0]));
+ *(ptemp + sizeof(pdbr_enumStrs->strs[0]) - 1) = 0;
+ }
+ ptemp += sizeof(pdbr_enumStrs->strs[0]);
+ }
+ break;
+ default:
+ *options = (*options) ^ DBR_ENUM_STRS; /*Turn off option */
+ break;
+ }
+ *ppbuffer = ((char *)*ppbuffer) + dbr_enumStrs_size;
+ return;
}
static void get_graphics(DBADDR *paddr, char **ppbuffer,
- rset *prset,long *options)
+ rset * prset, long *options)
{
- struct dbr_grDouble grd;
- int got_data=FALSE;
-
- grd.upper_disp_limit = grd.lower_disp_limit = 0.0;
- if( prset && prset->get_graphic_double ) {
- (*prset->get_graphic_double)(paddr,&grd);
- got_data=TRUE;
- }
- if( (*options) & (DBR_GR_LONG) ) {
- char *pbuffer=*ppbuffer;
-
- if(got_data) {
- struct dbr_grLong *pgr=(struct dbr_grLong*)pbuffer;
- pgr->upper_disp_limit = (epicsInt32)grd.upper_disp_limit;
- pgr->lower_disp_limit = (epicsInt32)grd.lower_disp_limit;
- } else {
- memset(pbuffer,'\0',dbr_grLong_size);
- *options = (*options) ^ DBR_GR_LONG; /*Turn off option*/
- }
- *ppbuffer = ((char *)*ppbuffer) + dbr_grLong_size;
- }
- if( (*options) & (DBR_GR_DOUBLE) ) {
- char *pbuffer=*ppbuffer;
-
- if(got_data) {
- struct dbr_grDouble *pgr=(struct dbr_grDouble*)pbuffer;
- pgr->upper_disp_limit = grd.upper_disp_limit;
- pgr->lower_disp_limit = grd.lower_disp_limit;
- } else {
- memset(pbuffer,'\0',dbr_grDouble_size);
- *options = (*options) ^ DBR_GR_DOUBLE; /*Turn off option*/
- }
- *ppbuffer = ((char *)*ppbuffer) + dbr_grDouble_size;
- }
- return;
+ struct dbr_grDouble grd;
+ int got_data = FALSE;
+
+ grd.upper_disp_limit = grd.lower_disp_limit = 0.0;
+ if (prset && prset->get_graphic_double) {
+ (*prset->get_graphic_double) (paddr, &grd);
+ got_data = TRUE;
+ }
+ if ((*options) & (DBR_GR_LONG)) {
+ char *pbuffer = *ppbuffer;
+
+ if (got_data) {
+ struct dbr_grLong *pgr = (struct dbr_grLong *)pbuffer;
+ pgr->upper_disp_limit = (epicsInt32) grd.upper_disp_limit;
+ pgr->lower_disp_limit = (epicsInt32) grd.lower_disp_limit;
+ } else {
+ memset(pbuffer, '\0', dbr_grLong_size);
+ *options = (*options) ^ DBR_GR_LONG; /*Turn off option */
+ }
+ *ppbuffer = ((char *)*ppbuffer) + dbr_grLong_size;
+ }
+ if ((*options) & (DBR_GR_DOUBLE)) {
+ char *pbuffer = *ppbuffer;
+
+ if (got_data) {
+ struct dbr_grDouble *pgr = (struct dbr_grDouble *)pbuffer;
+ pgr->upper_disp_limit = grd.upper_disp_limit;
+ pgr->lower_disp_limit = grd.lower_disp_limit;
+ } else {
+ memset(pbuffer, '\0', dbr_grDouble_size);
+ *options = (*options) ^ DBR_GR_DOUBLE; /*Turn off option */
+ }
+ *ppbuffer = ((char *)*ppbuffer) + dbr_grDouble_size;
+ }
+ return;
}
static void get_control(DBADDR *paddr, char **ppbuffer,
- rset *prset,long *options)
+ rset * prset, long *options)
{
- struct dbr_ctrlDouble ctrld;
- int got_data=FALSE;
-
- ctrld.upper_ctrl_limit = ctrld.lower_ctrl_limit = 0.0;
- if( prset && prset->get_control_double ) {
- (*prset->get_control_double)(paddr,&ctrld);
- got_data=TRUE;
- }
- if( (*options) & (DBR_CTRL_LONG) ) {
- char *pbuffer=*ppbuffer;
-
- if(got_data) {
- struct dbr_ctrlLong *pctrl=(struct dbr_ctrlLong*)pbuffer;
- pctrl->upper_ctrl_limit = (epicsInt32)ctrld.upper_ctrl_limit;
- pctrl->lower_ctrl_limit = (epicsInt32)ctrld.lower_ctrl_limit;
- } else {
- memset(pbuffer,'\0',dbr_ctrlLong_size);
- *options = (*options) ^ DBR_CTRL_LONG; /*Turn off option*/
- }
- *ppbuffer = ((char *)*ppbuffer) + dbr_ctrlLong_size;
- }
- if( (*options) & (DBR_CTRL_DOUBLE) ) {
- char *pbuffer=*ppbuffer;
-
- if(got_data) {
- struct dbr_ctrlDouble *pctrl=(struct dbr_ctrlDouble*)pbuffer;
- pctrl->upper_ctrl_limit = ctrld.upper_ctrl_limit;
- pctrl->lower_ctrl_limit = ctrld.lower_ctrl_limit;
- } else {
- memset(pbuffer,'\0',dbr_ctrlDouble_size);
- *options = (*options) ^ DBR_CTRL_DOUBLE; /*Turn off option*/
- }
- *ppbuffer = ((char *)*ppbuffer) + dbr_ctrlDouble_size;
- }
- return;
+ struct dbr_ctrlDouble ctrld;
+ int got_data = FALSE;
+
+ ctrld.upper_ctrl_limit = ctrld.lower_ctrl_limit = 0.0;
+ if (prset && prset->get_control_double) {
+ (*prset->get_control_double) (paddr, &ctrld);
+ got_data = TRUE;
+ }
+ if ((*options) & (DBR_CTRL_LONG)) {
+ char *pbuffer = *ppbuffer;
+
+ if (got_data) {
+ struct dbr_ctrlLong *pctrl = (struct dbr_ctrlLong *)pbuffer;
+ pctrl->upper_ctrl_limit = (epicsInt32) ctrld.upper_ctrl_limit;
+ pctrl->lower_ctrl_limit = (epicsInt32) ctrld.lower_ctrl_limit;
+ } else {
+ memset(pbuffer, '\0', dbr_ctrlLong_size);
+ *options = (*options) ^ DBR_CTRL_LONG; /*Turn off option */
+ }
+ *ppbuffer = ((char *)*ppbuffer) + dbr_ctrlLong_size;
+ }
+ if ((*options) & (DBR_CTRL_DOUBLE)) {
+ char *pbuffer = *ppbuffer;
+
+ if (got_data) {
+ struct dbr_ctrlDouble *pctrl = (struct dbr_ctrlDouble *)pbuffer;
+ pctrl->upper_ctrl_limit = ctrld.upper_ctrl_limit;
+ pctrl->lower_ctrl_limit = ctrld.lower_ctrl_limit;
+ } else {
+ memset(pbuffer, '\0', dbr_ctrlDouble_size);
+ *options = (*options) ^ DBR_CTRL_DOUBLE; /*Turn off option */
+ }
+ *ppbuffer = ((char *)*ppbuffer) + dbr_ctrlDouble_size;
+ }
+ return;
}
static void get_alarm(DBADDR *paddr, char **ppbuffer,
- rset *prset, long *options)
+ rset * prset, long *options)
{
char *pbuffer = *ppbuffer;
- struct dbr_alDouble ald = {epicsNAN, epicsNAN, epicsNAN, epicsNAN};
+ struct dbr_alDouble ald = { epicsNAN, epicsNAN, epicsNAN, epicsNAN };
long no_data = TRUE;
if (prset && prset->get_alarm_double)
no_data = prset->get_alarm_double(paddr, &ald);
if (*options & DBR_AL_LONG) {
- struct dbr_alLong *pal = (struct dbr_alLong*) pbuffer;
+ struct dbr_alLong *pal = (struct dbr_alLong *)pbuffer;
- pal->upper_alarm_limit = finite(ald.upper_alarm_limit) ?
+ pal->upper_alarm_limit = finite(ald.upper_alarm_limit) ?
(epicsInt32) ald.upper_alarm_limit : 0;
pal->upper_warning_limit = finite(ald.upper_warning_limit) ?
(epicsInt32) ald.upper_warning_limit : 0;
pal->lower_warning_limit = finite(ald.lower_warning_limit) ?
(epicsInt32) ald.lower_warning_limit : 0;
- pal->lower_alarm_limit = finite(ald.lower_alarm_limit) ?
+ pal->lower_alarm_limit = finite(ald.lower_alarm_limit) ?
(epicsInt32) ald.lower_alarm_limit : 0;
if (no_data)
- *options ^= DBR_AL_LONG; /*Turn off option*/
+ *options ^= DBR_AL_LONG; /*Turn off option */
*ppbuffer += dbr_alLong_size;
}
if (*options & DBR_AL_DOUBLE) {
- struct dbr_alDouble *pal = (struct dbr_alDouble*) pbuffer;
+ struct dbr_alDouble *pal = (struct dbr_alDouble *)pbuffer;
- pal->upper_alarm_limit = ald.upper_alarm_limit;
+ pal->upper_alarm_limit = ald.upper_alarm_limit;
pal->upper_warning_limit = ald.upper_warning_limit;
pal->lower_warning_limit = ald.lower_warning_limit;
- pal->lower_alarm_limit = ald.lower_alarm_limit;
+ pal->lower_alarm_limit = ald.lower_alarm_limit;
if (no_data)
- *options ^= DBR_AL_DOUBLE; /*Turn off option*/
+ *options ^= DBR_AL_DOUBLE; /*Turn off option */
*ppbuffer += dbr_alDouble_size;
}
@@ -330,88 +332,89 @@ static void get_alarm(DBADDR *paddr, char **ppbuffer,
* blocks only changing the buffer pointer in a way that does not break alignment.
*/
static void getOptions(DBADDR *paddr, char **poriginal, long *options,
- void *pflin)
+ void *pflin)
{
- db_field_log *pfl= (db_field_log *)pflin;
- rset *prset;
- short field_type;
- dbCommon *pcommon;
- char *pbuffer = *poriginal;
-
- if (!pfl || pfl->type == dbfl_type_rec)
- field_type = paddr->field_type;
- else
- field_type = pfl->field_type;
- prset=dbGetRset(paddr);
- /* Process options */
- pcommon = paddr->precord;
- if( (*options) & DBR_STATUS ) {
- unsigned short *pushort = (unsigned short *)pbuffer;
-
- if (!pfl || pfl->type == dbfl_type_rec) {
- *pushort++ = pcommon->stat;
- *pushort++ = pcommon->sevr;
- } else {
- *pushort++ = pfl->stat;
- *pushort++ = pfl->sevr;
- }
- *pushort++ = pcommon->acks;
- *pushort++ = pcommon->ackt;
- pbuffer = (char *)pushort;
- }
- if( (*options) & DBR_UNITS ) {
- memset(pbuffer,'\0',dbr_units_size);
- if( prset && prset->get_units ){
- (*prset->get_units)(paddr, pbuffer);
- pbuffer[DB_UNITS_SIZE-1] = '\0';
- } else {
- *options ^= DBR_UNITS; /*Turn off DBR_UNITS*/
- }
- pbuffer += dbr_units_size;
- }
- if( (*options) & DBR_PRECISION ) {
- memset(pbuffer, '\0', dbr_precision_size);
- if((field_type==DBF_FLOAT || field_type==DBF_DOUBLE)
- && prset && prset->get_precision ){
- (*prset->get_precision)(paddr,(long *)pbuffer);
- } else {
- *options ^= DBR_PRECISION; /*Turn off DBR_PRECISION*/
- }
- pbuffer += dbr_precision_size;
- }
- if( (*options) & DBR_TIME ) {
- epicsUInt32 *ptime = (epicsUInt32 *)pbuffer;
-
- if (!pfl || pfl->type == dbfl_type_rec) {
- *ptime++ = pcommon->time.secPastEpoch;
- *ptime++ = pcommon->time.nsec;
- } else {
- *ptime++ = pfl->time.secPastEpoch;
- *ptime++ = pfl->time.nsec;
- }
- pbuffer = (char *)ptime;
- }
- if( (*options) & DBR_ENUM_STRS )
- get_enum_strs(paddr, &pbuffer, prset, options);
- if( (*options) & (DBR_GR_LONG|DBR_GR_DOUBLE ))
- get_graphics(paddr, &pbuffer, prset, options);
- if((*options) & (DBR_CTRL_LONG | DBR_CTRL_DOUBLE ))
- get_control(paddr, &pbuffer, prset, options);
- if((*options) & (DBR_AL_LONG | DBR_AL_DOUBLE ))
- get_alarm(paddr, &pbuffer, prset, options);
- *poriginal = pbuffer;
+ db_field_log *pfl = (db_field_log *) pflin;
+ rset *prset;
+ short field_type;
+ dbCommon *pcommon;
+ char *pbuffer = *poriginal;
+
+ if (!pfl)
+ field_type = paddr->field_type;
+ else
+ field_type = pfl->field_type;
+ prset = dbGetRset(paddr);
+ /* Process options */
+ pcommon = paddr->precord;
+ if ((*options) & DBR_STATUS) {
+ unsigned short *pushort = (unsigned short *)pbuffer;
+
+ if (!pfl) {
+ *pushort++ = pcommon->stat;
+ *pushort++ = pcommon->sevr;
+ } else {
+ *pushort++ = pfl->stat;
+ *pushort++ = pfl->sevr;
+ }
+ *pushort++ = pcommon->acks;
+ *pushort++ = pcommon->ackt;
+ pbuffer = (char *)pushort;
+ }
+ if ((*options) & DBR_UNITS) {
+ memset(pbuffer, '\0', dbr_units_size);
+ if (prset && prset->get_units) {
+ (*prset->get_units) (paddr, pbuffer);
+ pbuffer[DB_UNITS_SIZE - 1] = '\0';
+ } else {
+ *options ^= DBR_UNITS; /*Turn off DBR_UNITS */
+ }
+ pbuffer += dbr_units_size;
+ }
+ if ((*options) & DBR_PRECISION) {
+ memset(pbuffer, '\0', dbr_precision_size);
+ if ((field_type == DBF_FLOAT || field_type == DBF_DOUBLE)
+ && prset && prset->get_precision) {
+ (*prset->get_precision) (paddr, (long *)pbuffer);
+ } else {
+ *options ^= DBR_PRECISION; /*Turn off DBR_PRECISION */
+ }
+ pbuffer += dbr_precision_size;
+ }
+ if ((*options) & DBR_TIME) {
+ epicsUInt32 *ptime = (epicsUInt32 *) pbuffer;
+
+ if (!pfl) {
+ *ptime++ = pcommon->time.secPastEpoch;
+ *ptime++ = pcommon->time.nsec;
+ } else {
+ *ptime++ = pfl->time.secPastEpoch;
+ *ptime++ = pfl->time.nsec;
+ }
+ pbuffer = (char *)ptime;
+ }
+ if ((*options) & DBR_ENUM_STRS)
+ get_enum_strs(paddr, &pbuffer, prset, options);
+ if ((*options) & (DBR_GR_LONG | DBR_GR_DOUBLE))
+ get_graphics(paddr, &pbuffer, prset, options);
+ if ((*options) & (DBR_CTRL_LONG | DBR_CTRL_DOUBLE))
+ get_control(paddr, &pbuffer, prset, options);
+ if ((*options) & (DBR_AL_LONG | DBR_AL_DOUBLE))
+ get_alarm(paddr, &pbuffer, prset, options);
+ *poriginal = pbuffer;
}
-rset * dbGetRset(const struct dbAddr *paddr)
+rset *dbGetRset(const struct dbAddr *paddr)
{
- struct dbFldDes *pfldDes = paddr->pfldDes;
+ struct dbFldDes *pfldDes = paddr->pfldDes;
- if(!pfldDes) return(0);
- return(pfldDes->pdbRecordType->prset);
+ if (!pfldDes)
+ return (0);
+ return (pfldDes->pdbRecordType->prset);
}
-long dbPutAttribute(
- const char *recordTypename, const char *name, const char *value)
+long dbPutAttribute(const char *recordTypename, const char *name,
+ const char *value)
{
DBENTRY dbEntry;
DBENTRY *pdbEntry = &dbEntry;
@@ -430,7 +433,7 @@ long dbPutAttribute(
if (!status)
status = dbPutRecordAttribute(pdbEntry, name, value);
dbFinishEntry(pdbEntry);
-done:
+ done:
if (status)
errMessage(status, "dbPutAttribute failure");
return status;
@@ -458,7 +461,7 @@ int dbGetFieldIndex(const struct dbAddr *paddr)
* 5. Run the process routine specific to the record type.
* 6. Check to see if record contents should be automatically printed.
*/
-long dbProcess(dbCommon *precord)
+long dbProcess(dbCommon * precord)
{
rset *prset = precord->rset;
dbRecordType *pdbRecordType = precord->rdes;
@@ -466,7 +469,7 @@ long dbProcess(dbCommon *precord)
char context[40] = "";
long status = 0;
int *ptrace;
- int set_trace = FALSE;
+ int set_trace = FALSE;
dbFldDes *pdbFldDes;
int callNotifyCompletion = FALSE;
@@ -492,7 +495,7 @@ long dbProcess(dbCommon *precord)
goto all_done;
}
- /* check for trace processing*/
+ /* check for trace processing */
if (tpro) {
if (!*ptrace) {
*ptrace = 1;
@@ -519,19 +522,17 @@ long dbProcess(dbCommon *precord)
/* raise scan alarm after MAX_LOCK times */
if ((precord->stat == SCAN_ALARM) ||
- (precord->lcnt++ < MAX_LOCK) ||
- (precord->sevr >= INVALID_ALARM)) goto all_done;
+ (precord->lcnt++ < MAX_LOCK) || (precord->sevr >= INVALID_ALARM))
+ goto all_done;
recGblSetSevr(precord, SCAN_ALARM, INVALID_ALARM);
monitor_mask = recGblResetAlarms(precord);
- monitor_mask |= DBE_VALUE|DBE_LOG;
+ monitor_mask |= DBE_VALUE | DBE_LOG;
pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->indvalFlddes];
db_post_events(precord,
- (void *)(((char *)precord) + pdbFldDes->offset),
- monitor_mask);
+ (void *)(((char *)precord) + pdbFldDes->offset), monitor_mask);
goto all_done;
- }
- else
+ } else
precord->lcnt = 0;
/*
@@ -547,7 +548,7 @@ long dbProcess(dbCommon *precord)
printf("%s: dbProcess of Disabled '%s'\n",
context, precord->name);
- /*take care of caching and notifyCompletion*/
+ /*take care of caching and notifyCompletion */
precord->rpro = FALSE;
precord->putf = FALSE;
callNotifyCompletion = TRUE;
@@ -564,8 +565,8 @@ long dbProcess(dbCommon *precord)
db_post_events(precord, &precord->sevr, DBE_VALUE);
pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->indvalFlddes];
db_post_events(precord,
- (void *)(((char *)precord) + pdbFldDes->offset),
- DBE_VALUE|DBE_ALARM);
+ (void *)(((char *)precord) + pdbFldDes->offset),
+ DBE_VALUE | DBE_ALARM);
goto all_done;
}
@@ -573,7 +574,7 @@ long dbProcess(dbCommon *precord)
/* FIXME: put this in iocInit() !!! */
if (!prset || !prset->process) {
callNotifyCompletion = TRUE;
- precord->pact = 1;/*set pact so error is issued only once*/
+ precord->pact = 1; /*set pact so error is issued only once */
recGblRecordError(S_db_noRSET, (void *)precord, "dbProcess");
status = S_db_noRSET;
if (*ptrace)
@@ -592,7 +593,7 @@ long dbProcess(dbCommon *precord)
dbPrint(precord);
}
-all_done:
+ all_done:
if (set_trace)
*ptrace = 0;
if (callNotifyCompletion && precord->ppn)
@@ -601,7 +602,7 @@ all_done:
return status;
}
-long dbEntryToAddr(const DBENTRY *pdbentry, DBADDR *paddr)
+long dbEntryToAddr(const DBENTRY * pdbentry, DBADDR *paddr)
{
dbFldDes *pflddes = pdbentry->pflddes;
short dbfType = pflddes->field_type;
@@ -610,9 +611,9 @@ long dbEntryToAddr(const DBENTRY *pdbentry, DBADDR *paddr)
paddr->pfield = pdbentry->pfield;
paddr->pfldDes = pflddes;
paddr->no_elements = 1;
- paddr->field_type = dbfType;
- paddr->field_size = pflddes->size;
- paddr->special = pflddes->special;
+ paddr->field_type = dbfType;
+ paddr->field_size = pflddes->size;
+ paddr->special = pflddes->special;
paddr->dbr_field_type = mapDBFToDBR[dbfType];
if (paddr->special == SPC_DBADDR) {
@@ -643,16 +644,20 @@ long dbNameToAddr(const char *pname, DBADDR *paddr)
dbInitEntry(pdbbase, &dbEntry);
status = dbFindRecordPart(&dbEntry, &pname);
- if (status) goto finish;
+ if (status)
+ goto finish;
- if (*pname == '.') ++pname;
+ if (*pname == '.')
+ ++pname;
status = dbFindFieldPart(&dbEntry, &pname);
if (status == S_dbLib_fieldNotFound)
status = dbGetAttributePart(&dbEntry, &pname);
- if (status) goto finish;
+ if (status)
+ goto finish;
status = dbEntryToAddr(&dbEntry, paddr);
- if (status) goto finish;
+ if (status)
+ goto finish;
/* Handle field modifiers */
if (*pname++ == '$') {
@@ -664,29 +669,27 @@ long dbNameToAddr(const char *pname, DBADDR *paddr)
paddr->field_type = DBF_CHAR;
paddr->field_size = 1;
paddr->dbr_field_type = DBR_CHAR;
- }
- else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
+ } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
/* Clients see a char array, but keep original dbfType */
paddr->no_elements = PVLINK_STRINGSZ;
paddr->field_size = 1;
paddr->dbr_field_type = DBR_CHAR;
- }
- else {
+ } else {
status = S_dbLib_fieldNotFound;
}
}
-finish:
+ finish:
dbFinishEntry(&dbEntry);
return status;
}
-void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY *pdbentry)
+void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY * pdbentry)
{
struct dbCommon *prec = paddr->precord;
dbCommonPvt *ppvt = dbRec2Pvt(prec);
- memset((char *)pdbentry,'\0',sizeof(DBENTRY));
+ memset((char *)pdbentry, '\0', sizeof(DBENTRY));
pdbentry->pdbbase = pdbbase;
pdbentry->precordType = prec->rdes;
@@ -696,24 +699,24 @@ void dbInitEntryFromAddr(struct dbAddr *paddr, DBENTRY *pdbentry)
pdbentry->indfield = paddr->pfldDes->indRecordType;
}
-void dbInitEntryFromRecord(struct dbCommon *prec, DBENTRY *pdbentry)
+void dbInitEntryFromRecord(struct dbCommon *prec, DBENTRY * pdbentry)
{
dbCommonPvt *ppvt = dbRec2Pvt(prec);
- memset((char *)pdbentry,'\0',sizeof(DBENTRY));
+ memset((char *)pdbentry, '\0', sizeof(DBENTRY));
pdbentry->pdbbase = pdbbase;
pdbentry->precordType = prec->rdes;
pdbentry->precnode = ppvt->recnode;
}
-struct link* dbGetDevLink(struct dbCommon* prec)
+struct link *dbGetDevLink(struct dbCommon *prec)
{
DBLINK *plink = 0;
DBENTRY entry;
dbInitEntryFromRecord(prec, &entry);
- if(dbFindField(&entry, "INP")==0 || dbFindField(&entry, "OUT")==0) {
- plink = (DBLINK*)entry.pfield;
+ if (dbFindField(&entry, "INP") == 0 || dbFindField(&entry, "OUT") == 0) {
+ plink = (DBLINK *) entry.pfield;
}
dbFinishEntry(&entry);
return plink;
@@ -723,41 +726,53 @@ long dbValueSize(short dbr_type)
{
/* sizes for value associated with each DBR request type */
static long size[] = {
- MAX_STRING_SIZE, /* STRING */
- sizeof(epicsInt8), /* CHAR */
- sizeof(epicsUInt8), /* UCHAR */
- sizeof(epicsInt16), /* SHORT */
- sizeof(epicsUInt16), /* USHORT */
- sizeof(epicsInt32), /* LONG */
- sizeof(epicsUInt32), /* ULONG */
- sizeof(epicsInt64), /* INT64 */
- sizeof(epicsUInt64), /* UINT64 */
- sizeof(epicsFloat32), /* FLOAT */
- sizeof(epicsFloat64), /* DOUBLE */
- sizeof(epicsEnum16)}; /* ENUM */
-
- return(size[dbr_type]);
+ MAX_STRING_SIZE, /* STRING */
+ sizeof(epicsInt8), /* CHAR */
+ sizeof(epicsUInt8), /* UCHAR */
+ sizeof(epicsInt16), /* SHORT */
+ sizeof(epicsUInt16), /* USHORT */
+ sizeof(epicsInt32), /* LONG */
+ sizeof(epicsUInt32), /* ULONG */
+ sizeof(epicsInt64), /* INT64 */
+ sizeof(epicsUInt64), /* UINT64 */
+ sizeof(epicsFloat32), /* FLOAT */
+ sizeof(epicsFloat64), /* DOUBLE */
+ sizeof(epicsEnum16)
+ }; /* ENUM */
+
+ return (size[dbr_type]);
}
-
long dbBufferSize(short dbr_type, long options, long no_elements)
{
- long nbytes=0;
+ long nbytes = 0;
nbytes += dbValueSize(dbr_type) * no_elements;
- if (options & DBR_STATUS) nbytes += dbr_status_size;
- if (options & DBR_UNITS) nbytes += dbr_units_size;
- if (options & DBR_PRECISION) nbytes += dbr_precision_size;
- if (options & DBR_TIME) nbytes += dbr_time_size;
- if (options & DBR_ENUM_STRS) nbytes += dbr_enumStrs_size;
- if (options & DBR_GR_LONG) nbytes += dbr_grLong_size;
- if (options & DBR_GR_DOUBLE) nbytes += dbr_grDouble_size;
- if (options & DBR_CTRL_LONG) nbytes += dbr_ctrlLong_size;
- if (options & DBR_CTRL_DOUBLE) nbytes += dbr_ctrlDouble_size;
- if (options & DBR_AL_LONG) nbytes += dbr_alLong_size;
- if (options & DBR_AL_DOUBLE) nbytes += dbr_alDouble_size;
- return(nbytes);
+ if (options & DBR_STATUS)
+ nbytes += dbr_status_size;
+ if (options & DBR_UNITS)
+ nbytes += dbr_units_size;
+ if (options & DBR_PRECISION)
+ nbytes += dbr_precision_size;
+ if (options & DBR_TIME)
+ nbytes += dbr_time_size;
+ if (options & DBR_ENUM_STRS)
+ nbytes += dbr_enumStrs_size;
+ if (options & DBR_GR_LONG)
+ nbytes += dbr_grLong_size;
+ if (options & DBR_GR_DOUBLE)
+ nbytes += dbr_grDouble_size;
+ if (options & DBR_CTRL_LONG)
+ nbytes += dbr_ctrlLong_size;
+ if (options & DBR_CTRL_DOUBLE)
+ nbytes += dbr_ctrlDouble_size;
+ if (options & DBR_AL_LONG)
+ nbytes += dbr_alLong_size;
+ if (options & DBR_AL_DOUBLE)
+ nbytes += dbr_alDouble_size;
+ return (nbytes);
}
+
int dbLoadDatabase(const char *file, const char *path, const char *subs)
{
if (!file) {
@@ -767,7 +782,7 @@ int dbLoadDatabase(const char *file, const char *path, const char *subs)
return dbReadDatabase(&pdbbase, file, path, subs);
}
-int dbLoadRecords(const char* file, const char* subs)
+int dbLoadRecords(const char *file, const char *subs)
{
int status;
@@ -781,7 +796,6 @@ int dbLoadRecords(const char* file, const char* subs)
return status;
}
-
static long getLinkValue(DBADDR *paddr, short dbrType,
char *pbuf, long *nRequest)
{
@@ -797,7 +811,7 @@ static long getLinkValue(DBADDR *paddr, short dbrType,
* valid DBADDR, so no point to check again.
* Request for zero elements always succeeds
*/
- if(!nReq)
+ if (!nReq)
return 0;
switch (dbrType) {
@@ -806,8 +820,9 @@ static long getLinkValue(DBADDR *paddr, short dbrType,
nReq = 1;
break;
- case DBR_DOUBLE: /* Needed for dbCa links */
- if (nRequest) *nRequest = 1;
+ case DBR_DOUBLE: /* Needed for dbCa links */
+ if (nRequest)
+ *nRequest = 1;
*(double *)pbuf = epicsNAN;
return 0;
@@ -821,27 +836,30 @@ static long getLinkValue(DBADDR *paddr, short dbrType,
dbInitEntry(pdbbase, &dbEntry);
status = dbFindRecord(&dbEntry, precord->name);
- if (!status) status = dbFindField(&dbEntry, pfldDes->name);
+ if (!status)
+ status = dbFindField(&dbEntry, pfldDes->name);
if (!status) {
const char *rtnString = dbGetString(&dbEntry);
- strncpy(pbuf, rtnString, maxlen-1);
- pbuf[maxlen-1] = 0;
- if(dbrType!=DBR_STRING)
- nReq = strlen(pbuf)+1;
- if(nRequest) *nRequest = nReq;
+ strncpy(pbuf, rtnString, maxlen - 1);
+ pbuf[maxlen - 1] = 0;
+ if (dbrType != DBR_STRING)
+ nReq = strlen(pbuf) + 1;
+ if (nRequest)
+ *nRequest = nReq;
}
dbFinishEntry(&dbEntry);
return status;
}
static long getAttrValue(DBADDR *paddr, short dbrType,
- char *pbuf, long *nRequest)
+ char *pbuf, long *nRequest)
{
int maxlen;
long nReq = nRequest ? *nRequest : 1;
- if (!paddr->pfield) return S_db_badField;
+ if (!paddr->pfield)
+ return S_db_badField;
switch (dbrType) {
case DBR_STRING:
@@ -859,22 +877,23 @@ static long getAttrValue(DBADDR *paddr, short dbrType,
return S_db_badDbrtype;
}
- strncpy(pbuf, paddr->pfield, maxlen-1);
- pbuf[maxlen-1] = 0;
- if(dbrType!=DBR_STRING)
- nReq = strlen(pbuf)+1;
- if(nRequest) *nRequest = nReq;
+ strncpy(pbuf, paddr->pfield, maxlen - 1);
+ pbuf[maxlen - 1] = 0;
+ if (dbrType != DBR_STRING)
+ nReq = strlen(pbuf) + 1;
+ if (nRequest)
+ *nRequest = nReq;
return 0;
}
-long dbGetField(DBADDR *paddr,short dbrType,
- void *pbuffer, long *options, long *nRequest, void *pflin)
+long dbGetField(DBADDR *paddr, short dbrType,
+ void *pbuffer, long *options, long *nRequest)
{
dbCommon *precord = paddr->precord;
long status = 0;
dbScanLock(precord);
- status = dbGet(paddr, dbrType, pbuffer, options, nRequest, pflin);
+ status = dbGet(paddr, dbrType, pbuffer, options, nRequest, NULL);
dbScanUnlock(precord);
return status;
}
@@ -884,7 +903,7 @@ long dbGet(DBADDR *paddr, short dbrType,
{
char *pbuf = pbuffer;
void *pfieldsave = paddr->pfield;
- db_field_log *pfl = (db_field_log *)pflin;
+ db_field_log *pfl = (db_field_log *) pflin;
short field_type;
long capacity, no_elements, offset;
rset *prset;
@@ -895,7 +914,7 @@ long dbGet(DBADDR *paddr, short dbrType,
if (nRequest && *nRequest == 0)
return 0;
- if (!pfl || pfl->type == dbfl_type_rec) {
+ if (!pfl) {
field_type = paddr->field_type;
no_elements = capacity = paddr->no_elements;
@@ -903,15 +922,14 @@ long dbGet(DBADDR *paddr, short dbrType,
* may modify paddr->pfield
*/
if (paddr->pfldDes->special == SPC_DBADDR &&
- (prset = dbGetRset(paddr)) &&
- prset->get_array_info) {
+ (prset = dbGetRset(paddr)) && prset->get_array_info) {
status = prset->get_array_info(paddr, &no_elements, &offset);
} else
offset = 0;
} else {
field_type = pfl->field_type;
no_elements = capacity = pfl->no_elements;
- offset = 0;
+ offset = pfl->offset;
}
if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) {
@@ -937,11 +955,11 @@ long dbGet(DBADDR *paddr, short dbrType,
if (offset == 0 && (!nRequest || no_elements == 1)) {
if (nRequest)
*nRequest = 1;
- if (!pfl || pfl->type == dbfl_type_rec) {
+ if (!pfl) {
status = dbFastGetConvertRoutine[field_type][dbrType]
(paddr->pfield, pbuf, paddr);
} else {
- DBADDR localAddr = *paddr; /* Structure copy */
+ DBADDR localAddr = *paddr; /* Structure copy */
if (pfl->no_elements < 1) {
status = S_db_badField;
@@ -950,11 +968,12 @@ long dbGet(DBADDR *paddr, short dbrType,
localAddr.field_type = pfl->field_type;
localAddr.field_size = pfl->field_size;
+ /* not used by dbFastConvert: */
localAddr.no_elements = pfl->no_elements;
if (pfl->type == dbfl_type_val)
- localAddr.pfield = (char *) &pfl->u.v.field;
+ localAddr.pfield = (char *)&pfl->u.v.field;
else
- localAddr.pfield = (char *) pfl->u.r.field;
+ localAddr.pfield = (char *)pfl->u.r.field;
status = dbFastGetConvertRoutine[field_type][dbrType]
(localAddr.pfield, pbuf, &localAddr);
}
@@ -974,52 +993,55 @@ long dbGet(DBADDR *paddr, short dbrType,
char message[80];
sprintf(message, "dbGet: Missing conversion for [%d][%d]\n",
- field_type, dbrType);
+ field_type, dbrType);
recGblDbaddrError(S_db_badDbrtype, paddr, message);
status = S_db_badDbrtype;
goto done;
}
/* convert data into the caller's buffer */
if (n <= 0) {
- ;/*do nothing*/
- } else if (!pfl || pfl->type == dbfl_type_rec) {
+ ; /*do nothing */
+ } else if (!pfl) {
status = convert(paddr, pbuf, n, capacity, offset);
} else {
- DBADDR localAddr = *paddr; /* Structure copy */
+ DBADDR localAddr = *paddr; /* Structure copy */
localAddr.field_type = pfl->field_type;
localAddr.field_size = pfl->field_size;
+ /* not used by dbConvert, it uses the passed capacity instead: */
localAddr.no_elements = pfl->no_elements;
if (pfl->type == dbfl_type_val)
- localAddr.pfield = (char *) &pfl->u.v.field;
+ localAddr.pfield = (char *)&pfl->u.v.field;
else
- localAddr.pfield = (char *) pfl->u.r.field;
+ localAddr.pfield = (char *)pfl->u.r.field;
status = convert(&localAddr, pbuf, n, capacity, offset);
}
- if(!status && dbrType==DBF_CHAR && nRequest &&
- paddr->pfldDes && paddr->pfldDes->field_type==DBF_STRING)
- {
+ if (!status && dbrType == DBF_CHAR && nRequest &&
+ paddr->pfldDes && paddr->pfldDes->field_type == DBF_STRING) {
/* long string ensure nil and truncate to actual length */
long nReq = *nRequest;
- pbuf[nReq-1] = '\0';
- *nRequest = strlen(pbuf)+1;
+ pbuf[nReq - 1] = '\0';
+ *nRequest = strlen(pbuf) + 1;
}
}
-done:
+ done:
paddr->pfield = pfieldsave;
return status;
}
-devSup* dbDTYPtoDevSup(dbRecordType *prdes, int dtyp) {
- return (devSup *)ellNth(&prdes->devList, dtyp+1);
+devSup *dbDTYPtoDevSup(dbRecordType * prdes, int dtyp)
+{
+ return (devSup *) ellNth(&prdes->devList, dtyp + 1);
}
-devSup* dbDSETtoDevSup(dbRecordType *prdes, dset *pdset) {
- devSup *pdevSup = (devSup *)ellFirst(&prdes->devList);
+devSup *dbDSETtoDevSup(dbRecordType * prdes, dset * pdset)
+{
+ devSup *pdevSup = (devSup *) ellFirst(&prdes->devList);
while (pdevSup) {
- if (pdset == pdevSup->pdset) return pdevSup;
- pdevSup = (devSup *)ellNext(&pdevSup->node);
+ if (pdset == pdevSup->pdset)
+ return pdevSup;
+ pdevSup = (devSup *) ellNext(&pdevSup->node);
}
return NULL;
}
@@ -1027,24 +1049,24 @@ devSup* dbDSETtoDevSup(dbRecordType *prdes, dset *pdset) {
static long dbPutFieldLink(DBADDR *paddr,
short dbrType, const void *pbuffer, long nRequest)
{
- dbLinkInfo link_info;
- dbChannel *chan = NULL;
- dbCommon *precord = paddr->precord;
- dbCommon *lockrecs[2];
- dbLocker locker;
- dbFldDes *pfldDes = paddr->pfldDes;
- long special = paddr->special;
+ dbLinkInfo link_info;
+ dbChannel *chan = NULL;
+ dbCommon *precord = paddr->precord;
+ dbCommon *lockrecs[2];
+ dbLocker locker;
+ dbFldDes *pfldDes = paddr->pfldDes;
+ long special = paddr->special;
struct link *plink = (struct link *)paddr->pfield;
- const char *pstring = (const char *)pbuffer;
+ const char *pstring = (const char *)pbuffer;
struct dsxt *old_dsxt = NULL;
dset *new_dset = NULL;
struct dsxt *new_dsxt = NULL;
- devSup *new_devsup = NULL;
- long status;
- int isDevLink;
- short scan;
+ devSup *new_devsup = NULL;
+ long status;
+ int isDevLink;
+ short scan;
- STATIC_ASSERT(DBLOCKER_NALLOC>=2);
+ STATIC_ASSERT(DBLOCKER_NALLOC >= 2);
switch (dbrType) {
case DBR_CHAR:
@@ -1068,14 +1090,14 @@ static long dbPutFieldLink(DBADDR *paddr,
(link_info.modifiers & (pvlOptCA | pvlOptCP | pvlOptCPP)) == 0) {
chan = dbChannelCreate(link_info.target);
if (chan && dbChannelOpen(chan) != 0) {
- errlogPrintf("ERROR: dbPutFieldLink %s.%s=%s: dbChannelOpen() failed\n",
+ errlogPrintf
+ ("ERROR: dbPutFieldLink %s.%s=%s: dbChannelOpen() failed\n",
precord->name, pfldDes->name, link_info.target);
goto cleanup;
}
}
- isDevLink = ellCount(&precord->rdes->devList) > 0 &&
- pfldDes->isDevLink;
+ isDevLink = ellCount(&precord->rdes->devList) > 0 && pfldDes->isDevLink;
memset(&locker, 0, sizeof(locker));
lockrecs[0] = precord;
@@ -1130,17 +1152,19 @@ static long dbPutFieldLink(DBADDR *paddr,
if (dbLinkIsDefined(plink)) {
dbRemoveLink(&locker, plink); /* Clear out old link */
- }
- else if (!isDevLink) {
+ } else if (!isDevLink) {
status = S_db_badHWaddr;
goto restoreScan;
}
- if (special) status = dbPutSpecial(paddr, 0);
+ if (special)
+ status = dbPutSpecial(paddr, 0);
- if (!status) status = dbSetLink(plink, &link_info, new_devsup);
+ if (!status)
+ status = dbSetLink(plink, &link_info, new_devsup);
- if (!status && special) status = dbPutSpecial(paddr, 1);
+ if (!status && special)
+ status = dbPutSpecial(paddr, 1);
if (status) {
if (isDevLink) {
@@ -1163,20 +1187,20 @@ static long dbPutFieldLink(DBADDR *paddr,
}
}
- switch (plink->type) { /* New link type */
+ switch (plink->type) { /* New link type */
case PV_LINK:
case CONSTANT:
case JSON_LINK:
dbAddLink(&locker, plink, pfldDes->field_type, chan);
- chan = NULL; /* don't clean it up */
+ chan = NULL; /* don't clean it up */
break;
case DB_LINK:
case CA_LINK:
case MACRO_LINK:
- break; /* should never get here */
+ break; /* should never get here */
- default: /* Hardware address */
+ default: /* Hardware address */
if (!isDevLink) {
status = S_db_badHWaddr;
goto postScanEvent;
@@ -1185,19 +1209,18 @@ static long dbPutFieldLink(DBADDR *paddr,
}
db_post_events(precord, plink, DBE_VALUE | DBE_LOG);
-restoreScan:
- if (isDevLink &&
- scan == menuScanI_O_Intr) { /* undo scanDelete() */
+ restoreScan:
+ if (isDevLink && scan == menuScanI_O_Intr) { /* undo scanDelete() */
precord->scan = scan;
scanAdd(precord);
}
-postScanEvent:
+ postScanEvent:
if (scan != precord->scan)
db_post_events(precord, &precord->scan, DBE_VALUE | DBE_LOG);
-unlock:
+ unlock:
dbScanUnlockMany(&locker);
dbLockerFinalize(&locker);
-cleanup:
+ cleanup:
if (chan)
dbChannelDelete(chan);
free(link_info.target);
@@ -1207,16 +1230,16 @@ cleanup:
long dbPutField(DBADDR *paddr, short dbrType,
const void *pbuffer, long nRequest)
{
- long status = 0;
- long special = paddr->special;
- dbFldDes *pfldDes = paddr->pfldDes;
- dbCommon *precord = paddr->precord;
- short dbfType = paddr->field_type;
+ long status = 0;
+ long special = paddr->special;
+ dbFldDes *pfldDes = paddr->pfldDes;
+ dbCommon *precord = paddr->precord;
+ short dbfType = paddr->field_type;
if (special == SPC_ATTRIBUTE)
return S_db_noMod;
- /*check for putField disabled*/
+ /*check for putField disabled */
if (precord->disp && paddr->pfield != &precord->disp)
return S_db_putDisabled;
@@ -1228,8 +1251,7 @@ long dbPutField(DBADDR *paddr, short dbrType,
if (status == 0) {
if (paddr->pfield == &precord->proc ||
(pfldDes->process_passive &&
- precord->scan == 0 &&
- dbrType < DBR_PUT_ACKT)) {
+ precord->scan == 0 && dbrType < DBR_PUT_ACKT)) {
if (precord->pact) {
if (dbAccessDebugPUTF && precord->tpro)
printf("%s: dbPutField to Active '%s', setting RPRO=1\n",
@@ -1252,11 +1274,11 @@ static long putAckt(DBADDR *paddr, const void *pbuffer, long nRequest,
dbCommon *precord = paddr->precord;
const unsigned short *ptrans = pbuffer;
- if (*ptrans == precord->ackt) return 0;
+ if (*ptrans == precord->ackt)
+ return 0;
precord->ackt = *ptrans;
db_post_events(precord, &precord->ackt, DBE_VALUE | DBE_ALARM);
- if (!precord->ackt &&
- precord->acks > precord->sevr) {
+ if (!precord->ackt && precord->acks > precord->sevr) {
precord->acks = precord->sevr;
db_post_events(precord, &precord->acks, DBE_VALUE | DBE_ALARM);
}
@@ -1278,14 +1300,13 @@ static long putAcks(DBADDR *paddr, const void *pbuffer, long nRequest,
return 0;
}
-long dbPut(DBADDR *paddr, short dbrType,
- const void *pbuffer, long nRequest)
+long dbPut(DBADDR *paddr, short dbrType, const void *pbuffer, long nRequest)
{
dbCommon *precord = paddr->precord;
- short field_type = paddr->field_type;
- long no_elements = paddr->no_elements;
- long special = paddr->special;
- void *pfieldsave = paddr->pfield;
+ short field_type = paddr->field_type;
+ long no_elements = paddr->no_elements;
+ long special = paddr->special;
+ void *pfieldsave = paddr->pfield;
rset *prset = dbGetRset(paddr);
long status = 0;
long offset;
@@ -1309,7 +1330,8 @@ long dbPut(DBADDR *paddr, short dbrType,
if (special) {
status = dbPutSpecial(paddr, 0);
- if (status) return status;
+ if (status)
+ return status;
}
if (paddr->pfldDes->special == SPC_DBADDR &&
@@ -1318,18 +1340,19 @@ long dbPut(DBADDR *paddr, short dbrType,
status = prset->get_array_info(paddr, &dummy, &offset);
/* paddr->pfield may be modified */
- if (status) goto done;
+ if (status)
+ goto done;
} else
offset = 0;
if (no_elements <= 1) {
- status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
+ status = dbFastPutConvertRoutine[dbrType][field_type] (pbuffer,
paddr->pfield, paddr);
nRequest = 1;
} else {
if (no_elements < nRequest)
nRequest = no_elements;
- status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
+ status = dbPutConvertRoutine[dbrType][field_type] (paddr, pbuffer,
nRequest, no_elements, offset);
}
@@ -1343,17 +1366,19 @@ long dbPut(DBADDR *paddr, short dbrType,
/* Always do special processing if needed */
if (special) {
long status2 = dbPutSpecial(paddr, 1);
- if (status2) goto done;
+ if (status2)
+ goto done;
}
- if (status) goto done;
+ if (status)
+ goto done;
/* Propagate monitor events for this field, */
/* unless the field is VAL and PP is true. */
pfldDes = paddr->pfldDes;
isValueField = dbIsValueField(pfldDes);
- if (isValueField) precord->udf = FALSE;
- if (precord->mlis.count &&
- !(isValueField && pfldDes->process_passive))
+ if (isValueField)
+ precord->udf = FALSE;
+ if (precord->mlis.count && !(isValueField && pfldDes->process_passive))
db_post_events(precord, pfieldsave, DBE_VALUE | DBE_LOG);
/* If this field is a property (metadata) field,
* then post a property change event (even if the field
@@ -1361,7 +1386,7 @@ long dbPut(DBADDR *paddr, short dbrType,
*/
if (precord->mlis.count && pfldDes->prop)
db_post_events(precord, NULL, DBE_PROPERTY);
-done:
+ done:
paddr->pfield = pfieldsave;
return status;
}
diff --git a/modules/database/src/ioc/db/dbAccessDefs.h b/modules/database/src/ioc/db/dbAccessDefs.h
index 805dfd4..4a95989 100644
--- a/modules/database/src/ioc/db/dbAccessDefs.h
+++ b/modules/database/src/ioc/db/dbAccessDefs.h
@@ -243,7 +243,7 @@ epicsShareFunc devSup* dbDTYPtoDevSup(dbRecordType *prdes, int dtyp);
epicsShareFunc devSup* dbDSETtoDevSup(dbRecordType *prdes, dset *pdset);
epicsShareFunc long dbGetField(
struct dbAddr *,short dbrType,void *pbuffer,long *options,
- long *nRequest,void *pfl);
+ long *nRequest);
epicsShareFunc long dbGet(
struct dbAddr *,short dbrType,void *pbuffer,long *options,
long *nRequest,void *pfl);
diff --git a/modules/database/src/ioc/db/dbChannel.c b/modules/database/src/ioc/db/dbChannel.c
index a8bfbf1..e361f3b 100644
--- a/modules/database/src/ioc/db/dbChannel.c
+++ b/modules/database/src/ioc/db/dbChannel.c
@@ -49,14 +49,12 @@ typedef struct parseContext {
static void *dbChannelFreeList;
static void *chFilterFreeList;
-static void *dbchStringFreeList;
void dbChannelExit(void)
{
freeListCleanup(dbChannelFreeList);
freeListCleanup(chFilterFreeList);
- freeListCleanup(dbchStringFreeList);
- dbChannelFreeList = chFilterFreeList = dbchStringFreeList = NULL;
+ dbChannelFreeList = chFilterFreeList = NULL;
}
void dbChannelInit (void)
@@ -66,7 +64,6 @@ void dbChannelInit (void)
freeListInitPvt(&dbChannelFreeList, sizeof(dbChannel), 128);
freeListInitPvt(&chFilterFreeList, sizeof(chFilter), 64);
- freeListInitPvt(&dbchStringFreeList, sizeof(epicsOldString), 128);
db_init_event_freelists();
}
@@ -446,28 +443,6 @@ static long parseArrayRange(dbChannel* chan, const char *pname, const char **ppn
return status;
}
-/* Stolen from dbAccess.c: */
-static short mapDBFToDBR[DBF_NTYPES] =
- {
- /* DBF_STRING => */DBR_STRING,
- /* DBF_CHAR => */DBR_CHAR,
- /* DBF_UCHAR => */DBR_UCHAR,
- /* DBF_SHORT => */DBR_SHORT,
- /* DBF_USHORT => */DBR_USHORT,
- /* DBF_LONG => */DBR_LONG,
- /* DBF_ULONG => */DBR_ULONG,
- /* DBF_INT64 => */DBR_INT64,
- /* DBF_UINT64 => */DBR_UINT64,
- /* DBF_FLOAT => */DBR_FLOAT,
- /* DBF_DOUBLE => */DBR_DOUBLE,
- /* DBF_ENUM, => */DBR_ENUM,
- /* DBF_MENU, => */DBR_ENUM,
- /* DBF_DEVICE => */DBR_ENUM,
- /* DBF_INLINK => */DBR_STRING,
- /* DBF_OUTLINK => */DBR_STRING,
- /* DBF_FWDLINK => */DBR_STRING,
- /* DBF_NOACCESS => */DBR_NOACCESS };
-
dbChannel * dbChannelCreate(const char *name)
{
const char *pname = name;
@@ -736,39 +711,6 @@ void dbChannelDelete(dbChannel *chan)
freeListFree(dbChannelFreeList, chan);
}
-static void freeArray(db_field_log *pfl) {
- if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
- freeListFree(dbchStringFreeList, pfl->u.r.field);
- } else {
- free(pfl->u.r.field);
- }
-}
-
-void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan)
-{
- void *p;
- struct dbCommon *prec = dbChannelRecord(chan);
-
- if (pfl->type != dbfl_type_rec) return;
-
- pfl->type = dbfl_type_ref;
- pfl->stat = prec->stat;
- pfl->sevr = prec->sevr;
- pfl->time = prec->time;
- pfl->field_type = chan->addr.field_type;
- pfl->no_elements = chan->addr.no_elements;
- pfl->field_size = chan->addr.field_size;
- pfl->u.r.dtor = freeArray;
- pfl->u.r.pvt = pvt;
- if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
- p = freeListCalloc(dbchStringFreeList);
- } else {
- p = calloc(pfl->no_elements, pfl->field_size);
- }
- if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL);
- pfl->u.r.field = p;
-}
-
/* FIXME: Do these belong in a different file? */
void dbRegisterFilter(const char *name, const chFilterIf *fif, void *puser)
diff --git a/modules/database/src/ioc/db/dbChannel.h b/modules/database/src/ioc/db/dbChannel.h
index fab9c66..6e98dee 100644
--- a/modules/database/src/ioc/db/dbChannel.h
+++ b/modules/database/src/ioc/db/dbChannel.h
@@ -64,8 +64,9 @@ typedef struct dbChannel {
/* Prototype for the channel event function that is called in filter stacks
*
* When invoked the scan lock for the record associated with 'chan' _may_ be locked.
- * If pLog->type==dbfl_type_rec then dbScanLock() must be called before copying
- * data out of the associated record.
+ * If pLog->type==dbfl_type_ref and pLog->u.r.dtor is NULL, then dbScanLock() must
+ * be called before accessing the data, as this indicates the data is owned by the
+ * record.
*
* This function has ownership of the field log pLog, if it wishes to discard
* this update it should free the field log with db_delete_field_log() and
@@ -224,7 +225,6 @@ epicsShareFunc void dbRegisterFilter(const char *key, const chFilterIf *fif, voi
epicsShareFunc db_field_log* dbChannelRunPreChain(dbChannel *chan, db_field_log *pLogIn);
epicsShareFunc db_field_log* dbChannelRunPostChain(dbChannel *chan, db_field_log *pLogIn);
epicsShareFunc const chFilterPlugin * dbFindFilter(const char *key, size_t len);
-epicsShareFunc void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan);
#ifdef __cplusplus
}
diff --git a/modules/database/src/ioc/db/dbDbLink.c b/modules/database/src/ioc/db/dbDbLink.c
index 466552d..8677add 100644
--- a/modules/database/src/ioc/db/dbDbLink.c
+++ b/modules/database/src/ioc/db/dbDbLink.c
@@ -181,7 +181,10 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer,
if (ellCount(&chan->filters)) {
db_field_log *pfl;
- /* For the moment, empty arrays are not supported by EPICS */
+ /*
+ * For the moment, empty arrays are not supported by EPICS.
+ * See the remark in src/std/filters/arr.c for details.
+ */
if (dbChannelFinalElements(chan) <= 0) /* empty array request */
return S_db_badField;
pfl = db_create_read_log(chan);
diff --git a/modules/database/src/ioc/db/dbEvent.c b/modules/database/src/ioc/db/dbEvent.c
index ed73529..532c2ba 100644
--- a/modules/database/src/ioc/db/dbEvent.c
+++ b/modules/database/src/ioc/db/dbEvent.c
@@ -667,27 +667,22 @@ int db_post_extra_labor (dbEventCtx ctx)
return DB_EVENT_OK;
}
-/*
- * DB_CREATE_EVENT_LOG()
- *
- * NOTE: This assumes that the db scan lock is already applied
- * (as it copies data from the record)
- */
-db_field_log* db_create_event_log (struct evSubscrip *pevent)
+static db_field_log* db_create_field_log (struct dbChannel *chan, int use_val)
{
db_field_log *pLog = (db_field_log *) freeListCalloc(dbevFieldLogFreeList);
if (pLog) {
- struct dbChannel *chan = pevent->chan;
struct dbCommon *prec = dbChannelRecord(chan);
- pLog->ctx = dbfl_context_event;
- if (pevent->useValque) {
+ pLog->stat = prec->stat;
+ pLog->sevr = prec->sevr;
+ pLog->time = prec->time;
+ pLog->field_type = dbChannelFieldType(chan);
+ pLog->field_size = dbChannelFieldSize(chan);
+ pLog->no_elements = dbChannelElements(chan);
+ pLog->offset = 0;
+
+ if (use_val) {
pLog->type = dbfl_type_val;
- pLog->stat = prec->stat;
- pLog->sevr = prec->sevr;
- pLog->time = prec->time;
- pLog->field_type = dbChannelFieldType(chan);
- pLog->no_elements = dbChannelElements(chan);
/*
* use memcpy to avoid a bus error on
* union copy of char in the db at an odd
@@ -697,23 +692,62 @@ db_field_log* db_create_event_log (struct evSubscrip *pevent)
dbChannelField(chan),
dbChannelFieldSize(chan));
} else {
- pLog->type = dbfl_type_rec;
+ rset *prset;
+
+ pLog->type = dbfl_type_ref;
+
+ if (dbChannelSpecial(chan) == SPC_DBADDR &&
+ (prset = dbGetRset(&chan->addr)) &&
+ prset->get_array_info)
+ /* This condition implies !use_val, see db_add_event */
+ {
+ void *pfieldsave = dbChannelField(chan);
+ prec = dbChannelRecord(chan);
+ prset->get_array_info(&chan->addr, &pLog->no_elements, &pLog->offset);
+ /* don't make a copy yet, just reference the field value */
+ pLog->u.r.field = dbChannelField(chan);
+ dbChannelField(chan) = pfieldsave;
+ }
+ else {
+ /* don't make a copy yet, just reference the field value */
+ pLog->u.r.field = dbChannelField(chan);
+ }
+ /* indicate field value still owned by record */
+ pLog->u.r.dtor = NULL;
+ /* no private data yet, may be set by a filter */
+ pLog->u.r.pvt = NULL;
}
}
return pLog;
}
/*
+ * DB_CREATE_EVENT_LOG()
+ *
+ * NOTE: This assumes that the db scan lock is already applied
+ * (as it calls rset->get_array_info)
+ */
+db_field_log* db_create_event_log (struct evSubscrip *pevent)
+{
+ db_field_log *pLog = db_create_field_log(pevent->chan, pevent->useValque);
+ if (pLog) {
+ pLog->ctx = dbfl_context_event;
+ }
+ return pLog;
+}
+
+/*
* DB_CREATE_READ_LOG()
*
*/
db_field_log* db_create_read_log (struct dbChannel *chan)
{
- db_field_log *pLog = (db_field_log *) freeListCalloc(dbevFieldLogFreeList);
-
+ db_field_log *pLog = db_create_field_log(chan,
+ dbChannelElements(chan) == 1 &&
+ dbChannelSpecial(chan) != SPC_DBADDR &&
+ dbChannelFieldSize(chan) <= sizeof(union native_value));
if (pLog) {
pLog->ctx = dbfl_context_read;
- pLog->type = dbfl_type_rec;
}
return pLog;
}
@@ -737,20 +771,6 @@ static void db_queue_event_log (evSubscrip *pevent, db_field_log *pLog)
LOCKEVQUE (ev_que);
/*
- * if we have an event on the queue and both the last
- * event on the queue and the current event are emtpy
- * (i.e. of type dbfl_type_rec), simply ignore duplicate
- * events (saving empty events serves no purpose)
- */
- if (pevent->npend > 0u &&
- (*pevent->pLastLog)->type == dbfl_type_rec &&
- pLog->type == dbfl_type_rec) {
- db_delete_field_log(pLog);
- UNLOCKEVQUE (ev_que);
- return;
- }
-
- /*
* add to task local event que
*/
diff --git a/modules/database/src/ioc/db/dbExtractArray.c b/modules/database/src/ioc/db/dbExtractArray.c
index e16ab4c..f0ab281 100644
--- a/modules/database/src/ioc/db/dbExtractArray.c
+++ b/modules/database/src/ioc/db/dbExtractArray.c
@@ -13,11 +13,12 @@
/*
* Author: Ralph Lange <Ralph.Lange at bessy.de>
*
- * based on dbConvert.c
+ * based on dbConvert.c, see copyNoConvert
* written by: Bob Dalesio, Marty Kraimer
*/
#include <string.h>
+#include <assert.h>
#include "epicsTypes.h"
@@ -25,61 +26,31 @@
#include "dbAddr.h"
#include "dbExtractArray.h"
-void dbExtractArrayFromRec(const dbAddr *paddr, void *pto,
- long nRequest, long no_elements, long offset, long increment)
+void dbExtractArray(const void *pfrom, void *pto,
+ short field_size, short field_type,
+ long nRequest, long no_elements, long offset, long increment)
{
char *pdst = (char *) pto;
- char *psrc = (char *) paddr->pfield;
- long nUpperPart;
- int i;
- short srcSize = paddr->field_size;
- short dstSize = srcSize;
- char isString = (paddr->field_type == DBF_STRING);
+ const char *psrc = (char *) pfrom;
- if (nRequest > no_elements) nRequest = no_elements;
- if (isString && srcSize > MAX_STRING_SIZE) dstSize = MAX_STRING_SIZE;
+ /* assert preconditions */
+ assert(nRequest >= 0);
+ assert(no_elements >= 0);
+ assert(increment > 0);
+ assert(0 <= offset);
+ assert(offset < no_elements);
- if (increment == 1 && dstSize == srcSize) {
- nUpperPart = nRequest < no_elements - offset ? nRequest : no_elements - offset;
- memcpy(pdst, &psrc[offset * srcSize], dstSize * nUpperPart);
+ if (increment == 1) {
+ long nUpperPart =
+ nRequest < no_elements - offset ? nRequest : no_elements - offset;
+ memcpy(pdst, psrc + (offset * field_size), field_size * nUpperPart);
if (nRequest > nUpperPart)
- memcpy(&pdst[dstSize * nUpperPart], psrc, dstSize * (nRequest - nUpperPart));
- if (isString)
- for (i = 1; i <= nRequest; i++)
- pdst[dstSize*i-1] = '\0';
+ memcpy(pdst + (field_size * nUpperPart), psrc,
+ field_size * (nRequest - nUpperPart));
} else {
- for (; nRequest > 0; nRequest--, pdst += dstSize, offset += increment) {
+ for (; nRequest > 0; nRequest--, pdst += field_size, offset += increment) {
offset %= no_elements;
- memcpy(pdst, &psrc[offset*srcSize], dstSize);
- if (isString) pdst[dstSize-1] = '\0';
- }
- }
-}
-
-void dbExtractArrayFromBuf(const void *pfrom, void *pto,
- short field_size, short field_type,
- long nRequest, long no_elements, long offset, long increment)
-{
- char *pdst = (char *) pto;
- char *psrc = (char *) pfrom;
- int i;
- short srcSize = field_size;
- short dstSize = srcSize;
- char isString = (field_type == DBF_STRING);
-
- if (nRequest > no_elements) nRequest = no_elements;
- if (offset > no_elements - 1) offset = no_elements - 1;
- if (isString && dstSize >= MAX_STRING_SIZE) dstSize = MAX_STRING_SIZE - 1;
-
- if (increment == 1) {
- memcpy(pdst, &psrc[offset * srcSize], dstSize * nRequest);
- if (isString)
- for (i = 1; i <= nRequest; i++)
- pdst[dstSize*i] = '\0';
- } else {
- for (; nRequest > 0; nRequest--, pdst += srcSize, offset += increment) {
- memcpy(pdst, &psrc[offset*srcSize], dstSize);
- if (isString) pdst[dstSize] = '\0';
+ memcpy(pdst, psrc + (offset * field_size), field_size);
}
}
}
diff --git a/modules/database/src/ioc/db/dbExtractArray.h b/modules/database/src/ioc/db/dbExtractArray.h
index 7ed3584..9680660 100644
--- a/modules/database/src/ioc/db/dbExtractArray.h
+++ b/modules/database/src/ioc/db/dbExtractArray.h
@@ -21,11 +21,22 @@
extern "C" {
#endif
-epicsShareFunc void dbExtractArrayFromRec(const DBADDR *paddr, void *pto,
- long nRequest, long no_elements, long offset, long increment);
-epicsShareFunc void dbExtractArrayFromBuf(const void *pfrom, void *pto,
- short field_size, short field_type,
- long nRequest, long no_elements, long offset, long increment);
+/*
+ * This function does not do any conversion. This means we don't have to
+ * truncate the field_size to MAX_STRING_SIZE or add extra null terminators
+ * for string values. All of this is done by the dbConvert routines which
+ * will be called whether or not a filter is active.
+ *
+ * Checked preconditions:
+ * - nRequest >= 0, no_elements >= 0, increment > 0
+ * - 0 <= offset < no_elements
+ * Unchecked preconditions:
+ * - pto points to a buffer with at least field_size*nRequest bytes
+ * - pfrom points to a buffer with at least field_size*no_elements bytes
+ */
+epicsShareFunc void dbExtractArray(const void *pfrom, void *pto,
+ short field_size, short field_type,
+ long nRequest, long no_elements, long offset, long increment);
#ifdef __cplusplus
}
diff --git a/modules/database/src/ioc/db/dbTest.c b/modules/database/src/ioc/db/dbTest.c
index 1193954..206d6c9 100644
--- a/modules/database/src/ioc/db/dbTest.c
+++ b/modules/database/src/ioc/db/dbTest.c
@@ -341,14 +341,14 @@ long dbgf(const char *pname)
no_elements = MIN(addr.no_elements, sizeof(buffer)/addr.field_size);
if (addr.dbr_field_type == DBR_ENUM) {
long status = dbGetField(&addr, DBR_STRING, pbuffer,
- &options, &no_elements, NULL);
+ &options, &no_elements);
printBuffer(status, DBR_STRING, pbuffer, 0L, 0L,
no_elements, &msg_Buff, 10);
}
else {
long status = dbGetField(&addr, addr.dbr_field_type, pbuffer,
- &options, &no_elements, NULL);
+ &options, &no_elements);
printBuffer(status, addr.dbr_field_type, pbuffer, 0L, 0L,
no_elements, &msg_Buff, 10);
@@ -487,7 +487,7 @@ long dbtgf(const char *pname)
ret_options = req_options;
no_elements = 0;
status = dbGetField(&addr, addr.dbr_field_type, pbuffer,
- &ret_options, &no_elements, NULL);
+ &ret_options, &no_elements);
printBuffer(status, addr.dbr_field_type, pbuffer,
req_options, ret_options, no_elements, pMsgBuff, tab_size);
@@ -496,62 +496,62 @@ long dbtgf(const char *pname)
dbr_type = DBR_STRING;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/MAX_STRING_SIZE));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_CHAR;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsInt8)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_UCHAR;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsUInt8)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_SHORT;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsInt16)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_USHORT;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsUInt16)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_LONG;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsInt32)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_ULONG;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsUInt32)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_INT64;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsInt64)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_UINT64;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsUInt64)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_FLOAT;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsFloat32)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_DOUBLE;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsFloat64)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
dbr_type = DBR_ENUM;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsEnum16)));
- status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
pmsg[0] = '\0';
@@ -651,7 +651,7 @@ long dbtpf(const char *pname, const char *pvalue)
printf("Put as DBR_%-6s Ok, result as ", dbr[put_type]);
status = dbGetField(&addr, addr.dbr_field_type, pbuffer,
- &options, &no_elements, NULL);
+ &options, &no_elements);
printBuffer(status, addr.dbr_field_type, pbuffer, 0L, 0L,
no_elements, pMsgBuff, tab_size);
}
diff --git a/modules/database/src/ioc/db/dbUnitTest.c b/modules/database/src/ioc/db/dbUnitTest.c
index 6846ef5..458a28b 100644
--- a/modules/database/src/ioc/db/dbUnitTest.c
+++ b/modules/database/src/ioc/db/dbUnitTest.c
@@ -197,7 +197,7 @@ void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap)
return;
}
- status = dbGetField(&addr, dbrType, pod.bytes, NULL, &nReq, NULL);
+ status = dbGetField(&addr, dbrType, pod.bytes, NULL, &nReq);
if (status) {
testFail("dbGetField(\"%s\", %d, ...) -> %#lx (%s)", pv, dbrType, status, errSymMsg(status));
return;
@@ -270,7 +270,7 @@ void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsign
return;
}
- status = dbGetField(&addr, dbfType, gbuf, NULL, &nRequest, NULL);
+ status = dbGetField(&addr, dbfType, gbuf, NULL, &nRequest);
if (status) {
testFail("dbGetField(\"%s\", %d, ...) -> %#lx", pv, dbfType, status);
diff --git a/modules/database/src/ioc/db/db_field_log.h b/modules/database/src/ioc/db/db_field_log.h
index 1534517..4b3b82d 100644
--- a/modules/database/src/ioc/db/db_field_log.h
+++ b/modules/database/src/ioc/db/db_field_log.h
@@ -56,20 +56,31 @@ union native_value {
struct db_field_log;
typedef void (dbfl_freeFunc)(struct db_field_log *pfl);
-/* Types of db_field_log: rec = use record, val = val inside, ref = reference inside */
+/*
+ * A db_field_log has one of two types:
+ *
+ * dbfl_type_ref - Reference to value
+ * Used for variable size (array) data types. Meta-data
+ * is stored in the field log, but value data is stored externally.
+ * Only the dbfl_ref side of the data union is valid.
+ *
+ * dbfl_type_val - Internal value
+ * Used to store small scalar data. Meta-data and value are
+ * present in this structure and no external references are used.
+ * Only the dbfl_val side of the data union is valid.
+ */
typedef enum dbfl_type {
- dbfl_type_rec = 0,
dbfl_type_val,
dbfl_type_ref
} dbfl_type;
/* Context of db_field_log: event = subscription update, read = read reply */
typedef enum dbfl_context {
- dbfl_context_read = 0,
+ dbfl_context_read,
dbfl_context_event
} dbfl_context;
-#define dbflTypeStr(t) (t==dbfl_type_val?"val":t==dbfl_type_rec?"rec":"ref")
+#define dbflTypeStr(t) (t==dbfl_type_val?"val":"ref")
struct dbfl_val {
union native_value field; /* Field value */
@@ -81,6 +92,8 @@ struct dbfl_val {
* db_delete_field_log(). Any code which changes a dbfl_type_ref
* field log to another type, or to reference different data,
* must explicitly call the dtor function.
+ * If the dtor is NULL, then this means the array data is still owned
+ * by a record.
*/
struct dbfl_ref {
dbfl_freeFunc *dtor; /* Callback to free filter-allocated resources */
@@ -88,8 +101,17 @@ struct dbfl_ref {
void *field; /* Field value */
};
+/*
+ * Note: The offset member is understood to apply an implicit index mapping
+ *
+ * i' = (i + offset) % no_elements
+ *
+ * of request index i. The resulting i' is used to to index into u.r.field.
+ *
+ * Also note that field_size may be larger than MAX_STRING_SIZE.
+ */
typedef struct db_field_log {
- unsigned int type:2; /* type (union) selector */
+ unsigned int type:1; /* type (union) selector */
/* ctx is used for all types */
unsigned int ctx:1; /* context (operation type) */
/* the following are used for value and reference types */
@@ -97,37 +119,15 @@ typedef struct db_field_log {
unsigned short stat; /* Alarm Status */
unsigned short sevr; /* Alarm Severity */
short field_type; /* DBF type of data */
- short field_size; /* Data size */
- long no_elements; /* No of array elements */
+ short field_size; /* Size of a single element */
+ long no_elements; /* No of valid array elements */
+ long offset; /* See above */
union {
struct dbfl_val v;
struct dbfl_ref r;
} u;
} db_field_log;
-/*
- * A db_field_log will in one of three types:
- *
- * dbfl_type_rec - Reference to record
- * The field log stores no data itself. Data must instead be taken
- * via the dbChannel* which must always be provided when along
- * with the field log.
- * For this type only the 'type' and 'ctx' members are used.
- *
- * dbfl_type_ref - Reference to outside value
- * Used for variable size (array) data types. Meta-data
- * is stored in the field log, but value data is stored externally
- * (see struct dbfl_ref).
- * For this type all meta-data members are used. The dbfl_ref side of the
- * data union is used.
- *
- * dbfl_type_val - Internal value
- * Used to store small scalar data. Meta-data and value are
- * present in this structure and no external references are used.
- * For this type all meta-data members are used. The dbfl_val side of the
- * data union is used.
- */
-
#ifdef __cplusplus
}
#endif
diff --git a/modules/database/src/std/filters/arr.c b/modules/database/src/std/filters/arr.c
index f91708a..b90335e 100644
--- a/modules/database/src/std/filters/arr.c
+++ b/modules/database/src/std/filters/arr.c
@@ -12,16 +12,13 @@
#include <stdio.h>
-#include <freeList.h>
-#include <dbAccess.h>
-#include <dbExtractArray.h>
-#include <db_field_log.h>
-#include <dbLock.h>
-#include <recSup.h>
-#include <epicsExit.h>
-#include <special.h>
-#include <chfPlugin.h>
-#include <epicsExport.h>
+#include "chfPlugin.h"
+#include "dbExtractArray.h"
+#include "db_field_log.h"
+#include "dbLock.h"
+#include "epicsExit.h"
+#include "freeList.h"
+#include "epicsExport.h"
typedef struct myStruct {
epicsInt32 start;
@@ -45,6 +42,8 @@ static void * allocPvt(void)
myStruct *my = (myStruct*) freeListCalloc(myStructFreeList);
if (!my) return NULL;
+ /* defaults */
+ my->start = 0;
my->incr = 1;
my->end = -1;
return (void *) my;
@@ -93,78 +92,61 @@ static long wrapArrayIndices(long *start, const long increment, long *end,
static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl)
{
myStruct *my = (myStruct*) pvt;
- struct dbCommon *prec;
- rset *prset;
+ int must_lock;
long start = my->start;
long end = my->end;
- long nTarget = 0;
- long offset = 0;
- long nSource = dbChannelElements(chan);
- long capacity = nSource;
- void *pdst;
+ long nTarget;
+ void *pTarget;
+ /* initial values for the source array */
+ long offset = pfl->offset;
+ long nSource = pfl->no_elements;
switch (pfl->type) {
case dbfl_type_val:
- /* Only filter arrays */
+ /* TODO Treat scalars as arrays with 1 element */
break;
- case dbfl_type_rec:
- /* Extract from record */
- if (dbChannelSpecial(chan) == SPC_DBADDR &&
- nSource > 1 &&
- (prset = dbGetRset(&chan->addr)) &&
- prset->get_array_info)
- {
- void *pfieldsave = dbChannelField(chan);
- prec = dbChannelRecord(chan);
- dbScanLock(prec);
- prset->get_array_info(&chan->addr, &nSource, &offset);
- nTarget = wrapArrayIndices(&start, my->incr, &end, nSource);
- pfl->type = dbfl_type_ref;
- pfl->stat = prec->stat;
- pfl->sevr = prec->sevr;
- pfl->time = prec->time;
- pfl->field_type = dbChannelFieldType(chan);
- pfl->field_size = dbChannelFieldSize(chan);
- pfl->no_elements = nTarget;
- if (nTarget) {
- pdst = freeListCalloc(my->arrayFreeList);
- if (pdst) {
- pfl->u.r.dtor = freeArray;
- pfl->u.r.pvt = my->arrayFreeList;
- offset = (offset + start) % dbChannelElements(chan);
- dbExtractArrayFromRec(&chan->addr, pdst, nTarget, capacity,
- offset, my->incr);
- pfl->u.r.field = pdst;
- }
- }
- dbScanUnlock(prec);
- dbChannelField(chan) = pfieldsave;
- }
- break;
-
- /* Extract from buffer */
case dbfl_type_ref:
- pdst = NULL;
- nSource = pfl->no_elements;
+ must_lock = !pfl->u.r.dtor;
+ if (must_lock)
+ dbScanLock(dbChannelRecord(chan));
nTarget = wrapArrayIndices(&start, my->incr, &end, nSource);
- pfl->no_elements = nTarget;
- if (nTarget) {
- /* Copy the data out */
- void *psrc = pfl->u.r.field;
-
- pdst = freeListCalloc(my->arrayFreeList);
- if (!pdst) break;
- offset = start;
- dbExtractArrayFromBuf(psrc, pdst, pfl->field_size, pfl->field_type,
- nTarget, nSource, offset, my->incr);
- }
- if (pfl->u.r.dtor) pfl->u.r.dtor(pfl);
- if (nTarget) {
+ /*
+ * Side note: it would be nice if we could avoid the copying in
+ * the case of my->incr==1. This is currently not possible due to
+ * the way the offset member is interpreted (namely as shifting the
+ * array in a ring-buffer style).
+ */
+ if (nTarget > 0) {
+ /* copy the data */
+ void *pSource = pfl->u.r.field;
+ pTarget = freeListCalloc(my->arrayFreeList);
+ if (!pTarget) break;
+ offset = (offset + start) % nSource;
+ dbExtractArray(pSource, pTarget, pfl->field_size,
+ pfl->field_type, nTarget, nSource, offset, my->incr);
+ if (pfl->u.r.dtor) pfl->u.r.dtor(pfl);
+ pfl->u.r.field = pTarget;
pfl->u.r.dtor = freeArray;
pfl->u.r.pvt = my->arrayFreeList;
- pfl->u.r.field = pdst;
}
+ /* adjust offset and no_elements to refer to the new pTarget */
+ pfl->offset = 0;
+ /*
+ * Setting pfl->no_elements outside of the "if" clause above is
+ * done to make requests fail if nTarget is zero, that is, if all
+ * elements selected by the filter are outside the array bounds.
+ * TODO:
+ * It would be possible to lift this restriction by interpreting
+ * a request with *no* number of elements (NULL pointer) as scalar
+ * (meaning: fail if we get less than one element); in contrast,
+ * a request that explicitly specifies one element would be
+ * interpreted as an array request, for which zero elements would
+ * be a normal expected result.
+ */
+ pfl->no_elements = nTarget;
+ if (must_lock)
+ dbScanUnlock(dbChannelRecord(chan));
break;
}
return pfl;
diff --git a/modules/database/src/std/filters/ts.c b/modules/database/src/std/filters/ts.c
index 5925b0b..56c9f5b 100644
--- a/modules/database/src/std/filters/ts.c
+++ b/modules/database/src/std/filters/ts.c
@@ -11,21 +11,39 @@
*/
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
-#include <chfPlugin.h>
-#include <dbLock.h>
-#include <db_field_log.h>
-#include <epicsExport.h>
+#include "chfPlugin.h"
+#include "db_field_log.h"
+#include "dbLock.h"
+#include "epicsExport.h"
+
+/*
+ * The size of the data is different for each channel, and can even
+ * change at runtime, so a freeList doesn't make much sense here.
+ */
+static void freeArray(db_field_log *pfl) {
+ free(pfl->u.r.field);
+}
static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) {
epicsTimeStamp now;
epicsTimeGetCurrent(&now);
- /* If string or array, must make a copy (to ensure coherence between time and data) */
- if (pfl->type == dbfl_type_rec) {
- dbScanLock(dbChannelRecord(chan));
- dbChannelMakeArrayCopy(pvt, pfl, chan);
- dbScanUnlock(dbChannelRecord(chan));
+ /* If reference and not already copied,
+ must make a copy (to ensure coherence between time and data) */
+ if (pfl->type == dbfl_type_ref && !pfl->u.r.dtor) {
+ void *pTarget = calloc(pfl->no_elements, pfl->field_size);
+ void *pSource = pfl->u.r.field;
+ if (pTarget) {
+ dbScanLock(dbChannelRecord(chan));
+ memcpy(pTarget, pSource, pfl->field_size * pfl->no_elements);
+ pfl->u.r.field = pTarget;
+ pfl->u.r.dtor = freeArray;
+ pfl->u.r.pvt = pvt;
+ dbScanUnlock(dbChannelRecord(chan));
+ }
}
pfl->time = now;
diff --git a/modules/database/test/ioc/db/dbChArrTest.cpp b/modules/database/test/ioc/db/dbChArrTest.cpp
index 8255fdc..ff74e01 100644
--- a/modules/database/test/ioc/db/dbChArrTest.cpp
+++ b/modules/database/test/ioc/db/dbChArrTest.cpp
@@ -130,7 +130,7 @@ static void check(short dbr_type) {
memset(buf, 0, sizeof(buf)); \
(void) dbPutField(&offaddr, DBR_LONG, &off, 1); \
pfl = db_create_read_log(pch); \
- testOk(pfl && pfl->type == dbfl_type_rec, "Valid pfl, type = rec"); \
+ testOk(pfl && pfl->type == dbfl_type_ref, "Valid pfl, type = ref"); \
testOk(!dbChannelGetField(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \
testOk(req == Size, "Got %ld elements (expected %d)", req, Size); \
if (!testOk(!memcmp(buf, Expected, sizeof(Expected)), "Data correct")) \
@@ -178,6 +178,7 @@ static void check(short dbr_type) {
pfl->field_type = DBF_CHAR; \
pfl->field_size = 1; \
pfl->no_elements = 26; \
+ pfl->offset = 0; \
pfl->u.r.dtor = freeArray; \
pfl->u.r.field = epicsStrDup("abcdefghijklmnopqrsstuvwxyz"); \
testOk(!dbChannelGetField(pch, DBR_LONG, buf, NULL, &req, pfl), "Got Field value"); \
diff --git a/modules/database/test/std/filters/arrTest.cpp b/modules/database/test/std/filters/arrTest.cpp
index 1ec16b3..08ba07b 100644
--- a/modules/database/test/std/filters/arrTest.cpp
+++ b/modules/database/test/std/filters/arrTest.cpp
@@ -56,25 +56,26 @@ const char *server_port = CA_SERVER_PORT;
static int fl_equals_array(short type, const db_field_log *pfl1, void *p2) {
for (int i = 0; i < pfl1->no_elements; i++) {
+ int j = (i + pfl1->offset) % pfl1->no_elements;
switch (type) {
case DBR_DOUBLE:
- if (((epicsFloat64*)pfl1->u.r.field)[i] != ((epicsInt32*)p2)[i]) {
+ if (((epicsFloat64*)pfl1->u.r.field)[j] != ((epicsInt32*)p2)[i]) {
testDiag("at index=%d: field log has %g, should be %d",
- i, ((epicsFloat64*)pfl1->u.r.field)[i], ((epicsInt32*)p2)[i]);
+ i, ((epicsFloat64*)pfl1->u.r.field)[j], ((epicsInt32*)p2)[i]);
return 0;
}
break;
case DBR_LONG:
- if (((epicsInt32*)pfl1->u.r.field)[i] != ((epicsInt32*)p2)[i]) {
+ if (((epicsInt32*)pfl1->u.r.field)[j] != ((epicsInt32*)p2)[i]) {
testDiag("at index=%d: field log has %d, should be %d",
- i, ((epicsInt32*)pfl1->u.r.field)[i], ((epicsInt32*)p2)[i]);
+ i, ((epicsInt32*)pfl1->u.r.field)[j], ((epicsInt32*)p2)[i]);
return 0;
}
break;
case DBR_STRING:
- if (strtol(&((const char*)pfl1->u.r.field)[i*MAX_STRING_SIZE], NULL, 0) != ((epicsInt32*)p2)[i]) {
+ if (strtol(&((const char*)pfl1->u.r.field)[j*pfl1->field_size], NULL, 0) != ((epicsInt32*)p2)[i]) {
testDiag("at index=%d: field log has '%s', should be '%d'",
- i, &((const char*)pfl1->u.r.field)[i*MAX_STRING_SIZE], ((epicsInt32*)p2)[i]);
+ i, &((const char*)pfl1->u.r.field)[j*pfl1->field_size], ((epicsInt32*)p2)[i]);
return 0;
}
break;
@@ -119,7 +120,7 @@ static void testHead (const char *title, const char *typ = "") {
off = Offset; \
(void) dbPutField(&offaddr, DBR_LONG, &off, 1); \
pfl = db_create_read_log(pch); \
- testOk(pfl->type == dbfl_type_rec, "original field log has type rec"); \
+ testOk(pfl->type == dbfl_type_ref, "original field log has type ref"); \
pfl2 = dbChannelRunPostChain(pch, pfl); \
testOk(pfl2 == pfl, "call does not drop or replace field_log"); \
testOk(pfl->type == dbfl_type_ref, "filtered field log has type ref"); \
diff --git a/modules/database/test/std/filters/dbndTest.c b/modules/database/test/std/filters/dbndTest.c
index 4d70f83..fd4a472 100644
--- a/modules/database/test/std/filters/dbndTest.c
+++ b/modules/database/test/std/filters/dbndTest.c
@@ -129,7 +129,7 @@ MAIN(dbndTest)
dbEventCtx evtctx;
int logsFree, logsFinal;
- testPlan(77);
+ testPlan(72);
testdbPrepare();
@@ -170,12 +170,9 @@ MAIN(dbndTest)
"dbnd has one filter with argument in pre chain");
testOk((ellCount(&pch->post_chain) == 0), "dbnd has no filter in post chain");
- /* Field logs of type ref and rec: pass any update */
-
- testHead("Field logs of type ref and rec");
- fl1.type = dbfl_type_rec;
- mustPassTwice(pch, &fl1, "abs field_log=rec", 0., 0);
+ /* Field logs of type ref: pass any update */
+ testHead("Field logs of type ref");
fl1.type = dbfl_type_ref;
mustPassTwice(pch, &fl1, "abs field_log=ref", 0., 0);
- Replies:
- Re: [Merge] ~bfrk/epics-base:write-filters into epics-base:7.0 Ben Franksen via Core-talk
- [Merge] ~bfrk/epics-base:write-filters into epics-base:7.0 Ben Franksen via Core-talk
- Navigate by Date:
- Prev:
[Merge] ~bfrk/epics-base:write-filters into epics-base:7.0 Ben Franksen via Core-talk
- Next:
Re: [Merge] ~bfrk/epics-base:write-filters into epics-base:7.0 Ben Franksen via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
<2020>
2021
2022
2023
2024
2025
- Navigate by Thread:
- Prev:
[Merge] ~bfrk/epics-base:write-filters into epics-base:7.0 Ben Franksen via Core-talk
- Next:
Re: [Merge] ~bfrk/epics-base:write-filters into epics-base:7.0 Ben Franksen via Core-talk
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
<2020>
2021
2022
2023
2024
2025
|