Move dbGetStringNum() to dbStaticLib.c

use getpMessage() and keep it private
This commit is contained in:
Michael Davidsaver
2016-01-12 11:36:58 -05:00
parent ef39f658cd
commit ecedd9c362
2 changed files with 221 additions and 219 deletions
+221 -1
View File
@@ -52,6 +52,9 @@ static char *pNullString = "";
#define messagesize 276
#define RPCL_LEN INFIX_TO_POSTFIX_SIZE(80)
/* must be long enough to hold 32-bit signed integer in base 10 */
STATIC_ASSERT(messagesize>=11);
static char *ppstring[5]={" NPP"," PP"," CA"," CP"," CPP"};
static char *msstring[4]={" NMS"," MS"," MSI"," MSS"};
@@ -83,6 +86,133 @@ static int mapDBFtoDCT[DBF_NOACCESS+1] = {
DCT_INLINK,DCT_OUTLINK,DCT_FWDLINK,
DCT_NOACCESS};
static char hex_digit_to_ascii[16]={'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f'};
static void ulongToHexString(epicsUInt32 source,char *pdest)
{
epicsUInt32 val,temp;
char digit[10];
int i,j;
if(source==0) {
strcpy(pdest,"0x0");
return;
}
*pdest++ = '0'; *pdest++ = 'x';
val = source;
for(i=0; val!=0; i++) {
temp = val/16;
digit[i] = hex_digit_to_ascii[val - temp*16];
val = temp;
}
for(j=i-1; j>=0; j--) {
*pdest++ = digit[j];
}
*pdest = 0;
return;
}
static double delta[2] = {1e-6, 1e-15};
static int precision[2] = {6, 14};
static void realToString(double value, char *preturn, int isdouble)
{
double absvalue;
int logval,prec;
size_t end;
char tstr[30];
char *ptstr = &tstr[0];
int round;
int ise = FALSE;
char *loce = NULL;
if (value == 0) {
strcpy(preturn, "0");
return;
}
absvalue = value < 0 ? -value : value;
if (absvalue < (double)INT_MAX) {
epicsInt32 intval = (epicsInt32) value;
double diff = value - intval;
if (diff < 0) diff = -diff;
if (diff < absvalue * delta[isdouble]) {
cvtLongToString(intval, preturn);
return;
}
}
/*Now starts the hard cases*/
if (value < 0) {
*preturn++ = '-';
value = -value;
}
logval = (int)log10(value);
if (logval > 6 || logval < -2) {
int nout;
ise = TRUE;
prec = precision[isdouble];
nout = sprintf(ptstr, "%.*e", prec, value);
loce = strchr(ptstr, 'e');
if (!loce) {
ptstr[nout] = 0;
strcpy(preturn, ptstr);
return;
}
*loce++ = 0;
} else {
prec = precision[isdouble] - logval;
if ( prec < 0) prec = 0;
sprintf(ptstr, "%.*f", prec, value);
}
if (prec > 0) {
end = strlen(ptstr) - 1;
round = FALSE;
while (end > 0) {
if (tstr[end] == '.') {end--; break;}
if (tstr[end] == '0') {end--; continue;}
if (!round && end < precision[isdouble]) break;
if (!round && tstr[end] < '8') break;
if (tstr[end-1] == '.') {
if (round) end = end-2;
break;
}
if (tstr[end-1] != '9') break;
round = TRUE;
end--;
}
tstr[end+1] = 0;
while (round) {
if (tstr[end] < '9') {tstr[end]++; break;}
if (end == 0) { *preturn++ = '1'; tstr[end] = '0'; break;}
tstr[end--] = '0';
}
}
strcpy(preturn, &tstr[0]);
if (ise) {
if (!(strchr(preturn, '.'))) strcat(preturn, ".0");
strcat(preturn, "e");
strcat(preturn, loce);
}
}
static void floatToString(float value,char *preturn)
{
realToString((double)value,preturn,0);
return;
}
static void doubleToString(double value,char *preturn)
{
realToString(value,preturn,1);
return;
}
/*forward references for private routines*/
static FILE *openOutstream(const char *filename);
@@ -207,7 +337,7 @@ static char *getpMessage(DBENTRY *pdbentry)
msg = dbCalloc(1, messagesize);
pdbentry->message = msg;
}
*msg = 0;
*msg = '\0';
return msg;
}
@@ -1913,6 +2043,96 @@ char * dbGetString(DBENTRY *pdbentry)
return pdbentry->message;
}
char *dbGetStringNum(DBENTRY *pdbentry)
{
dbFldDes *pflddes = pdbentry->pflddes;
void *pfield = pdbentry->pfield;
char *message;
unsigned char cvttype;
/* 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:
if(cvttype==CT_DECIMAL)
cvtCharToString(*(char*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(char*)pfield),message);
break;
case DBF_UCHAR:
if(cvttype==CT_DECIMAL)
cvtUcharToString(*(unsigned char*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(unsigned char*)pfield),message);
break;
case DBF_SHORT:
if(cvttype==CT_DECIMAL)
cvtShortToString(*(short*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(short*)pfield),message);
break;
case DBF_USHORT:
case DBF_ENUM:
if(cvttype==CT_DECIMAL)
cvtUshortToString(*(unsigned short*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(unsigned short*)pfield),message);
break;
case DBF_LONG:
if(cvttype==CT_DECIMAL)
cvtLongToString(*(epicsInt32*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(epicsInt32*)pfield), message);
break;
case DBF_ULONG:
if(cvttype==CT_DECIMAL)
cvtUlongToString(*(epicsUInt32 *)pfield, message);
else
ulongToHexString(*(epicsUInt32*)pfield, message);
break;
case DBF_FLOAT:
floatToString(*(float *)pfield,message);
break;
case DBF_DOUBLE:
doubleToString(*(double *)pfield,message);
break;
case DBF_MENU: {
dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
short choice_ind;
char *pchoice;
if(!pfield) {dbMsgCpy(pdbentry, "Field not found"); return(message);}
choice_ind = *((short *) pdbentry->pfield);
if(!pdbMenu || choice_ind<0 || choice_ind>=pdbMenu->nChoice)
return(NULL);
pchoice = pdbMenu->papChoiceValue[choice_ind];
dbMsgCpy(pdbentry, pchoice);
}
break;
case DBF_DEVICE: {
dbDeviceMenu *pdbDeviceMenu;
char *pchoice;
short choice_ind;
if(!pfield) {dbMsgCpy(pdbentry, "Field not found"); return(message);}
pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
if(!pdbDeviceMenu) return(NULL);
choice_ind = *((short *) pdbentry->pfield);
if(choice_ind<0 || choice_ind>=pdbDeviceMenu->nChoice)
return(NULL);
pchoice = pdbDeviceMenu->papChoice[choice_ind];
dbMsgCpy(pdbentry, pchoice);
}
break;
default:
return(NULL);
}
return (message);
}
long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec)
{
short i;
-218
View File
@@ -31,136 +31,6 @@
#include "devSup.h"
#include "special.h"
static char hex_digit_to_ascii[16]={'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f'};
static void ulongToHexString(epicsUInt32 source,char *pdest)
{
epicsUInt32 val,temp;
char digit[10];
int i,j;
if(source==0) {
strcpy(pdest,"0x0");
return;
}
*pdest++ = '0'; *pdest++ = 'x';
val = source;
for(i=0; val!=0; i++) {
temp = val/16;
digit[i] = hex_digit_to_ascii[val - temp*16];
val = temp;
}
for(j=i-1; j>=0; j--) {
*pdest++ = digit[j];
}
*pdest = 0;
return;
}
static double delta[2] = {1e-6, 1e-15};
static int precision[2] = {6, 14};
static void realToString(double value, char *preturn, int isdouble)
{
double absvalue;
int logval,prec;
size_t end;
char tstr[30];
char *ptstr = &tstr[0];
int round;
int ise = FALSE;
char *loce = NULL;
if (value == 0) {
strcpy(preturn, "0");
return;
}
absvalue = value < 0 ? -value : value;
if (absvalue < (double)INT_MAX) {
epicsInt32 intval = (epicsInt32) value;
double diff = value - intval;
if (diff < 0) diff = -diff;
if (diff < absvalue * delta[isdouble]) {
cvtLongToString(intval, preturn);
return;
}
}
/*Now starts the hard cases*/
if (value < 0) {
*preturn++ = '-';
value = -value;
}
logval = (int)log10(value);
if (logval > 6 || logval < -2) {
int nout;
ise = TRUE;
prec = precision[isdouble];
nout = sprintf(ptstr, "%.*e", prec, value);
loce = strchr(ptstr, 'e');
if (!loce) {
ptstr[nout] = 0;
strcpy(preturn, ptstr);
return;
}
*loce++ = 0;
} else {
prec = precision[isdouble] - logval;
if ( prec < 0) prec = 0;
sprintf(ptstr, "%.*f", prec, value);
}
if (prec > 0) {
end = strlen(ptstr) - 1;
round = FALSE;
while (end > 0) {
if (tstr[end] == '.') {end--; break;}
if (tstr[end] == '0') {end--; continue;}
if (!round && end < precision[isdouble]) break;
if (!round && tstr[end] < '8') break;
if (tstr[end-1] == '.') {
if (round) end = end-2;
break;
}
if (tstr[end-1] != '9') break;
round = TRUE;
end--;
}
tstr[end+1] = 0;
while (round) {
if (tstr[end] < '9') {tstr[end]++; break;}
if (end == 0) { *preturn++ = '1'; tstr[end] = '0'; break;}
tstr[end--] = '0';
}
}
strcpy(preturn, &tstr[0]);
if (ise) {
if (!(strchr(preturn, '.'))) strcat(preturn, ".0");
strcat(preturn, "e");
strcat(preturn, loce);
}
}
static void floatToString(float value,char *preturn)
{
realToString((double)value,preturn,0);
return;
}
static void doubleToString(double value,char *preturn)
{
realToString(value,preturn,1);
return;
}
static long do_nothing(struct dbCommon *precord) { return 0; }
/* Dummy DSXT used for soft device supports */
@@ -480,95 +350,7 @@ epicsShareFunc int dbIsDefaultValue(DBENTRY *pdbentry)
}
return(FALSE);
}
char *dbGetStringNum(DBENTRY *pdbentry)
{
dbFldDes *pflddes = pdbentry->pflddes;
void *pfield = pdbentry->pfield;
char *message;
unsigned char cvttype;
if(!pdbentry->message) pdbentry->message = dbCalloc(1,50);
message = pdbentry->message;
cvttype = pflddes->base;
switch (pflddes->field_type) {
case DBF_CHAR:
if(cvttype==CT_DECIMAL)
cvtCharToString(*(char*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(char*)pfield),message);
break;
case DBF_UCHAR:
if(cvttype==CT_DECIMAL)
cvtUcharToString(*(unsigned char*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(unsigned char*)pfield),message);
break;
case DBF_SHORT:
if(cvttype==CT_DECIMAL)
cvtShortToString(*(short*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(short*)pfield),message);
break;
case DBF_USHORT:
case DBF_ENUM:
if(cvttype==CT_DECIMAL)
cvtUshortToString(*(unsigned short*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(unsigned short*)pfield),message);
break;
case DBF_LONG:
if(cvttype==CT_DECIMAL)
cvtLongToString(*(epicsInt32*)pfield, message);
else
ulongToHexString((epicsUInt32)(*(epicsInt32*)pfield), message);
break;
case DBF_ULONG:
if(cvttype==CT_DECIMAL)
cvtUlongToString(*(epicsUInt32 *)pfield, message);
else
ulongToHexString(*(epicsUInt32*)pfield, message);
break;
case DBF_FLOAT:
floatToString(*(float *)pfield,message);
break;
case DBF_DOUBLE:
doubleToString(*(double *)pfield,message);
break;
case DBF_MENU: {
dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
short choice_ind;
char *pchoice;
if(!pfield) {strcpy(message,"Field not found"); return(message);}
choice_ind = *((short *) pdbentry->pfield);
if(!pdbMenu || choice_ind<0 || choice_ind>=pdbMenu->nChoice)
return(NULL);
pchoice = pdbMenu->papChoiceValue[choice_ind];
strcpy(message, pchoice);
}
break;
case DBF_DEVICE: {
dbDeviceMenu *pdbDeviceMenu;
char *pchoice;
short choice_ind;
if(!pfield) {strcpy(message,"Field not found"); return(message);}
pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
if(!pdbDeviceMenu) return(NULL);
choice_ind = *((short *) pdbentry->pfield);
if(choice_ind<0 || choice_ind>=pdbDeviceMenu->nChoice)
return(NULL);
pchoice = pdbDeviceMenu->papChoice[choice_ind];
strcpy(message, pchoice);
}
break;
default:
return(NULL);
}
return (message);
}
long dbPutStringNum(DBENTRY *pdbentry,const char *pstring)
{
dbFldDes *pflddes = pdbentry->pflddes;