From ecedd9c3623b70345908b8f11ffa03c61a9f044c Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 12 Jan 2016 11:36:58 -0500 Subject: [PATCH] Move dbGetStringNum() to dbStaticLib.c use getpMessage() and keep it private --- src/ioc/dbStatic/dbStaticLib.c | 222 ++++++++++++++++++++++++++++++++- src/ioc/dbStatic/dbStaticRun.c | 218 -------------------------------- 2 files changed, 221 insertions(+), 219 deletions(-) diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c index c7271b5df..1039da9b5 100644 --- a/src/ioc/dbStatic/dbStaticLib.c +++ b/src/ioc/dbStatic/dbStaticLib.c @@ -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; diff --git a/src/ioc/dbStatic/dbStaticRun.c b/src/ioc/dbStatic/dbStaticRun.c index f7fcbd5c5..886fa3501 100644 --- a/src/ioc/dbStatic/dbStaticRun.c +++ b/src/ioc/dbStatic/dbStaticRun.c @@ -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;