Fix for GH issue #219, menu fields with non-choice values
It's rare, but menu fields may hold a value that does not correspond to one of the menu choices; the default value of the SSCN fields is the most common example (65535). Change the type conversion routines to return a numeric string instead of giving an error. DBF_DEVICE was fixed in dbFastLinkConv.c before the 7.0.7 release.
This commit is contained in:
committed by
Michael Davidsaver
parent
7ccc3ab82d
commit
b460c2659e
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
@@ -24,6 +23,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "epicsConvert.h"
|
||||
#include "epicsStdlib.h"
|
||||
#include "epicsStdio.h"
|
||||
#include "errlog.h"
|
||||
#include "errMdef.h"
|
||||
|
||||
@@ -1335,24 +1335,26 @@ static long cvt_menu_st(
|
||||
epicsEnum16 *from,
|
||||
char *to,
|
||||
const dbAddr *paddr)
|
||||
{
|
||||
dbFldDes *pdbFldDes;
|
||||
dbMenu *pdbMenu;
|
||||
char **papChoiceValue;
|
||||
char *pchoice;
|
||||
{
|
||||
dbFldDes *pdbFldDes;
|
||||
dbMenu *pdbMenu;
|
||||
|
||||
if(! paddr
|
||||
|| !(pdbFldDes = paddr->pfldDes)
|
||||
|| !(pdbMenu = (dbMenu *)pdbFldDes->ftPvt)
|
||||
|| *from>=pdbMenu->nChoice
|
||||
|| !(papChoiceValue = pdbMenu->papChoiceValue)
|
||||
|| !(pchoice=papChoiceValue[*from])) {
|
||||
recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_menu_st)");
|
||||
return(S_db_badChoice);
|
||||
if (!paddr ||
|
||||
!(pdbFldDes = paddr->pfldDes) ||
|
||||
!(pdbMenu = (dbMenu *)pdbFldDes->ftPvt)) {
|
||||
recGblDbaddrError(S_db_badChoice, paddr, "dbFastLinkConv(cvt_menu_st)");
|
||||
return S_db_badChoice;
|
||||
}
|
||||
strncpy(to,pchoice,MAX_STRING_SIZE);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (*from < pdbMenu->nChoice) {
|
||||
strncpy(to, pdbMenu->papChoiceValue[*from], MAX_STRING_SIZE);
|
||||
}
|
||||
else {
|
||||
/* Convert out-of-range values to numeric strings */
|
||||
epicsSnprintf(to, MAX_STRING_SIZE, "%u", *from);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Get Device to String */
|
||||
|
||||
@@ -2041,13 +2041,17 @@ char *dbGetStringNum(DBENTRY *pdbentry)
|
||||
{
|
||||
dbFldDes *pflddes = pdbentry->pflddes;
|
||||
void *pfield = pdbentry->pfield;
|
||||
char *message;
|
||||
char *message = getpMessage(pdbentry);
|
||||
unsigned char cvttype;
|
||||
|
||||
if (!pfield) {
|
||||
dbMsgCpy(pdbentry, "Field not found");
|
||||
return message;
|
||||
}
|
||||
|
||||
/* the following assumes that messagesize is large enough
|
||||
* to hold the base 10 encoded value of a 32-bit integer.
|
||||
*/
|
||||
message = getpMessage(pdbentry);
|
||||
cvttype = pflddes->base;
|
||||
switch (pflddes->field_type) {
|
||||
case DBF_CHAR:
|
||||
@@ -2109,37 +2113,34 @@ char *dbGetStringNum(DBENTRY *pdbentry)
|
||||
{
|
||||
dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
|
||||
epicsEnum16 choice_ind;
|
||||
char *pchoice;
|
||||
|
||||
if (!pfield) {
|
||||
dbMsgCpy(pdbentry, "Field not found");
|
||||
return message;
|
||||
}
|
||||
choice_ind = *((epicsEnum16 *) pdbentry->pfield);
|
||||
if (!pdbMenu || choice_ind < 0 || choice_ind >= pdbMenu->nChoice)
|
||||
if (!pdbMenu)
|
||||
return NULL;
|
||||
pchoice = pdbMenu->papChoiceValue[choice_ind];
|
||||
dbMsgCpy(pdbentry, pchoice);
|
||||
|
||||
choice_ind = *((epicsEnum16 *) pdbentry->pfield);
|
||||
if (choice_ind >= pdbMenu->nChoice) {
|
||||
dbMsgPrint(pdbentry, "%u", choice_ind);
|
||||
}
|
||||
else {
|
||||
dbMsgCpy(pdbentry, pdbMenu->papChoiceValue[choice_ind]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DBF_DEVICE:
|
||||
{
|
||||
dbDeviceMenu *pdbDeviceMenu;
|
||||
dbDeviceMenu *pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
|
||||
epicsEnum16 choice_ind;
|
||||
char *pchoice;
|
||||
|
||||
if (!pfield) {
|
||||
dbMsgCpy(pdbentry, "Field not found");
|
||||
return message;
|
||||
if (!pdbDeviceMenu) {
|
||||
dbMsgCpy(pdbentry, "");
|
||||
break;
|
||||
}
|
||||
pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
|
||||
if (!pdbDeviceMenu)
|
||||
return NULL;
|
||||
|
||||
choice_ind = *((epicsEnum16 *) pdbentry->pfield);
|
||||
if (choice_ind<0 || choice_ind>=pdbDeviceMenu->nChoice)
|
||||
if (choice_ind>=pdbDeviceMenu->nChoice)
|
||||
return NULL;
|
||||
pchoice = pdbDeviceMenu->papChoice[choice_ind];
|
||||
dbMsgCpy(pdbentry, pchoice);
|
||||
|
||||
dbMsgCpy(pdbentry, pdbDeviceMenu->papChoice[choice_ind]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user