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.
This commit is contained in:
@@ -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)
|
||||
|
||||
140
src/db/recGbl.c
140
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;
|
||||
dbFldDes *pdbFldDes = paddr->pfldDes;
|
||||
|
||||
getMaxRangeValues(pdbFldDes->field_type,&pcd->upper_ctrl_limit,
|
||||
&pcd->lower_ctrl_limit);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user