allow hex and octal strings in dbPut

Setting EPICS_DB_CONVERT_DECIMAL_ONLY turns dbPut/dbGet
string to integer conversions back the the old decimal only
policy.
This commit is contained in:
2025-07-15 10:05:55 +02:00
parent 60277e0980
commit 46f046c751
6 changed files with 59 additions and 27 deletions

View File

@@ -0,0 +1,13 @@
### Allow hex and octal strings in dbPut and dbGet
It is now possible to convert hex and octal strings to integer fields
with `dbPut()`, `dbGet()` and related functions like the iocsh command
`dbpf` or through database links.
Possible incompatibility: Up to now, leading `0`s have been ignored,
now they switch to octal mode.
For backward compatibility, this behavior can be switched off, returning
to the old decimal only conversions, by setting the environment variable
`EPICS_DB_CONVERT_DECIMAL_ONLY` to anything except the empty string or
strings starting with `n`, `N`, `f`, `F` or `0` before `iocInit`.

View File

@@ -171,7 +171,7 @@ static long getStringChar(const dbAddr *paddr,
*pdst++ = 0;
else {
char *end;
long status = epicsParseInt8(psrc, pdst++, 10, &end);
long status = epicsParseInt8(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -195,7 +195,7 @@ static long getStringUchar(const dbAddr *paddr,
*pdst++ = 0;
else {
char *end;
long status = epicsParseUInt8(psrc, pdst++, 10, &end);
long status = epicsParseUInt8(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -219,7 +219,7 @@ static long getStringShort(const dbAddr *paddr,
*pdst++ = 0;
else {
char *end;
long status = epicsParseInt16(psrc, pdst++, 10, &end);
long status = epicsParseInt16(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -243,7 +243,7 @@ static long getStringUshort(const dbAddr *paddr,
*pdst++ = 0;
else {
char *end;
long status = epicsParseUInt16(psrc, pdst++, 10, &end);
long status = epicsParseUInt16(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -267,7 +267,7 @@ static long getStringLong(const dbAddr *paddr,
*pdst++ = 0;
else {
char *end;
long status = epicsParseInt32(psrc, pdst++, 10, &end);
long status = epicsParseInt32(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -291,7 +291,7 @@ static long getStringUlong(const dbAddr *paddr,
*pdst++ = 0;
else {
char *end;
long status = epicsParseUInt32(psrc, pdst, 10, &end);
long status = epicsParseUInt32(psrc, pdst, dbConvertBase, &end);
if (status == S_stdlib_noConversion ||
(!status && (*end == '.' || *end == 'e' || *end == 'E'))) {
@@ -328,7 +328,7 @@ static long getStringInt64(const dbAddr *paddr,
*pdst++ = 0;
else {
char *end;
long status = epicsParseInt64(psrc, pdst++, 10, &end);
long status = epicsParseInt64(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -946,7 +946,7 @@ static long putStringChar(dbAddr *paddr,
while (nRequest--) {
char *end;
long status = epicsParseInt8(psrc, pdst++, 10, &end);
long status = epicsParseInt8(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -965,7 +965,7 @@ static long putStringUchar(dbAddr *paddr,
while (nRequest--) {
char *end;
long status = epicsParseUInt8(psrc, pdst++, 10, &end);
long status = epicsParseUInt8(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -984,7 +984,7 @@ static long putStringShort(dbAddr *paddr,
while (nRequest--) {
char *end;
long status = epicsParseInt16(psrc, pdst++, 10, &end);
long status = epicsParseInt16(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -1003,7 +1003,7 @@ static long putStringUshort(dbAddr *paddr,
while (nRequest--) {
char *end;
long status = epicsParseUInt16(psrc, pdst++, 10, &end);
long status = epicsParseUInt16(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -1022,7 +1022,7 @@ static long putStringLong(dbAddr *paddr,
while (nRequest--) {
char *end;
long status = epicsParseInt32(psrc, pdst++, 10, &end);
long status = epicsParseInt32(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -1041,7 +1041,7 @@ static long putStringUlong(dbAddr *paddr,
while (nRequest--) {
char *end;
long status = epicsParseUInt32(psrc, pdst, 10, &end);
long status = epicsParseUInt32(psrc, pdst, dbConvertBase, &end);
if (status == S_stdlib_noConversion ||
(!status && (*end == '.' || *end == 'e' || *end == 'E'))) {
@@ -1074,7 +1074,7 @@ static long putStringInt64(dbAddr *paddr,
while (nRequest--) {
char *end;
long status = epicsParseInt64(psrc, pdst++, 10, &end);
long status = epicsParseInt64(psrc, pdst++, dbConvertBase, &end);
if (status)
return status;
@@ -1178,7 +1178,7 @@ static long putStringEnum(dbAddr *paddr,
epicsEnum16 val;
char *end;
status = epicsParseUInt16(pfrom, &val, 10, &end);
status = epicsParseUInt16(pfrom, &val, dbConvertBase, &end);
if (!status && val < enumStrs.no_str) {
*pfield = val;
return 0;
@@ -1219,7 +1219,7 @@ static long putStringMenu(dbAddr *paddr,
}
}
if (!epicsParseUInt16(pfrom, &val, 10, NULL)
if (!epicsParseUInt16(pfrom, &val, dbConvertBase, NULL)
&& val < nChoice) {
*pfield = val;
return 0;
@@ -1258,7 +1258,7 @@ static long putStringDevice(dbAddr *paddr,
}
}
if (!epicsParseUInt16(pfrom, &val, 10, NULL) && val < nChoice) {
if (!epicsParseUInt16(pfrom, &val, dbConvertBase, NULL) && val < nChoice) {
*pfield = val;
return 0;
}

View File

@@ -98,7 +98,7 @@ static long cvt_st_c(const void *f, void *t, const dbAddr *paddr)
*to = 0;
return 0;
}
return epicsParseInt8(from, to, 10, &end);
return epicsParseInt8(from, to, dbConvertBase, &end);
}
/* Convert String to Unsigned Char */
@@ -112,7 +112,7 @@ static long cvt_st_uc(const void *f, void *t, const dbAddr *paddr)
*to = 0;
return 0;
}
return epicsParseUInt8(from, to, 10, &end);
return epicsParseUInt8(from, to, dbConvertBase, &end);
}
/* Convert String to Short */
@@ -126,7 +126,7 @@ static long cvt_st_s(const void *f, void *t, const dbAddr *paddr)
*to = 0;
return 0;
}
return epicsParseInt16(from, to, 10, &end);
return epicsParseInt16(from, to, dbConvertBase, &end);
}
/* Convert String to Unsigned Short */
@@ -140,7 +140,7 @@ static long cvt_st_us(const void *f, void *t, const dbAddr *paddr)
*to = 0;
return 0;
}
return epicsParseUInt16(from, to, 10, &end);
return epicsParseUInt16(from, to, dbConvertBase, &end);
}
/* Convert String to Long */
@@ -154,7 +154,7 @@ static long cvt_st_l(const void *f, void *t, const dbAddr *paddr)
*to = 0;
return 0;
}
return epicsParseInt32(from, to, 10, &end);
return epicsParseInt32(from, to, dbConvertBase, &end);
}
/* Convert String to Unsigned Long */
@@ -169,7 +169,7 @@ static long cvt_st_ul(const void *f, void *t, const dbAddr *paddr)
*to = 0;
return 0;
}
status = epicsParseUInt32(from, to, 10, &end);
status = epicsParseUInt32(from, to, dbConvertBase, &end);
if (status == S_stdlib_noConversion ||
(!status && (*end == '.' || *end == 'e' || *end == 'E'))) {
/*
@@ -198,7 +198,7 @@ static long cvt_st_q(const void *f, void *t, const dbAddr *paddr)
*to = 0;
return 0;
}
return epicsParseInt64(from, to, 10, &end);
return epicsParseInt64(from, to, dbConvertBase, &end);
}
/* Convert String to UInt64 */
@@ -269,7 +269,7 @@ static long cvt_st_e(const void *f, void *t, const dbAddr *paddr)
if (!status) {
epicsEnum16 val;
status = epicsParseUInt16(from, &val, 10, NULL);
status = epicsParseUInt16(from, &val, dbConvertBase, NULL);
if (!status && val < enumStrs.no_str) {
*to = val;
return 0;
@@ -306,7 +306,7 @@ static long cvt_st_menu(const void *f, void *t, const dbAddr *paddr)
}
}
if (!epicsParseUInt16(from, &val, 10, NULL) && val < nChoice) {
if (!epicsParseUInt16(from, &val, dbConvertBase, NULL) && val < nChoice) {
*to = val;
return 0;
}
@@ -339,7 +339,7 @@ static long cvt_st_device(const void *f, void *t, const dbAddr *paddr)
}
}
if (!epicsParseUInt16(from, &val, 10, NULL) && val < nChoice) {
if (!epicsParseUInt16(from, &val, dbConvertBase, NULL) && val < nChoice) {
*to = val;
return 0;
}

View File

@@ -59,6 +59,7 @@
#include "devSup.h"
#include "drvSup.h"
#include "epicsRelease.h"
#include "epicsConvert.h"
#include "initHooks.h"
#include "iocInit.h"
#include "link.h"
@@ -129,6 +130,16 @@ static int iocBuild_1(void)
errlogPrintf("iocBuild: " ERL_ERROR " Aborting, bad database definition (DBD)!\n");
return -1;
}
{
/* fall back to "old" decimal-only conversion if EPICS_DB_CONVERT_DECIMAL_ONLY
is set and does not look like meaning no/false/0 */
const char* dec_only = getenv("EPICS_DB_CONVERT_DECIMAL_ONLY");
if (dec_only && *dec_only && !strchr("nNfF0", *dec_only)) {
dbConvertBase = 10;
}
}
epicsSignalInstallSigHupIgnore();
initHookAnnounce(initHookAtBeginning);

View File

@@ -33,3 +33,5 @@ LIBCOM_API float epicsConvertDoubleToFloat(double value)
return (float) value;
}
int dbConvertBase = 0;

View File

@@ -20,6 +20,12 @@ extern "C" {
LIBCOM_API float epicsConvertDoubleToFloat(double value);
/* dbConvertBase is used in dbPut and dbGet string to integer conversions.
It defaults to 0 but is set to 10 if the EPICS_DB_CONVERT_DECIMAL_ONLY
environment variable is set.
*/
LIBCOM_API extern int dbConvertBase;
#ifdef __cplusplus
}
#endif