From e889336458c85d69a8d55fc0f51e7f3dc95f9924 Mon Sep 17 00:00:00 2001 From: Andrew Johnson <anj@aps.anl.gov> Date: Wed, 17 Oct 2012 18:08:39 -0500 Subject: [PATCH] db: Undefined alarm limits should return NaN Where the record doesn't provide get_alarm_double() or for fields where the default applies, we were still returning 0. --- src/db/dbAccess.c | 70 +++++++++++------------ src/db/recGbl.c | 140 ++++++++++++++++++++++------------------------ 2 files changed, 98 insertions(+), 112 deletions(-) diff --git a/src/db/dbAccess.c b/src/db/dbAccess.c index 94f8a1b79b..d3e47062c7 100644 --- a/src/db/dbAccess.c +++ b/src/db/dbAccess.c @@ -27,6 +27,7 @@ #include "errlog.h" #include "cantProceed.h" #include "cvtFast.h" +#include "epicsMath.h" #include "epicsTime.h" #include "alarm.h" #include "ellLib.h" @@ -281,48 +282,41 @@ static void get_control(DBADDR *paddr, char **ppbuffer, } static void get_alarm(DBADDR *paddr, char **ppbuffer, - struct rset *prset,long *options) + struct rset *prset, long *options) { - struct dbr_alDouble ald; - int got_data=FALSE; + char *pbuffer = *ppbuffer; + struct dbr_alDouble ald = {epicsNAN, epicsNAN, epicsNAN, epicsNAN}; + long no_data = TRUE; - ald.upper_alarm_limit = ald.upper_warning_limit = 0.0; - ald.lower_warning_limit = ald.lower_alarm_limit = 0.0; - if( prset && prset->get_alarm_double ) { - (*prset->get_alarm_double)(paddr,&ald); - got_data=TRUE; - } - if( (*options) & (DBR_AL_LONG) ) { - char *pbuffer=*ppbuffer; + if (prset && prset->get_alarm_double) + no_data = prset->get_alarm_double(paddr, &ald); - if(got_data) { - struct dbr_alLong *pal=(struct dbr_alLong*)pbuffer; - pal->upper_alarm_limit = (epicsInt32)ald.upper_alarm_limit; - pal->upper_warning_limit = (epicsInt32)ald.upper_warning_limit; - pal->lower_warning_limit = (epicsInt32)ald.lower_warning_limit; - pal->lower_alarm_limit = (epicsInt32)ald.lower_alarm_limit; - } else { - memset(pbuffer,'\0',dbr_alLong_size); - *options = (*options) ^ DBR_AL_LONG; /*Turn off option*/ - } - *ppbuffer = ((char *)*ppbuffer) + dbr_alLong_size; - } - if( (*options) & (DBR_AL_DOUBLE) ) { - char *pbuffer=*ppbuffer; + if (*options & DBR_AL_LONG) { + struct dbr_alLong *pal = (struct dbr_alLong*) pbuffer; - if(got_data) { - struct dbr_alDouble *pal=(struct dbr_alDouble*)pbuffer; - 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; - } else { - memset(pbuffer,'\0',dbr_alDouble_size); - *options = (*options) ^ DBR_AL_DOUBLE; /*Turn off option*/ - } - *ppbuffer = ((char *)*ppbuffer) + dbr_alDouble_size; - } - return; + pal->upper_alarm_limit = (epicsInt32) ald.upper_alarm_limit; + pal->upper_warning_limit = (epicsInt32) ald.upper_warning_limit; + pal->lower_warning_limit = (epicsInt32) ald.lower_warning_limit; + pal->lower_alarm_limit = (epicsInt32) ald.lower_alarm_limit; + + if (no_data) + *options ^= DBR_AL_LONG; /*Turn off option*/ + + *ppbuffer += dbr_alLong_size; + } + if (*options & DBR_AL_DOUBLE) { + struct dbr_alDouble *pal = (struct dbr_alDouble*) pbuffer; + + 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; + + if (no_data) + *options ^= DBR_AL_DOUBLE; /*Turn off option*/ + + *ppbuffer += dbr_alDouble_size; + } } static void getOptions(DBADDR *paddr,char **poriginal,long *options,void *pflin) diff --git a/src/db/recGbl.c b/src/db/recGbl.c index 7cdf69a19d..2d58c9dab3 100644 --- a/src/db/recGbl.c +++ b/src/db/recGbl.c @@ -21,6 +21,7 @@ #include <limits.h> #include "dbDefs.h" +#include "epicsMath.h" #include "epicsTime.h" #include "epicsPrint.h" #include "dbBase.h" @@ -107,64 +108,56 @@ void epicsShareAPI recGblRecSupError(long status, const struct dbAddr *paddr, return; } -void epicsShareAPI recGblGetPrec(const struct dbAddr *paddr,long *precision) +void epicsShareAPI recGblGetPrec(const struct dbAddr *paddr, long *precision) { dbFldDes *pdbFldDes = paddr->pfldDes; - switch(pdbFldDes->field_type){ - case(DBF_SHORT): - *precision = 0; - break; - case(DBF_USHORT): - *precision = 0; - break; - case(DBF_LONG): - *precision = 0; - break; - case(DBF_ULONG): - *precision = 0; - break; - case(DBF_FLOAT): - case(DBF_DOUBLE): - if(*precision<0 || *precision>15) *precision=15; - break; + switch (pdbFldDes->field_type) { + case DBF_CHAR: + case DBF_UCHAR: + case DBF_SHORT: + case DBF_USHORT: + case DBF_LONG: + case DBF_ULONG: + *precision = 0; + break; + + case DBF_FLOAT: + case DBF_DOUBLE: + if (*precision < 0 || *precision > 15) + *precision = 15; + break; + default: break; } - return; } -void epicsShareAPI recGblGetGraphicDouble( - const struct dbAddr *paddr,struct dbr_grDouble *pgd) +void epicsShareAPI recGblGetGraphicDouble(const struct dbAddr *paddr, + struct dbr_grDouble *pgd) { dbFldDes *pdbFldDes = paddr->pfldDes; - getMaxRangeValues(pdbFldDes->field_type,&pgd->upper_disp_limit, - &pgd->lower_disp_limit); - - return; + getMaxRangeValues(pdbFldDes->field_type, + &pgd->upper_disp_limit, &pgd->lower_disp_limit); } -void epicsShareAPI recGblGetAlarmDouble( - const struct dbAddr *paddr,struct dbr_alDouble *pad) +void epicsShareAPI recGblGetAlarmDouble(const struct dbAddr *paddr, + struct dbr_alDouble *pad) { - pad->upper_alarm_limit = 0; - pad->upper_warning_limit = 0; - pad->lower_warning_limit = 0; - pad->lower_alarm_limit = 0; - - return; + pad->upper_alarm_limit = epicsNAN; + pad->upper_warning_limit = epicsNAN; + pad->lower_warning_limit = epicsNAN; + pad->lower_alarm_limit = epicsNAN; } -void epicsShareAPI recGblGetControlDouble( - const struct dbAddr *paddr,struct dbr_ctrlDouble *pcd) +void epicsShareAPI recGblGetControlDouble(const struct dbAddr *paddr, + struct dbr_ctrlDouble *pcd) { - dbFldDes *pdbFldDes=paddr->pfldDes; - - getMaxRangeValues(pdbFldDes->field_type,&pcd->upper_ctrl_limit, - &pcd->lower_ctrl_limit); + dbFldDes *pdbFldDes = paddr->pfldDes; - return; + getMaxRangeValues(pdbFldDes->field_type, + &pcd->upper_ctrl_limit, &pcd->lower_ctrl_limit); } int epicsShareAPI recGblInitConstantLink( @@ -319,40 +312,39 @@ static void getMaxRangeValues(short field_type, double *pupper_limit, double *plower_limit) { switch(field_type){ - case(DBF_CHAR): - *pupper_limit = -128.0; - *plower_limit = 127.0; - break; - case(DBF_UCHAR): - *pupper_limit = 255.0; - *plower_limit = 0.0; - break; - case(DBF_SHORT): - *pupper_limit = (double)SHRT_MAX; - *plower_limit = (double)SHRT_MIN; - break; - case(DBF_ENUM): - case(DBF_USHORT): - *pupper_limit = (double)USHRT_MAX; - *plower_limit = (double)0; - break; - case(DBF_LONG): - /* long did not work using cast to double */ - *pupper_limit = 2147483647.; - *plower_limit = -2147483648.; - break; - case(DBF_ULONG): - *pupper_limit = (double)ULONG_MAX; - *plower_limit = (double)0; - break; - case(DBF_FLOAT): - *pupper_limit = (double)1e+30; - *plower_limit = (double)-1e30; - break; - case(DBF_DOUBLE): - *pupper_limit = (double)1e+30; - *plower_limit = (double)-1e30; - break; + case DBF_CHAR: + *pupper_limit = -128.0; + *plower_limit = 127.0; + break; + case DBF_UCHAR: + *pupper_limit = 255.0; + *plower_limit = 0.0; + break; + case DBF_SHORT: + *pupper_limit = (double) SHRT_MAX; + *plower_limit = (double) SHRT_MIN; + break; + case DBF_ENUM: + case DBF_USHORT: + *pupper_limit = (double) USHRT_MAX; + *plower_limit = 0.0; + break; + case DBF_LONG: + *pupper_limit = 2147483647.0; + *plower_limit = -2147483648.0; + break; + case DBF_ULONG: + *pupper_limit = (double) 0xffffffffU; + *plower_limit = 0.0; + break; + case DBF_FLOAT: + *pupper_limit = 1e30; + *plower_limit = -1e30; + break; + case DBF_DOUBLE: + *pupper_limit = 1e300; + *plower_limit = -1e300; + break; } return; } -- GitLab