diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index e43fde5bf..14326737a 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -21,6 +21,45 @@
-->
+
IOC Database Support for 64-bit integers
+
+The IOC now supports the 64-bit integer field types DBF_INT64 and
+DBF_UINT64, and there are new record types int64in and
+int64out derived from the longin and longout types
+respectively that use the DBF_INT64 data type for their VAL and related
+fields. The usual range of Soft Channel device support are included for these
+new record types.
+
+All internal IOC APIs such as dbAccess can handle the new field types and
+their associated request values DBR_INT64 and DBR_UINT64,
+which are implemented using the epicsInt64 and epicsUInt64
+typedef's from the epicsTypes.h header.
+
+The waveform record type has been updated to support these new field types.
+All waveform device support layers must be updated to recognize the new
+type enumeration values, which had to be inserted before the
+FLOAT value in the enum dbfType and in menuFtype. C
+or C++ code can detect at compile-time whether this version of base provides
+64-bit support by checking for the presence of the DBR_INT64 macro as
+follows (Note that DBF_INT64 is an enum tag and not a
+preprocessor macro):
+
+
+#ifdef DBR_INT64
+ /* Code where Base has INT64 support */
+#else
+ /* Code for older versions */
+#endif
+
+
+Channel Access does not (and probably never will) directly support 64-bit
+integer types, so the new field types are presented to the CA server as
+DBF_DOUBLE values. This means that field values larger than 2^52
+(0x10_0000_0000_0000 = 4503599627370496) cannot be transported over Channel
+Access without their least significant bits being truncated. The EPICS V4
+pvAccess network protocol can transport 64-bit data types however, and
+a future release of the pvaSrv module will connect this ability to the IOC.
+
Add EPICS_CA_MCAST_TTL
Add option EPICS_CA_MCAST_TTL to set the Time To Live (TTL) of any IP multi-cast
diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c
index 4c6e1c7f5..973a66836 100644
--- a/src/ioc/db/dbAccess.c
+++ b/src/ioc/db/dbAccess.c
@@ -77,6 +77,8 @@ static short mapDBFToDBR[DBF_NTYPES] = {
/* DBF_USHORT => */ DBR_USHORT,
/* DBF_LONG => */ DBR_LONG,
/* DBF_ULONG => */ DBR_ULONG,
+ /* DBF_INT64 => */ DBR_INT64,
+ /* DBF_UINT64 => */ DBR_UINT64,
/* DBF_FLOAT => */ DBR_FLOAT,
/* DBF_DOUBLE => */ DBR_DOUBLE,
/* DBF_ENUM, => */ DBR_ENUM,
@@ -718,6 +720,8 @@ long dbValueSize(short dbr_type)
sizeof(epicsUInt16), /* USHORT */
sizeof(epicsInt32), /* LONG */
sizeof(epicsUInt32), /* ULONG */
+ sizeof(epicsInt64), /* INT64 */
+ sizeof(epicsUInt64), /* UINT64 */
sizeof(epicsFloat32), /* FLOAT */
sizeof(epicsFloat64), /* DOUBLE */
sizeof(epicsEnum16)}; /* ENUM */
diff --git a/src/ioc/db/dbChannel.c b/src/ioc/db/dbChannel.c
index a790fc22f..5ce1be4ef 100644
--- a/src/ioc/db/dbChannel.c
+++ b/src/ioc/db/dbChannel.c
@@ -454,6 +454,8 @@ static short mapDBFToDBR[DBF_NTYPES] =
/* DBF_USHORT => */DBR_USHORT,
/* DBF_LONG => */DBR_LONG,
/* DBF_ULONG => */DBR_ULONG,
+ /* DBF_INT64 => */DBR_INT64,
+ /* DBF_UINT64 => */DBR_UINT64,
/* DBF_FLOAT => */DBR_FLOAT,
/* DBF_DOUBLE => */DBR_DOUBLE,
/* DBF_ENUM, => */DBR_ENUM,
diff --git a/src/ioc/db/dbConvert.c b/src/ioc/db/dbConvert.c
index 9c2964811..5d2c71f4c 100644
--- a/src/ioc/db/dbConvert.c
+++ b/src/ioc/db/dbConvert.c
@@ -1,22 +1,18 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
+* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* dbConvert.c */
/*
* Original Author: Bob Dalesio
- * Current Author: Marty Kraimer
* Date: 11-7-90
*/
#include
-#include
-#include
#include
#include
#include
@@ -25,6 +21,7 @@
#include "cvtFast.h"
#include "dbDefs.h"
#include "epicsConvert.h"
+#include "epicsStdlib.h"
#include "errlog.h"
#include "errMdef.h"
@@ -63,2202 +60,808 @@ static void copyNoConvert(const void *pfrom,
#define COPYNOCONVERT(N, FROM, TO, NREQ, NO_ELEM, OFFSET) \
copyNoConvert(FROM, TO, (N)*(NREQ), (N)*(NO_ELEM), (N)*(OFFSET))
-/* DATABASE ACCESS GET CONVERSION SUPPORT */
+#define GET(typea, typeb) (const dbAddr *paddr, \
+ void *pto, long nRequest, long no_elements, long offset) \
+{ \
+ typea *psrc = (typea *) paddr->pfield; \
+ typeb *pdst = (typeb *) pto; \
+ \
+ if (nRequest==1 && offset==0) { \
+ *pdst = (typeb) *psrc; \
+ return 0; \
+ } \
+ psrc += offset; \
+ while (nRequest--) { \
+ *pdst++ = (typeb) *psrc++; \
+ if (++offset == no_elements) \
+ psrc = (typea *) paddr->pfield; \
+ } \
+ return 0; \
+}
+
+#define GET_NOCONVERT(typea, typeb) (const dbAddr *paddr, \
+ void *pto, long nRequest, long no_elements, long offset) \
+{ \
+ if (nRequest==1 && offset==0) { \
+ typea *psrc = (typea *) paddr->pfield; \
+ typeb *pdst = (typeb *) pto; \
+ \
+ *pdst = (typeb) *psrc; \
+ return 0; \
+ } \
+ COPYNOCONVERT(sizeof(typeb), paddr->pfield, pto, nRequest, no_elements, offset); \
+ return 0; \
+}
+
+#define PUT(typea, typeb) (dbAddr *paddr, \
+ const void *pfrom, long nRequest, long no_elements, long offset) \
+{ \
+ const typea *psrc = (const typea *) pfrom; \
+ typeb *pdst = (typeb *) paddr->pfield; \
+ \
+ if (nRequest==1 && offset==0) { \
+ *pdst = (typeb) *psrc; \
+ return 0; \
+ } \
+ pdst += offset; \
+ while (nRequest--) { \
+ *pdst++ = (typeb) *psrc++; \
+ if (++offset == no_elements) \
+ pdst = (typeb *) paddr->pfield; \
+ } \
+ return 0; \
+}
+
+#define PUT_NOCONVERT(typea, typeb) (dbAddr *paddr, \
+ const void *pfrom, long nRequest, long no_elements, long offset) \
+{ \
+ if (nRequest==1 && offset==0) { \
+ const typea *psrc = (const typea *) pfrom; \
+ typeb *pdst = (typeb *) paddr->pfield; \
+ \
+ *pdst = (typeb) *psrc; \
+ return 0; \
+ } \
+ COPYNOCONVERT(sizeof(typeb), pfrom, paddr->pfield, nRequest, no_elements, offset); \
+ return 0; \
+}
+
-static long getStringString (
- const dbAddr *paddr,
+/* dbAccess Get conversion support routines */
+
+static long getStringString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- char *pbuffer = (char *) pto;
char *psrc = paddr->pfield;
+ char *pdst = (char *) pto;
short size = paddr->field_size;
short sizeto;
/* always force result string to be null terminated*/
sizeto = size;
- if (sizeto>=MAX_STRING_SIZE) sizeto = MAX_STRING_SIZE-1;
+ if (sizeto >= MAX_STRING_SIZE)
+ sizeto = MAX_STRING_SIZE - 1;
if (nRequest==1 && offset==0) {
- strncpy(pbuffer,psrc,sizeto);
- pbuffer[sizeto] = 0;
+ strncpy(pdst, psrc, sizeto);
+ pdst[sizeto] = 0;
return 0;
}
- psrc+= (size*offset);
- while (nRequest) {
- strncpy(pbuffer,psrc,sizeto);
- pbuffer[sizeto] = 0;
- pbuffer += MAX_STRING_SIZE;
+ psrc += size * offset;
+ while (nRequest--) {
+ strncpy(pdst, psrc, sizeto);
+ pdst[sizeto] = 0;
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = paddr->pfield;
+ psrc = paddr->pfield;
else
- psrc += size;
- nRequest--;
+ psrc += size;
}
return 0;
}
-static long getStringChar(
- const dbAddr *paddr,
+static long getStringChar(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- char *pbuffer = (char *) pto;
- char *psrc = (char *) paddr->pfield;
- short value;
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsInt8 *pdst = pto;
- if (nRequest==1 && offset==0) {
- if (sscanf(psrc,"%hd",&value) == 1) {
- *pbuffer = (char)value;
- return 0;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- return 0;
- } else {
- return(-1);
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseInt8(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
}
- }
- psrc += MAX_STRING_SIZE*offset;
- while (nRequest) {
- if (sscanf(psrc,"%hd",&value) == 1) {
- *pbuffer = (char)value;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- } else {
- return(-1);
- }
- pbuffer++;
if (++offset == no_elements)
psrc = paddr->pfield;
else
psrc += MAX_STRING_SIZE;
- nRequest--;
}
return 0;
}
+
+static long getStringUchar(const dbAddr *paddr,
+ void *pto, long nRequest, long no_elements, long offset)
+{
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsUInt8 *pdst = pto;
+
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseUInt8(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+ }
+ if (++offset == no_elements)
+ psrc = paddr->pfield;
+ else
+ psrc += MAX_STRING_SIZE;
+ }
+ return 0;
+}
+
+static long getStringShort(const dbAddr *paddr,
+ void *pto, long nRequest, long no_elements, long offset)
+{
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsInt16 *pdst = pto;
+
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseInt16(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+ }
+ if (++offset == no_elements)
+ psrc = paddr->pfield;
+ else
+ psrc += MAX_STRING_SIZE;
+ }
+ return 0;
+}
+
+static long getStringUshort(const dbAddr *paddr,
+ void *pto, long nRequest, long no_elements, long offset)
+{
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsUInt16 *pdst = pto;
+
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseUInt16(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+ }
+ if (++offset == no_elements)
+ psrc = paddr->pfield;
+ else
+ psrc += MAX_STRING_SIZE;
+ }
+ return 0;
+}
+
+static long getStringLong(const dbAddr *paddr,
+ void *pto, long nRequest, long no_elements, long offset)
+{
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsInt32 *pdst = pto;
+
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseInt32(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+ }
+ if (++offset == no_elements)
+ psrc = paddr->pfield;
+ else
+ psrc += MAX_STRING_SIZE;
+ }
+ return 0;
+}
+
+static long getStringUlong(const dbAddr *paddr,
+ void *pto, long nRequest, long no_elements, long offset)
+{
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsUInt32 *pdst = pto;
+
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseUInt32(psrc, pdst, 10, &end);
+
+ if (status == S_stdlib_noConversion ||
+ (!status && (*end == '.' || *end == 'e' || *end == 'E'))) {
+ /*
+ * Convert via double so numbers like 1.0e3 convert properly.
+ * db_access pretends unsigned long is double.
+ */
+ epicsFloat64 dval;
+
+ status = epicsParseFloat64(psrc, &dval, &end);
+ if (!status && 0 <= dval && dval <= ULONG_MAX)
+ *pdst = dval;
+ }
+ if (status)
+ return status;
+ pdst++;
+ }
+ if (++offset == no_elements)
+ psrc = paddr->pfield;
+ else
+ psrc += MAX_STRING_SIZE;
+ }
+ return 0;
+}
+
+static long getStringInt64(const dbAddr *paddr,
+ void *pto, long nRequest, long no_elements, long offset)
+{
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsInt64 *pdst = pto;
+
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseInt64(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+ }
+ if (++offset == no_elements)
+ psrc = paddr->pfield;
+ else
+ psrc += MAX_STRING_SIZE;
+ }
+ return 0;
+}
+
+static long getStringUInt64(const dbAddr *paddr,
+ void *pto, long nRequest, long no_elements, long offset)
+{
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsUInt64 *pdst = pto;
+
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseUInt64(psrc, pdst++, 0, &end);
+
+ if (status)
+ return status;
+ }
+ if (++offset == no_elements)
+ psrc = paddr->pfield;
+ else
+ psrc += MAX_STRING_SIZE;
+ }
+ return 0;
+}
+
+static long getStringFloat(const dbAddr *paddr,
+ void *pto, long nRequest, long no_elements, long offset)
+{
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsFloat32 *pdst = pto;
+
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseFloat32(psrc, pdst++, &end);
+
+ if (status)
+ return status;
+ }
+ if (++offset == no_elements)
+ psrc = paddr->pfield;
+ else
+ psrc += MAX_STRING_SIZE;
+ }
+ return 0;
+}
+
+static long getStringDouble(const dbAddr *paddr,
+ void *pto, long nRequest, long no_elements, long offset)
+{
+ char *psrc = (char *) paddr->pfield + MAX_STRING_SIZE * offset;
+ epicsFloat64 *pdst = pto;
+
+ while (nRequest--) {
+ if (*psrc == 0)
+ *pdst++ = 0;
+ else {
+ char *end;
+ long status = epicsParseFloat64(psrc, pdst++, &end);
+
+ if (status)
+ return status;
+ }
+ if (++offset == no_elements)
+ psrc = paddr->pfield;
+ else
+ psrc += MAX_STRING_SIZE;
+ }
+ return 0;
+}
+
-static long getStringUchar(
- const dbAddr *paddr,
+static long getCharString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
char *psrc = (char *) paddr->pfield;
- unsigned short value;
+ char *pdst = (char *) pto;
if (nRequest==1 && offset==0) {
- if (sscanf(psrc,"%hu",&value) == 1) {
- *pbuffer = (epicsUInt8)value;
- return 0;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- return 0;
- } else {
- return(-1);
- }
- }
- psrc += MAX_STRING_SIZE*offset;
- while (nRequest) {
- if (sscanf(psrc,"%hu",&value) == 1) {
- *pbuffer = (epicsUInt8)value;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- } else {
- return(-1);
- }
- pbuffer++;
- if (++offset == no_elements)
- psrc = paddr->pfield;
- else
- psrc += MAX_STRING_SIZE;
- nRequest--;
- }
- return 0;
-}
-
-static long getStringShort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
- char *psrc = (char *) paddr->pfield;
- short value;
-
- if (nRequest==1 && offset==0) {
- if (sscanf(psrc,"%hd",&value) == 1) {
- *pbuffer = value;
- return 0;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- return 0;
- } else {
- return(-1);
- }
- }
- psrc += MAX_STRING_SIZE*offset;
- while (nRequest) {
- if (sscanf(psrc,"%hd",&value) == 1) {
- *pbuffer = value;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- } else {
- return(-1);
- }
- pbuffer++;
- if (++offset == no_elements)
- psrc = paddr->pfield;
- else
- psrc += MAX_STRING_SIZE;
- nRequest--;
- }
- return 0;
-}
-
-static long getStringUshort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- char *psrc = (char *) paddr->pfield;
- unsigned short value;
-
- if (nRequest==1 && offset==0) {
- if (sscanf(psrc,"%hu",&value) == 1) {
- *pbuffer = value;
- return 0;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- return 0;
- } else {
- return(-1);
- }
- }
- psrc += MAX_STRING_SIZE*offset;
- while (nRequest) {
- if (sscanf(psrc,"%hu",&value) == 1) {
- *pbuffer = value;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- } else {
- return(-1);
- }
- pbuffer++;
- if (++offset == no_elements)
- psrc = paddr->pfield;
- else
- psrc += MAX_STRING_SIZE;
- nRequest--;
- }
- return 0;
-}
-
-static long getStringLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- char *psrc = (char *) paddr->pfield;
- epicsInt32 value;
-
- if (nRequest==1 && offset==0) {
- if (sscanf(psrc,"%d",&value) == 1) {
- *pbuffer = value;
- return 0;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- return 0;
- } else {
- return(-1);
- }
- }
- psrc += MAX_STRING_SIZE*offset;
- while (nRequest) {
- if (sscanf(psrc,"%d",&value) == 1) {
- *pbuffer = value;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- } else {
- return(-1);
- }
- pbuffer++;
- if (++offset == no_elements)
- psrc = paddr->pfield;
- else
- psrc += MAX_STRING_SIZE;
- nRequest--;
- }
- return 0;
-}
-
-static long getStringUlong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- char *psrc = (char *) paddr->pfield;
- double value;
-
- /*Convert to double first so that numbers like 1.0e3 convert properly*/
- /*Problem was old database access said to get unsigned long as double*/
- if (nRequest==1 && offset==0) {
- if (epicsScanDouble(psrc, &value) == 1) {
- *pbuffer = (epicsUInt32)value;
- return 0;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- return 0;
- } else {
- return(-1);
- }
- }
- psrc += MAX_STRING_SIZE*offset;
- while (nRequest) {
- if (epicsScanDouble(psrc, &value) == 1) {
- *pbuffer = (epicsUInt32)value;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- } else {
- return(-1);
- }
- pbuffer++;
- if (++offset == no_elements)
- psrc = paddr->pfield;
- else
- psrc += MAX_STRING_SIZE;
- nRequest--;
- }
- return 0;
-}
-
-static long getStringFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- float *pbuffer = (float *) pto;
- char *psrc = (char *) paddr->pfield;
- float value;
-
- if (nRequest==1 && offset==0) {
- if (epicsScanFloat(psrc, &value) == 1) {
- *pbuffer = value;
- return 0;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- return 0;
- } else {
- return(-1);
- }
- }
- psrc += MAX_STRING_SIZE*offset;
- while (nRequest) {
- if (epicsScanFloat(psrc, &value) == 1) {
- *pbuffer = value;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0;
- } else {
- return(-1);
- }
- pbuffer++;
- if (++offset == no_elements)
- psrc = paddr->pfield;
- else
- psrc += MAX_STRING_SIZE;
- nRequest--;
- }
- return 0;
-}
-
-static long getStringDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- double *pbuffer = (double *) pto;
- char *psrc = (char *) paddr->pfield;
- double value;
-
- if (nRequest==1 && offset==0) {
- if (epicsScanDouble(psrc, &value) == 1) {
- *pbuffer = value;
- return 0;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0.0;
- return 0;
- } else {
- return(-1);
- }
- }
- psrc += MAX_STRING_SIZE*offset;
- while (nRequest) {
- if (epicsScanDouble(psrc, &value) == 1) {
- *pbuffer = value;
- } else if (strlen(psrc) == 0) {
- *pbuffer = 0.0;
- } else {
- return(-1);
- }
- pbuffer++;
- if (++offset == no_elements)
- psrc = paddr->pfield;
- else
- psrc += MAX_STRING_SIZE;
- nRequest--;
- }
- return 0;
-}
-
-static long getStringEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- return(getStringUshort(paddr,pto,nRequest,no_elements,offset));
-}
-
-static long getCharString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
- char *psrc = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- cvtCharToString(*psrc,pbuffer);
+ cvtCharToString(*psrc, pdst);
return 0;
}
psrc += offset;
- while (nRequest) {
- cvtCharToString(*psrc,pbuffer);
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ cvtCharToString(*psrc, pdst);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
psrc = (char *) paddr->pfield;
else
psrc++;
- nRequest--;
}
return 0;
}
-static long getCharChar(
- const dbAddr *paddr,
+static long getCharChar(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- char *pbuffer = (char *) pto;
char *psrc = (char *) paddr->pfield;
+ char *pdst = (char *) pto;
if (paddr->pfldDes && paddr->pfldDes->field_type == DBF_STRING) {
/* This is a DBF_STRING field being read as a long string.
* The buffer we return must be zero-terminated.
*/
- pbuffer[--nRequest] = 0;
- if (nRequest == 0) return 0;
+ pdst[--nRequest] = 0;
+ if (nRequest == 0)
+ return 0;
}
if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(char), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getCharUchar(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
- char *psrc = (char *) paddr->pfield;
-
- if (paddr->pfldDes && paddr->pfldDes->field_type == DBF_STRING) {
- /* This is a DBF_STRING field being read as a long string.
- * The buffer we return must be zero-terminated.
- */
- pbuffer[--nRequest] = 0;
- if (nRequest == 0) return 0;
- }
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
+ *pdst = *psrc;
return 0;
}
COPYNOCONVERT(sizeof(char), paddr->pfield, pto, nRequest, no_elements, offset);
return 0;
}
-static long getCharShort(
- const dbAddr *paddr,
+static long getCharUchar(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
char *psrc = (char *) paddr->pfield;
+ epicsUInt8 *pdst = (epicsUInt8 *) pto;
+ if (paddr->pfldDes && paddr->pfldDes->field_type == DBF_STRING) {
+ /* This is a DBF_STRING field being read as a long string.
+ * The buffer we return must be zero-terminated.
+ */
+ pdst[--nRequest] = 0;
+ if (nRequest == 0)
+ return 0;
+ }
if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
+ *pdst = *psrc;
return 0;
}
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (char *) paddr->pfield;
- nRequest--;
- }
+ COPYNOCONVERT(sizeof(char), paddr->pfield, pto, nRequest, no_elements, offset);
return 0;
}
+
+static long getCharShort GET(char, epicsInt16)
+static long getCharUshort GET(char, epicsUInt16)
+static long getCharLong GET(char, epicsInt32)
+static long getCharUlong GET(char, epicsUInt32)
+static long getCharInt64 GET(char, epicsInt64)
+static long getCharUInt64 GET(char, epicsUInt64)
+static long getCharFloat GET(char, epicsFloat32)
+static long getCharDouble GET(char, epicsFloat64)
+static long getCharEnum GET(char, epicsEnum16)
-static long getCharUshort(
- const dbAddr *paddr,
+static long getUcharString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- char *psrc = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getCharLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- char *psrc = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getCharUlong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- char *psrc = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getCharFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- float *pbuffer = (float *) pto;
- char *psrc = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getCharDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- double *pbuffer = (double *) pto;
- char *psrc = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getCharEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsEnum16 *pbuffer = (epicsEnum16 *) pto;
- char *psrc = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUcharString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
+ char *pdst = (char *) pto;
if (nRequest==1 && offset==0) {
- cvtUcharToString(*psrc,pbuffer);
+ cvtUcharToString(*psrc, pdst);
return 0;
}
psrc += offset;
- while (nRequest) {
- cvtUcharToString(*psrc,pbuffer);
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ cvtUcharToString(*psrc, pdst);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = (epicsUInt8 *) paddr->pfield;
+ psrc = (epicsUInt8 *) paddr->pfield;
else
- psrc++;
- nRequest--;
+ psrc++;
}
return 0;
}
-static long getUcharChar(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- char *pbuffer = (char *) pto;
- epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt8), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
+static long getUcharChar GET_NOCONVERT(epicsUInt8, char)
+static long getUcharUchar GET_NOCONVERT(epicsUInt8, epicsUInt8)
+static long getUcharShort GET(epicsUInt8, epicsInt16)
+static long getUcharUshort GET(epicsUInt8, epicsUInt16)
+static long getUcharLong GET(epicsUInt8, epicsInt32)
+static long getUcharUlong GET(epicsUInt8, epicsUInt32)
+static long getUcharInt64 GET(epicsUInt8, epicsInt64)
+static long getUcharUInt64 GET(epicsUInt8, epicsUInt64)
+static long getUcharFloat GET(epicsUInt8, epicsFloat32)
+static long getUcharDouble GET(epicsUInt8, epicsFloat64)
+static long getUcharEnum GET(epicsUInt8, epicsEnum16)
-static long getUcharUchar(
- const dbAddr *paddr,
+static long getShortString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- if (nRequest==1 && offset==0) {
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
- epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt8), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getUcharShort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
- epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUcharUshort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUcharLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUcharUlong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUcharFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- float *pbuffer = (float *) pto;
- epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUcharDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- double *pbuffer = (double *) pto;
- epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUcharEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsEnum16 *pbuffer = (epicsEnum16 *) pto;
- epicsUInt8 *psrc = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getShortString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
+ char *pdst = (char *) pto;
if (nRequest==1 && offset==0) {
- cvtShortToString(*psrc,pbuffer);
+ cvtShortToString(*psrc, pdst);
return 0;
}
psrc += offset;
- while (nRequest) {
- cvtShortToString(*psrc,pbuffer);
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ cvtShortToString(*psrc, pdst);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = (epicsInt16 *) paddr->pfield;
+ psrc = (epicsInt16 *) paddr->pfield;
else
- psrc++;
- nRequest--;
+ psrc++;
}
return 0;
}
-static long getShortChar(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
- epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (char)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (char)*psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long getShortChar GET(epicsInt16, char)
+static long getShortUchar GET(epicsInt16, epicsUInt8)
+static long getShortShort GET_NOCONVERT(epicsInt16, epicsInt16)
+static long getShortUshort GET_NOCONVERT(epicsInt16, epicsUInt16)
+static long getShortLong GET(epicsInt16, epicsInt32)
+static long getShortUlong GET(epicsInt16, epicsUInt32)
+static long getShortInt64 GET(epicsInt16, epicsInt64)
+static long getShortUInt64 GET(epicsInt16, epicsUInt64)
+static long getShortFloat GET(epicsInt16, epicsFloat32)
+static long getShortDouble GET(epicsInt16, epicsFloat64)
+static long getShortEnum GET(epicsInt16, epicsEnum16)
-static long getShortUchar(
- const dbAddr *paddr,
+static long getUshortString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
- epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsUInt8)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsUInt8)*psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getShortShort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
- epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsInt16), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getShortUshort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsInt16), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getShortLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getShortUlong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getShortFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- float *pbuffer = (float *) pto;
- epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getShortDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- double *pbuffer = (double *) pto;
- epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getShortEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsEnum16 *pbuffer = (epicsEnum16 *) pto;
- epicsInt16 *psrc = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUshortString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
+ char *pdst = (char *) pto;
if (nRequest==1 && offset==0) {
- cvtUshortToString(*psrc,pbuffer);
+ cvtUshortToString(*psrc, pdst);
return 0;
}
psrc += offset;
- while (nRequest) {
- cvtUshortToString(*psrc,pbuffer);
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ cvtUshortToString(*psrc, pdst);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = (epicsUInt16 *) paddr->pfield;
+ psrc = (epicsUInt16 *) paddr->pfield;
else
- psrc++;
- nRequest--;
+ psrc++;
}
return 0;
}
-static long getUshortChar(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
- epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (char)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (char)*psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long getUshortChar GET(epicsUInt16, char)
+static long getUshortUchar GET(epicsUInt16, epicsUInt8)
+static long getUshortShort GET_NOCONVERT(epicsUInt16, epicsInt16)
+static long getUshortUshort GET_NOCONVERT(epicsUInt16, epicsUInt16)
+static long getUshortLong GET(epicsUInt16, epicsInt32)
+static long getUshortUlong GET(epicsUInt16, epicsUInt32)
+static long getUshortInt64 GET(epicsUInt16, epicsInt64)
+static long getUshortUInt64 GET(epicsUInt16, epicsUInt64)
+static long getUshortFloat GET(epicsUInt16, epicsFloat32)
+static long getUshortDouble GET(epicsUInt16, epicsFloat64)
+static long getUshortEnum GET(epicsUInt16, epicsEnum16)
-static long getUshortUchar(
- const dbAddr *paddr,
+static long getLongString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
- epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsUInt8)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsUInt8)*psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-static long getUshortShort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
- epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt16), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getUshortUshort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt16), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getUshortLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUshortUlong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUshortFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- float *pbuffer = (float *) pto;
- epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUshortDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- double *pbuffer = (double *) pto;
- epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUshortEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsEnum16 *pbuffer = (epicsEnum16 *) pto;
- epicsUInt16 *psrc = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getLongString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
+ char *pdst = (char *) pto;
if (nRequest==1 && offset==0) {
- cvtLongToString(*psrc,pbuffer);
+ cvtLongToString(*psrc, pdst);
return 0;
}
psrc += offset;
- while (nRequest) {
- cvtLongToString(*psrc,pbuffer);
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ cvtLongToString(*psrc, pdst);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = (epicsInt32 *) paddr->pfield;
+ psrc = (epicsInt32 *) paddr->pfield;
else
- psrc++;
- nRequest--;
+ psrc++;
}
return 0;
}
-static long getLongChar(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
- epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long getLongChar GET(epicsInt32, char)
+static long getLongUchar GET(epicsInt32, epicsUInt8)
+static long getLongShort GET(epicsInt32, epicsInt16)
+static long getLongUshort GET(epicsInt32, epicsUInt16)
+static long getLongLong GET_NOCONVERT(epicsInt32, epicsInt32)
+static long getLongUlong GET_NOCONVERT(epicsInt32, epicsUInt32)
+static long getLongInt64 GET(epicsInt32, epicsInt64)
+static long getLongUInt64 GET(epicsInt32, epicsUInt64)
+static long getLongFloat GET(epicsInt32, epicsFloat32)
+static long getLongDouble GET(epicsInt32, epicsFloat64)
+static long getLongEnum GET(epicsInt32, epicsEnum16)
-static long getLongUchar(
- const dbAddr *paddr,
+static long getUlongString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
- epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getLongShort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
- epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getLongUshort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getLongLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsInt32), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getLongUlong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsInt32), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getLongFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- float *pbuffer = (float *) pto;
- epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (float)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (float)*psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getLongDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- double *pbuffer = (double *) pto;
- epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getLongEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsEnum16 *pbuffer = (epicsEnum16 *) pto;
- epicsInt32 *psrc = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUlongString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
+ char *pdst = (char *) pto;
if (nRequest==1 && offset==0) {
- cvtUlongToString(*psrc,pbuffer);
+ cvtUlongToString(*psrc, pdst);
return 0;
}
psrc += offset;
- while (nRequest) {
- cvtUlongToString(*psrc,pbuffer);
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ cvtUlongToString(*psrc, pdst);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = (epicsUInt32 *) paddr->pfield;
+ psrc = (epicsUInt32 *) paddr->pfield;
else
- psrc++;
- nRequest--;
+ psrc++;
}
return 0;
}
-static long getUlongChar(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
- epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long getUlongChar GET(epicsUInt32, char)
+static long getUlongUchar GET(epicsUInt32, epicsUInt8)
+static long getUlongShort GET(epicsUInt32, epicsInt16)
+static long getUlongUshort GET(epicsUInt32, epicsUInt16)
+static long getUlongLong GET_NOCONVERT(epicsUInt32, epicsInt32)
+static long getUlongUlong GET_NOCONVERT(epicsUInt32, epicsUInt32)
+static long getUlongInt64 GET(epicsUInt32, epicsInt64)
+static long getUlongUInt64 GET(epicsUInt32, epicsUInt64)
+static long getUlongFloat GET(epicsUInt32, epicsFloat32)
+static long getUlongDouble GET(epicsUInt32, epicsFloat64)
+static long getUlongEnum GET(epicsUInt32, epicsEnum16)
-static long getUlongUchar(
- const dbAddr *paddr,
+static long getInt64String(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
- epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
+ epicsInt64 *psrc = (epicsInt64 *) paddr->pfield;
+ char *pdst = (char *) pto;
if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
+ cvtInt64ToString(*psrc, pdst);
return 0;
}
psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
+ while (nRequest--) {
+ cvtInt64ToString(*psrc, pdst);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = (epicsUInt32 *) paddr->pfield;
- nRequest--;
+ psrc = (epicsInt64 *) paddr->pfield;
+ else
+ psrc++;
}
return 0;
}
-static long getUlongShort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
- epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long getInt64Char GET(epicsInt64, char)
+static long getInt64Uchar GET(epicsInt64, epicsUInt8)
+static long getInt64Short GET(epicsInt64, epicsInt16)
+static long getInt64Ushort GET(epicsInt64, epicsUInt16)
+static long getInt64Long GET(epicsInt64, epicsInt32)
+static long getInt64Ulong GET(epicsInt64, epicsUInt32)
+static long getInt64Int64 GET_NOCONVERT(epicsInt64, epicsInt64)
+static long getInt64UInt64 GET_NOCONVERT(epicsInt64, epicsUInt64)
+static long getInt64Float GET(epicsInt64, epicsFloat32)
+static long getInt64Double GET(epicsInt64, epicsFloat64)
+static long getInt64Enum GET(epicsInt64, epicsEnum16)
-static long getUlongUshort(
- const dbAddr *paddr,
+static long getUInt64String(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
+ epicsUInt64 *psrc = (epicsUInt64 *) paddr->pfield;
+ char *pdst = (char *) pto;
if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
+ cvtUInt64ToString(*psrc, pdst);
return 0;
}
psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
+ while (nRequest--) {
+ cvtUInt64ToString(*psrc, pdst);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = (epicsUInt32 *) paddr->pfield;
- nRequest--;
+ psrc = (epicsUInt64 *) paddr->pfield;
+ else
+ psrc++;
}
return 0;
}
-static long getUlongLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt32), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
+static long getUInt64Char GET(epicsUInt64, char)
+static long getUInt64Uchar GET(epicsUInt64, epicsUInt8)
+static long getUInt64Short GET(epicsUInt64, epicsInt16)
+static long getUInt64Ushort GET(epicsUInt64, epicsUInt16)
+static long getUInt64Long GET(epicsUInt64, epicsInt32)
+static long getUInt64Ulong GET(epicsUInt64, epicsUInt32)
+static long getUInt64Int64 GET_NOCONVERT(epicsUInt64, epicsInt64)
+static long getUInt64UInt64 GET_NOCONVERT(epicsUInt64, epicsUInt64)
+static long getUInt64Float GET(epicsUInt64, epicsFloat32)
+static long getUInt64Double GET(epicsUInt64, epicsFloat64)
+static long getUInt64Enum GET(epicsUInt64, epicsEnum16)
-static long getUlongUlong(
- const dbAddr *paddr,
+static long getFloatString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- if (nRequest==1 && offset==0) {
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt32), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getUlongFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- float *pbuffer = (float *) pto;
- epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (float)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (float)*psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUlongDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- double *pbuffer = (double *) pto;
- epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getUlongEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsEnum16 *pbuffer = (epicsEnum16 *) pto;
- epicsUInt32 *psrc = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getFloatString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
- float *psrc = (float *) paddr->pfield;
+ epicsFloat32 *psrc = (epicsFloat32 *) paddr->pfield;
+ char *pdst = (char *) pto;
long status = 0;
long precision = 6;
rset *prset = 0;
- if (paddr) prset = dbGetRset(paddr);
- if (prset && (prset->get_precision))
- status = (*prset->get_precision)(paddr,&precision);
+ if (paddr)
+ prset = dbGetRset(paddr);
+ if (prset && prset->get_precision)
+ status = prset->get_precision(paddr, &precision);
if (nRequest==1 && offset==0) {
- cvtFloatToString(*psrc,pbuffer,precision);
+ cvtFloatToString(*psrc, pdst, precision);
return(status);
}
psrc += offset;
- while (nRequest) {
- cvtFloatToString(*psrc,pbuffer,precision);
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ cvtFloatToString(*psrc, pdst, precision);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = (float *) paddr->pfield;
+ psrc = (epicsFloat32 *) paddr->pfield;
else
- psrc++;
- nRequest--;
+ psrc++;
}
return(status);
}
-static long getFloatChar(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
- float *psrc = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (char)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (char)*psrc++;
- if (++offset == no_elements)
- psrc = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long getFloatChar GET(epicsFloat32, char)
+static long getFloatUchar GET(epicsFloat32, epicsUInt8)
+static long getFloatShort GET(epicsFloat32, epicsInt16)
+static long getFloatUshort GET(epicsFloat32, epicsUInt16)
+static long getFloatLong GET(epicsFloat32, epicsInt32)
+static long getFloatUlong GET(epicsFloat32, epicsUInt32)
+static long getFloatInt64 GET(epicsFloat32, epicsInt64)
+static long getFloatUInt64 GET(epicsFloat32, epicsUInt64)
+static long getFloatFloat GET_NOCONVERT(epicsFloat32, epicsFloat32)
+static long getFloatDouble GET(epicsFloat32, epicsFloat64)
+static long getFloatEnum GET(epicsFloat32, epicsEnum16)
-static long getFloatUchar(
- const dbAddr *paddr,
+static long getDoubleString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
- float *psrc = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsUInt8)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsUInt8)*psrc++;
- if (++offset == no_elements)
- psrc = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getFloatShort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
- float *psrc = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsInt16)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsInt16)*psrc++;
- if (++offset == no_elements)
- psrc = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getFloatUshort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- float *psrc = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsUInt16)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsUInt16)*psrc++;
- if (++offset == no_elements)
- psrc = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getFloatLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- float *psrc = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsInt32)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsInt32)*psrc++;
- if (++offset == no_elements)
- psrc = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getFloatUlong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- float *psrc = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsUInt32)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsUInt32)*psrc++;
- if (++offset == no_elements)
- psrc = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getFloatFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- float *pbuffer = (float *) pto;
- float *psrc = (float *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(float), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getFloatDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- double *pbuffer = (double *) pto;
- float *psrc = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getFloatEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsEnum16 *pbuffer = (epicsEnum16 *) pto;
- float *psrc = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsEnum16)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsEnum16)*psrc++;
- if (++offset == no_elements)
- psrc = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getDoubleString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
- double *psrc = (double *) paddr->pfield;
+ epicsFloat64 *psrc = (epicsFloat64 *) paddr->pfield;
+ char *pdst = (char *) pto;
long status = 0;
long precision = 6;
rset *prset = 0;
- if (paddr) prset = dbGetRset(paddr);
- if (prset && (prset->get_precision))
- status = (*prset->get_precision)(paddr,&precision);
+ if (paddr)
+ prset = dbGetRset(paddr);
+ if (prset && prset->get_precision)
+ status = prset->get_precision(paddr, &precision);
if (nRequest==1 && offset==0) {
- cvtDoubleToString(*psrc,pbuffer,precision);
+ cvtDoubleToString(*psrc, pdst, precision);
return(status);
}
psrc += offset;
- while (nRequest) {
- cvtDoubleToString(*psrc,pbuffer,precision);
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ cvtDoubleToString(*psrc, pdst, precision);
+ pdst += MAX_STRING_SIZE;
if (++offset == no_elements)
- psrc = (double *) paddr->pfield;
+ psrc = (epicsFloat64 *) paddr->pfield;
else
- psrc++;
- nRequest--;
+ psrc++;
}
return(status);
}
-static long getDoubleChar(
- const dbAddr *paddr,
+static long getDoubleChar GET(epicsFloat64, char)
+static long getDoubleUchar GET(epicsFloat64, epicsUInt8)
+static long getDoubleShort GET(epicsFloat64, epicsInt16)
+static long getDoubleUshort GET(epicsFloat64, epicsUInt16)
+static long getDoubleLong GET(epicsFloat64, epicsInt32)
+static long getDoubleUlong GET(epicsFloat64, epicsUInt32)
+static long getDoubleInt64 GET(epicsFloat64, epicsInt64)
+static long getDoubleUInt64 GET(epicsFloat64, epicsUInt64)
+
+static long getDoubleFloat(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- char *pbuffer = (char *) pto;
- double *psrc = (double *) paddr->pfield;
+ epicsFloat64 *psrc = (epicsFloat64 *) paddr->pfield;
+ epicsFloat32 *pdst = (epicsFloat32 *) pto;
if (nRequest==1 && offset==0) {
- *pbuffer = (char)*psrc;
+ *pdst = epicsConvertDoubleToFloat(*psrc);
return 0;
}
psrc += offset;
- while (nRequest) {
- *pbuffer++ = (char)*psrc++;
+ while (nRequest--) {
+ *pdst = epicsConvertDoubleToFloat(*psrc);
+ ++psrc; ++pdst;
if (++offset == no_elements)
- psrc = (double *) paddr->pfield;
- nRequest--;
+ psrc = (epicsFloat64 *) paddr->pfield;
}
return 0;
}
+
+static long getDoubleDouble GET_NOCONVERT(epicsFloat64, epicsFloat64)
+static long getDoubleEnum GET(epicsFloat64, epicsEnum16)
-static long getDoubleUchar(
- const dbAddr *paddr,
+static long getEnumString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
- double *psrc = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsUInt8)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsUInt8)*psrc++;
- if (++offset == no_elements)
- psrc = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getDoubleShort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
- double *psrc = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsInt16)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsInt16)*psrc++;
- if (++offset == no_elements)
- psrc = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getDoubleUshort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- double *psrc = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsUInt16)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsUInt16)*psrc++;
- if (++offset == no_elements)
- psrc = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getDoubleLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- double *psrc = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsInt32)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsInt32)*psrc++;
- if (++offset == no_elements)
- psrc = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getDoubleUlong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- double *psrc = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsUInt32)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsUInt32)*psrc++;
- if (++offset == no_elements)
- psrc = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getDoubleFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- float *pbuffer = (float *) pto;
- double *psrc = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = epicsConvertDoubleToFloat(*psrc);
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer = epicsConvertDoubleToFloat(*psrc);
- ++psrc; ++pbuffer;
- if (++offset == no_elements)
- psrc = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getDoubleDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- double *pbuffer = (double *) pto;
- double *psrc = (double *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(double), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getDoubleEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsEnum16 *pbuffer = (epicsEnum16 *) pto;
- double *psrc = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsEnum16)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsEnum16)*psrc++;
- if (++offset == no_elements)
- psrc = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getEnumString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
+ char *pdst = (char *) pto;
rset *prset;
long status;
- if ((prset=dbGetRset(paddr)) && (prset->get_enum_str))
- return( (*prset->get_enum_str)(paddr,pbuffer) );
- status=S_db_noRSET;
- recGblRecSupError(status,paddr,"dbGet","get_enum_str");
- return(S_db_badDbrtype);
+ prset = dbGetRset(paddr);
+ if (prset && prset->get_enum_str)
+ return prset->get_enum_str(paddr, pdst);
+
+ status = S_db_noRSET;
+ recGblRecSupError(status, paddr, "dbGet", "get_enum_str");
+ return S_db_badDbrtype;
}
-static long getEnumChar(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
- epicsEnum16 *psrc = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (char)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (char)*psrc++;
- if (++offset == no_elements)
- psrc = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long getEnumChar GET(epicsEnum16, char)
+static long getEnumUchar GET(epicsEnum16, epicsUInt8)
+static long getEnumShort GET(epicsEnum16, epicsInt16)
+static long getEnumUshort GET(epicsEnum16, epicsUInt16)
+static long getEnumLong GET(epicsEnum16, epicsInt32)
+static long getEnumUlong GET(epicsEnum16, epicsUInt32)
+static long getEnumInt64 GET(epicsEnum16, epicsInt64)
+static long getEnumUInt64 GET(epicsEnum16, epicsUInt64)
+static long getEnumFloat GET(epicsEnum16, epicsFloat32)
+static long getEnumDouble GET(epicsEnum16, epicsFloat64)
+static long getEnumEnum GET_NOCONVERT(epicsEnum16, epicsEnum16)
-static long getEnumUchar(
- const dbAddr *paddr,
+static long getMenuString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- epicsUInt8 *pbuffer = (epicsUInt8 *) pto;
- epicsEnum16 *psrc = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = (epicsUInt8)*psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = (epicsUInt8)*psrc++;
- if (++offset == no_elements)
- psrc = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getEnumShort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt16 *pbuffer = (epicsInt16 *) pto;
- epicsEnum16 *psrc = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getEnumUshort(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt16 *pbuffer = (epicsUInt16 *) pto;
- epicsEnum16 *psrc = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getEnumLong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsInt32 *pbuffer = (epicsInt32 *) pto;
- epicsEnum16 *psrc = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getEnumUlong(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- epicsUInt32 *pbuffer = (epicsUInt32 *) pto;
- epicsEnum16 *psrc = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getEnumFloat(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- float *pbuffer = (float *) pto;
- epicsEnum16 *psrc = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getEnumDouble(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- double *pbuffer = (double *) pto;
- epicsEnum16 *psrc = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pbuffer = *psrc;
- return 0;
- }
- psrc += offset;
- while (nRequest) {
- *pbuffer++ = *psrc++;
- if (++offset == no_elements)
- psrc = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long getEnumEnum(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- epicsEnum16 *pbuffer = (epicsEnum16 *) pto;
- epicsEnum16 *psrc = (epicsEnum16 *) paddr->pfield;
-
- *pbuffer = *psrc;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsEnum16), paddr->pfield, pto, nRequest, no_elements, offset);
- return 0;
-}
-
-static long getMenuString(
- const dbAddr *paddr,
- void *pto, long nRequest, long no_elements, long offset)
-{
- char *pbuffer = (char *) pto;
+ char *pdst = (char *) pto;
dbFldDes *pdbFldDes = paddr->pfldDes;
dbMenu *pdbMenu;
char **papChoiceValue;
@@ -2266,26 +869,25 @@ static long getMenuString(
epicsEnum16 choice_ind= *((epicsEnum16*) paddr->pfield);
if (no_elements!=1){
- recGblDbaddrError(S_db_onlyOne,paddr,"dbGet(getMenuString)");
+ recGblDbaddrError(S_db_onlyOne, paddr, "dbGet(getMenuString)");
return(S_db_onlyOne);
}
if (!pdbFldDes
- || !(pdbMenu = (dbMenu *)pdbFldDes->ftPvt)
+ || !(pdbMenu = (dbMenu *) pdbFldDes->ftPvt)
|| (choice_ind>=pdbMenu->nChoice)
|| !(papChoiceValue = pdbMenu->papChoiceValue)
|| !(pchoice=papChoiceValue[choice_ind])) {
- recGblDbaddrError(S_db_badChoice,paddr,"dbGet(getMenuString)");
+ recGblDbaddrError(S_db_badChoice, paddr, "dbGet(getMenuString)");
return(S_db_badChoice);
}
- strncpy(pbuffer,pchoice,MAX_STRING_SIZE);
+ strncpy(pdst, pchoice, MAX_STRING_SIZE);
return 0;
}
-static long getDeviceString(
- const dbAddr *paddr,
+static long getDeviceString(const dbAddr *paddr,
void *pto, long nRequest, long no_elements, long offset)
{
- char *pbuffer = (char *) pto;
+ char *pdst = (char *) pto;
dbFldDes *pdbFldDes = paddr->pfldDes;
dbDeviceMenu *pdbDeviceMenu;
char **papChoice;
@@ -2293,2280 +895,804 @@ static long getDeviceString(
epicsEnum16 choice_ind= *((epicsEnum16*) paddr->pfield);
if (no_elements!=1){
- recGblDbaddrError(S_db_onlyOne,paddr,"dbGet(getDeviceString)");
+ recGblDbaddrError(S_db_onlyOne, paddr, "dbGet(getDeviceString)");
return(S_db_onlyOne);
}
if (!pdbFldDes
- || !(pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt)
+ || !(pdbDeviceMenu = (dbDeviceMenu *) pdbFldDes->ftPvt)
|| (choice_ind>=pdbDeviceMenu->nChoice )
|| !(papChoice = pdbDeviceMenu->papChoice)
|| !(pchoice=papChoice[choice_ind])) {
- recGblDbaddrError(S_db_badChoice,paddr,"dbGet(getDeviceString)");
+ recGblDbaddrError(S_db_badChoice, paddr, "dbGet(getDeviceString)");
return(S_db_badChoice);
}
- strncpy(pbuffer,pchoice,MAX_STRING_SIZE);
+ strncpy(pdst, pchoice, MAX_STRING_SIZE);
return 0;
}
-
-/* DATABASE ACCESS PUT CONVERSION SUPPORT */
-static long putStringString(
- dbAddr *paddr,
+
+/* dbAccess put conversion support routines */
+
+static long putStringString(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- char *pdest = paddr->pfield;
+ const char *psrc = (const char *) pfrom;
+ char *pdst = paddr->pfield;
short size = paddr->field_size;
if (nRequest==1 && offset==0) {
- strncpy(pdest,pbuffer,size);
- *(pdest+size-1) = 0;
+ strncpy(pdst, psrc, size);
+ *(pdst+size-1) = 0;
return 0;
}
- pdest+= (size*offset);
- while (nRequest) {
- strncpy(pdest,pbuffer,size);
- *(pdest+size-1) = 0;
- pbuffer += MAX_STRING_SIZE;
+ pdst+= (size*offset);
+ while (nRequest--) {
+ strncpy(pdst, psrc, size);
+ pdst[size-1] = 0;
+ psrc += MAX_STRING_SIZE;
if (++offset == no_elements)
- pdest = paddr->pfield;
+ pdst = paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
return 0;
}
-static long putStringChar(
- dbAddr *paddr,
+static long putStringChar(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- char *pdest = (char *) paddr->pfield;
- short value;
+ const char *psrc = pfrom;
+ epicsInt8 *pdst = (epicsInt8 *) paddr->pfield + offset;
- if (nRequest==1 && offset==0) {
- if (sscanf(pbuffer,"%hd",&value) == 1) {
- *pdest = (char)value;
- return 0;
- }
- else return(-1);
- }
- pdest += offset;
- while (nRequest) {
- if (sscanf(pbuffer,"%hd",&value) == 1) {
- *pdest = (char)value;
- } else {
- return(-1);
- }
- pbuffer += MAX_STRING_SIZE;
- if (++offset == no_elements)
- pdest = paddr->pfield;
- else
- pdest++;
- nRequest--;
- }
- return 0;
-}
-
-static long putStringUchar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const char *pbuffer = (const char *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
- unsigned short value;
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseInt8(psrc, pdst++, 10, &end);
- if (nRequest==1 && offset==0) {
- if (sscanf(pbuffer,"%hu",&value) == 1) {
- *pdest = (epicsUInt8)value;
- return 0;
- }
- else return(-1);
- }
- pdest += offset;
- while (nRequest) {
- if (sscanf(pbuffer,"%hu",&value) == 1) {
- *pdest = (epicsUInt8)value;
- } else {
- return(-1);
- }
- pbuffer += MAX_STRING_SIZE;
+ if (status)
+ return status;
+ psrc += MAX_STRING_SIZE;
if (++offset == no_elements)
- pdest = paddr->pfield;
- else
- pdest++;
- nRequest--;
+ pdst = paddr->pfield;
}
return 0;
}
-static long putStringShort(
- dbAddr *paddr,
+static long putStringUchar(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
- short value;
+ const char *psrc = pfrom;
+ epicsUInt8 *pdst = (epicsUInt8 *) paddr->pfield + offset;
- if (nRequest==1 && offset==0) {
- if (sscanf(pbuffer,"%hd",&value) == 1) {
- *pdest = value;
- return 0;
- }
- else return(-1);
- }
- pdest += offset;
- while (nRequest) {
- if (sscanf(pbuffer,"%hd",&value) == 1) {
- *pdest = value;
- } else {
- return(-1);
- }
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseUInt8(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+ psrc += MAX_STRING_SIZE;
if (++offset == no_elements)
- pdest = paddr->pfield;
- else
- pdest++;
- nRequest--;
+ pdst = paddr->pfield;
}
return 0;
}
-static long putStringUshort(
- dbAddr *paddr,
+static long putStringShort(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
- unsigned short value;
+ const char *psrc = pfrom;
+ epicsInt16 *pdst = (epicsInt16 *) paddr->pfield + offset;
- if (nRequest==1 && offset==0) {
- if (sscanf(pbuffer,"%hu",&value) == 1) {
- *pdest = value;
- return 0;
- }
- else return(-1);
- }
- pdest += offset;
- while (nRequest) {
- if (sscanf(pbuffer,"%hu",&value) == 1) {
- *pdest = value;
- } else {
- return(-1);
- }
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseInt16(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+ psrc += MAX_STRING_SIZE;
if (++offset == no_elements)
- pdest = paddr->pfield;
- else
- pdest++;
- nRequest--;
+ pdst = paddr->pfield;
}
return 0;
}
-static long putStringLong(
- dbAddr *paddr,
+static long putStringUshort(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
- long value;
+ const char *psrc = pfrom;
+ epicsUInt16 *pdst = (epicsUInt16 *) paddr->pfield + offset;
- if (nRequest==1 && offset==0) {
- if (sscanf(pbuffer,"%ld",&value) == 1) {
- *pdest = value;
- return 0;
- }
- else return(-1);
- }
- pdest += offset;
- while (nRequest) {
- if (sscanf(pbuffer,"%ld",&value) == 1) {
- *pdest = value;
- } else {
- return(-1);
- }
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseUInt16(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+ psrc += MAX_STRING_SIZE;
if (++offset == no_elements)
- pdest = paddr->pfield;
- else
- pdest++;
- nRequest--;
+ pdst = paddr->pfield;
}
return 0;
}
-static long putStringUlong(
- dbAddr *paddr,
+static long putStringLong(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
- double value;
+ const char *psrc = pfrom;
+ epicsInt32 *pdst = (epicsInt32 *) paddr->pfield + offset;
- /*Convert to double first so that numbers like 1.0e3 convert properly*/
- /*Problem was old database access said to get unsigned long as double*/
- if (nRequest==1 && offset==0) {
- if (epicsScanDouble(pbuffer, &value) == 1) {
- *pdest = (epicsUInt32)value;
- return 0;
- }
- else return(-1);
- }
- pdest += offset;
- while (nRequest) {
- if (epicsScanDouble(pbuffer, &value) == 1) {
- *pdest = (epicsUInt32)value;
- } else {
- return(-1);
- }
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseInt32(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+ psrc += MAX_STRING_SIZE;
if (++offset == no_elements)
- pdest = paddr->pfield;
- else
- pdest++;
- nRequest--;
+ pdst = paddr->pfield;
}
return 0;
}
-static long putStringFloat(
- dbAddr *paddr,
+static long putStringUlong(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- float *pdest = (float *) paddr->pfield;
- float value;
+ const char *psrc = pfrom;
+ epicsUInt32 *pdst = (epicsUInt32 *) paddr->pfield + offset;
- if (nRequest==1 && offset==0) {
- if (epicsScanFloat(pbuffer, &value) == 1) {
- *pdest = value;
- return 0;
- } else {
- return(-1);
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseUInt32(psrc, pdst, 10, &end);
+
+ if (status == S_stdlib_noConversion ||
+ (!status && (*end == '.' || *end == 'e' || *end == 'E'))) {
+ /*
+ * Convert via double so numbers like 1.0e3 convert properly.
+ * db_access pretends unsigned long is double.
+ */
+ epicsFloat64 dval;
+
+ status = epicsParseFloat64(psrc, &dval, &end);
+ if (!status && 0 <= dval && dval <= ULONG_MAX)
+ *pdst = dval;
}
- }
- pdest += offset;
- while (nRequest) {
- if (epicsScanFloat(pbuffer, &value) == 1) {
- *pdest = value;
- } else {
- return(-1);
- }
- pbuffer += MAX_STRING_SIZE;
+ if (status)
+ return status;
+ psrc += MAX_STRING_SIZE;
if (++offset == no_elements)
- pdest = paddr->pfield;
+ pdst = paddr->pfield;
else
- pdest++;
- nRequest--;
+ pdst++;
}
return 0;
}
-static long putStringDouble(
- dbAddr *paddr,
+static long putStringInt64(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- double *pdest = (double *) paddr->pfield;
- double value;
+ const char *psrc = pfrom;
+ epicsInt64 *pdst = (epicsInt64 *) paddr->pfield + offset;
- if (nRequest==1 && offset==0) {
- if (epicsScanDouble(pbuffer, &value) == 1) {
- *pdest = value;
- return 0;
- } else {
- return(-1);
- }
- }
- pdest += offset;
- while (nRequest) {
- if (epicsScanDouble(pbuffer, &value) == 1) {
- *pdest = value;
- } else {
- return(-1);
- }
- pbuffer += MAX_STRING_SIZE;
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseInt64(psrc, pdst++, 10, &end);
+
+ if (status)
+ return status;
+
+ psrc += MAX_STRING_SIZE;
if (++offset == no_elements)
- pdest = paddr->pfield;
- else
- pdest++;
- nRequest--;
+ pdst = paddr->pfield;
}
return 0;
}
-
-static long putStringEnum(
- dbAddr *paddr,
+
+static long putStringUInt64(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- rset *prset;
- epicsEnum16 *pfield = (epicsEnum16*) paddr->pfield;
- long status;
- unsigned int nchoices,ind;
- int nargs,nchars;
+ const char *psrc = pfrom;
+ epicsUInt64 *pdst = (epicsUInt64 *) paddr->pfield + offset;
+
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseUInt64(psrc, pdst, 0, &end);
+
+ if (status)
+ return status;
+
+ psrc += MAX_STRING_SIZE;
+ if (++offset == no_elements)
+ pdst = paddr->pfield;
+ else
+ pdst++;
+ }
+ return 0;
+}
+
+static long putStringFloat(dbAddr *paddr,
+ const void *pfrom, long nRequest, long no_elements, long offset)
+{
+ const char *psrc = pfrom;
+ epicsFloat32 *pdst = (epicsFloat32 *) paddr->pfield + offset;
+
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseFloat32(psrc, pdst++, &end);
+
+ if (status)
+ return status;
+ psrc += MAX_STRING_SIZE;
+ if (++offset == no_elements)
+ pdst = paddr->pfield;
+ }
+ return 0;
+}
+
+static long putStringDouble(dbAddr *paddr,
+ const void *pfrom, long nRequest, long no_elements, long offset)
+{
+ const char *psrc = pfrom;
+ epicsFloat64 *pdst = (epicsFloat64 *) paddr->pfield + offset;
+
+ while (nRequest--) {
+ char *end;
+ long status = epicsParseFloat64(psrc, pdst++, &end);
+
+ if (status)
+ return status;
+ psrc += MAX_STRING_SIZE;
+ if (++offset == no_elements)
+ pdst = paddr->pfield;
+ }
+ return 0;
+}
+
+static long putStringEnum(dbAddr *paddr,
+ const void *pfrom, long nRequest, long no_elements, long offset)
+{
+ epicsEnum16 *pfield = paddr->pfield;
+ rset *prset = dbGetRset(paddr);
+ long status = S_db_noRSET;
struct dbr_enumStrs enumStrs;
- if ((prset=dbGetRset(paddr))
- && (prset->put_enum_str)) {
- status = (*prset->put_enum_str)(paddr,pbuffer);
- if (!status) return 0;
- if (prset->get_enum_strs) {
- status = (*prset->get_enum_strs)(paddr,&enumStrs);
- if (!status) {
- nchoices = enumStrs.no_str;
- nargs = sscanf(pbuffer,"%u%n",&ind,&nchars);
- if (nargs==1 && nchars==strlen(pbuffer) && indput_enum_str) {
+ recGblRecSupError(status, paddr, "dbPut(putStringEnum)", "put_enum_str");
+ return status;
+ }
+
+ status = prset->put_enum_str(paddr, pfrom);
+ if (!status)
+ return status;
+
+ if (!prset->get_enum_strs) {
+ recGblRecSupError(status, paddr, "dbPut(putStringEnum)", "get_enum_strs");
+ return status;
+ }
+
+ status = prset->get_enum_strs(paddr, &enumStrs);
+ if (!status) {
+ epicsEnum16 val;
+ char *end;
+
+ status = epicsParseUInt16(pfrom, &val, 10, &end);
+ if (!status && val < enumStrs.no_str) {
+ *pfield = val;
+ return 0;
}
- } else {
- status=S_db_noRSET;
+ status = S_db_badChoice;
}
- if (status == S_db_noRSET) {
- recGblRecSupError(status,paddr,"dbPutField","put_enum_str");
- } else {
- recGblRecordError(status,(void *) paddr->precord,pbuffer);
- }
- return(status);
+
+ recGblRecordError(status, paddr->precord, pfrom);
+ return status;
}
-
-static long putStringMenu(
- dbAddr *paddr,
+
+static long putStringMenu(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const char *pbuffer = (const char *) pfrom;
- dbFldDes *pdbFldDes = paddr->pfldDes;
- dbMenu *pdbMenu;
- char **papChoiceValue;
- char *pchoice;
- epicsEnum16 *pfield = (epicsEnum16*) paddr->pfield;
- unsigned int nChoice,ind;
- int nargs,nchars;
+ dbFldDes *pdbFldDes = paddr->pfldDes;
+ epicsEnum16 *pfield = paddr->pfield;
+ dbMenu *pdbMenu;
+ char **pchoices, *pchoice;
- if (no_elements!=1){
- recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringMenu)");
- return(S_db_onlyOne);
+ if (no_elements != 1) {
+ recGblDbaddrError(S_db_onlyOne, paddr, "dbPut(putStringMenu)");
+ return S_db_onlyOne;
}
- if (pdbFldDes
- && (pdbMenu = (dbMenu *)pdbFldDes->ftPvt)
- && (papChoiceValue = pdbMenu->papChoiceValue)) {
- nChoice = pdbMenu->nChoice;
- for(ind=0; indftPvt) &&
+ (pchoices = pdbMenu->papChoiceValue)) {
+ int i, nChoice = pdbMenu->nChoice;
+ epicsEnum16 val;
+
+ for (i = 0; i < nChoice; i++) {
+ pchoice = pchoices[i];
+ if (!pchoice)
+ continue;
+ if (strcmp(pchoice, pfrom) == 0) {
+ *pfield = i;
return 0;
}
}
- nargs = sscanf(pbuffer,"%u%n",&ind,&nchars);
- if (nargs==1 && nchars==strlen(pbuffer) && indpfldDes;
- dbDeviceMenu *pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt;
- char **papChoice;
- char *pchoice;
- epicsEnum16 *pfield = (epicsEnum16*) paddr->pfield;
- unsigned int nChoice,ind;
- int nargs,nchars;
+ dbFldDes *pdbFldDes = paddr->pfldDes;
+ dbDeviceMenu *pdbDeviceMenu = pdbFldDes->ftPvt;
+ epicsEnum16 *pfield = paddr->pfield;
+ char **pchoices, *pchoice;
- if (no_elements!=1){
- recGblDbaddrError(S_db_onlyOne,paddr,"dbPut(putStringDevice)");
- return(S_db_onlyOne);
+ if (no_elements != 1) {
+ recGblDbaddrError(S_db_onlyOne, paddr, "dbPut(putStringDevice)");
+ return S_db_onlyOne;
}
- if (pdbFldDes
- && (pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt)
- && (papChoice = pdbDeviceMenu->papChoice)) {
- nChoice = pdbDeviceMenu->nChoice;
- for(ind=0; indftPvt) &&
+ (pchoices = pdbDeviceMenu->papChoice)) {
+ int i, nChoice = pdbDeviceMenu->nChoice;
+ epicsEnum16 val;
+
+ for (i = 0; i < nChoice; i++) {
+ pchoice = pchoices[i];
+ if (!pchoice)
+ continue;
+ if (strcmp(pchoice, pfrom) == 0) {
+ *pfield = i;
return 0;
}
}
- nargs = sscanf(pbuffer,"%u%n",&ind,&nchars);
- if (nargs==1 && nchars==strlen(pbuffer) && indpfield;
+ const char *psrc = (const char *) pfrom;
+ char *pdst = (char *) paddr->pfield;
+ short size = paddr->field_size;
+
+ if (nRequest==1 && offset==0) {
+ cvtCharToString(*psrc, pdst);
+ return 0;
+ }
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtCharToString(*psrc, pdst);
+ psrc++;
+ if (++offset == no_elements)
+ pdst = paddr->pfield;
+ else
+ pdst += size;
+ }
+ return 0;
+}
+
+static long putCharChar PUT_NOCONVERT(char, char)
+static long putCharUchar PUT_NOCONVERT(char, epicsUInt8)
+static long putCharShort PUT(char, epicsInt16)
+static long putCharUshort PUT(char, epicsUInt16)
+static long putCharLong PUT(char, epicsInt32)
+static long putCharUlong PUT(char, epicsUInt32)
+static long putCharInt64 PUT(char, epicsInt64)
+static long putCharUInt64 PUT(char, epicsUInt64)
+static long putCharFloat PUT(char, epicsFloat32)
+static long putCharDouble PUT(char, epicsFloat64)
+static long putCharEnum PUT(char, epicsEnum16)
+
+static long putUcharString(dbAddr *paddr,
+ const void *pfrom, long nRequest, long no_elements, long offset)
+{
+ const epicsUInt8 *psrc = (const epicsUInt8 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
short size = paddr->field_size;
if (nRequest==1 && offset==0) {
- cvtCharToString(*pbuffer,pdest);
+ cvtUcharToString(*psrc, pdst);
return 0;
}
- pdest += (size*offset);
- while (nRequest) {
- cvtCharToString(*pbuffer,pdest);
- pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtUcharToString(*psrc, pdst);
+ psrc++;
if (++offset == no_elements)
- pdest = paddr->pfield;
+ pdst = paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
return 0;
}
-static long putCharChar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const char *pbuffer = (const char *) pfrom;
- char *pdest = (char *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(char), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
+static long putUcharChar PUT_NOCONVERT(epicsUInt8, char)
+static long putUcharUchar PUT_NOCONVERT(epicsUInt8, epicsUInt8)
+static long putUcharShort PUT(epicsUInt8, epicsInt16)
+static long putUcharUshort PUT(epicsUInt8, epicsUInt16)
+static long putUcharLong PUT(epicsUInt8, epicsInt32)
+static long putUcharUlong PUT(epicsUInt8, epicsUInt32)
+static long putUcharInt64 PUT(epicsUInt8, epicsInt64)
+static long putUcharUInt64 PUT(epicsUInt8, epicsUInt64)
+static long putUcharFloat PUT(epicsUInt8, epicsFloat32)
+static long putUcharDouble PUT(epicsUInt8, epicsFloat64)
+static long putUcharEnum PUT(epicsUInt8, epicsEnum16)
-static long putCharUchar(
- dbAddr *paddr,
+static long putShortString(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- if (nRequest==1 && offset==0) {
- const char *pbuffer = (const char *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt8), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putCharShort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const char *pbuffer = (const char *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putCharUshort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const char *pbuffer = (const char *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putCharLong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const char *pbuffer = (const char *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putCharUlong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const char *pbuffer = (const char *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putCharFloat(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const char *pbuffer = (const char *) pfrom;
- float *pdest = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putCharDouble(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const char *pbuffer = (const char *) pfrom;
- double *pdest = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putCharEnum(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const char *pbuffer = (const char *) pfrom;
- epicsEnum16 *pdest = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUcharString(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- char *pdest = (char *) paddr->pfield;
+ const epicsInt16 *psrc = (const epicsInt16 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
short size = paddr->field_size;
if (nRequest==1 && offset==0) {
- cvtUcharToString(*pbuffer,pdest);
+ cvtShortToString(*psrc, pdst);
return 0;
}
- pdest += (size*offset);
- while (nRequest) {
- cvtUcharToString(*pbuffer,pdest);
- pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtShortToString(*psrc, pdst);
+ psrc++;
if (++offset == no_elements)
- pdest = paddr->pfield;
+ pdst = (char *) paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
return 0;
}
-static long putUcharChar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- char *pdest = (char *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt8), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
+static long putShortChar PUT(epicsInt16, char)
+static long putShortUchar PUT(epicsInt16, epicsUInt8)
+static long putShortShort PUT_NOCONVERT(epicsInt16, epicsInt16)
+static long putShortUshort PUT_NOCONVERT(epicsInt16, epicsUInt16)
+static long putShortLong PUT(epicsInt16, epicsInt32)
+static long putShortUlong PUT(epicsInt16, epicsUInt32)
+static long putShortInt64 PUT(epicsInt16, epicsInt64)
+static long putShortUInt64 PUT(epicsInt16, epicsUInt64)
+static long putShortFloat PUT(epicsInt16, epicsFloat32)
+static long putShortDouble PUT(epicsInt16, epicsFloat64)
+static long putShortEnum PUT(epicsInt16, epicsEnum16)
-static long putUcharUchar(
- dbAddr *paddr,
+static long putUshortString(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- if (nRequest==1 && offset==0) {
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt8), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putUcharShort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUcharUshort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUcharLong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUcharUlong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUcharFloat(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- float *pdest = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUcharDouble(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- double *pdest = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUcharEnum(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt8 *pbuffer = (const epicsUInt8 *) pfrom;
- epicsEnum16 *pdest = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putShortString(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- char *pdest = (char *) paddr->pfield;
+ const epicsUInt16 *psrc = (const epicsUInt16 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
short size = paddr->field_size;
if (nRequest==1 && offset==0) {
- cvtShortToString(*pbuffer,pdest);
+ cvtUshortToString(*psrc, pdst);
return 0;
}
- pdest += (size*offset);
- while (nRequest) {
- cvtShortToString(*pbuffer,pdest);
- pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtUshortToString(*psrc, pdst);
+ psrc++;
if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
+ pdst = (char *) paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
return 0;
}
-static long putShortChar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- char *pdest = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (char) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (char) *pbuffer++;
- if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long putUshortChar PUT(epicsUInt16, char)
+static long putUshortUchar PUT(epicsUInt16, epicsUInt8)
+static long putUshortShort PUT_NOCONVERT(epicsUInt16, epicsInt16)
+static long putUshortUshort PUT_NOCONVERT(epicsUInt16, epicsUInt16)
+static long putUshortLong PUT(epicsUInt16, epicsInt32)
+static long putUshortUlong PUT(epicsUInt16, epicsUInt32)
+static long putUshortInt64 PUT(epicsUInt16, epicsInt64)
+static long putUshortUInt64 PUT(epicsUInt16, epicsUInt64)
+static long putUshortFloat PUT(epicsUInt16, epicsFloat32)
+static long putUshortDouble PUT(epicsUInt16, epicsFloat64)
+static long putUshortEnum PUT(epicsUInt16, epicsEnum16)
-static long putShortUchar(
- dbAddr *paddr,
+static long putLongString(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsUInt8) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsUInt8) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putShortShort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsInt16), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putShortUshort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsInt16), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putShortLong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putShortUlong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putShortFloat(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- float *pdest = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putShortDouble(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- double *pdest = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putShortEnum(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt16 *pbuffer = (const epicsInt16 *) pfrom;
- epicsEnum16 *pdest = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUshortString(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- char *pdest = (char *) paddr->pfield;
+ const epicsInt32 *psrc = (const epicsInt32 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
short size = paddr->field_size;
if (nRequest==1 && offset==0) {
- cvtUshortToString(*pbuffer,pdest);
+ cvtLongToString(*psrc, pdst);
return 0;
}
- pdest += (size*offset);
- while (nRequest) {
- cvtUshortToString(*pbuffer,pdest);
- pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtLongToString(*psrc, pdst);
+ psrc++;
if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
+ pdst = (char *) paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
return 0;
}
-static long putUshortChar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- char *pdest = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (char) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (char) *pbuffer++;
- if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long putLongChar PUT(epicsInt32, char)
+static long putLongUchar PUT(epicsInt32, epicsUInt8)
+static long putLongShort PUT(epicsInt32, epicsInt16)
+static long putLongUshort PUT(epicsInt32, epicsUInt16)
+static long putLongLong PUT_NOCONVERT(epicsInt32, epicsInt32)
+static long putLongUlong PUT_NOCONVERT(epicsInt32, epicsUInt32)
+static long putLongInt64 PUT(epicsInt32, epicsInt64)
+static long putLongUInt64 PUT(epicsInt32, epicsUInt64)
+static long putLongFloat PUT(epicsInt32, epicsFloat32)
+static long putLongDouble PUT(epicsInt32, epicsFloat64)
+static long putLongEnum PUT(epicsInt32, epicsEnum16)
-static long putUshortUchar(
- dbAddr *paddr,
+static long putUlongString(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsUInt8) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsUInt8) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUshortShort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt16), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putUshortUshort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt16), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putUshortLong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUshortUlong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUshortFloat(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- float *pdest = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUshortDouble(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- double *pdest = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUshortEnum(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt16 *pbuffer = (const epicsUInt16 *) pfrom;
- epicsEnum16 *pdest = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putLongString(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- char *pdest = (char *) paddr->pfield;
+ const epicsUInt32 *psrc = (const epicsUInt32 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
short size = paddr->field_size;
if (nRequest==1 && offset==0) {
- cvtLongToString(*pbuffer,pdest);
+ cvtUlongToString(*psrc, pdst);
return 0;
}
- pdest += (size*offset);
- while (nRequest) {
- cvtLongToString(*pbuffer,pdest);
- pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtUlongToString(*psrc, pdst);
+ psrc++;
if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
+ pdst = (char *) paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
return 0;
}
-static long putLongChar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- char *pdest = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long putUlongChar PUT(epicsUInt32, char)
+static long putUlongUchar PUT(epicsUInt32, epicsUInt8)
+static long putUlongShort PUT(epicsUInt32, epicsInt16)
+static long putUlongUshort PUT(epicsUInt32, epicsUInt16)
+static long putUlongLong PUT_NOCONVERT(epicsUInt32, epicsInt32)
+static long putUlongUlong PUT_NOCONVERT(epicsUInt32, epicsUInt32)
+static long putUlongInt64 PUT(epicsUInt32, epicsInt64)
+static long putUlongUInt64 PUT(epicsUInt32, epicsUInt64)
+static long putUlongFloat PUT(epicsUInt32, epicsFloat32)
+static long putUlongDouble PUT(epicsUInt32, epicsFloat64)
+static long putUlongEnum PUT(epicsUInt32, epicsEnum16)
-static long putLongUchar(
- dbAddr *paddr,
+static long putInt64String(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
+ const epicsInt64 *psrc = (const epicsInt64 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
+ short size=paddr->field_size;
+
if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
+ cvtInt64ToString(*psrc, pdst);
return 0;
}
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtInt64ToString(*psrc, pdst);
+ psrc++;
if (++offset == no_elements)
- pdest = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putLongShort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putLongUshort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putLongLong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsInt32), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putLongUlong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsInt32), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putLongFloat(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- float *pdest = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (float) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (float) *pbuffer++;
- if (++offset == no_elements)
- pdest = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putLongDouble(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- double *pdest = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putLongEnum(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsInt32 *pbuffer = (const epicsInt32 *) pfrom;
- epicsEnum16 *pdest = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUlongString(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- char *pdest = (char *) paddr->pfield;
- short size = paddr->field_size;
-
-
- if (nRequest==1 && offset==0) {
- cvtUlongToString(*pbuffer,pdest);
- return 0;
- }
- pdest += (size*offset);
- while (nRequest) {
- cvtUlongToString(*pbuffer,pdest);
- pbuffer++;
- if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
+ pdst = (char *) paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
return 0;
}
-static long putUlongChar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- char *pdest = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long putInt64Char PUT(epicsInt64, char)
+static long putInt64Uchar PUT(epicsInt64, epicsUInt8)
+static long putInt64Short PUT(epicsInt64, epicsInt16)
+static long putInt64Ushort PUT(epicsInt64, epicsUInt16)
+static long putInt64Long PUT(epicsInt64, epicsInt32)
+static long putInt64Ulong PUT(epicsInt64, epicsUInt32)
+static long putInt64Int64 PUT_NOCONVERT(epicsInt64, epicsInt64)
+static long putInt64UInt64 PUT_NOCONVERT(epicsInt64, epicsUInt64)
+static long putInt64Float PUT(epicsInt64, epicsFloat32)
+static long putInt64Double PUT(epicsInt64, epicsFloat64)
+static long putInt64Enum PUT(epicsInt64, epicsEnum16)
-static long putUlongUchar(
- dbAddr *paddr,
+static long putUInt64String(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
+ const epicsUInt64 *psrc = (const epicsUInt64 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
+ short size=paddr->field_size;
+
if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
+ cvtUlongToString(*psrc, pdst);
return 0;
}
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtUlongToString(*psrc, pdst);
+ psrc++;
if (++offset == no_elements)
- pdest = (epicsUInt8 *) paddr->pfield;
- nRequest--;
+ pdst = (char *) paddr->pfield;
+ else
+ pdst += size;
}
return 0;
}
-static long putUlongShort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long putUInt64Char PUT(epicsUInt64, char)
+static long putUInt64Uchar PUT(epicsUInt64, epicsUInt8)
+static long putUInt64Short PUT(epicsUInt64, epicsInt16)
+static long putUInt64Ushort PUT(epicsUInt64, epicsUInt16)
+static long putUInt64Long PUT(epicsUInt64, epicsInt32)
+static long putUInt64Ulong PUT(epicsUInt64, epicsUInt32)
+static long putUInt64Int64 PUT_NOCONVERT(epicsUInt64, epicsInt64)
+static long putUInt64UInt64 PUT_NOCONVERT(epicsUInt64, epicsUInt64)
+static long putUInt64Float PUT(epicsUInt64, epicsFloat32)
+static long putUInt64Double PUT(epicsUInt64, epicsFloat64)
+static long putUInt64Enum PUT(epicsUInt64, epicsEnum16)
-static long putUlongUshort(
- dbAddr *paddr,
+static long putFloatString(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUlongLong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt32), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putUlongUlong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsUInt32), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putUlongFloat(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- float *pdest = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (float) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (float) *pbuffer++;
- if (++offset == no_elements)
- pdest = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUlongDouble(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- double *pdest = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putUlongEnum(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsUInt32 *pbuffer = (const epicsUInt32 *) pfrom;
- epicsEnum16 *pdest = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putFloatString(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const float *pbuffer = (const float *) pfrom;
- char *pdest = (char *) paddr->pfield;
+ const epicsFloat32 *psrc = (const epicsFloat32 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
long status = 0;
long precision = 6;
- rset *prset = dbGetRset(paddr);
+ rset *prset = 0;
short size = paddr->field_size;
- if (prset && (prset->get_precision))
- status = (*prset->get_precision)(paddr,&precision);
+ if (paddr)
+ prset = dbGetRset(paddr);
+ if (prset && prset->get_precision)
+ status = prset->get_precision(paddr, &precision);
if (nRequest==1 && offset==0) {
- cvtFloatToString(*pbuffer,pdest,precision);
+ cvtFloatToString(*psrc, pdst, precision);
return(status);
}
- pdest += (size*offset);
- while (nRequest) {
- cvtFloatToString(*pbuffer,pdest,precision);
- pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtFloatToString(*psrc, pdst, precision);
+ psrc++;
if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
+ pdst = (char *) paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
return(status);
}
-static long putFloatChar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const float *pbuffer = (const float *) pfrom;
- char *pdest = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (char) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (char) *pbuffer++;
- if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
+static long putFloatChar PUT(epicsFloat32, char)
+static long putFloatUchar PUT(epicsFloat32, epicsUInt8)
+static long putFloatShort PUT(epicsFloat32, epicsInt16)
+static long putFloatUshort PUT(epicsFloat32, epicsUInt16)
+static long putFloatLong PUT(epicsFloat32, epicsInt32)
+static long putFloatUlong PUT(epicsFloat32, epicsUInt32)
+static long putFloatInt64 PUT(epicsFloat32, epicsInt64)
+static long putFloatUInt64 PUT(epicsFloat32, epicsUInt64)
+static long putFloatFloat PUT_NOCONVERT(epicsFloat32, epicsFloat32)
+static long putFloatDouble PUT(epicsFloat32, epicsFloat64)
+static long putFloatEnum PUT(epicsFloat32, epicsEnum16)
-static long putFloatUchar(
- dbAddr *paddr,
+static long putDoubleString(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const float *pbuffer = (const float *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsUInt8) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsUInt8) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putFloatShort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const float *pbuffer = (const float *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsInt16) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsInt16) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putFloatUshort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const float *pbuffer = (const float *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsUInt16) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsUInt16) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putFloatLong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const float *pbuffer = (const float *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsInt32) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsInt32) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putFloatUlong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const float *pbuffer = (const float *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsUInt32) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsUInt32) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putFloatFloat(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const float *pbuffer = (const float *) pfrom;
- float *pdest = (float *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(float), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putFloatDouble(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const float *pbuffer = (const float *) pfrom;
- double *pdest = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putFloatEnum(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const float *pbuffer = (const float *) pfrom;
- epicsEnum16 *pdest = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsEnum16) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsEnum16) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putDoubleString(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const double *pbuffer = (const double *) pfrom;
- char *pdest = (char *) paddr->pfield;
+ const epicsFloat64 *psrc = (const epicsFloat64 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
long status = 0;
long precision = 6;
- rset *prset = dbGetRset(paddr);
+ rset *prset = 0;
short size = paddr->field_size;
- if (prset && (prset->get_precision))
- status = (*prset->get_precision)(paddr,&precision);
+ if (paddr)
+ prset = dbGetRset(paddr);
+ if (prset && prset->get_precision)
+ status = prset->get_precision(paddr, &precision);
if (nRequest==1 && offset==0) {
- cvtDoubleToString(*pbuffer,pdest,precision);
- return(status);
+ cvtDoubleToString(*psrc, pdst, precision);
+ return status;
}
- pdest += (size*offset);
- while (nRequest) {
- cvtDoubleToString(*pbuffer,pdest,precision);
- pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtDoubleToString(*psrc, pdst, precision);
+ psrc++;
if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
+ pdst = (char *) paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
- return(status);
+ return status;
}
-static long putDoubleChar(
- dbAddr *paddr,
+static long putDoubleChar PUT(epicsFloat64, char)
+static long putDoubleUchar PUT(epicsFloat64, epicsUInt8)
+static long putDoubleShort PUT(epicsFloat64, epicsInt16)
+static long putDoubleUshort PUT(epicsFloat64, epicsUInt16)
+static long putDoubleLong PUT(epicsFloat64, epicsInt32)
+static long putDoubleUlong PUT(epicsFloat64, epicsUInt32)
+static long putDoubleInt64 PUT(epicsFloat64, epicsInt64)
+static long putDoubleUInt64 PUT(epicsFloat64, epicsUInt64)
+
+static long putDoubleFloat(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const double *pbuffer = (const double *) pfrom;
- char *pdest = (char *) paddr->pfield;
+ const epicsFloat64 *psrc = (const epicsFloat64 *) pfrom;
+ epicsFloat32 *pdst = (epicsFloat32 *) paddr->pfield;
if (nRequest==1 && offset==0) {
- *pdest = (char) *pbuffer;
+ *pdst = epicsConvertDoubleToFloat(*psrc);
return 0;
}
- pdest += offset;
- while (nRequest) {
- *pdest++ = (char) *pbuffer++;
+ pdst += offset;
+ while (nRequest--) {
+ *pdst++ = epicsConvertDoubleToFloat(*psrc++);
if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
- nRequest--;
+ pdst = (epicsFloat32 *) paddr->pfield;
}
return 0;
}
+
+static long putDoubleDouble PUT_NOCONVERT(epicsFloat64, epicsFloat64)
+static long putDoubleEnum PUT(epicsFloat64, epicsEnum16)
-static long putDoubleUchar(
- dbAddr *paddr,
+static long putEnumString(dbAddr *paddr,
const void *pfrom, long nRequest, long no_elements, long offset)
{
- const double *pbuffer = (const double *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsUInt8) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsUInt8) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putDoubleShort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const double *pbuffer = (const double *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsInt16) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsInt16) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putDoubleUshort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const double *pbuffer = (const double *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsUInt16) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsUInt16) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putDoubleLong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const double *pbuffer = (const double *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsInt32) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsInt32) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putDoubleUlong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const double *pbuffer = (const double *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsUInt32) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsUInt32) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putDoubleFloat(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const double *pbuffer = (const double *) pfrom;
- float *pdest = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = epicsConvertDoubleToFloat(*pbuffer);
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest = epicsConvertDoubleToFloat(*pbuffer);
- ++pbuffer; ++pdest;
- if (++offset == no_elements)
- pdest = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putDoubleDouble(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const double *pbuffer = (const double *) pfrom;
- double *pdest = (double *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(double), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
-
-static long putDoubleEnum(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const double *pbuffer = (const double *) pfrom;
- epicsEnum16 *pdest = (epicsEnum16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsEnum16) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsEnum16) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsEnum16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putEnumString(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- char *pdest = (char *) paddr->pfield;
+ const epicsEnum16 *psrc = (const epicsEnum16 *) pfrom;
+ char *pdst = (char *) paddr->pfield;
short size = paddr->field_size;
if (nRequest==1 && offset==0) {
- cvtUshortToString(*pbuffer,pdest);
+ cvtUshortToString(*psrc, pdst);
return 0;
}
- pdest += (size*offset);
- while (nRequest) {
- cvtUshortToString(*pbuffer,pdest);
- pbuffer++;
+ pdst += (size*offset);
+ while (nRequest--) {
+ cvtUshortToString(*psrc, pdst);
+ psrc++;
if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
+ pdst = (char *) paddr->pfield;
else
- pdest += size;
- nRequest--;
+ pdst += size;
}
return 0;
}
-static long putEnumChar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- char *pdest = (char *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (char) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (char) *pbuffer++;
- if (++offset == no_elements)
- pdest = (char *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putEnumUchar(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- epicsUInt8 *pdest = (epicsUInt8 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = (epicsUInt8) *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = (epicsUInt8) *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt8 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putEnumShort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- epicsInt16 *pdest = (epicsInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putEnumUshort(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- epicsUInt16 *pdest = (epicsUInt16 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt16 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putEnumLong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- epicsInt32 *pdest = (epicsInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putEnumUlong(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- epicsUInt32 *pdest = (epicsUInt32 *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (epicsUInt32 *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putEnumFloat(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- float *pdest = (float *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (float *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putEnumDouble(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- double *pdest = (double *) paddr->pfield;
-
- if (nRequest==1 && offset==0) {
- *pdest = *pbuffer;
- return 0;
- }
- pdest += offset;
- while (nRequest) {
- *pdest++ = *pbuffer++;
- if (++offset == no_elements)
- pdest = (double *) paddr->pfield;
- nRequest--;
- }
- return 0;
-}
-
-static long putEnumEnum(
- dbAddr *paddr,
- const void *pfrom, long nRequest, long no_elements, long offset)
-{
- if (nRequest==1 && offset==0) {
- const epicsEnum16 *pbuffer = (const epicsEnum16 *) pfrom;
- epicsEnum16 *pdest = (epicsEnum16 *) paddr->pfield;
-
- *pdest = *pbuffer;
- return 0;
- }
- COPYNOCONVERT(sizeof(epicsEnum16), pfrom, paddr->pfield, nRequest, no_elements, offset);
- return 0;
-}
+static long putEnumChar PUT(epicsEnum16, char)
+static long putEnumUchar PUT(epicsEnum16, epicsUInt8)
+static long putEnumShort PUT(epicsEnum16, epicsInt16)
+static long putEnumUshort PUT(epicsEnum16, epicsUInt16)
+static long putEnumLong PUT(epicsEnum16, epicsInt32)
+static long putEnumUlong PUT(epicsEnum16, epicsUInt32)
+static long putEnumInt64 PUT(epicsEnum16, epicsInt64)
+static long putEnumUInt64 PUT(epicsEnum16, epicsUInt64)
+static long putEnumFloat PUT(epicsEnum16, epicsFloat32)
+static long putEnumDouble PUT(epicsEnum16, epicsFloat64)
+static long putEnumEnum PUT_NOCONVERT(epicsEnum16, epicsEnum16)
/* This is the table of routines for converting database fields */
/* the rows represent the field type of the database field */
@@ -4574,47 +1700,68 @@ static long putEnumEnum(
/* buffer types are********************************************************
DBR_STRING, DBR_CHR, DBR_UCHAR, DBR_SHORT, DBR_USHORT,
- DBR_LONG, DBR_ULONG, DBR_FLOAT, DBR_DOUBLE, DBR_ENUM
+ DBR_LONG, DBR_ULONG, DBR_INT64, DBR_UINT64,
+ DBR_FLOAT, DBR_DOUBLE, DBR_ENUM
***************************************************************************/
epicsShareDef GETCONVERTFUNC dbGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1] = {
/* source is a DBF_STRING */
{getStringString, getStringChar, getStringUchar, getStringShort, getStringUshort,
- getStringLong, getStringUlong, getStringFloat, getStringDouble, getStringEnum},
+ getStringLong, getStringUlong, getStringInt64, getStringUInt64,
+ getStringFloat, getStringDouble, getStringUshort},
/* source is a DBF_CHAR */
{getCharString, getCharChar, getCharUchar, getCharShort, getCharUshort,
- getCharLong, getCharUlong, getCharFloat, getCharDouble, getCharEnum},
+ getCharLong, getCharUlong, getCharInt64, getCharUInt64,
+ getCharFloat, getCharDouble, getCharEnum},
/* source is a DBF_UCHAR */
{getUcharString, getUcharChar, getUcharUchar, getUcharShort, getUcharUshort,
- getUcharLong, getUcharUlong, getUcharFloat, getUcharDouble, getUcharEnum},
+ getUcharLong, getUcharUlong, getUcharInt64, getUcharUInt64,
+ getUcharFloat, getUcharDouble, getUcharEnum},
/* source is a DBF_SHORT */
{getShortString, getShortChar, getShortUchar, getShortShort, getShortUshort,
- getShortLong, getShortUlong, getShortFloat, getShortDouble, getShortEnum},
+ getShortLong, getShortUlong, getShortInt64, getShortUInt64,
+ getShortFloat, getShortDouble, getShortEnum},
/* source is a DBF_USHORT */
{getUshortString, getUshortChar, getUshortUchar, getUshortShort, getUshortUshort,
- getUshortLong, getUshortUlong, getUshortFloat, getUshortDouble, getUshortEnum},
-/* source is a DBF_LONG */
+ getUshortLong, getUshortUlong, getUshortInt64, getUshortUInt64,
+ getUshortFloat, getUshortDouble, getUshortEnum},
+/* source is a DBF_LONG */
{getLongString, getLongChar, getLongUchar, getLongShort, getLongUshort,
- getLongLong, getLongUlong, getLongFloat, getLongDouble, getLongEnum},
+ getLongLong, getLongUlong, getLongInt64, getLongUInt64,
+ getLongFloat, getLongDouble, getLongEnum},
/* source is a DBF_ULONG */
{getUlongString, getUlongChar, getUlongUchar, getUlongShort, getUlongUshort,
- getUlongLong, getUlongUlong, getUlongFloat, getUlongDouble, getUlongEnum},
+ getUlongLong, getUlongUlong, getUlongInt64, getUlongUInt64,
+ getUlongFloat, getUlongDouble, getUlongEnum},
+/* source is a DBF_INT64 */
+{getInt64String, getInt64Char, getInt64Uchar, getInt64Short, getInt64Ushort,
+ getInt64Long, getInt64Ulong, getInt64Int64, getInt64UInt64,
+ getInt64Float, getInt64Double, getInt64Enum},
+/* source is a DBF_UINT64 */
+{getUInt64String, getUInt64Char, getUInt64Uchar, getUInt64Short, getUInt64Ushort,
+ getUInt64Long, getUInt64Ulong, getUInt64Int64, getUInt64UInt64,
+ getUInt64Float, getUInt64Double, getUInt64Enum},
/* source is a DBF_FLOAT */
{getFloatString, getFloatChar, getFloatUchar, getFloatShort, getFloatUshort,
- getFloatLong, getFloatUlong, getFloatFloat, getFloatDouble, getFloatEnum},
+ getFloatLong, getFloatUlong, getFloatInt64, getFloatUInt64,
+ getFloatFloat, getFloatDouble, getFloatEnum},
/* source is a DBF_DOUBLE */
{getDoubleString, getDoubleChar, getDoubleUchar, getDoubleShort, getDoubleUshort,
- getDoubleLong, getDoubleUlong, getDoubleFloat, getDoubleDouble, getDoubleEnum},
-/* source is a DBF_ENUM */
+ getDoubleLong, getDoubleUlong, getDoubleInt64, getDoubleUInt64,
+ getDoubleFloat, getDoubleDouble, getDoubleEnum},
+/* source is a DBF_ENUM */
{getEnumString, getEnumChar, getEnumUchar, getEnumShort, getEnumUshort,
- getEnumLong, getEnumUlong, getEnumFloat, getEnumDouble, getEnumEnum},
-/* source is a DBF_MENU */
+ getEnumLong, getEnumUlong, getEnumInt64, getEnumUInt64,
+ getEnumFloat, getEnumDouble, getEnumEnum},
+/* source is a DBF_MENU */
{getMenuString, getEnumChar, getEnumUchar, getEnumShort, getEnumUshort,
- getEnumLong, getEnumUlong, getEnumFloat, getEnumDouble, getEnumEnum},
-/* source is a DBF_DEVICE */
-{getDeviceString,getEnumChar, getEnumUchar, getEnumShort, getEnumUshort,
- getEnumLong, getEnumUlong, getEnumFloat, getEnumDouble, getEnumEnum},
+ getEnumLong, getEnumUlong, getEnumInt64, getEnumUInt64,
+ getEnumFloat, getEnumDouble, getEnumEnum},
+/* source is a DBF_DEVICE */
+{getDeviceString, getEnumChar, getEnumUchar, getEnumShort, getEnumUshort,
+ getEnumLong, getEnumUlong, getEnumInt64, getEnumUInt64,
+ getEnumFloat, getEnumDouble, getEnumEnum},
};
/* This is the table of routines for converting database fields */
@@ -4623,49 +1770,70 @@ epicsShareDef GETCONVERTFUNC dbGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1] = {
/* field types are********************************************************
DBF_STRING, DBF_CHAR, DBF_UCHAR, DBF_SHORT, DBF_USHORT,
- DBF_LONG, DBF_ULONG, DBF_FLOAT, DBF_DOUBLE, DBF_ENUM
+ DBF_LONG, DBF_ULONG, DBF_INT64, DBF_UINT64,
+ DBF_FLOAT, DBF_DOUBLE, DBF_ENUM
DBF_MENU, DBF_DEVICE
***************************************************************************/
epicsShareDef PUTCONVERTFUNC dbPutConvertRoutine[DBR_ENUM+1][DBF_DEVICE+1] = {
/* source is a DBR_STRING */
{putStringString, putStringChar, putStringUchar, putStringShort, putStringUshort,
- putStringLong, putStringUlong, putStringFloat, putStringDouble, putStringEnum,
- putStringMenu,putStringDevice},
-/* source is a DBR_CHAR */
+ putStringLong, putStringUlong, putStringInt64, putStringUInt64,
+ putStringFloat, putStringDouble, putStringEnum,
+ putStringMenu, putStringDevice},
+/* source is a DBR_CHAR */
{putCharString, putCharChar, putCharUchar, putCharShort, putCharUshort,
- putCharLong, putCharUlong, putCharFloat, putCharDouble, putCharEnum,
+ putCharLong, putCharUlong, putCharInt64, putCharUInt64,
+ putCharFloat, putCharDouble, putCharEnum,
putCharEnum, putCharEnum},
/* source is a DBR_UCHAR */
{putUcharString, putUcharChar, putUcharUchar, putUcharShort, putUcharUshort,
- putUcharLong, putUcharUlong, putUcharFloat, putUcharDouble, putUcharEnum,
+ putUcharLong, putUcharUlong, putUcharInt64, putUcharUInt64,
+ putUcharFloat, putUcharDouble, putUcharEnum,
putUcharEnum, putUcharEnum},
/* source is a DBR_SHORT */
{putShortString, putShortChar, putShortUchar, putShortShort, putShortUshort,
- putShortLong, putShortUlong, putShortFloat, putShortDouble, putShortEnum,
+ putShortLong, putShortUlong, putShortInt64, putShortUInt64,
+ putShortFloat, putShortDouble, putShortEnum,
putShortEnum, putShortEnum},
/* source is a DBR_USHORT */
{putUshortString, putUshortChar, putUshortUchar, putUshortShort, putUshortUshort,
- putUshortLong, putUshortUlong, putUshortFloat, putUshortDouble, putUshortEnum,
+ putUshortLong, putUshortUlong, putUshortInt64, putUshortUInt64,
+ putUshortFloat, putUshortDouble, putUshortEnum,
putUshortEnum, putUshortEnum},
-/* source is a DBR_LONG */
+/* source is a DBR_LONG */
{putLongString, putLongChar, putLongUchar, putLongShort, putLongUshort,
- putLongLong, putLongUlong, putLongFloat, putLongDouble, putLongEnum,
+ putLongLong, putLongUlong, putLongInt64, putLongUInt64,
+ putLongFloat, putLongDouble, putLongEnum,
putLongEnum, putLongEnum},
/* source is a DBR_ULONG */
{putUlongString, putUlongChar, putUlongUchar, putUlongShort, putUlongUshort,
- putUlongLong, putUlongUlong, putUlongFloat, putUlongDouble, putUlongEnum,
+ putUlongLong, putUlongUlong, putUlongInt64, putUlongUInt64,
+ putUlongFloat, putUlongDouble, putUlongEnum,
putUlongEnum, putUlongEnum},
+/* source is a DBR_INT64 */
+{putInt64String, putInt64Char, putInt64Uchar, putInt64Short, putInt64Ushort,
+ putInt64Long, putInt64Ulong, putInt64Int64, putInt64UInt64,
+ putInt64Float, putInt64Double, putInt64Enum,
+ putInt64Enum, putInt64Enum},
+/* source is a DBR_UINT64 */
+{putUInt64String, putUInt64Char, putUInt64Uchar, putUInt64Short, putUInt64Ushort,
+ putUInt64Long, putUInt64Ulong, putUInt64Int64, putUInt64UInt64,
+ putUInt64Float, putUInt64Double, putUInt64Enum,
+ putUInt64Enum, putUInt64Enum},
/* source is a DBR_FLOAT */
{putFloatString, putFloatChar, putFloatUchar, putFloatShort, putFloatUshort,
- putFloatLong, putFloatUlong, putFloatFloat, putFloatDouble, putFloatEnum,
+ putFloatLong, putFloatUlong, putFloatInt64, putFloatUInt64,
+ putFloatFloat, putFloatDouble, putFloatEnum,
putFloatEnum, putFloatEnum},
/* source is a DBR_DOUBLE */
{putDoubleString, putDoubleChar, putDoubleUchar, putDoubleShort, putDoubleUshort,
- putDoubleLong, putDoubleUlong, putDoubleFloat, putDoubleDouble, putDoubleEnum,
+ putDoubleLong, putDoubleUlong, putDoubleInt64, putDoubleUInt64,
+ putDoubleFloat, putDoubleDouble, putDoubleEnum,
putDoubleEnum, putDoubleEnum},
-/* source is a DBR_ENUM */
+/* source is a DBR_ENUM */
{putEnumString, putEnumChar, putEnumUchar, putEnumShort, putEnumUshort,
- putEnumLong, putEnumUlong, putEnumFloat, putEnumDouble, putEnumEnum,
+ putEnumLong, putEnumUlong, putEnumInt64, putEnumUInt64,
+ putEnumFloat, putEnumDouble, putEnumEnum,
putEnumEnum, putEnumEnum}
};
diff --git a/src/ioc/db/dbFastLinkConv.c b/src/ioc/db/dbFastLinkConv.c
index 637e2122c..00a37f710 100644
--- a/src/ioc/db/dbFastLinkConv.c
+++ b/src/ioc/db/dbFastLinkConv.c
@@ -1,17 +1,17 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* dbFastLinkConv.c */
/*
* Author: Matthew Needes
* Date: 12-9-93
*/
+
#include
#include
#include
@@ -55,6 +55,8 @@
* us - epicsUInt16
* l - epicsInt32
* ul - epicsUInt32
+ * q - epicsInt64
+ * uq - epicsUInt64
* f - epicsFloat32
* d - epicsFloat64
* e - enum
@@ -74,16 +76,16 @@ static long cvt_st_st(
char *to,
const dbAddr *paddr)
{
- size_t size;
+ size_t size;
- if (paddr && paddr->field_size < MAX_STRING_SIZE) {
- size = paddr->field_size - 1;
- } else {
- size = MAX_STRING_SIZE - 1;
- }
- strncpy(to, from, size);
- to[size] = 0;
- return 0;
+ if (paddr && paddr->field_size < MAX_STRING_SIZE) {
+ size = paddr->field_size - 1;
+ } else {
+ size = MAX_STRING_SIZE - 1;
+ }
+ strncpy(to, from, size);
+ to[size] = 0;
+ return 0;
}
/* Convert String to Char */
@@ -92,268 +94,272 @@ static long cvt_st_c(
epicsInt8 *to,
const dbAddr *paddr)
{
- char *end;
- long value;
+ char *end;
- if (*from == 0) {
- *to = 0;
- return 0;
- }
- value = strtol(from, &end, 10);
- if (end > from) {
- *to = (epicsInt8) value;
- return 0;
- }
- return -1;
+ if (*from == 0) {
+ *to = 0;
+ return 0;
+ }
+ return epicsParseInt8(from, to, 10, &end);
}
/* Convert String to Unsigned Char */
static long cvt_st_uc(
- char *from,
- epicsUInt8 *to,
- const dbAddr *paddr)
+ char *from,
+ epicsUInt8 *to,
+ const dbAddr *paddr)
{
- char *end;
- unsigned long value;
+ char *end;
- if (*from == 0) {
- *to = 0;
- return 0;
- }
- value = strtoul(from, &end, 10);
- if (end > from) {
- *to = (epicsUInt8) value;
- return 0;
- }
- return -1;
+ if (*from == 0) {
+ *to = 0;
+ return 0;
+ }
+ return epicsParseUInt8(from, to, 10, &end);
}
/* Convert String to Short */
static long cvt_st_s(
- char *from,
- epicsInt16 *to,
- const dbAddr *paddr)
+ char *from,
+ epicsInt16 *to,
+ const dbAddr *paddr)
{
- char *end;
- long value;
+ char *end;
- if (*from == 0) {
- *to = 0;
- return 0;
- }
- value = strtol(from, &end, 10);
- if (end > from) {
- *to = (epicsInt16) value;
- return 0;
- }
- return -1;
+ if (*from == 0) {
+ *to = 0;
+ return 0;
+ }
+ return epicsParseInt16(from, to, 10, &end);
}
/* Convert String to Unsigned Short */
static long cvt_st_us(
- char *from,
- epicsUInt16 *to,
- const dbAddr *paddr)
+ char *from,
+ epicsUInt16 *to,
+ const dbAddr *paddr)
{
- char *end;
- unsigned long value;
+ char *end;
- if (*from == 0) {
- *to = 0;
- return 0;
- }
- value = strtoul(from, &end, 10);
- if (end > from) {
- *to = (epicsUInt16) value;
- return 0;
- }
- return -1;
+ if (*from == 0) {
+ *to = 0;
+ return 0;
+ }
+ return epicsParseUInt16(from, to, 10, &end);
}
/* Convert String to Long */
static long cvt_st_l(
- char *from,
- epicsInt32 *to,
- const dbAddr *paddr)
- {
- char *end;
- long value;
+ char *from,
+ epicsInt32 *to,
+ const dbAddr *paddr)
+{
+ char *end;
- if (*from == 0) {
- *to = 0;
- return 0;
- }
- value = strtol(from, &end, 10);
- if (end > from) {
- *to = (epicsInt32) value;
- return 0;
- }
- return -1;
- }
+ if (*from == 0) {
+ *to = 0;
+ return 0;
+ }
+ return epicsParseInt32(from, to, 10, &end);
+}
/* Convert String to Unsigned Long */
static long cvt_st_ul(
char *from,
epicsUInt32 *to,
const dbAddr *paddr)
- {
- double value;
+{
+ char *end;
+ long status;
- if (*from == 0) {
- *to = 0;
- return 0;
- }
- /*Convert via double so that numbers like 1.0e3 convert properly*/
- /*Problem was old database access said to get unsigned long as double*/
- if (epicsScanDouble(from, &value) == 1) {
- *to = (epicsUInt32)value;
- return 0;
- }
- return -1;
- }
+ if (*from == 0) {
+ *to = 0;
+ return 0;
+ }
+ status = epicsParseUInt32(from, to, 10, &end);
+ if (status == S_stdlib_noConversion ||
+ (!status && (*end == '.' || *end == 'e' || *end == 'E'))) {
+ /*
+ * Convert via double so numbers like 1.0e3 convert properly.
+ * db_access pretends unsigned long is double.
+ */
+ double dval;
+
+ status = epicsParseFloat64(from, &dval, &end);
+ if (!status &&
+ dval >=0 &&
+ dval <= ULONG_MAX)
+ *to = dval;
+ }
+ return status;
+}
+
+/* Convert String to Int64 */
+static long cvt_st_q(
+ char *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+{
+ char *end;
+
+ if (*from == 0) {
+ *to = 0;
+ return 0;
+ }
+ return epicsParseInt64(from, to, 10, &end);
+}
+
+/* Convert String to UInt64 */
+static long cvt_st_uq(
+ char *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+{
+ char *end;
+
+ if (*from == 0) {
+ *to = 0;
+ return 0;
+ }
+ return epicsParseUInt64(from, to, 0, &end);
+}
/* Convert String to Float */
static long cvt_st_f(
char *from,
epicsFloat32 *to,
const dbAddr *paddr)
- {
- float value;
+{
+ char *end;
if (*from == 0) {
*to = 0;
return 0;
}
- if (epicsScanFloat(from, &value) == 1) {
- *to = value;
- return 0;
- }
- return -1;
- }
+ return epicsParseFloat32(from, to, &end);
+}
/* Convert String to Double */
static long cvt_st_d(
char *from,
epicsFloat64 *to,
const dbAddr *paddr)
- {
- double value;
+{
+ char *end;
if (*from == 0) {
*to = 0.0;
return 0;
}
- if (epicsScanDouble(from, &value) == 1) {
- *to = value;
- return 0;
- }
- return -1;
- }
+ return epicsParseFloat64(from, to, &end);
+}
/* Convert String to Enumerated */
static long cvt_st_e(
- char *from,
- epicsEnum16 *to,
- const dbAddr *paddr)
- {
- rset *prset = 0;
- long status;
- epicsEnum16 *pfield= (epicsEnum16*)(paddr->pfield);
- unsigned int nchoices,ind;
- int nargs,nchars;
- struct dbr_enumStrs enumStrs;
+ char *from,
+ epicsEnum16 *to,
+ const dbAddr *paddr)
+{
+ rset *prset = dbGetRset(paddr);
+ long status = S_db_noRSET;
+ struct dbr_enumStrs enumStrs;
- if(paddr && (prset=dbGetRset(paddr))
- && (prset->put_enum_str)) {
- status = (*prset->put_enum_str)(paddr,from);
- if(!status) return(0);
- if(prset->get_enum_strs) {
- status = (*prset->get_enum_strs)(paddr,&enumStrs);
- if(!status) {
- nchoices = enumStrs.no_str;
- nargs = sscanf(from,"%u%n",&ind,&nchars);
- if(nargs==1 && nchars==strlen(from) && indput_enum_str) {
+ recGblRecSupError(status, paddr, "dbPutField", "put_enum_str");
+ return status;
}
- if(status == S_db_noRSET) {
- recGblRecSupError(status,paddr,"dbPutField","put_enum_str");
- } else {
- recGblRecordError(status,(void *)paddr->precord,from);
+
+ status = prset->put_enum_str(paddr, from);
+ if (!status) return 0;
+
+ if (!prset->get_enum_strs) {
+ recGblRecSupError(status, paddr, "dbPutField", "get_enum_strs");
+ return status;
}
- return(status);
- }
+
+ status = prset->get_enum_strs(paddr, &enumStrs);
+ if (!status) {
+ epicsEnum16 val;
+
+ status = epicsParseUInt16(from, &val, 10, NULL);
+ if (!status && val < enumStrs.no_str) {
+ *to = val;
+ return 0;
+ }
+ status = S_db_badChoice;
+ }
+
+ recGblRecordError(status, paddr->precord, from);
+ return status;
+}
/* Convert String to Menu */
static long cvt_st_menu(
- char *from,
- epicsEnum16 *to,
- const dbAddr *paddr)
+ char *from,
+ epicsEnum16 *to,
+ const dbAddr *paddr)
{
- dbFldDes *pdbFldDes = paddr->pfldDes;
- dbMenu *pdbMenu = (dbMenu *)pdbFldDes->ftPvt;
- char **papChoiceValue;
- char *pchoice;
- unsigned int nChoice,ind;
- int nargs,nchars;
+ dbFldDes *pdbFldDes = paddr->pfldDes;
+ dbMenu *pdbMenu;
+ char **pchoices;
+ char *pchoice;
- if( pdbMenu && (papChoiceValue = pdbMenu->papChoiceValue)) {
- nChoice = pdbMenu->nChoice;
- for(ind=0; indftPvt) &&
+ (pchoices = pdbMenu->papChoiceValue)) {
+ int i, nChoice = pdbMenu->nChoice;
+ epicsEnum16 val;
+
+ for (i = 0; i < nChoice; i++) {
+ pchoice = pchoices[i];
+ if (!pchoice) continue;
+ if (strcmp(pchoice, from) == 0) {
+ *to = i;
+ return 0;
+ }
+ }
+
+ if (!epicsParseUInt16(from, &val, 10, NULL) && val < nChoice) {
+ *to = val;
+ return 0;
+ }
}
- recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_st_menu)");
+ recGblDbaddrError(S_db_badChoice, paddr, "dbFastLinkConv(cvt_st_menu)");
return(S_db_badChoice);
}
/* Convert String to Device */
static long cvt_st_device(
- char *from,
- epicsEnum16 *to,
- const dbAddr *paddr)
+ char *from,
+ epicsEnum16 *to,
+ const dbAddr *paddr)
{
- dbFldDes *pdbFldDes = paddr->pfldDes;
- dbDeviceMenu *pdbDeviceMenu = (dbDeviceMenu *)pdbFldDes->ftPvt;
- char **papChoice;
- char *pchoice;
- unsigned int nChoice,ind;
- int nargs,nchars;
+ dbFldDes *pdbFldDes = paddr->pfldDes;
+ dbDeviceMenu *pdbDeviceMenu = pdbFldDes->ftPvt;
+ char **pchoices, *pchoice;
- if( pdbDeviceMenu && (papChoice = pdbDeviceMenu->papChoice)) {
- nChoice = pdbDeviceMenu->nChoice;
- for(ind=0; indftPvt) &&
+ (pchoices = pdbDeviceMenu->papChoice)) {
+ int i, nChoice = pdbDeviceMenu->nChoice;
+ epicsEnum16 val;
+
+ for (i = 0; i < nChoice; i++) {
+ pchoice = pchoices[i];
+ if (!pchoice) continue;
+ if (strcmp(pchoice, from) == 0) {
+ *to = i;
+ return 0;
+ }
+ }
+
+ if (!epicsParseUInt16(from, &val, 10, NULL) && val < nChoice) {
+ *to = val;
+ return 0;
+ }
}
- recGblDbaddrError(S_db_badChoice,paddr,"dbFastLinkConv(cvt_st_device)");
- return(S_db_badChoice);
+ recGblDbaddrError(S_db_badChoice, paddr, "dbFastLinkConv(cvt_st_device)");
+ return S_db_badChoice;
}
/* Convert Char to String */
@@ -405,6 +411,20 @@ static long cvt_c_ul(
const dbAddr *paddr)
{ *to=*from; return(0); }
+/* Convert Char to Int64 */
+static long cvt_c_q(
+ epicsInt8 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Char to UInt64 */
+static long cvt_c_uq(
+ epicsInt8 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
/* Convert Char to Float */
static long cvt_c_f(
epicsInt8 *from,
@@ -475,6 +495,20 @@ static long cvt_uc_ul(
const dbAddr *paddr)
{ *to=*from; return(0); }
+/* Convert Unsigned Char to Int64 */
+static long cvt_uc_q(
+ epicsUInt8 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Unsigned Char to UInt64 */
+static long cvt_uc_uq(
+ epicsUInt8 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
/* Convert Unsigned Char to Float */
static long cvt_uc_f(
epicsUInt8 *from,
@@ -545,6 +579,20 @@ static long cvt_s_ul(
const dbAddr *paddr)
{ *to=*from; return(0); }
+/* Convert Short to Int64 */
+static long cvt_s_q(
+ epicsInt16 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Short to UInt64 */
+static long cvt_s_uq(
+ epicsInt16 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
/* Convert Short to Float */
static long cvt_s_f(
epicsInt16 *from,
@@ -615,6 +663,20 @@ static long cvt_us_ul(
const dbAddr *paddr)
{ *to=*from; return(0); }
+/* Convert Unsigned Short to Int64 */
+static long cvt_us_q(
+ epicsUInt16 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Unsigned Short to UInt64 */
+static long cvt_us_uq(
+ epicsUInt16 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
/* Convert Unsigned Short to Float */
static long cvt_us_f(
epicsUInt16 *from,
@@ -685,6 +747,20 @@ static long cvt_l_ul(
const dbAddr *paddr)
{ *to=*from; return(0); }
+/* Convert Long to Int64 */
+static long cvt_l_q(
+ epicsInt32 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Long to UInt64 */
+static long cvt_l_uq(
+ epicsInt32 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
/* Convert Long to Float */
static long cvt_l_f(
epicsInt32 *from,
@@ -755,6 +831,20 @@ static long cvt_ul_ul(
const dbAddr *paddr)
{ *to=*from; return(0); }
+/* Convert Unsigned Long to Int64 */
+static long cvt_ul_q(
+ epicsUInt32 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Unsigned Long to UInt64 */
+static long cvt_ul_uq(
+ epicsUInt32 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
/* Convert Unsigned Long to Float */
static long cvt_ul_f(
epicsUInt32 *from,
@@ -776,6 +866,178 @@ static long cvt_ul_e(
const dbAddr *paddr)
{ *to=*from; return(0); }
+/* Convert Int64 to String */
+static long cvt_q_st(
+ epicsInt64 *from,
+ char *to,
+ const dbAddr *paddr)
+{ cvtInt64ToString(*from, to); return(0); }
+
+/* Convert Int64 to Char */
+static long cvt_q_c(
+ epicsInt64 *from,
+ epicsInt8 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Int64 to Unsigned Char */
+static long cvt_q_uc(
+ epicsInt64 *from,
+ epicsUInt8 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Int64 to Short */
+static long cvt_q_s(
+ epicsInt64 *from,
+ epicsInt16 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Int64 to Unsigned Short */
+static long cvt_q_us(
+ epicsInt64 *from,
+ epicsUInt16 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Int64 to Long */
+static long cvt_q_l(
+ epicsInt64 *from,
+ epicsInt32 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Int64 to Unsigned Long */
+static long cvt_q_ul(
+ epicsInt64 *from,
+ epicsUInt32 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Int64 to Int64 */
+static long cvt_q_q(
+ epicsInt64 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ {
+
+ *to=*from; return(0); }
+
+/* Convert Int64 to UInt64 */
+static long cvt_q_uq(
+ epicsInt64 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ {
+
+ *to=*from; return(0); }
+
+/* Convert Int64 to Float */
+static long cvt_q_f(
+ epicsInt64 *from,
+ epicsFloat32 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Int64 to Double */
+static long cvt_q_d(
+ epicsInt64 *from,
+ epicsFloat64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Int64 to Enumerated */
+static long cvt_q_e(
+ epicsInt32 *from,
+ epicsEnum16 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to String */
+static long cvt_uq_st(
+ epicsUInt64 *from,
+ char *to,
+ const dbAddr *paddr)
+{ cvtUInt64ToString(*from, to); return(0); }
+
+/* Convert UInt64 to Char */
+static long cvt_uq_c(
+ epicsUInt64 *from,
+ epicsInt8 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to Unsigned Char */
+static long cvt_uq_uc(
+ epicsUInt64 *from,
+ epicsUInt8 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to Short */
+static long cvt_uq_s(
+ epicsUInt64 *from,
+ epicsInt16 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to Unsigned Short */
+static long cvt_uq_us(
+ epicsUInt64 *from,
+ epicsUInt16 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to Long */
+static long cvt_uq_l(
+ epicsUInt64 *from,
+ epicsInt32 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to Unsigned Long */
+static long cvt_uq_ul(
+ epicsUInt64 *from,
+ epicsUInt32 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to Int64 */
+static long cvt_uq_q(
+ epicsUInt64 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to UInt64 */
+static long cvt_uq_uq(
+ epicsUInt64 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to Float */
+static long cvt_uq_f(
+ epicsUInt64 *from,
+ epicsFloat32 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to Double */
+static long cvt_uq_d(
+ epicsUInt64 *from,
+ epicsFloat64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert UInt64 to Enumerated */
+static long cvt_uq_e(
+ epicsUInt64 *from,
+ epicsEnum16 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
/* Convert Float to String */
static long cvt_f_st(
epicsFloat32 *from,
@@ -836,6 +1098,20 @@ static long cvt_f_ul(
const dbAddr *paddr)
{ *to=(epicsUInt32)*from; return(0); }
+/* Convert Float to Int64 */
+static long cvt_f_q(
+ epicsFloat32 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Float to UInt64 */
+static long cvt_f_uq(
+ epicsFloat32 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
/* Convert Float to Float */
static long cvt_f_f(
epicsFloat32 *from,
@@ -908,14 +1184,28 @@ static long cvt_d_l(
epicsFloat64 *from,
epicsInt32 *to,
const dbAddr *paddr)
- { *to=(epicsInt32)*from; return(0); }
+ { *to=*from; return(0); }
/* Convert Double to Unsigned Long */
static long cvt_d_ul(
epicsFloat64 *from,
epicsUInt32 *to,
const dbAddr *paddr)
- { *to=(epicsUInt32)*from; return(0); }
+ { *to=*from; return(0); }
+
+/* Convert Double to Int64 */
+static long cvt_d_q(
+ epicsFloat64 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Double to UInt64 */
+static long cvt_d_uq(
+ epicsFloat64 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
/* Convert Double to Float */
static long cvt_d_f(
@@ -980,6 +1270,20 @@ static long cvt_e_ul(
const dbAddr *paddr)
{ *to=*from; return(0); }
+/* Convert Enumerated to Int64 */
+static long cvt_e_q(
+ epicsEnum16 *from,
+ epicsInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
+/* Convert Enumerated to UInt64 */
+static long cvt_e_uq(
+ epicsEnum16 *from,
+ epicsUInt64 *to,
+ const dbAddr *paddr)
+ { *to=*from; return(0); }
+
/* Convert Enumerated to Float */
static long cvt_e_f(
epicsEnum16 *from,
@@ -1085,7 +1389,7 @@ static long cvt_device_st(
* Converts type X to ...
*
* DBR_STRING, DBR_CHR, DBR_UCHAR, DBR_SHORT, DBR_USHORT,
- * DBR_LONG, DBR_ULONG, DBR_FLOAT, DBR_DOUBLE, DBR_ENUM
+ * DBR_LONG, DBR_ULONG, DBR_INT64, DBR_UINT64, DBR_FLOAT, DBR_DOUBLE, DBR_ENUM
*
* NULL implies the conversion is not supported.
*/
@@ -1093,40 +1397,46 @@ static long cvt_device_st(
epicsShareDef long (*dbFastGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1])() = {
/* Convert DBF_STRING to ... */
-{ cvt_st_st, cvt_st_c, cvt_st_uc, cvt_st_s, cvt_st_us, cvt_st_l, cvt_st_ul, cvt_st_f, cvt_st_d, cvt_st_e },
+{ cvt_st_st, cvt_st_c, cvt_st_uc, cvt_st_s, cvt_st_us, cvt_st_l, cvt_st_ul, cvt_st_q, cvt_st_uq, cvt_st_f, cvt_st_d, cvt_st_e },
/* Convert DBF_CHAR to ... */
-{ cvt_c_st, cvt_c_c, cvt_c_uc, cvt_c_s, cvt_c_us, cvt_c_l, cvt_c_ul, cvt_c_f, cvt_c_d, cvt_c_e },
+{ cvt_c_st, cvt_c_c, cvt_c_uc, cvt_c_s, cvt_c_us, cvt_c_l, cvt_c_ul, cvt_c_q, cvt_c_uq, cvt_c_f, cvt_c_d, cvt_c_e },
/* Convert DBF_UCHAR to ... */
-{ cvt_uc_st, cvt_uc_c, cvt_uc_uc, cvt_uc_s, cvt_uc_us, cvt_uc_l, cvt_uc_ul, cvt_uc_f, cvt_uc_d, cvt_uc_e },
+{ cvt_uc_st, cvt_uc_c, cvt_uc_uc, cvt_uc_s, cvt_uc_us, cvt_uc_l, cvt_uc_ul, cvt_uc_q, cvt_uc_uq, cvt_uc_f, cvt_uc_d, cvt_uc_e },
/* Convert DBF_SHORT to ... */
-{ cvt_s_st, cvt_s_c, cvt_s_uc, cvt_s_s, cvt_s_us, cvt_s_l, cvt_s_ul, cvt_s_f, cvt_s_d, cvt_s_e },
+{ cvt_s_st, cvt_s_c, cvt_s_uc, cvt_s_s, cvt_s_us, cvt_s_l, cvt_s_ul, cvt_s_q, cvt_s_uq, cvt_s_f, cvt_s_d, cvt_s_e },
/* Convert DBF_USHORT to ... */
-{ cvt_us_st, cvt_us_c, cvt_us_uc, cvt_us_s, cvt_us_us, cvt_us_l, cvt_us_ul, cvt_us_f, cvt_us_d, cvt_us_e },
+{ cvt_us_st, cvt_us_c, cvt_us_uc, cvt_us_s, cvt_us_us, cvt_us_l, cvt_us_ul, cvt_us_q, cvt_us_uq, cvt_us_f, cvt_us_d, cvt_us_e },
/* Convert DBF_LONG to ... */
-{ cvt_l_st, cvt_l_c, cvt_l_uc, cvt_l_s, cvt_l_us, cvt_l_l, cvt_l_ul, cvt_l_f, cvt_l_d, cvt_l_e },
+{ cvt_l_st, cvt_l_c, cvt_l_uc, cvt_l_s, cvt_l_us, cvt_l_l, cvt_l_ul, cvt_l_q, cvt_l_uq, cvt_l_f, cvt_l_d, cvt_l_e },
/* Convert DBF_ULONG to ... */
-{ cvt_ul_st, cvt_ul_c, cvt_ul_uc, cvt_ul_s, cvt_ul_us, cvt_ul_l, cvt_ul_ul, cvt_ul_f, cvt_ul_d, cvt_ul_e },
+{ cvt_ul_st, cvt_ul_c, cvt_ul_uc, cvt_ul_s, cvt_ul_us, cvt_ul_l, cvt_ul_ul, cvt_ul_q, cvt_ul_uq, cvt_ul_f, cvt_ul_d, cvt_ul_e },
+
+ /* Convert DBF_INT64 to ... */
+{ cvt_q_st, cvt_q_c, cvt_q_uc, cvt_q_s, cvt_q_us, cvt_q_l, cvt_q_ul, cvt_q_q, cvt_q_uq, cvt_q_f, cvt_q_d, cvt_q_e },
+
+ /* Convert DBF_UINT64 to ... */
+{ cvt_uq_st, cvt_uq_c, cvt_uq_uc, cvt_uq_s, cvt_uq_us, cvt_uq_l, cvt_uq_ul, cvt_uq_q, cvt_uq_uq, cvt_uq_f, cvt_uq_d, cvt_uq_e },
/* Convert DBF_FLOAT to ... */
-{ cvt_f_st, cvt_f_c, cvt_f_uc, cvt_f_s, cvt_f_us, cvt_f_l, cvt_f_ul, cvt_f_f, cvt_f_d, cvt_f_e },
+{ cvt_f_st, cvt_f_c, cvt_f_uc, cvt_f_s, cvt_f_us, cvt_f_l, cvt_f_ul, cvt_f_q, cvt_f_uq, cvt_f_f, cvt_f_d, cvt_f_e },
/* Convert DBF_DOUBLE to ... */
-{ cvt_d_st, cvt_d_c, cvt_d_uc, cvt_d_s, cvt_d_us, cvt_d_l, cvt_d_ul, cvt_d_f, cvt_d_d, cvt_d_e },
+{ cvt_d_st, cvt_d_c, cvt_d_uc, cvt_d_s, cvt_d_us, cvt_d_l, cvt_d_ul, cvt_d_q, cvt_d_uq, cvt_d_f, cvt_d_d, cvt_d_e },
/* Convert DBF_ENUM to ... */
-{ cvt_e_st_get, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_f, cvt_e_d, cvt_e_e },
+{ cvt_e_st_get, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_q, cvt_e_uq, cvt_e_f, cvt_e_d, cvt_e_e },
/* Convert DBF_MENU to ... */
-{ cvt_menu_st, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_f, cvt_e_d, cvt_e_e },
+{ cvt_menu_st, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_q, cvt_e_uq, cvt_e_f, cvt_e_d, cvt_e_e },
/* Convert DBF_DEVICE to ... */
-{ cvt_device_st, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_f, cvt_e_d, cvt_e_e } };
+{ cvt_device_st, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_q, cvt_e_uq, cvt_e_f, cvt_e_d, cvt_e_e } };
/*
* Put conversion routine lookup table
@@ -1134,8 +1444,8 @@ epicsShareDef long (*dbFastGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1])() = {
* Converts type X to ...
*
* DBF_STRING DBF_CHAR DBF_UCHAR DBF_SHORT DBF_USHORT
- * DBF_LONG DBF_ULONG DBF_FLOAT DBF_DOUBLE DBF_ENUM
- * DBF_MENU DBF_DEVICE
+ * DBF_LONG DBF_ULONG DBF_INT64 DBF_UINT64 DBF_FLOAT DBF_DOUBLE DBF_ENUM
+ * DBF_MENU DBF_DEVICE
*
* NULL implies the conversion is not supported.
*/
@@ -1143,32 +1453,38 @@ epicsShareDef long (*dbFastGetConvertRoutine[DBF_DEVICE+1][DBR_ENUM+1])() = {
epicsShareDef long (*dbFastPutConvertRoutine[DBR_ENUM+1][DBF_DEVICE+1])() = {
/* Convert DBR_STRING to ... */
-{ cvt_st_st, cvt_st_c, cvt_st_uc, cvt_st_s, cvt_st_us, cvt_st_l, cvt_st_ul, cvt_st_f, cvt_st_d, cvt_st_e, cvt_st_menu, cvt_st_device},
+{ cvt_st_st, cvt_st_c, cvt_st_uc, cvt_st_s, cvt_st_us, cvt_st_l, cvt_st_ul, cvt_st_q, cvt_st_uq, cvt_st_f, cvt_st_d, cvt_st_e, cvt_st_menu, cvt_st_device},
/* Convert DBR_CHAR to ... */
-{ cvt_c_st, cvt_c_c, cvt_c_uc, cvt_c_s, cvt_c_us, cvt_c_l, cvt_c_ul, cvt_c_f, cvt_c_d, cvt_c_e, cvt_c_e, cvt_c_e},
+{ cvt_c_st, cvt_c_c, cvt_c_uc, cvt_c_s, cvt_c_us, cvt_c_l, cvt_c_ul, cvt_c_q, cvt_c_uq, cvt_c_f, cvt_c_d, cvt_c_e, cvt_c_e, cvt_c_e},
/* Convert DBR_UCHAR to ... */
-{ cvt_uc_st, cvt_uc_c, cvt_uc_uc, cvt_uc_s, cvt_uc_us, cvt_uc_l, cvt_uc_ul, cvt_uc_f, cvt_uc_d, cvt_uc_e, cvt_uc_e, cvt_uc_e},
+{ cvt_uc_st, cvt_uc_c, cvt_uc_uc, cvt_uc_s, cvt_uc_us, cvt_uc_l, cvt_uc_ul, cvt_uc_q, cvt_uc_uq, cvt_uc_f, cvt_uc_d, cvt_uc_e, cvt_uc_e, cvt_uc_e},
/* Convert DBR_SHORT to ... */
-{ cvt_s_st, cvt_s_c, cvt_s_uc, cvt_s_s, cvt_s_us, cvt_s_l, cvt_s_ul, cvt_s_f, cvt_s_d, cvt_s_e, cvt_s_e, cvt_s_e},
+{ cvt_s_st, cvt_s_c, cvt_s_uc, cvt_s_s, cvt_s_us, cvt_s_l, cvt_s_ul, cvt_s_q, cvt_s_uq, cvt_s_f, cvt_s_d, cvt_s_e, cvt_s_e, cvt_s_e},
/* Convert DBR_USHORT to ... */
-{ cvt_us_st, cvt_us_c, cvt_us_uc, cvt_us_s, cvt_us_us, cvt_us_l, cvt_us_ul, cvt_us_f, cvt_us_d, cvt_us_e, cvt_us_e, cvt_us_e},
+{ cvt_us_st, cvt_us_c, cvt_us_uc, cvt_us_s, cvt_us_us, cvt_us_l, cvt_us_ul, cvt_us_q, cvt_us_uq, cvt_us_f, cvt_us_d, cvt_us_e, cvt_us_e, cvt_us_e},
/* Convert DBR_LONG to ... */
-{ cvt_l_st, cvt_l_c, cvt_l_uc, cvt_l_s, cvt_l_us, cvt_l_l, cvt_l_ul, cvt_l_f, cvt_l_d, cvt_l_e, cvt_l_e, cvt_l_e},
+{ cvt_l_st, cvt_l_c, cvt_l_uc, cvt_l_s, cvt_l_us, cvt_l_l, cvt_l_ul, cvt_l_q, cvt_l_uq, cvt_l_f, cvt_l_d, cvt_l_e, cvt_l_e, cvt_l_e},
/* Convert DBR_ULONG to ... */
-{ cvt_ul_st, cvt_ul_c, cvt_ul_uc, cvt_ul_s, cvt_ul_us, cvt_ul_l, cvt_ul_ul, cvt_ul_f, cvt_ul_d, cvt_ul_e, cvt_ul_e, cvt_ul_e},
+{ cvt_ul_st, cvt_ul_c, cvt_ul_uc, cvt_ul_s, cvt_ul_us, cvt_ul_l, cvt_ul_ul, cvt_ul_q, cvt_ul_uq, cvt_ul_f, cvt_ul_d, cvt_ul_e, cvt_ul_e, cvt_ul_e},
+
+ /* Convert DBR_INT64 to ... */
+{ cvt_q_st, cvt_q_c, cvt_q_uc, cvt_q_s, cvt_q_us, cvt_q_l, cvt_q_ul, cvt_q_q, cvt_q_uq, cvt_q_f, cvt_q_d, cvt_q_e, cvt_q_e, cvt_q_e},
+
+ /* Convert DBR_UINT64 to ... */
+{ cvt_uq_st, cvt_uq_c, cvt_uq_uc, cvt_uq_s, cvt_uq_us, cvt_uq_l, cvt_uq_ul, cvt_uq_q, cvt_uq_uq, cvt_uq_f, cvt_uq_d, cvt_uq_e, cvt_uq_e, cvt_uq_e},
/* Convert DBR_FLOAT to ... */
-{ cvt_f_st, cvt_f_c, cvt_f_uc, cvt_f_s, cvt_f_us, cvt_f_l, cvt_f_ul, cvt_f_f, cvt_f_d, cvt_f_e, cvt_f_e, cvt_f_e},
+{ cvt_f_st, cvt_f_c, cvt_f_uc, cvt_f_s, cvt_f_us, cvt_f_l, cvt_f_ul, cvt_f_q, cvt_f_uq, cvt_f_f, cvt_f_d, cvt_f_e, cvt_f_e, cvt_f_e},
/* Convert DBR_DOUBLE to ... */
-{ cvt_d_st, cvt_d_c, cvt_d_uc, cvt_d_s, cvt_d_us, cvt_d_l, cvt_d_ul, cvt_d_f, cvt_d_d, cvt_d_e, cvt_d_e, cvt_d_e},
+{ cvt_d_st, cvt_d_c, cvt_d_uc, cvt_d_s, cvt_d_us, cvt_d_l, cvt_d_ul, cvt_d_q, cvt_d_uq, cvt_d_f, cvt_d_d, cvt_d_e, cvt_d_e, cvt_d_e},
/* Convert DBR_ENUM to ... */
-{ cvt_e_st_put, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_f, cvt_e_d, cvt_e_e, cvt_e_e, cvt_e_e} };
+{ cvt_e_st_put, cvt_e_c, cvt_e_uc, cvt_e_s, cvt_e_us, cvt_e_l, cvt_e_ul, cvt_e_q, cvt_e_uq, cvt_e_f, cvt_e_d, cvt_e_e, cvt_e_e, cvt_e_e} };
diff --git a/src/ioc/db/dbTest.c b/src/ioc/db/dbTest.c
index 97279de08..e707dab7f 100644
--- a/src/ioc/db/dbTest.c
+++ b/src/ioc/db/dbTest.c
@@ -13,6 +13,7 @@
#include
#include
+#include "cvtFast.h"
#include "dbDefs.h"
#include "ellLib.h"
#include "epicsMutex.h"
@@ -72,13 +73,13 @@ static void dbpr_msg_flush(TAB_BUFFER *pMsgBuff,int tab_size);
static char *dbf[DBF_NTYPES] = {
"STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG",
- "FLOAT","DOUBLE","ENUM","MENU","DEVICE",
+ "INT64","UINT64","FLOAT","DOUBLE","ENUM","MENU","DEVICE",
"INLINK","OUTLINK","FWDLINK","NOACCESS"
};
static char *dbr[DBR_ENUM+2] = {
"STRING","CHAR","UCHAR","SHORT","USHORT","LONG","ULONG",
- "FLOAT","DOUBLE","ENUM","NOACCESS"
+ "INT64","UINT64","FLOAT","DOUBLE","ENUM","NOACCESS"
};
long dba(const char*pname)
@@ -484,6 +485,16 @@ long dbtgf(const char *pname)
status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
+ dbr_type = DBR_INT64;
+ no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsInt64)));
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
+
+ dbr_type = DBR_UINT64;
+ no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsUInt64)));
+ status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
+ printBuffer(status,dbr_type,pbuffer,0L,0L,no_elements,pMsgBuff,tab_size);
+
dbr_type = DBR_FLOAT;
no_elements = MIN(addr.no_elements,((sizeof(buffer))/sizeof(epicsFloat32)));
status = dbGetField(&addr,dbr_type,pbuffer,&ret_options,&no_elements,NULL);
@@ -510,17 +521,7 @@ long dbtpf(const char *pname, const char *pvalue)
long buffer[100];
long *pbuffer = buffer;
DBADDR addr;
- long status = 0;
- long options, no_elements;
- char *pend;
- long val_long;
- int validLong;
- unsigned long val_ulong;
- int validULong;
- int valid = 1;
int put_type;
- epicsFloat32 fvalue;
- epicsFloat64 dvalue;
static TAB_BUFFER msg_Buff;
TAB_BUFFER *pMsgBuff = &msg_Buff;
char *pmsg = pMsgBuff->message;
@@ -530,91 +531,90 @@ long dbtpf(const char *pname, const char *pvalue)
printf("Usage: dbtpf \"pv name\", \"value\"\n");
return 1;
}
-
if (nameToAddr(pname, &addr))
return -1;
- val_long = strtol(pvalue, &pend, 10);
- validLong = (*pend == 0);
-
- val_ulong = strtoul(pvalue, &pend, 10);
- validULong = (*pend == 0);
-
for (put_type = DBR_STRING; put_type <= DBF_ENUM; put_type++) {
+ union {
+ epicsInt8 i8;
+ epicsUInt8 u8;
+ epicsInt16 i16;
+ epicsUInt16 u16;
+ epicsInt32 i32;
+ epicsUInt32 u32;
+ epicsInt64 i64;
+ epicsUInt64 u64;
+ epicsFloat32 f32;
+ epicsFloat64 f64;
+ epicsEnum16 e16;
+ } val;
+ const void *pval = &val;
+ int valid = 1;
+
switch (put_type) {
case DBR_STRING:
- status = dbPutField(&addr, put_type, pvalue, 1L);
+ pval = pvalue;
break;
case DBR_CHAR:
- if ((valid = validLong)) {
- epicsInt8 val_i8 = (epicsInt8)val_long;
- status = dbPutField(&addr, put_type, &val_i8, 1L);
- }
+ valid = !epicsParseInt8(pvalue, &val.i8, 10, NULL);
break;
case DBR_UCHAR:
- if ((valid = validULong)) {
- epicsUInt8 val_u8 = (epicsUInt8)val_ulong;
- status = dbPutField(&addr, put_type, &val_u8, 1L);
- }
+ valid = !epicsParseUInt8(pvalue, &val.u8, 10, NULL);
break;
case DBR_SHORT:
- if ((valid = validLong)) {
- epicsInt16 val_i16 = (epicsInt16) val_long;
- status = dbPutField(&addr, put_type, &val_i16,1L);
- }
+ valid = !epicsParseInt16(pvalue, &val.i16, 10, NULL);
break;
case DBR_USHORT:
- if ((valid = validULong)) {
- epicsUInt16 val_u16 = (epicsUInt16) val_ulong;
- status = dbPutField(&addr, put_type, &val_u16, 1L);
- }
+ valid = !epicsParseUInt16(pvalue, &val.u16, 10, NULL);
break;
case DBR_LONG:
- if ((valid = validLong)) {
- epicsInt32 val_i32 = val_long;
- status = dbPutField(&addr, put_type,&val_i32,1L);
- }
+ valid = !epicsParseInt32(pvalue, &val.i32, 10, NULL);
break;
case DBR_ULONG:
- if ((valid = validULong)) {
- epicsUInt32 val_u32 = val_ulong;
- status = dbPutField(&addr, put_type, &val_u32, 1L);
- }
+ valid = !epicsParseUInt32(pvalue, &val.u32, 10, NULL);
+ break;
+ case DBR_INT64:
+ valid = !epicsParseInt64(pvalue, &val.i64, 10, NULL);
+ break;
+ case DBR_UINT64:
+ valid = !epicsParseUInt64(pvalue, &val.u64, 10, NULL);
break;
case DBR_FLOAT:
- if ((valid = epicsScanFloat(pvalue, &fvalue) == 1))
- status = dbPutField(&addr, put_type, &fvalue, 1L);
+ valid = !epicsParseFloat32(pvalue, &val.f32, NULL);
break;
case DBR_DOUBLE:
- if ((valid = epicsScanDouble(pvalue, &dvalue) == 1))
- status = dbPutField(&addr, put_type, &dvalue, 1L);
+ valid = !epicsParseFloat64(pvalue, &val.f64, NULL);
break;
case DBR_ENUM:
- if ((valid = validULong)) {
- epicsEnum16 val_e16 = (epicsEnum16) val_ulong;
- status = dbPutField(&addr, put_type, &val_e16, 1L);
- }
+ valid = !epicsParseUInt16(pvalue, &val.e16, 10, NULL);
break;
}
if (valid) {
+ long status = dbPutField(&addr, put_type, pval, 1);
+
if (status) {
- printf("Put as DBR_%s Failed.\n", dbr[put_type]);
- } else {
- printf("Put as DBR_%-6s Ok, result as ", dbr[put_type]);
- no_elements = MIN(addr.no_elements,
+ printf("Put as DBR_%-6s Failed.\n", dbr[put_type]);
+ }
+ else {
+ long options = 0;
+ long no_elements = MIN(addr.no_elements,
((sizeof(buffer))/addr.field_size));
- options = 0;
+
+ printf("Put as DBR_%-6s Ok, result as ", dbr[put_type]);
status = dbGetField(&addr, addr.dbr_field_type, pbuffer,
&options, &no_elements, NULL);
printBuffer(status, addr.dbr_field_type, pbuffer, 0L, 0L,
no_elements, pMsgBuff, tab_size);
}
}
+ else {
+ printf("Cvt to DBR_%s failed.\n", dbr[put_type]);
+ }
}
pmsg[0] = '\0';
dbpr_msgOut(pMsgBuff, tab_size);
- return(0);
+ return 0;
}
long dbior(const char *pdrvName,int interest_level)
@@ -732,10 +732,8 @@ static void printBuffer(
long status, short dbr_type, void *pbuffer, long reqOptions,
long retOptions, long no_elements, TAB_BUFFER *pMsgBuff, int tab_size)
{
- epicsInt32 val_i32;
- epicsUInt32 val_u32;
char *pmsg = pMsgBuff->message;
- size_t i, len;
+ int i;
if (reqOptions & DBR_STATUS) {
if (retOptions & DBR_STATUS) {
@@ -898,221 +896,166 @@ static void printBuffer(
if (no_elements == 0)
return;
- switch (dbr_type) {
- case (DBR_STRING):
- if (no_elements == 1)
- sprintf(pmsg, "DBR_STRING: ");
- else
- sprintf(pmsg, "DBR_STRING[%ld]: ", no_elements);
- dbpr_msgOut(pMsgBuff, tab_size);
- if (status != 0) {
- sprintf(pmsg, "DBR_STRING: failed.");
- dbpr_msgOut(pMsgBuff, tab_size);
- break;
- }
+ if (no_elements == 1)
+ sprintf(pmsg, "DBF_%s: ", dbr[dbr_type]);
+ else
+ sprintf(pmsg, "DBF_%s[%ld]: ", dbr[dbr_type], no_elements);
+ dbpr_msgOut(pMsgBuff, tab_size);
- for(i=0; i 0) {
- sprintf(pmsg, " \"%s\"", (char *)pbuffer);
+ if (status != 0) {
+ strcpy(pmsg, "failed.");
+ dbpr_msgOut(pMsgBuff, tab_size);
+ }
+ else {
+ switch (dbr_type) {
+ case DBR_STRING:
+ for(i=0; i MAXLINE - 5) width = MAXLINE - 5;
- sprintf(pmsg, " \"%.*s\"", width, (char *)pbuffer + i);
- if (i + MAXLINE - 5 < no_elements) strcat(pmsg, " +");
+ case DBR_CHAR:
+ if (no_elements == 1) {
+ epicsInt32 val = *(epicsInt8 *) pbuffer;
+
+ if (isprint(val))
+ sprintf(pmsg, "%d = 0x%x = '%c'", val, val & 0xff, val);
+ else
+ sprintf(pmsg, "%d = 0x%x", val, val & 0xff);
dbpr_msgOut(pMsgBuff, tab_size);
+ } else {
+ size_t len = epicsStrnLen(pbuffer, no_elements);
+
+ i = 0;
+ while (len > 0) {
+ int chunk = (len > MAXLINE - 5) ? MAXLINE - 5 : len;
+
+ sprintf(pmsg, "\"%.*s\"", chunk, (char *)pbuffer + i);
+ len -= chunk;
+ if (len > 0)
+ strcat(pmsg, " +");
+ dbpr_msgOut(pMsgBuff, tab_size);
+ }
}
- }
- break;
+ break;
- case (DBR_UCHAR):
- if (no_elements == 1)
- sprintf(pmsg, "DBR_UCHAR: ");
- else
- sprintf(pmsg, "DBR_UCHAR[%ld]: ", no_elements);
- dbpr_msgOut(pMsgBuff, tab_size);
- if (status != 0) {
- sprintf(pmsg, " failed.");
+ case DBR_UCHAR:
+ for (i = 0; i < no_elements; i++) {
+ epicsUInt32 val = *(epicsUInt8 *) pbuffer;
+
+ sprintf(pmsg, "%u = 0x%x", val, val);
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pbuffer = (char *)pbuffer + sizeof(epicsUInt8);
+ }
+ break;
+
+ case DBR_SHORT:
+ for (i = 0; i < no_elements; i++) {
+ epicsInt16 val = *(epicsInt16 *) pbuffer;
+
+ sprintf(pmsg, "%hd = 0x%hx", val, val);
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pbuffer = (char *)pbuffer + sizeof(epicsInt16);
+ }
+ break;
+
+ case DBR_USHORT:
+ for (i = 0; i < no_elements; i++) {
+ epicsUInt16 val = *(epicsUInt16 *) pbuffer;
+
+ sprintf(pmsg, "%hu = 0x%hx", val, val);
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pbuffer = (char *)pbuffer + sizeof(epicsUInt16);
+ }
+ break;
+
+ case DBR_LONG:
+ for (i = 0; i < no_elements; i++) {
+ epicsInt32 val = *(epicsInt32 *) pbuffer;
+
+ sprintf(pmsg, "%d = 0x%x", val, val);
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pbuffer = (char *)pbuffer + sizeof(epicsInt32);
+ }
+ break;
+
+ case DBR_ULONG:
+ for (i = 0; i < no_elements; i++) {
+ epicsUInt32 val = *(epicsUInt32 *) pbuffer;
+
+ sprintf(pmsg, "%u = 0x%x", val, val);
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pbuffer = (char *)pbuffer + sizeof(epicsUInt32);
+ }
+ break;
+
+ case DBR_INT64:
+ for (i = 0; i < no_elements; i++) {
+ epicsInt64 val = *(epicsInt64 *) pbuffer;
+
+ pmsg += cvtInt64ToString(val, pmsg);
+ strcpy(pmsg, " = ");
+ pmsg += 3;
+ cvtInt64ToHexString(val, pmsg);
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pmsg = pMsgBuff->message;
+ pbuffer = (char *)pbuffer + sizeof(epicsInt64);
+ }
+ break;
+
+ case DBR_UINT64:
+ for (i = 0; i < no_elements; i++) {
+ epicsUInt64 val = *(epicsUInt64 *) pbuffer;
+
+ pmsg += cvtUInt64ToString(val, pmsg);
+ strcpy(pmsg, " = ");
+ pmsg += 3;
+ cvtUInt64ToHexString(val, pmsg);
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pmsg = pMsgBuff->message;
+ pbuffer = (char *)pbuffer + sizeof(epicsUInt64);
+ }
+ break;
+
+ case DBR_FLOAT:
+ for (i = 0; i < no_elements; i++) {
+ sprintf(pmsg, "%.6g", *((epicsFloat32 *) pbuffer));
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pbuffer = (char *)pbuffer + sizeof(epicsFloat32);
+ }
+ break;
+
+ case DBR_DOUBLE:
+ for (i = 0; i < no_elements; i++) {
+ sprintf(pmsg, "%.12g", *((epicsFloat64 *) pbuffer));
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pbuffer = (char *)pbuffer + sizeof(epicsFloat64);
+ }
+ break;
+
+ case DBR_ENUM:
+ for (i = 0; i < no_elements; i++) {
+ sprintf(pmsg, "%u", *((epicsEnum16 *) pbuffer));
+ dbpr_msgOut(pMsgBuff, tab_size);
+ pbuffer = (char *)pbuffer + sizeof(epicsEnum16);
+ }
+ break;
+
+ default:
+ sprintf(pmsg, "Bad DBR type %d", dbr_type);
dbpr_msgOut(pMsgBuff, tab_size);
break;
}
-
- for (i = 0; i < no_elements; i++) {
- val_u32 = *(epicsUInt8 *) pbuffer;
- sprintf(pmsg, "%-9u 0x%-9x", val_u32, val_u32);
- dbpr_msgOut(pMsgBuff, tab_size);
- pbuffer = (char *)pbuffer + sizeof(epicsUInt8);
- }
- break;
-
- case (DBR_SHORT):
- if (no_elements == 1)
- sprintf(pmsg, "DBR_SHORT: ");
- else
- sprintf(pmsg, "DBR_SHORT[%ld]: ", no_elements);
- dbpr_msgOut(pMsgBuff, tab_size);
- if (status != 0) {
- sprintf(pmsg, " failed.");
- dbpr_msgOut(pMsgBuff, tab_size);
- break;
- }
-
- for (i = 0; i < no_elements; i++) {
- val_i32 = *(epicsInt16 *) pbuffer;
- sprintf(pmsg, "%-9d 0x%-9x", val_i32, val_i32);
- dbpr_msgOut(pMsgBuff, tab_size);
- pbuffer = (char *)pbuffer + sizeof(epicsInt16);
- }
- break;
-
- case (DBR_USHORT):
- if (no_elements == 1)
- sprintf(pmsg, "DBR_USHORT: ");
- else
- sprintf(pmsg, "DBR_USHORT[%ld]: ", no_elements);
- dbpr_msgOut(pMsgBuff, tab_size);
- if (status != 0) {
- sprintf(pmsg, " failed.");
- dbpr_msgOut(pMsgBuff, tab_size);
- break;
- }
-
- for (i = 0; i < no_elements; i++) {
- val_u32 = *(epicsUInt16 *) pbuffer;
- sprintf(pmsg, "%-9u 0x%-9x", val_u32, val_u32);
- dbpr_msgOut(pMsgBuff, tab_size);
- pbuffer = (char *)pbuffer + sizeof(epicsUInt16);
- }
- break;
-
- case (DBR_LONG):
- if (no_elements == 1)
- sprintf(pmsg, "DBR_LONG: ");
- else
- sprintf(pmsg, "DBR_LONG[%ld]: ", no_elements);
- dbpr_msgOut(pMsgBuff, tab_size);
- if (status != 0) {
- sprintf(pmsg, " failed.");
- dbpr_msgOut(pMsgBuff, tab_size);
- break;
- }
-
- for (i = 0; i < no_elements; i++) {
- val_i32 = *(epicsInt32 *) pbuffer;
- sprintf(pmsg, "%-9d 0x%-9x", val_i32, val_i32);
- dbpr_msgOut(pMsgBuff, tab_size);
- pbuffer = (char *)pbuffer + sizeof(epicsInt32);
- }
- break;
-
- case (DBR_ULONG):
- if (no_elements == 1)
- sprintf(pmsg, "DBR_ULONG: ");
- else
- sprintf(pmsg, "DBR_ULONG[%ld]: ", no_elements);
- dbpr_msgOut(pMsgBuff, tab_size);
- if (status != 0) {
- sprintf(pmsg, " failed.");
- dbpr_msgOut(pMsgBuff, tab_size);
- break;
- }
-
- for (i = 0; i < no_elements; i++) {
- val_u32 = *(epicsUInt32 *) pbuffer;
- sprintf(pmsg, "%-9u 0x%-9x", val_u32, val_u32);
- dbpr_msgOut(pMsgBuff, tab_size);
- pbuffer = (char *)pbuffer + sizeof(epicsUInt32);
- }
- break;
-
- case (DBR_FLOAT):
- if (no_elements == 1)
- sprintf(pmsg, "DBR_FLOAT: ");
- else
- sprintf(pmsg, "DBR_FLOAT[%ld]: ", no_elements);
- dbpr_msgOut(pMsgBuff, tab_size);
- if (status != 0) {
- sprintf(pmsg, " failed.");
- dbpr_msgOut(pMsgBuff, tab_size);
- break;
- }
-
- for (i = 0; i < no_elements; i++) {
- sprintf(pmsg, "%-13.6g", *((epicsFloat32 *) pbuffer));
- dbpr_msgOut(pMsgBuff, tab_size);
- pbuffer = (char *)pbuffer + sizeof(epicsFloat32);
- }
- break;
-
- case (DBR_DOUBLE):
- if (no_elements == 1)
- sprintf(pmsg, "DBR_DOUBLE: ");
- else
- sprintf(pmsg, "DBR_DOUBLE[%ld]: ", no_elements);
- dbpr_msgOut(pMsgBuff, tab_size);
- if (status != 0) {
- sprintf(pmsg, " failed.");
- dbpr_msgOut(pMsgBuff, tab_size);
- break;
- }
-
- for (i = 0; i < no_elements; i++) {
- sprintf(pmsg, "%-13.6g", *((epicsFloat64 *) pbuffer));
- dbpr_msgOut(pMsgBuff, tab_size);
- pbuffer = (char *)pbuffer + sizeof(epicsFloat64);
- }
- break;
-
- case (DBR_ENUM):
- if (no_elements == 1)
- sprintf(pmsg, "DBR_ENUM: ");
- else
- sprintf(pmsg, "DBR_ENUM[%ld]: ", no_elements);
- dbpr_msgOut(pMsgBuff, tab_size);
- if (status != 0) {
- sprintf(pmsg, " failed.");
- dbpr_msgOut(pMsgBuff, tab_size);
- break;
- }
-
- for (i = 0; i < no_elements; i++) {
- sprintf(pmsg, "%-9u", *((epicsEnum16 *) pbuffer));
- dbpr_msgOut(pMsgBuff, tab_size);
- pbuffer = (char *)pbuffer + sizeof(epicsEnum16);
- }
- break;
-
- default:
- printf(" illegal request type.");
- break;
}
dbpr_msg_flush(pMsgBuff, tab_size);
- return;
}
static int dbpr_report(
@@ -1144,7 +1087,6 @@ static int dbpr_report(
pfield = ((char *)paddr->precord) + pdbFldDes->offset;
if (pdbFldDes->interest > interest_level )
continue;
-
switch (pdbFldDes->field_type) {
case DBF_STRING:
case DBF_USHORT:
@@ -1155,6 +1097,8 @@ static int dbpr_report(
case DBF_SHORT:
case DBF_LONG:
case DBF_ULONG:
+ case DBF_INT64:
+ case DBF_UINT64:
case DBF_DOUBLE:
case DBF_MENU:
case DBF_DEVICE:
diff --git a/src/ioc/db/dbUnitTest.c b/src/ioc/db/dbUnitTest.c
index 644741e5e..dbd8c487e 100644
--- a/src/ioc/db/dbUnitTest.c
+++ b/src/ioc/db/dbUnitTest.c
@@ -134,6 +134,8 @@ long testdbVPutField(const char* pv, short dbrType, va_list ap)
OP(DBR_USHORT, int, uInt16);
OP(DBR_LONG, int, int32);
OP(DBR_ULONG, unsigned int, uInt32);
+ OP(DBR_INT64, long long, int64);
+ OP(DBR_UINT64, unsigned long long, uInt64);
OP(DBR_FLOAT, double, float32);
OP(DBR_DOUBLE, double, float64);
OP(DBR_ENUM, int, enum16);
@@ -220,10 +222,14 @@ void testdbVGetFieldEqual(const char* pv, short dbrType, va_list ap)
OP(DBR_USHORT, int, uInt16, "%d");
OP(DBR_LONG, int, int32, "%d");
OP(DBR_ULONG, unsigned int, uInt32, "%u");
+ OP(DBR_INT64, long long, int64, "%lld");
+ OP(DBR_UINT64, unsigned long long, uInt64, "%llu");
OP(DBR_FLOAT, double, float32, "%e");
OP(DBR_DOUBLE, double, float64, "%e");
OP(DBR_ENUM, int, enum16, "%d");
#undef OP
+ default:
+ testFail("dbGetField(\"%s\", %d) -> unsupported dbf", pv, dbrType);
}
}
@@ -295,6 +301,8 @@ void testdbGetArrFieldEqual(const char* pv, short dbfType, long nRequest, unsign
OP(DBR_USHORT, unsigned short, "%u");
OP(DBR_LONG, int, "%d");
OP(DBR_ULONG, unsigned int, "%u");
+ OP(DBR_INT64, long long, "%lld");
+ OP(DBR_UINT64, unsigned long long, "%llu");
OP(DBR_FLOAT, float, "%e");
OP(DBR_DOUBLE, double, "%e");
OP(DBR_ENUM, int, "%d");
diff --git a/src/ioc/db/dbUnitTest.h b/src/ioc/db/dbUnitTest.h
index 31d068350..8fe8011af 100644
--- a/src/ioc/db/dbUnitTest.h
+++ b/src/ioc/db/dbUnitTest.h
@@ -38,6 +38,8 @@ epicsShareFunc void testdbCleanup(void);
*
* int for DBR_UCHAR, DBR_CHAR, DBR_USHORT, DBR_SHORT, DBR_LONG
* unsigned int for DBR_ULONG
+ * long long for DBF_INT64
+ * unsigned long long for DBF_UINT64
* double for DBR_FLOAT and DBR_DOUBLE
* const char* for DBR_STRING
*
diff --git a/src/ioc/db/db_convert.h b/src/ioc/db/db_convert.h
index 694c0dd07..d06164f02 100644
--- a/src/ioc/db/db_convert.h
+++ b/src/ioc/db/db_convert.h
@@ -23,8 +23,8 @@ epicsShareExtern struct dbBase *pdbbase;
epicsShareExtern volatile int interruptAccept;
/*Definitions that allow old database access to use new conversion routines*/
-#define newDBF_DEVICE 11
-#define newDBR_ENUM 9
+#define newDBF_DEVICE 13
+#define newDBR_ENUM 11
epicsShareExtern long (*dbGetConvertRoutine[newDBF_DEVICE+1][newDBR_ENUM+1])
(struct dbAddr *paddr, void *pbuffer,long nRequest,
long no_elements, long offset);
@@ -43,11 +43,11 @@ epicsShareExtern unsigned short dbDBRnewToDBRold[newDBR_ENUM+1];
epicsShareDef unsigned short dbDBRoldToDBFnew[DBR_DOUBLE+1] = {
0, /*DBR_STRING to DBF_STRING*/
3, /*DBR_INT to DBF_SHORT*/
- 7, /*DBR_FLOAT to DBF_FLOAT*/
- 9, /*DBR_ENUM to DBF_ENUM*/
+ 9, /*DBR_FLOAT to DBF_FLOAT*/
+ 11, /*DBR_ENUM to DBF_ENUM*/
1, /*DBR_CHAR to DBF_CHAR*/
5, /*DBR_LONG to DBF_LONG*/
- 8 /*DBR_DOUBLE to DBF_DOUBLE*/
+ 10 /*DBR_DOUBLE to DBF_DOUBLE*/
};
epicsShareDef unsigned short dbDBRnewToDBRold[newDBR_ENUM+1] = {
0, /*DBR_STRING to DBR_STRING*/
@@ -57,6 +57,8 @@ epicsShareDef unsigned short dbDBRnewToDBRold[newDBR_ENUM+1] = {
5, /*DBR_USHORT to DBR_LONG*/
5, /*DBR_LONG to DBR_LONG*/
6, /*DBR_ULONG to DBR_DOUBLE*/
+ 6, /*DBR_INT64 to DBR_DOUBLE*/
+ 6, /*DBR_UINT64 to DBR_DOUBLE*/
2, /*DBR_FLOAT to DBR_FLOAT*/
6, /*DBR_DOUBLE to DBR_DOUBLE*/
3, /*DBR_ENUM to DBR_ENUM*/
diff --git a/src/ioc/db/menuFtype.dbd b/src/ioc/db/menuFtype.dbd
index ff20e0ca4..af6a8803d 100644
--- a/src/ioc/db/menuFtype.dbd
+++ b/src/ioc/db/menuFtype.dbd
@@ -1,10 +1,9 @@
#*************************************************************************
-# Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+# Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
# National Laboratory.
# Copyright (c) 2002 The Regents of the University of California, as
# Operator of Los Alamos National Laboratory.
-# EPICS BASE Versions 3.13.7
-# and higher are distributed subject to a Software License Agreement found
+# EPICS BASE is distributed subject to a Software License Agreement found
# in file LICENSE that is included with this distribution.
#*************************************************************************
menu(menuFtype) {
@@ -15,6 +14,8 @@ menu(menuFtype) {
choice(menuFtypeUSHORT,"USHORT")
choice(menuFtypeLONG,"LONG")
choice(menuFtypeULONG,"ULONG")
+ choice(menuFtypeINT64,"INT64")
+ choice(menuFtypeUINT64,"UINT64")
choice(menuFtypeFLOAT,"FLOAT")
choice(menuFtypeDOUBLE,"DOUBLE")
choice(menuFtypeENUM,"ENUM")
diff --git a/src/ioc/db/recGbl.c b/src/ioc/db/recGbl.c
index 2bf44322f..a614b5268 100644
--- a/src/ioc/db/recGbl.c
+++ b/src/ioc/db/recGbl.c
@@ -120,6 +120,8 @@ void recGblGetPrec(const struct dbAddr *paddr, long *precision)
case DBF_USHORT:
case DBF_LONG:
case DBF_ULONG:
+ case DBF_INT64:
+ case DBF_UINT64:
*precision = 0;
break;
@@ -345,7 +347,15 @@ static void getMaxRangeValues(short field_type, double *pupper_limit,
*plower_limit = -2147483648.0;
break;
case DBF_ULONG:
- *pupper_limit = (double) 0xffffffffU;
+ *pupper_limit = 4294967295.0;
+ *plower_limit = 0.0;
+ break;
+ case DBF_INT64:
+ *pupper_limit = 9223372036854775808.0;
+ *plower_limit = -9223372036854775808.0;
+ break;
+ case DBF_UINT64:
+ *pupper_limit = 18446744073709551615.0;
*plower_limit = 0.0;
break;
case DBF_FLOAT:
diff --git a/src/ioc/db/test/dbPutGetTest.db b/src/ioc/db/test/dbPutGetTest.db
index bacaa5638..793750e6e 100644
--- a/src/ioc/db/test/dbPutGetTest.db
+++ b/src/ioc/db/test/dbPutGetTest.db
@@ -11,7 +11,7 @@ record(x, "recempty") {
record(x, "recoverwrite") {
# first with non-default values
-# field(DTYP, "Scan I/O")
+ field(DTYP, "Scan I/O")
field(DESC, "hello")
field(PHAS, "2")
field(TSE , "5")
diff --git a/src/ioc/dbStatic/dbFldTypes.h b/src/ioc/dbStatic/dbFldTypes.h
index 0d2b9e1da..ba1a69573 100644
--- a/src/ioc/dbStatic/dbFldTypes.h
+++ b/src/ioc/dbStatic/dbFldTypes.h
@@ -29,6 +29,8 @@ typedef enum {
DBF_USHORT,
DBF_LONG,
DBF_ULONG,
+ DBF_INT64,
+ DBF_UINT64,
DBF_FLOAT,
DBF_DOUBLE,
DBF_ENUM,
@@ -56,6 +58,8 @@ epicsShareDef mapdbfType pamapdbfType[DBF_NTYPES] = {
{"DBF_USHORT",DBF_USHORT},
{"DBF_LONG",DBF_LONG},
{"DBF_ULONG",DBF_ULONG},
+ {"DBF_INT64",DBF_INT64},
+ {"DBF_UINT64",DBF_UINT64},
{"DBF_FLOAT",DBF_FLOAT},
{"DBF_DOUBLE",DBF_DOUBLE},
{"DBF_ENUM",DBF_ENUM},
@@ -76,6 +80,8 @@ epicsShareDef mapdbfType pamapdbfType[DBF_NTYPES] = {
#define DBR_USHORT DBF_USHORT
#define DBR_LONG DBF_LONG
#define DBR_ULONG DBF_ULONG
+#define DBR_INT64 DBF_INT64
+#define DBR_UINT64 DBF_UINT64
#define DBR_FLOAT DBF_FLOAT
#define DBR_DOUBLE DBF_DOUBLE
#define DBR_ENUM DBF_ENUM
diff --git a/src/ioc/dbStatic/dbLexRoutines.c b/src/ioc/dbStatic/dbLexRoutines.c
index dc447e5ce..19bea450d 100644
--- a/src/ioc/dbStatic/dbLexRoutines.c
+++ b/src/ioc/dbStatic/dbLexRoutines.c
@@ -1086,10 +1086,12 @@ static void dbRecordField(char *name,char *value)
dbTranslateEscape(value, value); /* in-place; safe & legal */
status = dbPutString(pdbentry,value);
if(status) {
- epicsPrintf("Can't set \"%s.%s\" to \"%s\"\n",
- dbGetRecordName(pdbentry), name, value);
- yyerror(NULL);
- return;
+ char msg[128];
+ errSymLookup(status, msg, sizeof(msg));
+ epicsPrintf("Can't set \"%s.%s\" to \"%s\" %s\n",
+ dbGetRecordName(pdbentry), name, value, msg);
+ yyerror(NULL);
+ return;
}
}
diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c
index 0f2a1d97e..d647f787d 100644
--- a/src/ioc/dbStatic/dbStaticLib.c
+++ b/src/ioc/dbStatic/dbStaticLib.c
@@ -234,7 +234,7 @@ void dbMsgPrint(DBENTRY *pdbentry, const char *fmt, ...)
va_end(args);
}
-static void ulongToHexString(epicsUInt32 source,char *pdest)
+static void ulongToHexString(epicsUInt32 source, char *pdest)
{
static const char hex_digit_to_ascii[16] = "0123456789abcdef";
epicsUInt32 val,temp;
@@ -1893,6 +1893,8 @@ char * dbGetString(DBENTRY *pdbentry)
case DBF_ENUM:
case DBF_LONG:
case DBF_ULONG:
+ case DBF_INT64:
+ case DBF_UINT64:
case DBF_FLOAT:
case DBF_DOUBLE:
case DBF_MENU:
@@ -2056,60 +2058,72 @@ char *dbGetStringNum(DBENTRY *pdbentry)
cvttype = pflddes->base;
switch (pflddes->field_type) {
case DBF_CHAR:
- if (cvttype==CT_DECIMAL)
- cvtCharToString(*(char*)pfield, message);
+ if (cvttype == CT_DECIMAL)
+ cvtCharToString(*(char *) pfield, message);
else
- ulongToHexString((epicsUInt32)(*(char*)pfield),message);
+ ulongToHexString(*(char *) pfield, message);
break;
case DBF_UCHAR:
if (cvttype==CT_DECIMAL)
- cvtUcharToString(*(unsigned char*)pfield, message);
+ cvtUcharToString(*(epicsUInt8 *) pfield, message);
else
- ulongToHexString((epicsUInt32)(*(unsigned char*)pfield),message);
+ ulongToHexString(*(epicsUInt8 *) pfield, message);
break;
case DBF_SHORT:
if (cvttype==CT_DECIMAL)
- cvtShortToString(*(short*)pfield, message);
+ cvtShortToString(*(epicsInt16 *) pfield, message);
else
- ulongToHexString((epicsUInt32)(*(short*)pfield),message);
+ ulongToHexString(*(epicsInt16 *) pfield, message);
break;
case DBF_USHORT:
case DBF_ENUM:
if (cvttype==CT_DECIMAL)
- cvtUshortToString(*(unsigned short*)pfield, message);
+ cvtUshortToString(*(epicsUInt16 *) pfield, message);
else
- ulongToHexString((epicsUInt32)(*(unsigned short*)pfield),message);
+ ulongToHexString(*(epicsUInt16 *) pfield, message);
break;
case DBF_LONG:
if (cvttype==CT_DECIMAL)
- cvtLongToString(*(epicsInt32*)pfield, message);
+ cvtLongToString(*(epicsInt32 *) pfield, message);
else
- ulongToHexString((epicsUInt32)(*(epicsInt32*)pfield), message);
+ ulongToHexString(*(epicsInt32 *) pfield, message);
break;
case DBF_ULONG:
if (cvttype==CT_DECIMAL)
- cvtUlongToString(*(epicsUInt32 *)pfield, message);
+ cvtUlongToString(*(epicsUInt32 *) pfield, message);
else
- ulongToHexString(*(epicsUInt32*)pfield, message);
+ ulongToHexString(*(epicsUInt32 *) pfield, message);
+ break;
+ case DBF_INT64:
+ if (cvttype==CT_DECIMAL)
+ cvtInt64ToString(*(epicsInt64 *) pfield, message);
+ else
+ cvtInt64ToHexString(*(epicsInt64 *) pfield, message);
+ break;
+ case DBF_UINT64:
+ if (cvttype==CT_DECIMAL)
+ cvtUInt64ToString(*(epicsUInt32 *) pfield, message);
+ else
+ cvtUInt64ToHexString(*(epicsUInt32 *) pfield, message);
break;
case DBF_FLOAT:
- floatToString(*(float *)pfield,message);
+ floatToString(*(epicsFloat32 *) pfield, message);
break;
case DBF_DOUBLE:
- doubleToString(*(double *)pfield,message);
+ doubleToString(*(epicsFloat64 *) pfield, message);
break;
case DBF_MENU:
{
- dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
- short choice_ind;
- char *pchoice;
+ dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
+ epicsEnum16 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)
+ choice_ind = *((epicsEnum16 *) pdbentry->pfield);
+ if (!pdbMenu || choice_ind < 0 || choice_ind >= pdbMenu->nChoice)
return NULL;
pchoice = pdbMenu->papChoiceValue[choice_ind];
dbMsgCpy(pdbentry, pchoice);
@@ -2117,9 +2131,9 @@ char *dbGetStringNum(DBENTRY *pdbentry)
break;
case DBF_DEVICE:
{
- dbDeviceMenu *pdbDeviceMenu;
- char *pchoice;
- short choice_ind;
+ dbDeviceMenu *pdbDeviceMenu;
+ epicsEnum16 choice_ind;
+ char *pchoice;
if (!pfield) {
dbMsgCpy(pdbentry, "Field not found");
@@ -2128,7 +2142,7 @@ char *dbGetStringNum(DBENTRY *pdbentry)
pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
if (!pdbDeviceMenu)
return NULL;
- choice_ind = *((short *) pdbentry->pfield);
+ choice_ind = *((epicsEnum16 *) pdbentry->pfield);
if (choice_ind<0 || choice_ind>=pdbDeviceMenu->nChoice)
return NULL;
pchoice = pdbDeviceMenu->papChoice[choice_ind];
@@ -2569,9 +2583,11 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
case DBF_CHAR:
case DBF_SHORT:
case DBF_LONG:
+ case DBF_INT64:
case DBF_UCHAR:
case DBF_USHORT:
case DBF_ULONG:
+ case DBF_UINT64:
case DBF_ENUM:
case DBF_FLOAT:
case DBF_DOUBLE:
@@ -2635,189 +2651,6 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
return(status);
}
-char * dbVerify(DBENTRY *pdbentry,const char *pstring)
-{
- dbFldDes *pflddes = pdbentry->pflddes;
- char *message;
- int stringHasMacro=FALSE;
-
- stringHasMacro = strstr(pstring,"$(") || strstr(pstring,"${");
- message = getpMessage(pdbentry);
- if(!pflddes) {strcpy(message,"fldDes not found"); return(message);}
- if(strstr(pstring,"$(") || strstr(pstring,"${")) return(NULL);
- switch (pflddes->field_type) {
- case DBF_STRING: {
- size_t length;
-
- length=strlen(pstring);
- if(length>=pflddes->size) {
- sprintf(message,"string to big. max=%hd",pflddes->size);
- return(message);
- }
- if((pflddes->special == SPC_CALC) && !stringHasMacro) {
- char rpcl[RPCL_LEN];
- short err;
- long status;
-
- status = postfix(pstring,rpcl,&err);
- if(status) {
- sprintf(message,"%s in CALC expression '%s'",
- calcErrorStr(err), pstring);
- return(message);
- }
- }
- }
- return(NULL);
- case DBF_CHAR :
- case DBF_SHORT :
- case DBF_LONG:{
- long value;
- char *endp;
-
- value = strtol(pstring,&endp,0);
- if(*endp!=0) {
- strcpy(message,"not an integer number");
- return(message);
- }
- switch (pflddes->field_type) {
- case DBF_CHAR :
- if(value<-128 || value>127) {
- strcpy(message,"must have -128<=value<=127");
- return(message);
- }
- return(NULL);
- case DBF_SHORT :
- if(value<-32768 || value>32767) {
- strcpy(message,"must have -32768<=value<=32767");
- return(message);
- }
- return(NULL);
- case DBF_LONG : return(NULL);
- default:
- errPrintf(-1,__FILE__, __LINE__,"Logic Error\n");
- return(NULL);
- }
- }
- case DBF_UCHAR:
- case DBF_USHORT:
- case DBF_ULONG:
- case DBF_ENUM:{
- unsigned long value;
- char *endp;
-
- if(strchr(pstring,'-')) {
- strcpy(message,"not an unsigned number");
- return(message);
- }
- value = strtoul(pstring,&endp,0);
- if(*endp!=0) {
- strcpy(message,"not an integer number");
- return(message);
- }
- switch (pflddes->field_type) {
- case DBF_UCHAR :
- if(value>255) {
- strcpy(message,"must have 0<=value<=255");
- return(message);
- }
- return(NULL);
- case DBF_ENUM:
- case DBF_USHORT :
- if(value>65535) {
- strcpy(message,"must have 0<=value<=65535");
- return(message);
- }
- return(NULL);
- case DBF_ULONG : return(NULL);
- default:
- errPrintf(-1,__FILE__, __LINE__,"Logic Error\n");
- return(NULL);
- }
- }
- case DBF_FLOAT:
- case DBF_DOUBLE: {
- char *endp;
-
- (void) epicsStrtod(pstring,&endp);
- if(*endp!=0) {
- strcpy(message,"not a number");
- return(message);
- }
- return(NULL);
- }
- case DBF_MENU: {
- dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
- char *pchoice;
- int i;
-
- if(!pdbMenu) return(NULL);
- for (i = 0; i < pdbMenu->nChoice; i++) {
- if(!(pchoice = pdbMenu->papChoiceValue[i])) continue;
- if(strcmp(pchoice, pstring) == 0) {
- return(NULL);
- }
- }
- }
- strcpy(message,"Not a valid menu choice");
- return (message);
- case DBF_DEVICE: {
- dbDeviceMenu *pdbDeviceMenu;
- char *pchoice;
- int i;
-
- pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
- if(!pdbDeviceMenu) return(NULL);
- if(pdbDeviceMenu->nChoice == 0) return(NULL);
- for (i = 0; i < pdbDeviceMenu->nChoice; i++) {
- if (!(pchoice = pdbDeviceMenu->papChoice[i]))
- continue;
- if (strcmp(pchoice, pstring) == 0) {
- return(NULL);
- }
- }
- }
- strcpy(message,"Not a valid menu choice");
- return (message);
- case DBF_INLINK:
- case DBF_OUTLINK:
- case DBF_FWDLINK:
- return(NULL);
- default: break;
- }
- strcpy(message,"Not a valid field type");
- return (message);
-}
-
-char *dbGetRange(DBENTRY *pdbentry)
-{
- dbFldDes *pflddes = pdbentry->pflddes;
- char *message;
-
- message = getpMessage(pdbentry);
- if(!pflddes) {strcpy(message,"fldDes not found"); return(message);}
- switch (pflddes->field_type) {
- case DBF_STRING: {strcpy(message,"STRING"); return(message);}
- case DBF_CHAR : {strcpy(message,"CHAR"); return(message);}
- case DBF_SHORT : {strcpy(message,"SHORT");return(message);}
- case DBF_LONG: {strcpy(message,"LONG"); return(message);}
- case DBF_UCHAR: {strcpy(message,"UCHAR");return(message);}
- case DBF_USHORT:{strcpy(message,"USHORT");return(message);}
- case DBF_ULONG:{strcpy(message,"ULONG:");return(message);}
- case DBF_ENUM: {strcpy(message,"ENUM");return(message);}
- case DBF_FLOAT: {strcpy(message,"FLOAT");return(message);}
- case DBF_DOUBLE: {strcpy(message,"DOUBLE");return(message);}
- case DBF_MENU: {strcpy(message,"MENU");return(message);}
- case DBF_DEVICE: {strcpy(message,"DEVICE");return(message);}
- case DBF_INLINK: {strcpy(message,"INLINK");return(message);}
- case DBF_OUTLINK: {strcpy(message,"OUTLINK");return(message);}
- case DBF_FWDLINK: {strcpy(message,"FWDLINK");return(message);}
- default:
- errPrintf(-1,__FILE__, __LINE__,"Logic Error\n");
- }
- strcpy(message,"Not a valid field type");
- return (message);
-}
-
long dbFirstInfo(DBENTRY *pdbentry)
{
dbRecordNode *precnode = pdbentry->precnode;
@@ -3270,7 +3103,7 @@ void dbDumpRecordType(DBBASE *pdbbase,const char *recordTypeName)
printf("\n");
printf("indvalFlddes %d name %s\n",pdbRecordType->indvalFlddes,
pdbRecordType->pvalFldDes->name);
- printf("struct rset * %p rec_size %d\n",
+ printf("rset * %p rec_size %d\n",
(void *)pdbRecordType->prset,pdbRecordType->rec_size);
if(recordTypeName) break;
}
diff --git a/src/ioc/dbStatic/dbStaticLib.h b/src/ioc/dbStatic/dbStaticLib.h
index 84ef94aef..15fc45f8d 100644
--- a/src/ioc/dbStatic/dbStaticLib.h
+++ b/src/ioc/dbStatic/dbStaticLib.h
@@ -263,6 +263,7 @@ epicsShareFunc void dbCatString(char **string, int *stringLength,
char *pnew, char *separator);
extern int dbStaticDebug;
+extern int dbConvertStrict;
#define S_dbLib_recordTypeNotFound (M_dbLib|1) /* Record Type does not exist */
#define S_dbLib_recExists (M_dbLib|3) /* Record Already exists */
diff --git a/src/ioc/dbStatic/dbStaticRun.c b/src/ioc/dbStatic/dbStaticRun.c
index 26bfa01d8..efc672270 100644
--- a/src/ioc/dbStatic/dbStaticRun.c
+++ b/src/ioc/dbStatic/dbStaticRun.c
@@ -23,7 +23,7 @@
#include "epicsTypes.h"
#include "errMdef.h"
-#define epicsExportSharedSymbols
+#include "epicsExport.h" /* #define epicsExportSharedSymbols */
#include "dbBase.h"
#include "dbCommonPvt.h"
#include "dbStaticLib.h"
@@ -31,6 +31,9 @@
#include "devSup.h"
#include "special.h"
+epicsShareDef int dbConvertStrict = 0;
+epicsExportAddress(int, dbConvertStrict);
+
static long do_nothing(struct dbCommon *precord) { return 0; }
/* Dummy DSXT used for soft device supports */
@@ -128,6 +131,8 @@ long dbAllocRecord(DBENTRY *pdbentry,const char *precordName)
case DBF_USHORT:
case DBF_LONG:
case DBF_ULONG:
+ case DBF_INT64:
+ case DBF_UINT64:
case DBF_FLOAT:
case DBF_DOUBLE:
case DBF_ENUM:
@@ -213,277 +218,341 @@ int dbIsMacroOk(DBENTRY *pdbentry) { return(FALSE); }
epicsShareFunc int dbIsDefaultValue(DBENTRY *pdbentry)
{
- dbFldDes *pflddes = pdbentry->pflddes;
- void *pfield = pdbentry->pfield;
+ dbFldDes *pflddes = pdbentry->pflddes;
+ void *pfield = pdbentry->pfield;
+
+ if (!pflddes || !pfield)
+ return FALSE;
- if(!pflddes) return(FALSE);
- if(!pfield) return(FALSE);
switch (pflddes->field_type) {
- case (DBF_STRING) : {
- char *p = (char *)pfield;
-
- if(!pflddes->initial) return((strlen(p)==0) ? TRUE : FALSE);
- return((strcmp(pflddes->initial,p)==0) ? TRUE : FALSE);
- }
- case DBF_CHAR: {
- char field = *(char *)pfield;
- long ltemp;
- if(pflddes->initial) {
- ltemp = strtol(pflddes->initial,NULL,0);
- return((field==ltemp));
- }
- return((field==0));
- }
- case DBF_UCHAR: {
- unsigned char field = *(unsigned char *)pfield;
- unsigned long ltemp;
+ case DBF_STRING: {
+ char *p = (char *)pfield;
- if(pflddes->initial) {
- ltemp = strtoul(pflddes->initial,NULL,0);
- return((field==ltemp));
- }
- return((field==0));
- }
- case DBF_SHORT: {
- short field = *(short *)pfield;
- long ltemp;
+ return pflddes->initial ? ! strcmp(pflddes->initial, p)
+ : ! strlen(p);
+ }
+ case DBF_CHAR: {
+ epicsInt8 field = *(epicsInt8 *)pfield;
+ epicsInt8 def;
- if(pflddes->initial) {
- ltemp = strtol(pflddes->initial,NULL,0);
- return((field==ltemp));
- }
- return((field==0));
- }
- case DBF_USHORT: {
- unsigned short field = *(unsigned short *)pfield;
- unsigned long ltemp;
+ if (!pflddes->initial)
+ return field == 0;
- if(pflddes->initial) {
- ltemp = strtoul(pflddes->initial,NULL,0);
- return((field==ltemp));
- }
- return((field==0));
- }
- case DBF_LONG: {
- long field = *(long *)pfield;
- long ltemp;
+ return ! epicsParseInt8(pflddes->initial, &def, 0, NULL)
+ && field == def;
+ }
+ case DBF_UCHAR: {
+ epicsUInt8 field = *(epicsUInt8 *)pfield;
+ epicsUInt8 def;
- if(pflddes->initial) {
- ltemp = strtol(pflddes->initial,NULL,0);
- return((field==ltemp));
- }
- return((field==0));
- }
- case DBF_ULONG: {
- unsigned long field = *(unsigned long *)pfield;
- unsigned long ltemp;
+ if (!pflddes->initial)
+ return field == 0;
- if(pflddes->initial) {
- ltemp = strtoul(pflddes->initial,NULL,0);
- return((field==ltemp));
- }
- return((field==0));
- }
- case DBF_FLOAT: {
- float field = *(float *)pfield;
- double dtemp;
+ return ! epicsParseUInt8(pflddes->initial, &def, 0, NULL)
+ && field == def;
+ }
+ case DBF_SHORT: {
+ epicsInt16 field = *(epicsInt16 *)pfield;
+ epicsInt16 def;
- if(pflddes->initial) {
- dtemp = epicsStrtod(pflddes->initial,NULL);
- return((field==dtemp));
- }
- return((field==0.0));
- }
- case DBF_DOUBLE: {
- double field = *(double *)pfield;
- double dtemp;
+ if (!pflddes->initial)
+ return field == 0;
- if(pflddes->initial) {
- dtemp = epicsStrtod(pflddes->initial,NULL);
- return((field==dtemp));
- }
- return((field==0.0));
- }
- case DBF_ENUM: {
- unsigned short field = *(unsigned short *)pfield;
- unsigned long ltemp;
+ return ! epicsParseInt16(pflddes->initial, &def, 0, NULL)
+ && field == def;
+ }
+ case DBF_ENUM:
+ case DBF_USHORT: {
+ epicsUInt16 field = *(epicsUInt16 *)pfield;
+ epicsUInt16 def;
- if(pflddes->initial) {
- ltemp = strtoul(pflddes->initial,NULL,0);
- return((field==ltemp));
- }
- return((field==0));
- }
- case DBF_MENU: {
- unsigned short field = *(unsigned short *)pfield;
- long value;
- char *endp;
+ if (!pflddes->initial)
+ return field == 0;
- if(pflddes->initial) {
- value = dbGetMenuIndexFromString(pdbentry,pflddes->initial);
- if(value==-1) {
- value = strtol(pflddes->initial,&endp,0);
- if(*endp!='\0') return(FALSE);
- }
- } else {
- value = 0;
- }
- if((unsigned short)value == field) return(TRUE);
- return(FALSE);
- }
- case DBF_DEVICE: {
- dbRecordType *precordType = pdbentry->precordType;
+ return ! epicsParseUInt16(pflddes->initial, &def, 0, NULL)
+ && field == def;
+ }
+ case DBF_LONG: {
+ epicsInt32 field = *(epicsInt32 *)pfield;
+ epicsInt32 def;
- if(!precordType) {
- epicsPrintf("dbIsDefaultValue: pdbRecordType is NULL??\n");
- return(FALSE);
- }
- if(ellCount(&precordType->devList)==0) return(TRUE);
- return(FALSE);
- }
- case DBF_INLINK:
- case DBF_OUTLINK:
- case DBF_FWDLINK: {
- struct link *plink = (struct link *)pfield;
+ if (!pflddes->initial)
+ return field == 0;
- if(!plink) return(FALSE);
- if(plink->type!=CONSTANT) return(FALSE);
- if(plink->value.constantStr == 0) return(TRUE);
- if(!pflddes->initial) return(FALSE);
- if(strcmp(plink->value.constantStr,pflddes->initial)==0)
- return(TRUE);
- return(FALSE);
- }
- default:
- return(TRUE);
+ return ! epicsParseInt32(pflddes->initial, &def, 0, NULL)
+ && field == def;
+ }
+ case DBF_ULONG: {
+ epicsUInt32 field = *(epicsUInt32 *)pfield;
+ epicsUInt32 def;
+
+ if (!pflddes->initial)
+ return field == 0;
+
+ return ! epicsParseUInt32(pflddes->initial, &def, 0, NULL)
+ && field == def;
+ }
+ case DBF_INT64: {
+ epicsInt64 field = *(epicsInt64 *)pfield;
+ epicsInt64 def;
+
+ if (!pflddes->initial)
+ return field == 0;
+
+ return ! epicsParseInt64(pflddes->initial, &def, 0, NULL)
+ && field == def;
+ }
+ case DBF_UINT64: {
+ epicsUInt64 field = *(epicsUInt64 *)pfield;
+ epicsUInt64 def;
+
+ if (!pflddes->initial)
+ return field == 0;
+
+ return ! epicsParseUInt64(pflddes->initial, &def, 0, NULL)
+ && field == def;
+ }
+ case DBF_FLOAT: {
+ epicsFloat32 field = *(epicsFloat32 *)pfield;
+ epicsFloat32 def;
+
+ if (!pflddes->initial)
+ return field == 0;
+
+ return ! epicsParseFloat32(pflddes->initial, &def, NULL)
+ && field == def;
+ }
+ case DBF_DOUBLE: {
+ epicsFloat64 field = *(epicsFloat64 *)pfield;
+ epicsFloat64 def;
+
+ if (!pflddes->initial)
+ return field == 0;
+
+ return ! epicsParseFloat64(pflddes->initial, &def, NULL)
+ && field == def;
+ }
+ case DBF_MENU: {
+ epicsEnum16 field = *(epicsEnum16 *)pfield;
+ epicsEnum16 def;
+ int index;
+
+ if (!pflddes->initial)
+ return field == 0;
+
+ index = dbGetMenuIndexFromString(pdbentry, pflddes->initial);
+ if (index < 0) {
+ if (epicsParseUInt16(pflddes->initial, &def, 0, NULL))
+ return FALSE;
+ }
+ else
+ def = index;
+ return field == def;
+ }
+ case DBF_DEVICE: {
+ dbRecordType *precordType = pdbentry->precordType;
+
+ if (!precordType) {
+ epicsPrintf("dbIsDefaultValue: pdbRecordType is NULL??\n");
+ return FALSE;
+ }
+ return ellCount(&precordType->devList) == 0;
+ }
+ case DBF_INLINK:
+ case DBF_OUTLINK:
+ case DBF_FWDLINK: {
+ struct link *plink = (struct link *)pfield;
+
+ if (!plink || plink->type != CONSTANT)
+ return FALSE;
+
+ /* These conditions don't make a lot of sense... */
+ if (!plink->value.constantStr)
+ return TRUE;
+
+ if (!pflddes->initial) /* Default value for a link field? */
+ return FALSE;
+
+ return !strcmp(plink->value.constantStr, pflddes->initial);
+ }
+ default:
+ return TRUE;
}
- return(FALSE);
}
-long dbPutStringNum(DBENTRY *pdbentry,const char *pstring)
+long dbPutStringNum(DBENTRY *pdbentry, const char *pstring)
{
- dbFldDes *pflddes = pdbentry->pflddes;
- void *pfield = pdbentry->pfield;
- long status=0;
+ dbFldDes *pflddes = pdbentry->pflddes;
+ void *pfield = pdbentry->pfield;
+ long status;
+ epicsUInt64 u64;
+ epicsInt64 i64;
+
+ if (!pfield)
+ return S_dbLib_fieldNotFound;
+
+ /* empty string is the same as writing numeric zero */
+ if (pstring[0] == '\0')
+ pstring = "0";
- if(!pfield) return(S_dbLib_fieldNotFound);
switch (pflddes->field_type) {
- case DBF_CHAR :
- case DBF_SHORT :
- case DBF_LONG:{
- long value;
- char *endp;
+ case DBF_CHAR:
+ if (dbConvertStrict)
+ return epicsParseInt8(pstring, pfield, 0, NULL);
+ goto lax_signed;
+
+ case DBF_SHORT:
+ if (dbConvertStrict)
+ return epicsParseInt16(pstring, pfield, 0, NULL);
+ goto lax_signed;
+
+ case DBF_LONG:
+ if (dbConvertStrict)
+ return epicsParseInt32(pstring, pfield, 0, NULL);
+ goto lax_signed;
+
+ case DBF_INT64:
+ if (dbConvertStrict)
+ return epicsParseInt64(pstring, pfield, 0, NULL);
+
+ lax_signed:
+ status = epicsParseInt64(pstring, &i64, 0, NULL);
+ if (status)
+ return status;
+
+ switch (pflddes->field_type) {
+ case DBF_CHAR: *(epicsInt8 *)pfield = (epicsInt8) i64; break;
+ case DBF_SHORT: *(epicsInt16*)pfield = (epicsInt16)i64; break;
+ case DBF_LONG: *(epicsInt32*)pfield = (epicsInt32)i64; break;
+ case DBF_INT64: *(epicsInt64*)pfield = (epicsInt64)i64; break;
+ default: break;
+ }
+ return status;
- value = strtol(pstring,&endp,0);
- if(*endp!=0) status = S_dbLib_badField;
- switch (pflddes->field_type) {
- case DBF_CHAR : *(char *)pfield = (char)value; break;
- case DBF_SHORT : *(short *)pfield = (short)value; break;
- case DBF_LONG : *(epicsInt32 *)pfield = (epicsInt32)value; break;
- default: epicsPrintf("Logic error in dbPutStringNum\n");
- }
- }
- break;
case DBF_UCHAR:
+ if (dbConvertStrict)
+ return epicsParseUInt8(pstring, pfield, 0, NULL);
+ goto lax_unsigned;
+
+ case DBF_ENUM:
case DBF_USHORT:
+ if (dbConvertStrict)
+ return epicsParseUInt16(pstring, pfield, 0, NULL);
+ goto lax_unsigned;
+
case DBF_ULONG:
- case DBF_ENUM:{
- unsigned long value;
- char *endp;
+ if (dbConvertStrict)
+ return epicsParseUInt32(pstring, pfield, 0, NULL);
+ goto lax_unsigned;
+
+ case DBF_UINT64:
+ if (dbConvertStrict)
+ return epicsParseUInt64(pstring, pfield, 0, NULL);
+
+ lax_unsigned:
+ status = epicsParseUInt64(pstring, &u64, 0, NULL);
+ if (status)
+ return status;
+
+ switch (pflddes->field_type) {
+ case DBF_UCHAR: *(epicsUInt8 *)pfield = (epicsInt8) u64; break;
+ case DBF_ENUM:
+ case DBF_USHORT: *(epicsUInt16*)pfield = (epicsInt16)u64; break;
+ case DBF_ULONG: *(epicsUInt32*)pfield = (epicsInt32)u64; break;
+ case DBF_UINT64: *(epicsUInt64*)pfield = (epicsInt64)u64; break;
+ default: break;
+ }
+ return status;
- value = strtoul(pstring,&endp,0);
- if(*endp!=0) status = S_dbLib_badField;
- switch (pflddes->field_type) {
- case DBF_UCHAR : *(unsigned char *)pfield = (unsigned char)value; break;
- case DBF_USHORT:
- case DBF_ENUM: *(unsigned short *)pfield = (unsigned short)value; break;
- case DBF_ULONG : *(epicsUInt32 *)pfield = (epicsUInt32)value; break;
- default: epicsPrintf("Logic error in dbPutStringNum\n");
- }
- }
- break;
case DBF_FLOAT:
- case DBF_DOUBLE: {
- double value;
- char *endp;
+ return epicsParseFloat32(pstring, pfield, NULL);
+
+ case DBF_DOUBLE:
+ return epicsParseFloat64(pstring, pfield, NULL);
- value = epicsStrtod(pstring,&endp);
- if(*endp!=0) status = S_dbLib_badField;
- if(pflddes->field_type == DBF_FLOAT)
- *(float *)pfield = (float)value;
- else
- *(double *)pfield = value;
- }
- break;
case DBF_MENU:
- case DBF_DEVICE: {/*Must allow value that is choice or index*/
- unsigned short *field= (unsigned short*)pfield;
- int ind;
- long value;
- char *endp;
+ case DBF_DEVICE: {
+ epicsEnum16 *field = (epicsEnum16 *) pfield;
+ int index = dbGetMenuIndexFromString(pdbentry, pstring);
+
+ if (index < 0) {
+ epicsEnum16 value;
+ long status = epicsParseUInt16(pstring, &value, 0, NULL);
+
+ if (status)
+ return status;
+
+ index = dbGetNMenuChoices(pdbentry);
+ if (value > index && index > 0)
+ return S_dbLib_badField;
+
+ *field = value;
+ }
+ else
+ *field = index;
+ return 0;
+ }
- ind = dbGetMenuIndexFromString(pdbentry,pstring);
- if(ind==-1) {
- value = strtol(pstring,&endp,0);
- if(*endp!='\0') return(S_dbLib_badField);
- ind = value;
- /*Check that ind is withing range*/
- if(!dbGetMenuStringFromIndex(pdbentry,ind))
- return(S_dbLib_badField);
- }
- *field = (unsigned short)ind;
- }
- return (0);
default:
- return (S_dbLib_badField);
+ return S_dbLib_badField;
}
- return(status);
}
-
+
epicsShareFunc int dbGetMenuIndex(DBENTRY *pdbentry)
{
- dbFldDes *pflddes = pdbentry->pflddes;
- void *pfield = pdbentry->pfield;
+ dbFldDes *pflddes = pdbentry->pflddes;
+ void *pfield = pdbentry->pfield;
+
+ if (!pflddes || !pfield)
+ return -1;
- if(!pflddes) return(-1);
- if(!pfield) return(-1);
switch (pflddes->field_type) {
- case (DBF_MENU):
- case (DBF_DEVICE):
- return((int)(*(unsigned short *)pfield));
- default:
- errPrintf(-1,__FILE__, __LINE__,"Logic Error\n");
+ case DBF_MENU:
+ case DBF_DEVICE:
+ return * (epicsEnum16 *) pfield;
+ default:
+ epicsPrintf("dbGetMenuIndex: Called for field type %d\n",
+ pflddes->field_type);
}
- return(-1);
+ return -1;
}
-
-epicsShareFunc long dbPutMenuIndex(DBENTRY *pdbentry,int index)
-{
- dbFldDes *pflddes = pdbentry->pflddes;
- unsigned short *pfield = pdbentry->pfield;
- if(!pflddes) return(S_dbLib_flddesNotFound);
- if(!pfield) return(S_dbLib_fieldNotFound);
+epicsShareFunc long dbPutMenuIndex(DBENTRY *pdbentry, int index)
+{
+ dbFldDes *pflddes = pdbentry->pflddes;
+ epicsEnum16 *pfield = pdbentry->pfield;
+
+ if (!pflddes)
+ return S_dbLib_flddesNotFound;
+ if (!pfield)
+ return S_dbLib_fieldNotFound;
+
switch (pflddes->field_type) {
case DBF_MENU: {
- dbMenu *pdbMenu = (dbMenu *)pflddes->ftPvt;
+ dbMenu *pdbMenu = (dbMenu *) pflddes->ftPvt;
- if(!pdbMenu) return(S_dbLib_menuNotFound);
- if(index<0 || index>=pdbMenu->nChoice) return(S_dbLib_badField);
- *pfield = (unsigned short)index;
- return(0);
- }
- case DBF_DEVICE: {
- dbDeviceMenu *pdbDeviceMenu;
+ if (!pdbMenu)
+ return S_dbLib_menuNotFound;
+ if (index < 0 || index >= pdbMenu->nChoice)
+ return S_dbLib_badField;
- pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
- if(!pdbDeviceMenu) return(S_dbLib_menuNotFound);
- if(index<0 || index>=pdbDeviceMenu->nChoice)
- return(S_dbLib_badField);
- return(dbPutString(pdbentry,pdbDeviceMenu->papChoice[index]));
- }
- default:
- break;
+ *pfield = index;
+ return 0;
}
- return (S_dbLib_badField);
+
+ case DBF_DEVICE: {
+ dbDeviceMenu *pdbDeviceMenu = dbGetDeviceMenu(pdbentry);
+
+ if (!pdbDeviceMenu)
+ return S_dbLib_menuNotFound;
+ if (index < 0 || index >= pdbDeviceMenu->nChoice)
+ return S_dbLib_badField;
+
+ return dbPutString(pdbentry, pdbDeviceMenu->papChoice[index]);
+ }
+
+ default:
+ break;
+ }
+ return S_dbLib_badField;
}
diff --git a/src/ioc/misc/dbCore.dbd b/src/ioc/misc/dbCore.dbd
index a2ce45806..7349994f7 100644
--- a/src/ioc/misc/dbCore.dbd
+++ b/src/ioc/misc/dbCore.dbd
@@ -14,6 +14,7 @@ variable(dbRecordsOnceOnly,int)
variable(dbRecordsAbcSorted,int)
variable(dbBptNotMonotonic,int)
variable(dbQuietMacroWarnings,int)
+variable(dbConvertStrict,int)
# dbLoadTemplate settings
variable(dbTemplateMaxVars,int)
diff --git a/src/libCom/cvtFast/cvtFast.c b/src/libCom/cvtFast/cvtFast.c
index 2f29dd51f..4e04b4515 100644
--- a/src/libCom/cvtFast/cvtFast.c
+++ b/src/libCom/cvtFast/cvtFast.c
@@ -1,73 +1,69 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
\*************************************************************************/
-/* Very efficient routines to convert numbers to strings
- * Author: Bob Dalesio wrote cvtFloatToString (called FF_TO_STR)
- * Code is same for cvtDoubleToString
- * Marty Kraimer wrote cvtCharToString,cvtUcharToString
- * cvtShortToString,cvtUshortToString,
- * cvtLongToString, and cvtUlongToString
- * Mark Anderson wrote cvtLongToHexString, cvtLongToOctalString,
- * adopted cvt[Float/Double]ExpString and
- * cvt[Float/Double]CompactString from fToEStr
- * and fixed calls to gcvt
- *
- * Date: 12 January 1993
+/* Fast numeric to string conversions
*
+ * Original Authors:
+ * Bob Dalesio, Mark Anderson and Marty Kraimer
+ * Date: 12 January 1993
*/
-#include
-#include
-#include
-#include /* XPG2/XPG3/POSIX.1/FIPS151-1/ANSI-C */
+#include
+#include
#define epicsExportSharedSymbols
#include "cvtFast.h"
#include "epicsMath.h"
-
-/*
- * This routine converts numbers less than 10,000,000. It defers to f_to_str for
- * numbers requiring more than 8 places of precision. There are only eight decimal
- */
-static epicsInt32 frac_multiplier[] =
- {1,10,100,1000,10000,100000,1000000,10000000,100000000};
+#include "epicsStdio.h"
-int epicsShareAPI cvtFloatToString(
- float flt_value,
- char *pstr_value,
- unsigned short precision)
+/*
+ * These routines convert numbers up to +/- 10,000,000.
+ * They defer to sprintf() for numbers requiring more than
+ * 8 places of precision.
+ */
+static epicsInt32 frac_multiplier[] =
+ {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000};
+
+int cvtFloatToString(float flt_value, char *pdest,
+ epicsUInt16 precision)
{
- unsigned short got_one,i;
- epicsInt32 whole,iplace,number,fraction,fplace;
+ int got_one, i;
+ epicsInt32 whole, iplace, number, fraction, fplace;
float ftemp;
char *startAddr;
/* can this routine handle this conversion */
- if (isnan(flt_value) || precision > 8 || flt_value > 10000000.0 || flt_value < -10000000.0) {
- sprintf(pstr_value,"%12.5e",(double)flt_value);
- return((int)strlen(pstr_value));
+ if (isnan(flt_value) || precision > 8 ||
+ flt_value > 10000000.0 || flt_value < -10000000.0) {
+ if (precision > 8 || flt_value >= 1e8 || flt_value <= -1e8) {
+ if (precision > 12) precision = 12; /* FIXME */
+ sprintf(pdest, "%*.*e", precision+6, precision, (double) flt_value);
+ } else {
+ if (precision > 3) precision = 3; /* FIXME */
+ sprintf(pdest, "%.*f", precision, (double) flt_value);
+ }
+ return((int)strlen(pdest));
}
- startAddr = pstr_value;
+ startAddr = pdest;
/* determine the sign */
if (flt_value < 0){
- *pstr_value++ = '-';
+ *pdest++ = '-';
flt_value = -flt_value;
};
- /* remove the whole number portion */
+ /* remove the whole number portion */
whole = (epicsInt32)flt_value;
ftemp = flt_value - whole;
/* multiplier to convert fractional portion to integer */
fplace = frac_multiplier[precision];
- fraction = (epicsInt32)(ftemp * fplace * 10);
+ fraction = (epicsInt32)(ftemp * fplace * 10);
fraction = (fraction + 5) / 10; /* round up */
/* determine rounding into the whole number portion */
@@ -83,41 +79,41 @@ int epicsShareAPI cvtFloatToString(
got_one = 1;
number = whole / iplace;
whole = whole - (number * iplace);
- *pstr_value = number + '0';
- pstr_value++;
+ *pdest = number + '0';
+ pdest++;
}else if (got_one){
- *pstr_value = '0';
- pstr_value++;
+ *pdest = '0';
+ pdest++;
}
}
if (!got_one){
- *pstr_value = '0';
- pstr_value++;
+ *pdest = '0';
+ pdest++;
}
/* fraction */
if (precision > 0){
/* convert fractional portional to ASCII */
- *pstr_value = '.';
- pstr_value++;
+ *pdest = '.';
+ pdest++;
for (fplace /= 10, i = precision; i > 0; fplace /= 10,i--){
number = fraction / fplace;
fraction -= number * fplace;
- *pstr_value = number + '0';
- pstr_value++;
+ *pdest = number + '0';
+ pdest++;
}
}
- *pstr_value = 0;
+ *pdest = 0;
- return((int)(pstr_value - startAddr));
+ return((int)(pdest - startAddr));
}
-
-int epicsShareAPI cvtDoubleToString(
+
+int cvtDoubleToString(
double flt_value,
- char *pstr_value,
- unsigned short precision)
+ char *pdest,
+ epicsUInt16 precision)
{
- unsigned short got_one,i;
+ epicsUInt16 got_one,i;
epicsInt32 whole,iplace,number,fraction,fplace;
double ftemp;
char *startAddr;
@@ -126,23 +122,23 @@ int epicsShareAPI cvtDoubleToString(
if (isnan(flt_value) || precision > 8 || flt_value > 10000000.0 || flt_value < -10000000.0) {
if (precision > 8 || flt_value > 1e16 || flt_value < -1e16) {
if(precision>17) precision=17;
- sprintf(pstr_value,"%*.*e",precision+7,precision,
+ sprintf(pdest,"%*.*e",precision+7,precision,
flt_value);
} else {
if(precision>3) precision=3;
- sprintf(pstr_value,"%.*f",precision,flt_value);
+ sprintf(pdest,"%.*f",precision,flt_value);
}
- return((int)strlen(pstr_value));
+ return((int)strlen(pdest));
}
- startAddr = pstr_value;
+ startAddr = pdest;
/* determine the sign */
if (flt_value < 0){
- *pstr_value++ = '-';
+ *pdest++ = '-';
flt_value = -flt_value;
};
- /* remove the whole number portion */
+ /* remove the whole number portion */
whole = (epicsInt32)flt_value;
ftemp = flt_value - whole;
@@ -164,432 +160,364 @@ int epicsShareAPI cvtDoubleToString(
got_one = 1;
number = whole / iplace;
whole = whole - (number * iplace);
- *pstr_value = number + '0';
- pstr_value++;
+ *pdest = number + '0';
+ pdest++;
}else if (got_one){
- *pstr_value = '0';
- pstr_value++;
+ *pdest = '0';
+ pdest++;
}
}
if (!got_one){
- *pstr_value = '0';
- pstr_value++;
+ *pdest = '0';
+ pdest++;
}
/* fraction */
if (precision > 0){
/* convert fractional portional to ASCII */
- *pstr_value = '.';
- pstr_value++;
+ *pdest = '.';
+ pdest++;
for (fplace /= 10, i = precision; i > 0; fplace /= 10,i--){
number = fraction / fplace;
fraction -= number * fplace;
- *pstr_value = number + '0';
- pstr_value++;
+ *pdest = number + '0';
+ pdest++;
}
}
- *pstr_value = 0;
+ *pdest = 0;
- return((int)(pstr_value - startAddr));
+ return((int)(pdest - startAddr));
}
+/*
+ * These routines are provided for backwards compatibility,
+ * extensions such as MEDM, edm and histtool use them.
+ */
+
/*
* cvtFloatToExpString
*
- * converts floating point numbers to E-format NULL terminated strings
+ * Converts a float to a %e formatted string
*/
-int epicsShareAPI cvtFloatToExpString(
- float f_value,
- char *pstr_value,
- unsigned short f_precision)
+int cvtFloatToExpString(float val, char *pdest, epicsUInt16 precision)
{
- /*sunos uses char*sprint as function prototype*/
- sprintf(pstr_value,"%.*e",(int)f_precision,(double)f_value);
- return((int)strlen(pstr_value));
+ return epicsSnprintf(pdest, MAX_STRING_SIZE, "%.*e", precision, val);
}
/*
* cvtFloatToCompactString
*
- * Converts floating point numbers to %g format NULL terminated strings,
- * resulting in the most "compact" expression of the value
- * ("f" notation if 10-4 < |value| < 10+4, otherwise "e" notation)
+ * Converts a float to a %g formatted string.
+ * The result uses %f notation for 10e-4 < |value| < 10e+4,
+ * otherwise %e notation.
*/
-int epicsShareAPI cvtFloatToCompactString(
- float f_value,
- char *pstr_value,
- unsigned short f_precision )
+int cvtFloatToCompactString(float val, char *pdest, epicsUInt16 precision)
{
- if ((f_value < 1.e4 && f_value > 1.e-4) ||
- (f_value > -1.e4 && f_value < -1.e-4) || f_value == 0.0) {
- return(cvtFloatToString(f_value,pstr_value,f_precision));
- } else {
- return(cvtFloatToExpString(f_value,pstr_value,f_precision));
- }
-}
+ if ((val < 1.e4 && val > 1.e-4) ||
+ (val > -1.e4 && val < -1.e-4) ||
+ val == 0.0)
+ return cvtFloatToString(val, pdest, precision);
+ return cvtFloatToExpString(val, pdest, precision);
+}
/*
* cvtDoubleToExpString
*
- * converts double precision floating point numbers to E-format NULL
- * terminated strings
+ * Converts a double to a %e formatted string
*/
-int epicsShareAPI cvtDoubleToExpString(
- double f_value,
- char *pstr_value,
- unsigned short f_precision )
+int cvtDoubleToExpString(double val, char *pdest, epicsUInt16 precision)
{
- sprintf(pstr_value,"%.*e",(int)f_precision,f_value);
- return((int)strlen(pstr_value));
+ return epicsSnprintf(pdest, MAX_STRING_SIZE, "%.*e", precision, val);
}
/*
* cvtDoubleToCompactString
*
- * Converts double precision floating point numbers to %g format NULL
- * terminated strings, resulting in the most "compact" expression
- * of the value ("f" notation if 10-4 < |value| < 10+4, otherwise
- * "e" notation)
+ * Converts a double to %g formatted string.
+ * The result uses %f notation for 10e-4 < |value| < 10e+4,
+ * otherwise %e notation.
*/
-int epicsShareAPI cvtDoubleToCompactString(
- double f_value,
- char *pstr_value,
- unsigned short f_precision )
+int cvtDoubleToCompactString(double val, char *pdest, epicsUInt16 precision)
{
- if ((f_value < 1.e4 && f_value > 1.e-4) ||
- (f_value > -1.e4 && f_value < -1.e-4) || f_value == 0.0) {
- return(cvtDoubleToString(f_value,pstr_value,f_precision));
- } else {
- return(cvtDoubleToExpString(f_value,pstr_value,f_precision));
- }
+ if ((val < 1.e4 && val > 1.e-4) ||
+ (val > -1.e4 && val < -1.e-4) ||
+ val == 0.0)
+ return cvtDoubleToString(val, pdest, precision);
+
+ return cvtDoubleToExpString(val, pdest, precision);
}
-
-/* Convert various integer types to ascii */
-static char digit_to_ascii[10]={'0','1','2','3','4','5','6','7','8','9'};
-int epicsShareAPI cvtCharToString(
- signed char source,
- char *pdest)
+/* Integer conversion primitives */
+
+static size_t
+ UInt32ToDec(epicsUInt32 val, char *pdest)
{
- unsigned char val,temp;
- char digit[3];
- int i,j;
- char *startAddr = pdest;
+ int i;
+ char digit[10];
+ size_t len;
- if(source==0) {
- *pdest++ = '0';
- *pdest = 0;
- return((int)(pdest-startAddr));
- }
- if(source<0) {
- if(source == CHAR_MIN) {
- sprintf(pdest,"%d",CHAR_MIN);
- return((int)strlen(pdest));
- }
- *pdest++ = '-';
- source = -source;
- }
- val = source;
- for(i=0; val!=0; i++) {
- temp = val/10;
- digit[i] = digit_to_ascii[val - temp*10];
- val = temp;
- }
- for(j=i-1; j>=0; j--) {
- *pdest++ = digit[j];
+ for (i = 0; val; i++) {
+ epicsUInt32 tenth = val / 10;
+
+ digit[i] = val - tenth * 10 + '0';
+ val = tenth;
}
+ len = i;
+
+ while (i > 0)
+ *pdest++ = digit[--i];
+
*pdest = 0;
- return((int)(pdest-startAddr));
+ return len;
}
-
-int epicsShareAPI cvtUcharToString(
- unsigned char source,
- char *pdest)
+static size_t
+ UInt32ToBase(epicsUInt32 val, char *pdest, int base)
{
- unsigned char val,temp;
- char digit[3];
- int i,j;
- char *startAddr = pdest;
+ int i;
+ char digit, digits[32];
+ size_t len;
- if(source==0) {
- *pdest++ = '0';
- *pdest = 0;
- return((int)(pdest-startAddr));
- }
- val = source;
- for(i=0; val!=0; i++) {
- temp = val/10;
- digit[i] = digit_to_ascii[val - temp*10];
- val = temp;
- }
- for(j=i-1; j>=0; j--) {
- *pdest++ = digit[j];
+ for (i = 0; val; i++) {
+ epicsUInt32 tenth = val / base;
+
+ digit = val - tenth * base;
+ digits[i] = digit < 10 ? digit + '0' : digit - 10 + 'a';
+ val = tenth;
}
+ len = i;
+
+ while (i > 0)
+ *pdest++ = digits[--i];
+
*pdest = 0;
- return((int)(pdest-startAddr));
+ return len;
}
-
-int epicsShareAPI cvtShortToString(
- short source,
- char *pdest)
+static size_t
+ UInt64ToDec(epicsUInt64 val, char *pdest)
{
- short val,temp;
- char digit[6];
- int i,j;
- char *startAddr = pdest;
+ int i;
+ char digit[20];
+ size_t len;
- if(source==0) {
- *pdest++ = '0';
- *pdest = 0;
- return((int)(pdest-startAddr));
- }
- if(source<0) {
- if(source == SHRT_MIN) {
- sprintf(pdest,"%d",SHRT_MIN);
- return((int)(strlen(pdest)));
- }
- *pdest++ = '-';
- source = -source;
- }
- val = source;
- for(i=0; val!=0; i++) {
- temp = val/10;
- digit[i] = digit_to_ascii[val - temp*10];
- val = temp;
- }
- for(j=i-1; j>=0; j--) {
- *pdest++ = digit[j];
+ for (i = 0; val; i++) {
+ epicsUInt64 tenth = val / 10;
+
+ digit[i] = val - tenth * 10 + '0';
+ val = tenth;
}
+
+ len = i;
+ while (i > 0)
+ *pdest++ = digit[--i];
+
*pdest = 0;
- return((int)(pdest-startAddr));
+ return len;
}
-
-int epicsShareAPI cvtUshortToString(
- unsigned short source,
- char *pdest)
+static size_t
+ UInt64ToBase(epicsUInt64 val, char *pdest, int base)
{
- unsigned short val,temp;
- char digit[5];
- int i,j;
- char *startAddr = pdest;
+ int i;
+ char digit, digits[64];
+ size_t len;
- if(source==0) {
- *pdest++ = '0';
- *pdest = 0;
- return((int)(pdest-startAddr));
- }
- val = source;
- for(i=0; val!=0; i++) {
- temp = val/10;
- digit[i] = digit_to_ascii[val - temp*10];
- val = temp;
- }
- for(j=i-1; j>=0; j--) {
- *pdest++ = digit[j];
+ for (i = 0; val; i++) {
+ epicsUInt64 tenth = val / base;
+
+ digit = val - tenth * base;
+ digits[i] = digit < 10 ? digit + '0' : digit - 10 + 'a';
+ val = tenth;
}
+ len = i;
+
+ while (i > 0)
+ *pdest++ = digits[--i];
+
*pdest = 0;
- return((int)(pdest-startAddr));
+ return len;
}
-int epicsShareAPI cvtLongToString(
- epicsInt32 source,
- char *pdest)
-{
- epicsInt32 val,temp;
- char digit[11];
- int i,j;
- char *startAddr = pdest;
+/* Integer conversion routines */
- if(source==0) {
- *pdest++ = '0';
- *pdest = 0;
- return((int)(pdest-startAddr));
+size_t
+ cvtUInt32ToString(epicsUInt32 val, char *pdest)
+{
+ if (val == 0) {
+ *pdest++ = '0';
+ *pdest = 0;
+ return 1;
}
- if(source<0) {
- if(source == INT_MIN) {
- sprintf(pdest,"%d",source);
- return((int)strlen(pdest));
- }
- *pdest++ = '-';
- source = -source;
+
+ return UInt32ToDec(val, pdest);
+}
+
+size_t
+ cvtInt32ToString(epicsInt32 val, char *pdest)
+{
+ if (val == 0) {
+ *pdest++ = '0';
+ *pdest = 0;
+ return 1;
}
- val = source;
- for(i=0; val!=0; i++) {
- temp = val/10;
- digit[i] = digit_to_ascii[val - temp*10];
- val = temp;
+
+ if (val > 0)
+ return UInt32ToDec(val, pdest);
+
+ if (val == -0x80000000) {
+ strcpy(pdest, "-2147483648");
+ return strlen(pdest);
}
- for(j=i-1; j>=0; j--) {
- *pdest++ = digit[j];
- }
- *pdest = 0;
- return((int)(pdest-startAddr));
+
+ *pdest++ = '-';
+ return 1 + UInt32ToDec(-val, pdest);
}
-int epicsShareAPI cvtUlongToString(
- epicsUInt32 source,
- char *pdest)
+size_t
+ cvtUInt64ToString(epicsUInt64 val, char *pdest)
{
- epicsUInt32 val,temp;
- char digit[10];
- int i,j;
- char *startAddr = pdest;
+ if (val == 0) {
+ *pdest++ = '0';
+ *pdest = 0;
+ return 1;
+ }
- if(source==0) {
- *pdest++ = '0';
- *pdest = 0;
- return((int)(pdest-startAddr));
+ return UInt64ToDec(val, pdest);
+}
+
+size_t
+ cvtInt64ToString(epicsInt64 val, char *pdest)
+{
+ if (val == 0) {
+ *pdest++ = '0';
+ *pdest = 0;
+ return 1;
}
- val = source;
- for(i=0; val!=0; i++) {
- temp = val/10;
- digit[i] = digit_to_ascii[val - temp*10];
- val = temp;
+
+ if (val > 0)
+ return UInt64ToDec(val, pdest);
+
+ if (val == -0x8000000000000000LL) {
+ strcpy(pdest, "-9223372036854775808");
+ return strlen(pdest);
}
- for(j=i-1; j>=0; j--) {
- *pdest++ = digit[j];
- }
- *pdest = 0;
- return((int)(pdest-startAddr));
+
+ *pdest++ = '-';
+ return 1 + UInt64ToDec(-val, pdest);
}
-/* Convert hex digits to ascii */
-
-static char hex_digit_to_ascii[16]={'0','1','2','3','4','5','6','7','8','9',
- 'a','b','c','d','e','f'};
-
-
-int epicsShareAPI cvtLongToHexString(
- epicsInt32 source,
- char *pdest)
+size_t
+ cvtInt32ToHexString(epicsInt32 val, char *pdest)
{
- epicsInt32 val,temp;
- char digit[10];
- int i,j;
- char *startAddr = pdest;
+ if (val < 0)
+ *pdest++ = '-';
- if(source==0) {
- *pdest++ = '0';
- *pdest = 0;
- return((int)(pdest-startAddr));
- }
- if(source<0) {
- if(source == INT_MIN) {
- sprintf(pdest,"-0x%x",source);
- return((int)strlen(pdest));
- }
- *pdest++ = '-';
- source = -source;
- }
- *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((int)(pdest-startAddr));
-}
-
-
-int epicsShareAPI cvtLongToOctalString(
- epicsInt32 source,
- char *pdest)
-{
- epicsInt32 val,temp;
- char digit[16];
- int i,j;
- char *startAddr = pdest;
-
- if(source==0) {
- *pdest++ = '0';
- *pdest = 0;
- return((int)(pdest-startAddr));
- }
- if(source<0) {
- if(source == INT_MIN) {
- sprintf(pdest,"-0%o",source);
- return((int)strlen(pdest));
- }
- *pdest++ = '-';
- source = -source;
- }
*pdest++ = '0';
- val = source;
- for(i=0; val!=0; i++) {
- temp = val/8;
- /* reuse digit_to_ascii since octal is a subset of decimal */
- digit[i] = digit_to_ascii[val - temp*8];
- val = temp;
+ *pdest++ = 'x';
+
+ if (val == 0) {
+ *pdest++ = '0';
+ *pdest = 0;
+ return 3;
}
- for(j=i-1; j>=0; j--) {
- *pdest++ = digit[j];
+
+ if (val > 0)
+ return 2 + UInt32ToBase(val, pdest, 16);
+
+ if (val == -0x80000000) {
+ strcpy(pdest, "80000000");
+ return 11;
}
- *pdest = 0;
- return((int)(pdest-startAddr));
+
+ return 3 + UInt32ToBase(-val, pdest, 16);
}
-
-
-
-/*
- *
- * cvtBitsToUlong()
- *
- * extract a bit field from the source epicsUInt32
- */
-epicsUInt32 epicsShareAPI cvtBitsToUlong(
-epicsUInt32 src,
-unsigned bitFieldOffset,
-unsigned bitFieldLength)
+size_t
+ cvtUInt32ToHexString(epicsUInt32 val, char *pdest)
{
- epicsUInt32 mask;
+ *pdest++ = '0';
+ *pdest++ = 'x';
- src = src >> bitFieldOffset;
+ if (val == 0) {
+ *pdest++ = '0';
+ *pdest = 0;
+ return 3;
+ }
- mask = (1< 0) {
+ *pdest++ = '0';
+ return 1 + UInt32ToBase(val, pdest, 8);
+ }
- return dest;
+ if (val == -0x80000000) {
+ strcpy(pdest, "-020000000000");
+ return strlen(pdest);
+ }
+
+ *pdest++ = '-';
+ *pdest++ = '0';
+ return 2 + UInt32ToBase(-val, pdest, 8);
}
+
+size_t
+ cvtInt64ToHexString(epicsInt64 val, char *pdest)
+{
+ if (val < 0)
+ *pdest++ = '-';
+
+ *pdest++ = '0';
+ *pdest++ = 'x';
+
+ if (val == 0) {
+ *pdest++ = '0';
+ *pdest = 0;
+ return 3;
+ }
+
+ if (val > 0)
+ return 2 + UInt64ToBase(val, pdest, 16);
+
+ if (val == -0x8000000000000000LL) {
+ strcpy(pdest, "8000000000000000");
+ return 19;
+ }
+
+ return 3 + UInt64ToBase(-val, pdest, 16);
+}
+
+size_t
+ cvtUInt64ToHexString(epicsUInt64 val, char *pdest)
+{
+ *pdest++ = '0';
+ *pdest++ = 'x';
+
+ if (val == 0) {
+ *pdest++ = '0';
+ *pdest = 0;
+ return 3;
+ }
+
+ return 2 + UInt64ToBase(val, pdest, 16);
+}
+
diff --git a/src/libCom/cvtFast/cvtFast.h b/src/libCom/cvtFast/cvtFast.h
index d2eb86ddf..db06dda53 100644
--- a/src/libCom/cvtFast/cvtFast.h
+++ b/src/libCom/cvtFast/cvtFast.h
@@ -1,30 +1,23 @@
/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
+* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
- * Very efficient routines to convert numbers to strings
+ * Fast numeric to string conversions
*
- * Author: Bob Dalesio wrote cvtFloatToString (called FF_TO_STR)
- * Code is same for cvtDoubleToString
- * Marty Kraimer wrote cvtCharToString,cvtUcharToString
- * cvtShortToString,cvtUshortToString,
- * cvtLongToString, and cvtUlongToString
- * Mark Anderson wrote cvtLongToHexString, cvtLongToOctalString,
- * adopted cvt[Float/Double]ExpString and
- * cvt[Float/Double]CompactString from fToEStr
- * and fixed calls to gcvt
- * Date: 12-9-92
+ * Original Authors:
+ * Bob Dalesio, Mark Anderson and Marty Kraimer
+ * Date: 12 January 1993
*/
+
#ifndef INCcvtFasth
#define INCcvtFasth
-#include
+#include
#include "epicsTypes.h"
#include "shareLib.h"
@@ -34,46 +27,54 @@ extern "C" {
#endif
/*
- * each of these functions return the number of characters "transmitted"
- * (as in ANSI-C/POSIX.1/XPG3 sprintf() functions)
+ * All functions return the number of characters in the output
*/
-epicsShareFunc int epicsShareAPI
- cvtFloatToString(float value, char *pstring, unsigned short precision);
-epicsShareFunc int epicsShareAPI
- cvtDoubleToString(double value, char *pstring, unsigned short precision);
-epicsShareFunc int epicsShareAPI
- cvtFloatToExpString(float value, char *pstring, unsigned short precision);
-epicsShareFunc int epicsShareAPI
- cvtDoubleToExpString(double value, char *pstring, unsigned short precision);
-epicsShareFunc int epicsShareAPI
- cvtFloatToCompactString(float value, char *pstring, unsigned short precision);
-epicsShareFunc int epicsShareAPI
- cvtDoubleToCompactString(double value, char *pstring, unsigned short precision);
-epicsShareFunc int epicsShareAPI
- cvtCharToString(signed char value, char *pstring);
-epicsShareFunc int epicsShareAPI
- cvtUcharToString(unsigned char value, char *pstring);
-epicsShareFunc int epicsShareAPI
- cvtShortToString(short value, char *pstring);
-epicsShareFunc int epicsShareAPI
- cvtUshortToString(unsigned short value, char *pstring);
-epicsShareFunc int epicsShareAPI
- cvtLongToString(epicsInt32 value, char *pstring);
-epicsShareFunc int epicsShareAPI
- cvtUlongToString(epicsUInt32 value, char *pstring);
-epicsShareFunc int epicsShareAPI
- cvtLongToHexString(epicsInt32 value, char *pstring);
-epicsShareFunc int epicsShareAPI
- cvtLongToOctalString(epicsInt32 value, char *pstring);
-epicsShareFunc epicsUInt32 epicsShareAPI cvtBitsToUlong(
- epicsUInt32 src,
- unsigned bitFieldOffset,
- unsigned bitFieldLength);
-epicsShareFunc epicsUInt32 epicsShareAPI cvtUlongToBits(
- epicsUInt32 src,
- epicsUInt32 dest,
- unsigned bitFieldOffset,
- unsigned bitFieldLength);
+epicsShareFunc int
+ cvtFloatToString(float val, char *pdest, epicsUInt16 prec);
+epicsShareFunc int
+ cvtDoubleToString(double val, char *pdest, epicsUInt16 prec);
+
+epicsShareFunc int
+ cvtFloatToExpString(float val, char *pdest, epicsUInt16 prec);
+epicsShareFunc int
+ cvtDoubleToExpString(double val, char *pdest, epicsUInt16 prec);
+epicsShareFunc int
+ cvtFloatToCompactString(float val, char *pdest, epicsUInt16 prec);
+epicsShareFunc int
+ cvtDoubleToCompactString(double val, char *pdest, epicsUInt16 prec);
+
+epicsShareFunc size_t
+ cvtInt32ToString(epicsInt32 val, char *pdest);
+epicsShareFunc size_t
+ cvtUInt32ToString(epicsUInt32 val, char *pdest);
+epicsShareFunc size_t
+ cvtInt64ToString(epicsInt64 val, char *pdest);
+epicsShareFunc size_t
+ cvtUInt64ToString(epicsUInt64 val, char *pdest);
+
+epicsShareFunc size_t
+ cvtInt32ToHexString(epicsInt32 val, char *pdest);
+epicsShareFunc size_t
+ cvtUInt32ToHexString(epicsUInt32 val, char *pdest);
+epicsShareFunc size_t
+ cvtInt32ToOctalString(epicsInt32 val, char *pdest);
+epicsShareFunc size_t
+ cvtInt64ToHexString(epicsInt64 val, char *pdest);
+epicsShareFunc size_t
+ cvtUInt64ToHexString(epicsUInt64 val, char *pdest);
+
+/* Support the original names */
+
+#define cvtCharToString(val, str) cvtInt32ToString(val, str)
+#define cvtUcharToString(val, str) cvtUInt32ToString(val, str)
+#define cvtShortToString(val, str) cvtInt32ToString(val, str)
+#define cvtUshortToString(val, str) cvtUInt32ToString(val, str)
+#define cvtLongToString(val, str) cvtInt32ToString(val, str)
+#define cvtUlongToString(val, str) cvtUInt32ToString(val, str)
+
+#define cvtLongToHexString(val, str) cvtInt32ToHexString(val, str)
+#define cvtULongToHexString(val, str) cvtUInt32ToHexString(val, str)
+#define cvtLongToOctalString(val, str) cvtInt32ToOctalString(val, str)
#ifdef __cplusplus
}
diff --git a/src/libCom/misc/epicsConvert.c b/src/libCom/misc/epicsConvert.c
index 11778c33a..9318ceb7e 100644
--- a/src/libCom/misc/epicsConvert.c
+++ b/src/libCom/misc/epicsConvert.c
@@ -18,28 +18,18 @@
epicsShareFunc float epicsConvertDoubleToFloat(double value)
{
- float rtnvalue;
+ double abs;
- if (value == 0) {
- rtnvalue = 0;
- } else if (!finite(value)) {
- rtnvalue = (float)value;
- } else {
- double abs = fabs(value);
+ if (value == 0 || !finite(value))
+ return (float) value;
- if (abs >= FLT_MAX) {
- if (value > 0)
- rtnvalue = FLT_MAX;
- else
- rtnvalue = -FLT_MAX;
- } else if (abs <= FLT_MIN) {
- if (value > 0)
- rtnvalue = FLT_MIN;
- else
- rtnvalue = -FLT_MIN;
- } else {
- rtnvalue = (float)value;
- }
- }
- return rtnvalue;
+ abs = fabs(value);
+
+ if (abs >= FLT_MAX)
+ return (value > 0) ? FLT_MAX : -FLT_MAX;
+
+ if (abs <= FLT_MIN)
+ return (value > 0) ? FLT_MIN : -FLT_MIN;
+
+ return (float) value;
}
diff --git a/src/libCom/misc/epicsStdlib.c b/src/libCom/misc/epicsStdlib.c
index 865c8069d..f4348981b 100644
--- a/src/libCom/misc/epicsStdlib.c
+++ b/src/libCom/misc/epicsStdlib.c
@@ -256,7 +256,7 @@ epicsParseInt32(const char *str, epicsInt32 *to, int base, char **units)
return S_stdlib_overflow;
#endif
- *to = value;
+ *to = (epicsInt32) value;
return 0;
}
@@ -274,7 +274,7 @@ epicsParseUInt32(const char *str, epicsUInt32 *to, int base, char **units)
return S_stdlib_overflow;
#endif
- *to = value;
+ *to = (epicsUInt32) value;
return 0;
}
@@ -292,7 +292,7 @@ epicsParseInt64(const char *str, epicsInt64 *to, int base, char **units)
if (status)
return status;
- *to = value;
+ *to = (epicsInt64) value;
return 0;
}
@@ -310,7 +310,7 @@ epicsParseUInt64(const char *str, epicsUInt64 *to, int base, char **units)
if (status)
return status;
- *to = value;
+ *to = (epicsUInt64) value;
return 0;
}
diff --git a/src/libCom/misc/epicsTypes.h b/src/libCom/misc/epicsTypes.h
index b5a947b43..efc6a91cb 100644
--- a/src/libCom/misc/epicsTypes.h
+++ b/src/libCom/misc/epicsTypes.h
@@ -82,6 +82,8 @@ typedef union epics_any {
epicsEnum16 enum16;
epicsInt32 int32;
epicsUInt32 uInt32;
+ epicsInt64 int64;
+ epicsUInt64 uInt64;
epicsFloat32 float32;
epicsFloat64 float64;
epicsString string;
diff --git a/src/libCom/osi/os/vxWorks/README b/src/libCom/osi/os/vxWorks/README
deleted file mode 100644
index bbc0046b3..000000000
--- a/src/libCom/osi/os/vxWorks/README
+++ /dev/null
@@ -1,3 +0,0 @@
-
-The source files here are vxWorks dependent.
-
diff --git a/src/libCom/osi/os/vxWorks/osdStrtod.h b/src/libCom/osi/os/vxWorks/osdStrtod.h
index f2c5b68a9..91c47d70e 100644
--- a/src/libCom/osi/os/vxWorks/osdStrtod.h
+++ b/src/libCom/osi/os/vxWorks/osdStrtod.h
@@ -1,11 +1,11 @@
/*************************************************************************\
* Copyright (c) 2002 The University of Saskatchewan
* EPICS BASE is distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
+* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
- * This header is included as part of epicsString.h and epicsStdlib.h
+ * This header is included by epicsString.h and epicsStdlib.h
*/
#ifdef __cplusplus
@@ -15,7 +15,7 @@ extern "C" {
/*
* epicsStrtod() for systems with broken strtod() routine
*/
-epicsShareFunc double epicsStrtod(const char *str, char **endp);
+double epicsStrtod(const char *str, char **endp);
/*
* VxWorks doesn't provide these routines, so for now we do
diff --git a/src/libCom/test/Makefile b/src/libCom/test/Makefile
index ee4d11071..04438854c 100755
--- a/src/libCom/test/Makefile
+++ b/src/libCom/test/Makefile
@@ -177,6 +177,11 @@ macDefExpandTest_SRCS += macDefExpandTest.c
testHarness_SRCS += macDefExpandTest.c
TESTS += macDefExpandTest
+TESTPROD_HOST += cvtFastTest
+cvtFastTest_SRCS += cvtFastTest.cpp
+testHarness_SRCS += cvtFastTest.cpp
+TESTS += cvtFastTest
+
TESTPROD_HOST += macLibTest
macLibTest_SRCS += macLibTest.c
testHarness_SRCS += macLibTest.c
diff --git a/src/libCom/test/cvtFastPerform.cpp b/src/libCom/test/cvtFastPerform.cpp
index f8ae7c270..c3f99dc61 100644
--- a/src/libCom/test/cvtFastPerform.cpp
+++ b/src/libCom/test/cvtFastPerform.cpp
@@ -1,10 +1,12 @@
-
-// Author: Jeff Hill, LANL
+// Original Author: Jeff Hill, LANL
#include
#include
#include
+#include
+#include
#include
+#include
#include "epicsStdio.h"
#include "cvtFast.h"
@@ -13,136 +15,337 @@
using namespace std;
-typedef void ( * PTestFunc ) ( const double &, char * pBug, size_t bufSize );
-
-class Test {
+class PerfConverter {
public:
- Test ();
- virtual ~Test ();
- void execute ();
-protected:
- char _pDst[128];
- double _srcVal;
- unsigned short _prec;
- static unsigned const _nUnrolled = 10;
- static const unsigned _uSecPerSec = 1000000;
- static unsigned const _nIterations = 10000;
- virtual void _target () = 0;
- void _measure ();
- Test ( const Test & );
- Test & operator = ( Test & );
+ virtual const char * name(void) const = 0;
+ virtual int maxPrecision(void) const = 0;
+ virtual void target (double srcD, float srcF, char *dst, size_t len, int prec) const = 0;
+ virtual void add(int prec, double elapsed) = 0;
+ virtual double total(int prec) = 0;
+ virtual ~PerfConverter () {};
};
-class TestCvtFastDouble : public Test {
+class Perf {
+public:
+ Perf ( int maxConverters );
+ virtual ~Perf ();
+ void addConverter( PerfConverter * c );
+ void execute (int count, bool verbose);
+ void report (const char *title, int count);
protected:
- void _target ();
+ static unsigned const nUnrolled = 10;
+ static const unsigned uSecPerSec = 1000000;
+ static unsigned const nIterations = 10000;
+
+ const int maxConverters;
+ PerfConverter **converters;
+ int nConverters;
+ int maxPrecision;
+ bool verbose;
+
+ void measure ( double srcD, float srcF, int prec );
+
+private:
+ Perf ( const Perf & );
+ Perf & operator = ( Perf & );
};
-class TestSNPrintf : public Test {
-protected:
- void _target ();
-};
-
-Test ::
- Test () :
- _srcVal ( 0.0 ), _prec ( 0 )
+Perf :: Perf ( int maxConverters_ ) :
+ maxConverters ( maxConverters_ ),
+ converters ( new PerfConverter * [ maxConverters_ ] ),
+ nConverters ( 0 ),
+ maxPrecision ( 0 )
{
}
-Test :: ~Test ()
+Perf :: ~Perf ()
{
+ for ( int j = 0; j < nConverters; j++ )
+ delete converters[ j ];
+
+ delete [] converters;
}
-void Test :: execute ()
+void Perf :: addConverter(PerfConverter *c)
{
- static const unsigned lowPrecision = 2;
- static const unsigned highPrecision = DBL_MANT_DIG;
-
- for ( unsigned i = 0; i < 3; i++ ) {
+ if ( nConverters >= maxConverters )
+ throw std :: runtime_error ( "Too many converters" );
+
+ converters[ nConverters++ ] = c;
+
+ int prec = c->maxPrecision();
+ if ( prec > maxPrecision )
+ maxPrecision = prec;
+}
+
+void Perf :: execute (const int count, bool verbose_)
+{
+ verbose = verbose_;
+
+ for ( int i = 0; i < count; i++ ) {
+ double srcDbl = rand ();
+ srcDbl /= (RAND_MAX + 1.0);
+ srcDbl *= 20.0;
+ srcDbl -= 10.0;
+ float srcFlt = (float) srcDbl;
+
+ for ( int prec = 0; prec <= maxPrecision; prec++ ) {
+ measure (srcFlt, srcDbl, prec);
+ }
+ }
+ report ( "Small numbers, -10..+10", count );
+
+ for ( int i = 0; i < count; i++ ) {
double mVal = rand ();
mVal /= (RAND_MAX + 1.0);
- double fEVal = rand ();
- fEVal /= (RAND_MAX + 1.0);
- fEVal *= DBL_MAX_EXP - DBL_MIN_EXP;
- fEVal += DBL_MIN_EXP;
- int eVal = static_cast < int > ( fEVal + 0.5 );
- _srcVal = ldexp ( mVal, eVal );
- for ( _prec = lowPrecision;
- _prec <= highPrecision; _prec += 4u ) {
- _measure ();
+ double eVal = rand ();
+ eVal /= (RAND_MAX + 1.0);
+
+ double dVal = eVal;
+ dVal *= FLT_MAX_EXP - FLT_MIN_EXP;
+ dVal += FLT_MIN_EXP;
+ int dEVal = static_cast < int > ( dVal + 0.5 );
+ double srcDbl = ldexp ( mVal, dEVal );
+ float srcFlt = (float) srcDbl;
+
+ for ( int prec = 0; prec <= maxPrecision; prec++ ) {
+ measure (srcFlt, srcDbl, prec);
}
- _srcVal = rand ();
- _srcVal /= (RAND_MAX + 1.0);
- _srcVal *= 10.0;
- _srcVal -= 5.0;
- for ( _prec = lowPrecision;
- _prec <= highPrecision; _prec += 4u ) {
- _measure ();
+ }
+ report ( "Random mantissa+exponent", count );
+}
+
+void Perf :: report (const char *title, const int count)
+{
+ printf( "\n%s\n\nprec\t", title );
+ for ( int j = 0; j < nConverters; j++ )
+ printf( "%-16s ", converters[j]->name() );
+
+ for (int prec = 0; prec <= maxPrecision; prec++ ) {
+ printf( "\n %2d\t", prec );
+ for (int j = 0; j < nConverters; j++ ) {
+ PerfConverter *c = converters[j];
+ if (prec > c->maxPrecision())
+ printf( "%11s ", "-" );
+ else {
+ printf( "%11.9f sec ", c->total(prec) / count );
+ }
}
}
+ printf( "\n\n" );
+}
+
+void Perf :: measure (double srcD, float srcF, int prec)
+{
+ char buf[40];
+
+ for ( int j = 0; j < nConverters; j++ ) {
+ PerfConverter *c = converters[j];
+
+ if (prec > c->maxPrecision())
+ continue;
+
+ std::memset(buf, 0, sizeof(buf));
+
+ epicsTime beg = epicsTime :: getCurrent ();
+ for ( unsigned i = 0; i < nIterations; i++ ) {
+ c->target (srcD, srcF, buf, sizeof(buf) - 1, prec);
+ }
+ epicsTime end = epicsTime :: getCurrent ();
+
+ double elapsed = end - beg;
+ elapsed /= nIterations * nUnrolled;
+ c->add( prec, elapsed );
+
+ if (verbose)
+ printf ( "%17s: %11.9f sec, prec=%2i '%s'\n",
+ c->name (), elapsed, prec, buf );
+ }
}
-void Test :: _measure ()
-{
- epicsTime beg = epicsTime :: getCurrent ();
- for ( unsigned i = 0; i < _nIterations; i++ ) {
- _target ();
+
+// Conversions to be measured
+
+class PerfCvtFastFloat : public PerfConverter {
+ static const int digits = 12;
+public:
+ PerfCvtFastFloat ()
+ {
+ for (int i = 0; i <= digits; i++)
+ measured[i] = 0; // Some targets seem to need this
}
- epicsTime end = epicsTime :: getCurrent ();
- double elapsed = end - beg;
- elapsed /= _nIterations * _nUnrolled;
- elapsed *= _uSecPerSec;
- printf ( " %4.4f usec, prec=%i, val=%4.4g, for %s\n",
- elapsed, _prec, _srcVal, typeid ( *this ).name () );
-}
-
-void TestCvtFastDouble :: _target ()
-{
- cvtDoubleToString ( _srcVal, _pDst, _prec );
- cvtDoubleToString ( _srcVal, _pDst, _prec );
- cvtDoubleToString ( _srcVal, _pDst, _prec );
- cvtDoubleToString ( _srcVal, _pDst, _prec );
- cvtDoubleToString ( _srcVal, _pDst, _prec );
+ int maxPrecision (void) const { return digits; }
+ const char *name (void) const { return "cvtFloatToString"; }
+ void target (double srcD, float srcF, char *dst, size_t len, int prec) const
+ {
+ cvtFloatToString ( srcF, dst, prec );
+ cvtFloatToString ( srcF, dst, prec );
+ cvtFloatToString ( srcF, dst, prec );
+ cvtFloatToString ( srcF, dst, prec );
+ cvtFloatToString ( srcF, dst, prec );
- cvtDoubleToString ( _srcVal, _pDst, _prec );
- cvtDoubleToString ( _srcVal, _pDst, _prec );
- cvtDoubleToString ( _srcVal, _pDst, _prec );
- cvtDoubleToString ( _srcVal, _pDst, _prec );
- cvtDoubleToString ( _srcVal, _pDst, _prec );
+ cvtFloatToString ( srcF, dst, prec );
+ cvtFloatToString ( srcF, dst, prec );
+ cvtFloatToString ( srcF, dst, prec );
+ cvtFloatToString ( srcF, dst, prec );
+ cvtFloatToString ( srcF, dst, prec );
+ }
+ void add (int prec, double elapsed) { measured[prec] += elapsed; }
+ double total (int prec) {
+ double total = measured[prec];
+ measured[prec] = 0;
+ return total;
+ }
+private:
+ double measured[digits+1];
+};
+
+
+class PerfCvtFastDouble : public PerfConverter {
+ static const int digits = 17;
+public:
+ PerfCvtFastDouble ()
+ {
+ for (int i = 0; i <= digits; i++)
+ measured[i] = 0; // Some targets seem to need this
+ }
+ int maxPrecision (void) const { return digits; }
+ const char *name (void) const { return "cvtDoubleToString"; }
+ void target (double srcD, float srcF, char *dst, size_t len, int prec) const
+ {
+ cvtDoubleToString ( srcD, dst, prec );
+ cvtDoubleToString ( srcD, dst, prec );
+ cvtDoubleToString ( srcD, dst, prec );
+ cvtDoubleToString ( srcD, dst, prec );
+ cvtDoubleToString ( srcD, dst, prec );
+
+ cvtDoubleToString ( srcD, dst, prec );
+ cvtDoubleToString ( srcD, dst, prec );
+ cvtDoubleToString ( srcD, dst, prec );
+ cvtDoubleToString ( srcD, dst, prec );
+ cvtDoubleToString ( srcD, dst, prec );
+ }
+ void add(int prec, double elapsed) { measured[prec] += elapsed; }
+ double total (int prec) {
+ double total = measured[prec];
+ measured[prec] = 0;
+ return total;
+ }
+private:
+ double measured[digits+1];
+};
+
+
+class PerfSNPrintf : public PerfConverter {
+ static const int digits = 17;
+public:
+ PerfSNPrintf ()
+ {
+ for (int i = 0; i <= digits; i++)
+ measured[i] = 0; // Some targets seem to need this
+ }
+ int maxPrecision (void) const { return digits; }
+ const char *name (void) const { return "epicsSnprintf"; }
+ void target (double srcD, float srcF, char *dst, size_t len, int prec) const
+ {
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+ epicsSnprintf ( dst, len, "%.*g", prec, srcD );
+ }
+ void add(int prec, double elapsed) { measured[prec] += elapsed; }
+ double total (int prec) {
+ double total = measured[prec];
+ measured[prec] = 0;
+ return total;
+ }
+private:
+ double measured[digits+1];
+};
+
+
+// This is a quick-and-dirty std::streambuf converter that writes directly
+// into the output buffer. Performance is slower than epicsSnprintf().
+
+struct membuf: public std::streambuf {
+ membuf(char *array, size_t size) {
+ this->setp(array, array + size - 1);
+ }
+};
+
+struct omemstream: virtual membuf, std::ostream {
+ omemstream(char *array, size_t size):
+ membuf(array, size),
+ std::ostream(this) {
+ }
+};
+
+static void ossConvertD(char *dst, size_t len, int prec, double src) {
+ omemstream oss(dst, len);
+ oss.precision(prec);
+ oss << src << ends;
}
-void TestSNPrintf :: _target ()
-{
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
-
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
- epicsSnprintf ( _pDst, sizeof ( _pDst ), "%.*g",
- static_cast < int > ( _prec ), _srcVal );
-}
+class PerfStreamBuf : public PerfConverter {
+ static const int digits = 17;
+public:
+ PerfStreamBuf ()
+ {
+ for (int i = 0; i <= digits; i++)
+ measured[i] = 0; // Some targets seem to need this
+ }
+ int maxPrecision (void) const { return digits; }
+ const char *name (void) const { return "std::streambuf"; }
+ void target (double srcD, float srcF, char *dst, size_t len, int prec) const
+ {
+ ossConvertD ( dst, len, prec, srcD );
+ ossConvertD ( dst, len, prec, srcD );
+ ossConvertD ( dst, len, prec, srcD );
+ ossConvertD ( dst, len, prec, srcD );
+ ossConvertD ( dst, len, prec, srcD );
+
+ ossConvertD ( dst, len, prec, srcD );
+ ossConvertD ( dst, len, prec, srcD );
+ ossConvertD ( dst, len, prec, srcD );
+ ossConvertD ( dst, len, prec, srcD );
+ ossConvertD ( dst, len, prec, srcD );
+ }
+ void add(int prec, double elapsed) { measured[prec] += elapsed; }
+ double total (int prec) {
+ double total = measured[prec];
+ measured[prec] = 0;
+ return total;
+ }
+private:
+ double measured[digits+1];
+};
+
MAIN(cvtFastPerform)
{
- TestCvtFastDouble testCvtFastDouble;
- TestSNPrintf testSNPrintf;
-
- testCvtFastDouble.execute ();
- testSNPrintf.execute ();
+ Perf t(4);
+
+ t.addConverter( new PerfCvtFastFloat );
+ t.addConverter( new PerfCvtFastDouble );
+ t.addConverter( new PerfSNPrintf );
+ t.addConverter( new PerfStreamBuf );
+
+ // The parameter to execute() below are:
+ // count = number of different random numbers to measure
+ // verbose = whether to display individual measurements
+
+#ifdef vxWorks
+ t.execute (3, true); // Slow...
+#else
+ t.execute (5, false);
+#endif
return 0;
}
diff --git a/src/libCom/test/cvtFastTest.c b/src/libCom/test/cvtFastTest.c
new file mode 100644
index 000000000..cb7eeaf8a
--- /dev/null
+++ b/src/libCom/test/cvtFastTest.c
@@ -0,0 +1,457 @@
+/*************************************************************************\
+* Copyright (c) 2013 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+/* cvtFastTest.c
+ *
+ * Test the string converters in libCom/cvtFast/cvtFast.c
+ *
+ * To Do: Test Char/Uchar/Short/Ushort/Long/Ulong versions
+ */
+
+#include
+#include
+
+#include "epicsUnitTest.h"
+#include "cvtFast.h"
+#include "epicsStdlib.h"
+#include "testMain.h"
+
+#define tryIString(typ, lit, siz) \
+ len = cvt##typ##ToString(lit, buf); \
+ if (!testOk(len == siz, "cvt"#typ"ToString(" #lit ") == " #siz)) \
+ testDiag("length returned was %u", (unsigned) len); \
+ status = epicsParse##typ(buf, &val_##typ, 10, NULL); \
+ testOk(!status, "epicsParse"#typ"('%s') OK", buf); \
+ testOk(val_##typ == lit, #lit " => '%s'", buf);
+
+#define tryFString(typ, lit, prec, siz) \
+ len = cvt##typ##ToString(lit, buf, prec); \
+ if (!testOk(len == siz, "cvt"#typ"ToString(" #lit ", %d) == " #siz, prec)) \
+ testDiag("length returned was %u", (unsigned) len); \
+ status = epicsParse##typ(buf, &val_##typ, NULL); \
+ testOk(!status, "epicsParse"#typ"('%s') OK", buf); \
+ testOk(fabs(val_##typ - lit) < 0.5 * pow(10, -prec), #lit " => '%s'", buf);
+
+
+MAIN(cvtFastTest)
+{
+ char buf[80];
+ size_t len;
+ long status;
+ epicsUInt32 val_UInt32;
+ epicsInt32 val_Int32;
+ epicsUInt64 val_UInt64;
+ epicsInt64 val_Int64;
+ epicsFloat32 val_Float;
+ epicsFloat64 val_Double;
+
+#if defined(WIN32) && (!defined(_MINGW) || __MSVCRT_VERSION__ >= 0x0800)
+ _set_output_format(_TWO_DIGIT_EXPONENT);
+#endif
+
+ testPlan(1062);
+
+ /* Arguments: type, value, num chars */
+ testDiag("------------------------------------------------------");
+ testDiag("** Positive Int32 **");
+ tryIString(Int32, 0, 1);
+ tryIString(Int32, 1, 1);
+ tryIString(Int32, 10, 2);
+ tryIString(Int32, 100, 3);
+ tryIString(Int32, 254, 3);
+ tryIString(Int32, 255, 3);
+ tryIString(Int32, 256, 3);
+ tryIString(Int32, 257, 3);
+ tryIString(Int32, 1000, 4);
+ tryIString(Int32, 10000, 5);
+ tryIString(Int32, 32766, 5);
+ tryIString(Int32, 32767, 5);
+ tryIString(Int32, 32768, 5);
+ tryIString(Int32, 32769, 5);
+ tryIString(Int32, 65534, 5);
+ tryIString(Int32, 65535, 5);
+ tryIString(Int32, 65536, 5);
+ tryIString(Int32, 65537, 5);
+ tryIString(Int32, 2147483646, 10);
+ tryIString(Int32, 2147483647, 10);
+
+ testDiag("------------------------------------------------------");
+ testDiag("** Negative Int32 **");
+ tryIString(Int32, -1, 2);
+ tryIString(Int32, -10, 3);
+ tryIString(Int32, -100, 4);
+ tryIString(Int32, -254, 4);
+ tryIString(Int32, -255, 4);
+ tryIString(Int32, -256, 4);
+ tryIString(Int32, -257, 4);
+ tryIString(Int32, -1000, 5);
+ tryIString(Int32, -10000, 6);
+ tryIString(Int32, -32766, 6);
+ tryIString(Int32, -32767, 6);
+ tryIString(Int32, -32768, 6);
+ tryIString(Int32, -32769, 6);
+ tryIString(Int32, -65534, 6);
+ tryIString(Int32, -65535, 6);
+ tryIString(Int32, -65536, 6);
+ tryIString(Int32, -65537, 6);
+ tryIString(Int32, -2147483647, 11);
+ tryIString(Int32, -2147483648LL, 11);
+
+ testDiag("------------------------------------------------------");
+ testDiag("** UInt32 **");
+ tryIString(UInt32, 0, 1);
+ tryIString(UInt32, 1, 1);
+ tryIString(UInt32, 10, 2);
+ tryIString(UInt32, 100, 3);
+ tryIString(UInt32, 254, 3);
+ tryIString(UInt32, 255, 3);
+ tryIString(UInt32, 256, 3);
+ tryIString(UInt32, 257, 3);
+ tryIString(UInt32, 1000, 4);
+ tryIString(UInt32, 10000, 5);
+ tryIString(UInt32, 32766, 5);
+ tryIString(UInt32, 32767, 5);
+ tryIString(UInt32, 32768, 5);
+ tryIString(UInt32, 32769, 5);
+ tryIString(UInt32, 65534, 5);
+ tryIString(UInt32, 65535, 5);
+ tryIString(UInt32, 65536, 5);
+ tryIString(UInt32, 65537, 5);
+ tryIString(UInt32, 2147483646ULL, 10);
+ tryIString(UInt32, 2147483647ULL, 10);
+ tryIString(UInt32, 2147483648ULL, 10);
+ tryIString(UInt32, 4294967294ULL, 10);
+ tryIString(UInt32, 4294967295ULL, 10);
+
+ testDiag("------------------------------------------------------");
+ testDiag("** Positive Int64 **");
+ tryIString(Int64, 0, 1);
+ tryIString(Int64, 1, 1);
+ tryIString(Int64, 10, 2);
+ tryIString(Int64, 100, 3);
+ tryIString(Int64, 254, 3);
+ tryIString(Int64, 255, 3);
+ tryIString(Int64, 256, 3);
+ tryIString(Int64, 257, 3);
+ tryIString(Int64, 1000, 4);
+ tryIString(Int64, 10000, 5);
+ tryIString(Int64, 32766, 5);
+ tryIString(Int64, 32767, 5);
+ tryIString(Int64, 32768, 5);
+ tryIString(Int64, 32769, 5);
+ tryIString(Int64, 65534, 5);
+ tryIString(Int64, 65535, 5);
+ tryIString(Int64, 65536, 5);
+ tryIString(Int64, 65537, 5);
+ tryIString(Int64, 2147483646, 10);
+ tryIString(Int64, 2147483647, 10);
+ tryIString(Int64, 2147483648LL, 10);
+ tryIString(Int64, 9223372036854775806LL, 19);
+ tryIString(Int64, 9223372036854775807LL, 19);
+
+ testDiag("------------------------------------------------------");
+ testDiag("** Negative Int64 **");
+ tryIString(Int64, -1, 2);
+ tryIString(Int64, -10, 3);
+ tryIString(Int64, -100, 4);
+ tryIString(Int64, -254, 4);
+ tryIString(Int64, -255, 4);
+ tryIString(Int64, -256, 4);
+ tryIString(Int64, -257, 4);
+ tryIString(Int64, -1000, 5);
+ tryIString(Int64, -10000, 6);
+ tryIString(Int64, -32766, 6);
+ tryIString(Int64, -32767, 6);
+ tryIString(Int64, -32768, 6);
+ tryIString(Int64, -32769, 6);
+ tryIString(Int64, -65534, 6);
+ tryIString(Int64, -65535, 6);
+ tryIString(Int64, -65536, 6);
+ tryIString(Int64, -65537, 6);
+ tryIString(Int64, -2147483647, 11);
+ tryIString(Int64, -2147483648LL, 11);
+ tryIString(Int64, -2147483649LL, 11);
+ tryIString(Int64, -9223372036854775806LL, 20);
+ tryIString(Int64, -9223372036854775807LL, 20);
+ tryIString(Int64, -9223372036854775807LL-1, 20);
+
+ testDiag("------------------------------------------------------");
+ testDiag("** UInt64 **");
+ tryIString(UInt64, 0, 1);
+ tryIString(UInt64, 1, 1);
+ tryIString(UInt64, 10, 2);
+ tryIString(UInt64, 100, 3);
+ tryIString(UInt64, 254, 3);
+ tryIString(UInt64, 255, 3);
+ tryIString(UInt64, 256, 3);
+ tryIString(UInt64, 257, 3);
+ tryIString(UInt64, 1000, 4);
+ tryIString(UInt64, 10000, 5);
+ tryIString(UInt64, 32766, 5);
+ tryIString(UInt64, 32767, 5);
+ tryIString(UInt64, 32768, 5);
+ tryIString(UInt64, 32769, 5);
+ tryIString(UInt64, 65534, 5);
+ tryIString(UInt64, 65535, 5);
+ tryIString(UInt64, 65536, 5);
+ tryIString(UInt64, 65537, 5);
+ tryIString(UInt64, 2147483646, 10);
+ tryIString(UInt64, 2147483647, 10);
+ tryIString(UInt64, 2147483648U, 10);
+ tryIString(UInt64, 2147483649U, 10);
+ tryIString(UInt64, 4294967294U, 10);
+ tryIString(UInt64, 4294967295U, 10);
+ tryIString(UInt64, 4294967296ULL, 10);
+ tryIString(UInt64, 4294967297ULL, 10);
+ tryIString(UInt64, 9223372036854775806ULL, 19);
+ tryIString(UInt64, 9223372036854775807ULL, 19);
+ tryIString(UInt64, 9223372036854775808ULL, 19);
+ tryIString(UInt64, 18446744073709551614ULL, 20);
+ tryIString(UInt64, 18446744073709551615ULL, 20);
+
+ /* Arguments: type, value, precision, num chars */
+ testDiag("------------------------------------------------------");
+ testDiag("** Positive Float fixed-point **");
+ tryFString(Float, 0, 0, 1);
+ tryFString(Float, 0, 1, 3);
+ tryFString(Float, 0, 2, 4);
+ tryFString(Float, 0, 3, 5);
+ tryFString(Float, 0, 4, 6);
+ tryFString(Float, 0, 5, 7);
+ tryFString(Float, 0, 6, 8);
+ tryFString(Float, 0, 7, 9);
+ tryFString(Float, 0, 8, 10);
+ tryFString(Float, FLT_MIN, 0, 1);
+ tryFString(Float, FLT_MIN, 1, 3);
+ tryFString(Float, FLT_MIN, 2, 4);
+ tryFString(Float, FLT_MIN, 3, 5);
+ tryFString(Float, FLT_MIN, 4, 6);
+ tryFString(Float, FLT_MIN, 5, 7);
+ tryFString(Float, FLT_MIN, 6, 8);
+ tryFString(Float, FLT_MIN, 7, 9);
+ tryFString(Float, FLT_MIN, 8, 10);
+ tryFString(Float, 0.000000004999999, 8, 10);
+ tryFString(Float, 0.000000005000001, 8, 10);
+ tryFString(Float, 0.00000004999999, 7, 9);
+ tryFString(Float, 0.00000005000001, 7, 9);
+ tryFString(Float, 0.0000004999999, 6, 8);
+ tryFString(Float, 0.0000005000001, 6, 8);
+ tryFString(Float, 0.000004999999, 5, 7);
+ tryFString(Float, 0.000005000001, 5, 7);
+ tryFString(Float, 0.00004999999, 4, 6);
+ tryFString(Float, 0.00005000001, 4, 6);
+ tryFString(Float, 0.0004999999, 3, 5);
+ tryFString(Float, 0.0005000001, 3, 5);
+ tryFString(Float, 0.004999999, 2, 4);
+ tryFString(Float, 0.005000001, 2, 4);
+ tryFString(Float, 0.04999999, 1, 3);
+ tryFString(Float, 0.05000001, 1, 3);
+ tryFString(Float, 0.4999999, 0, 1);
+ tryFString(Float, 0.5000001, 0, 1);
+ tryFString(Float, 1, 0, 1);
+ tryFString(Float, 1, 1, 3);
+ tryFString(Float, 1, 2, 4);
+ tryFString(Float, 1, 3, 5);
+ tryFString(Float, 1, 4, 6);
+ tryFString(Float, 1, 5, 7);
+ tryFString(Float, 1, 6, 8);
+ tryFString(Float, 1, 7, 9);
+ tryFString(Float, 1, 8, 10);
+ tryFString(Float, 1.0500001, 1, 3);
+ tryFString(Float, 1.1, 1, 3);
+ tryFString(Float, 1.1499999, 1, 3);
+ tryFString(Float, 9.5000001, 0, 2);
+ tryFString(Float, 10, 0, 2);
+ tryFString(Float, 10, 1, 4);
+ tryFString(Float, 10, 8, 11);
+ tryFString(Float, 100, 0, 3);
+ tryFString(Float, 100, 1, 5);
+ tryFString(Float, 100, 8, 12);
+ tryFString(Float, 1000, 0, 4);
+ tryFString(Float, 1000, 1, 6);
+ tryFString(Float, 1000, 8, 13);
+ tryFString(Float, 10000, 0, 5);
+ tryFString(Float, 10000, 1, 7);
+ tryFString(Float, 10000, 8, 14);
+ tryFString(Float, 100000, 0, 6);
+ tryFString(Float, 100000, 1, 8);
+ tryFString(Float, 100000, 8, 15);
+ tryFString(Float, 1000000, 0, 7);
+ tryFString(Float, 1000000, 1, 9);
+ tryFString(Float, 1000000, 8, 16);
+ tryFString(Float, 10000000, 0, 8);
+ tryFString(Float, 10000000, 1, 10);
+ tryFString(Float, 10000000, 8, 17);
+
+ testDiag("------------------------------------------------------");
+ testDiag("** Negative Float fixed-point **");
+ tryFString(Float, -FLT_MIN, 0, 2);
+ tryFString(Float, -FLT_MIN, 1, 4);
+ tryFString(Float, -FLT_MIN, 8, 11);
+ tryFString(Float, -1, 0, 2);
+ tryFString(Float, -1, 1, 4);
+ tryFString(Float, -1, 8, 11);
+ tryFString(Float, -1.0500001, 1, 4);
+ tryFString(Float, -1.1, 1, 4);
+ tryFString(Float, -1.1499999, 1, 4);
+ tryFString(Float, -9.5000001, 0, 3);
+ tryFString(Float, -10, 0, 3);
+ tryFString(Float, -10, 1, 5);
+ tryFString(Float, -10, 8, 12);
+ tryFString(Float, -100, 0, 4);
+ tryFString(Float, -100, 1, 6);
+ tryFString(Float, -100, 8, 13);
+ tryFString(Float, -1000, 0, 5);
+ tryFString(Float, -1000, 1, 7);
+ tryFString(Float, -1000, 8, 14);
+ tryFString(Float, -10000, 0, 6);
+ tryFString(Float, -10000, 1, 8);
+ tryFString(Float, -10000, 8, 15);
+ tryFString(Float, -100000, 0, 7);
+ tryFString(Float, -100000, 1, 9);
+ tryFString(Float, -100000, 8, 16);
+ tryFString(Float, -1000000, 0, 8);
+ tryFString(Float, -1000000, 1, 10);
+ tryFString(Float, -1000000, 8, 17);
+ tryFString(Float, -10000000, 0, 9);
+ tryFString(Float, -10000000, 1, 11);
+ tryFString(Float, -10000000, 8, 18);
+
+ /*
+ * Values > 1e7 trigger the %e format.
+ */
+ testDiag("------------------------------------------------------");
+ testDiag("** Positive Float scientific **");
+ tryFString(Float, 1e+08, 0, 6);
+ tryFString(Float, 1e+08, 1, 7);
+ tryFString(Float, 1e+08, 2, 8);
+ tryFString(Float, 1e+08, 3, 9);
+ tryFString(Float, 1e+08, 4, 10);
+ tryFString(Float, 1e+08, 5, 11);
+ tryFString(Float, 1e+08, 6, 12);
+
+ testDiag("------------------------------------------------------");
+ testDiag("** Positive Double fixed-point **");
+ tryFString(Double, 0, 0, 1);
+ tryFString(Double, 0, 1, 3);
+ tryFString(Double, 0, 2, 4);
+ tryFString(Double, 0, 3, 5);
+ tryFString(Double, 0, 4, 6);
+ tryFString(Double, 0, 5, 7);
+ tryFString(Double, 0, 6, 8);
+ tryFString(Double, 0, 7, 9);
+ tryFString(Double, 0, 8, 10);
+ tryFString(Double, DBL_MIN, 0, 1);
+ tryFString(Double, DBL_MIN, 1, 3);
+ tryFString(Double, DBL_MIN, 2, 4);
+ tryFString(Double, DBL_MIN, 3, 5);
+ tryFString(Double, DBL_MIN, 4, 6);
+ tryFString(Double, DBL_MIN, 5, 7);
+ tryFString(Double, DBL_MIN, 6, 8);
+ tryFString(Double, DBL_MIN, 7, 9);
+ tryFString(Double, DBL_MIN, 8, 10);
+ tryFString(Double, 0.000000004999999, 8, 10);
+ tryFString(Double, 0.000000005000001, 8, 10);
+ tryFString(Double, 0.00000004999999, 7, 9);
+ tryFString(Double, 0.00000005000001, 7, 9);
+ tryFString(Double, 0.0000004999999, 6, 8);
+ tryFString(Double, 0.0000005000001, 6, 8);
+ tryFString(Double, 0.000004999999, 5, 7);
+ tryFString(Double, 0.000005000001, 5, 7);
+ tryFString(Double, 0.00004999999, 4, 6);
+ tryFString(Double, 0.00005000001, 4, 6);
+ tryFString(Double, 0.0004999999, 3, 5);
+ tryFString(Double, 0.0005000001, 3, 5);
+ tryFString(Double, 0.004999999, 2, 4);
+ tryFString(Double, 0.005000001, 2, 4);
+ tryFString(Double, 0.04999999, 1, 3);
+ tryFString(Double, 0.05000001, 1, 3);
+ tryFString(Double, 0.4999999, 0, 1);
+ tryFString(Double, 0.5000001, 0, 1);
+ tryFString(Double, 1, 0, 1);
+ tryFString(Double, 1, 1, 3);
+ tryFString(Double, 1, 2, 4);
+ tryFString(Double, 1, 3, 5);
+ tryFString(Double, 1, 4, 6);
+ tryFString(Double, 1, 5, 7);
+ tryFString(Double, 1, 6, 8);
+ tryFString(Double, 1, 7, 9);
+ tryFString(Double, 1, 8, 10);
+ tryFString(Double, 1.0500001, 1, 3);
+ tryFString(Double, 1.1, 1, 3);
+ tryFString(Double, 1.1499999, 1, 3);
+ tryFString(Double, 9.5000001, 0, 2);
+ tryFString(Double, 10, 0, 2);
+ tryFString(Double, 10, 1, 4);
+ tryFString(Double, 10, 8, 11);
+ tryFString(Double, 100, 0, 3);
+ tryFString(Double, 100, 1, 5);
+ tryFString(Double, 100, 8, 12);
+ tryFString(Double, 1000, 0, 4);
+ tryFString(Double, 1000, 1, 6);
+ tryFString(Double, 1000, 8, 13);
+ tryFString(Double, 10000, 0, 5);
+ tryFString(Double, 10000, 1, 7);
+ tryFString(Double, 10000, 8, 14);
+ tryFString(Double, 100000, 0, 6);
+ tryFString(Double, 100000, 1, 8);
+ tryFString(Double, 100000, 8, 15);
+ tryFString(Double, 1000000, 0, 7);
+ tryFString(Double, 1000000, 1, 9);
+ tryFString(Double, 1000000, 8, 16);
+ tryFString(Double, 10000000, 0, 8);
+ tryFString(Double, 10000000, 1, 10);
+ tryFString(Double, 10000000, 8, 17);
+
+ testDiag("------------------------------------------------------");
+ testDiag("** Negative Double fixed-point **");
+ tryFString(Double, -DBL_MIN, 0, 2);
+ tryFString(Double, -DBL_MIN, 1, 4);
+ tryFString(Double, -DBL_MIN, 8, 11);
+ tryFString(Double, -1, 0, 2);
+ tryFString(Double, -1, 1, 4);
+ tryFString(Double, -1, 8, 11);
+ tryFString(Double, -1.0500001, 1, 4);
+ tryFString(Double, -1.1, 1, 4);
+ tryFString(Double, -1.1499999, 1, 4);
+ tryFString(Double, -9.5000001, 0, 3);
+ tryFString(Double, -10, 0, 3);
+ tryFString(Double, -10, 1, 5);
+ tryFString(Double, -10, 8, 12);
+ tryFString(Double, -100, 0, 4);
+ tryFString(Double, -100, 1, 6);
+ tryFString(Double, -100, 8, 13);
+ tryFString(Double, -1000, 0, 5);
+ tryFString(Double, -1000, 1, 7);
+ tryFString(Double, -1000, 8, 14);
+ tryFString(Double, -10000, 0, 6);
+ tryFString(Double, -10000, 1, 8);
+ tryFString(Double, -10000, 8, 15);
+ tryFString(Double, -100000, 0, 7);
+ tryFString(Double, -100000, 1, 9);
+ tryFString(Double, -100000, 8, 16);
+ tryFString(Double, -1000000, 0, 8);
+ tryFString(Double, -1000000, 1, 10);
+ tryFString(Double, -1000000, 8, 17);
+ tryFString(Double, -10000000, 0, 9);
+ tryFString(Double, -10000000, 1, 11);
+ tryFString(Double, -10000000, 8, 18);
+
+ /*
+ * Values > 1e7 trigger the %e format.
+ * Windows may print 3 digit exponents...
+ */
+ testDiag("------------------------------------------------------");
+ testDiag("** Positive Double scientific **");
+ tryFString(Double, 1e+17, 0, 7);
+ tryFString(Double, 1e+17, 1, 8);
+ tryFString(Double, 1e+17, 2, 9);
+ tryFString(Double, 1e+17, 3, 10);
+ tryFString(Double, 1e+17, 4, 11);
+ tryFString(Double, 1e+17, 5, 12);
+
+ return testDone();
+}
diff --git a/src/std/dev/Makefile b/src/std/dev/Makefile
index 8e4e242f9..ec3713bd6 100644
--- a/src/std/dev/Makefile
+++ b/src/std/dev/Makefile
@@ -28,6 +28,8 @@ dbRecStd_SRCS += devBoDbState.c
dbRecStd_SRCS += devCalcoutSoft.c
dbRecStd_SRCS += devEventSoft.c
dbRecStd_SRCS += devHistogramSoft.c
+dbRecStd_SRCS += devI64inSoft.c
+dbRecStd_SRCS += devI64outSoft.c
dbRecStd_SRCS += devLiSoft.c
dbRecStd_SRCS += devLoSoft.c
dbRecStd_SRCS += devLsiSoft.c
@@ -49,6 +51,7 @@ dbRecStd_SRCS += devGeneralTime.c
dbRecStd_SRCS += devAiSoftCallback.c
dbRecStd_SRCS += devBiSoftCallback.c
+dbRecStd_SRCS += devI64inSoftCallback.c
dbRecStd_SRCS += devLiSoftCallback.c
dbRecStd_SRCS += devMbbiDirectSoftCallback.c
dbRecStd_SRCS += devMbbiSoftCallback.c
@@ -57,6 +60,7 @@ dbRecStd_SRCS += devSiSoftCallback.c
dbRecStd_SRCS += devAoSoftCallback.c
dbRecStd_SRCS += devBoSoftCallback.c
dbRecStd_SRCS += devCalcoutSoftCallback.c
+dbRecStd_SRCS += devI64outSoftCallback.c
dbRecStd_SRCS += devLoSoftCallback.c
dbRecStd_SRCS += devLsoSoftCallback.c
dbRecStd_SRCS += devMbboSoftCallback.c
diff --git a/src/std/dev/devI64inSoft.c b/src/std/dev/devI64inSoft.c
new file mode 100644
index 000000000..d90e48fd6
--- /dev/null
+++ b/src/std/dev/devI64inSoft.c
@@ -0,0 +1,78 @@
+/*************************************************************************\
+* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* Copyright (c) 2002 The Regents of the University of California, as
+* Operator of Los Alamos National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/*
+ * Original Author: Janet Anderson
+ * Date: 09-23-91
+ */
+
+#include
+#include
+#include
+
+#include "alarm.h"
+#include "dbDefs.h"
+#include "dbAccess.h"
+#include "recGbl.h"
+#include "devSup.h"
+#include "int64inRecord.h"
+#include "epicsExport.h"
+
+/* Create the dset for devI64inSoft */
+static long init_record(int64inRecord *prec);
+static long read_int64in(int64inRecord *prec);
+
+struct {
+ long number;
+ DEVSUPFUN report;
+ DEVSUPFUN init;
+ DEVSUPFUN init_record;
+ DEVSUPFUN get_ioint_info;
+ DEVSUPFUN read_int64in;
+} devI64inSoft = {
+ 5,
+ NULL,
+ NULL,
+ init_record,
+ NULL,
+ read_int64in
+};
+epicsExportAddress(dset, devI64inSoft);
+
+static long init_record(int64inRecord *prec)
+{
+ /* INP must be CONSTANT, PV_LINK, DB_LINK or CA_LINK*/
+ switch (prec->inp.type) {
+ case CONSTANT:
+ if (recGblInitConstantLink(&prec->inp, DBF_INT64, &prec->val))
+ prec->udf = FALSE;
+ break;
+ case PV_LINK:
+ case DB_LINK:
+ case CA_LINK:
+ break;
+ default:
+ recGblRecordError(S_db_badField, (void *)prec,
+ "devI64inSoft (init_record) Illegal INP field");
+ return S_db_badField;
+ }
+ return 0;
+}
+
+static long read_int64in(int64inRecord *prec)
+{
+ long status;
+
+ status = dbGetLink(&prec->inp, DBR_INT64, &prec->val, 0, 0);
+ if (!status &&
+ prec->tsel.type == CONSTANT &&
+ prec->tse == epicsTimeEventDeviceTime)
+ dbGetTimeStamp(&prec->inp, &prec->time);
+ return status;
+}
diff --git a/src/std/dev/devI64inSoftCallback.c b/src/std/dev/devI64inSoftCallback.c
new file mode 100644
index 000000000..8c9e77896
--- /dev/null
+++ b/src/std/dev/devI64inSoftCallback.c
@@ -0,0 +1,222 @@
+/*************************************************************************\
+* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* Copyright (c) 2002 The Regents of the University of California, as
+* Operator of Los Alamos National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+/* devI64inSoftCallback.c */
+/*
+ * Authors: Marty Kraimer & Andrew Johnson
+ */
+
+#include
+#include
+
+#include "alarm.h"
+#include "callback.h"
+#include "cantProceed.h"
+#include "dbCommon.h"
+#include "dbDefs.h"
+#include "dbAccess.h"
+#include "dbChannel.h"
+#include "dbNotify.h"
+#include "epicsAssert.h"
+#include "recGbl.h"
+#include "recSup.h"
+#include "devSup.h"
+#include "link.h"
+#include "int64inRecord.h"
+#include "epicsExport.h"
+
+
+#define GET_OPTIONS (DBR_STATUS | DBR_TIME)
+
+typedef struct devPvt {
+ processNotify pn;
+ CALLBACK callback;
+ long options;
+ int status;
+ struct {
+ DBRstatus
+ DBRtime
+ epicsInt32 value;
+ } buffer;
+} devPvt;
+
+
+static void getCallback(processNotify *ppn, notifyGetType type)
+{
+ int64inRecord *prec = (int64inRecord *)ppn->usrPvt;
+ devPvt *pdevPvt = (devPvt *)prec->dpvt;
+ long no_elements = 1;
+
+ if (ppn->status == notifyCanceled) {
+ printf("devI64inSoftCallback::getCallback notifyCanceled\n");
+ return;
+ }
+
+ assert(type == getFieldType);
+ pdevPvt->status = dbChannelGetField(ppn->chan, DBR_INT64,
+ &pdevPvt->buffer, &pdevPvt->options, &no_elements, 0);
+}
+
+static void doneCallback(processNotify *ppn)
+{
+ int64inRecord *prec = (int64inRecord *)ppn->usrPvt;
+ devPvt *pdevPvt = (devPvt *)prec->dpvt;
+
+ callbackRequestProcessCallback(&pdevPvt->callback, prec->prio, prec);
+}
+
+static long add_record(dbCommon *pcommon)
+{
+ int64inRecord *prec = (int64inRecord *)pcommon;
+ DBLINK *plink = &prec->inp;
+ dbChannel *chan;
+ devPvt *pdevPvt;
+ processNotify *ppn;
+
+ if (plink->type == CONSTANT) return 0;
+
+ if (plink->type != PV_LINK) {
+ long status = S_db_badField;
+
+ recGblRecordError(status, (void *)prec,
+ "devI64inSoftCallback (add_record) Illegal INP field");
+ return status;
+ }
+
+ chan = dbChannelCreate(plink->value.pv_link.pvname);
+ if (!chan) {
+ long status = S_db_notFound;
+
+ recGblRecordError(status, (void *)prec,
+ "devI64inSoftCallback (init_record) linked record not found");
+ return status;
+ }
+
+ pdevPvt = calloc(1, sizeof(*pdevPvt));
+ if (!pdevPvt) {
+ long status = S_db_noMemory;
+
+ recGblRecordError(status, (void *)prec,
+ "devI64inSoftCallback (add_record) out of memory, calloc() failed");
+ return status;
+ }
+ ppn = &pdevPvt->pn;
+
+ plink->type = PN_LINK;
+ plink->value.pv_link.pvlMask &= pvlOptMsMode; /* Severity flags only */
+
+ ppn->usrPvt = prec;
+ ppn->chan = chan;
+ ppn->getCallback = getCallback;
+ ppn->doneCallback = doneCallback;
+ ppn->requestType = processGetRequest;
+
+ pdevPvt->options = GET_OPTIONS;
+
+ prec->dpvt = pdevPvt;
+ return 0;
+}
+
+static long del_record(dbCommon *pcommon) {
+ int64inRecord *prec = (int64inRecord *)pcommon;
+ DBLINK *plink = &prec->inp;
+ devPvt *pdevPvt = (devPvt *)prec->dpvt;
+
+ if (plink->type == CONSTANT) return 0;
+ assert(plink->type == PN_LINK);
+
+ dbNotifyCancel(&pdevPvt->pn);
+ dbChannelDelete(pdevPvt->pn.chan);
+ free(pdevPvt);
+
+ plink->type = PV_LINK;
+ return 0;
+}
+
+static struct dsxt dsxtSoftCallback = {
+ add_record, del_record
+};
+
+static long init(int pass)
+{
+ if (pass == 0) devExtend(&dsxtSoftCallback);
+ return 0;
+}
+
+static long init_record(int64inRecord *prec)
+{
+ /* INP must be CONSTANT or PN_LINK */
+ switch (prec->inp.type) {
+ case CONSTANT:
+ if (recGblInitConstantLink(&prec->inp, DBR_INT64, &prec->val))
+ prec->udf = FALSE;
+ break;
+ case PN_LINK:
+ /* Handled by add_record */
+ break;
+ default:
+ recGblRecordError(S_db_badField, (void *)prec,
+ "devI64inSoftCallback (init_record) Illegal INP field");
+ prec->pact = TRUE;
+ return S_db_badField;
+ }
+ return 0;
+}
+
+static long read_int64in(int64inRecord *prec)
+{
+ devPvt *pdevPvt = (devPvt *)prec->dpvt;
+
+ if (!prec->dpvt)
+ return 0;
+
+ if (!prec->pact) {
+ dbProcessNotify(&pdevPvt->pn);
+ prec->pact = TRUE;
+ return 0;
+ }
+
+ if (pdevPvt->status) {
+ recGblSetSevr(prec, READ_ALARM, INVALID_ALARM);
+ return pdevPvt->status;
+ }
+
+ prec->val = pdevPvt->buffer.value;
+ prec->udf = FALSE;
+
+ switch (prec->inp.value.pv_link.pvlMask & pvlOptMsMode) {
+ case pvlOptNMS:
+ break;
+ case pvlOptMSI:
+ if (pdevPvt->buffer.severity < INVALID_ALARM)
+ break;
+ /* else fall through */
+ case pvlOptMS:
+ recGblSetSevr(prec, LINK_ALARM, pdevPvt->buffer.severity);
+ break;
+ case pvlOptMSS:
+ recGblSetSevr(prec, pdevPvt->buffer.status,
+ pdevPvt->buffer.severity);
+ break;
+ }
+
+ if (prec->tsel.type == CONSTANT &&
+ prec->tse == epicsTimeEventDeviceTime)
+ prec->time = pdevPvt->buffer.time;
+ return 0;
+}
+
+/* Create the dset for devI64inSoftCallback */
+struct {
+ dset common;
+ DEVSUPFUN read_int64in;
+} devI64inSoftCallback = {
+ {5, NULL, init, init_record, NULL},
+ read_int64in
+};
+epicsExportAddress(dset, devI64inSoftCallback);
diff --git a/src/std/dev/devI64outSoft.c b/src/std/dev/devI64outSoft.c
new file mode 100644
index 000000000..f9ac70a7e
--- /dev/null
+++ b/src/std/dev/devI64outSoft.c
@@ -0,0 +1,57 @@
+/*************************************************************************\
+* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* Copyright (c) 2002 The Regents of the University of California, as
+* Operator of Los Alamos National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/*
+ * Original Author: Janet Anderson
+ * Date: 09-23-91
+*/
+
+#include
+#include
+#include
+
+#include "alarm.h"
+#include "dbDefs.h"
+#include "dbAccess.h"
+#include "recGbl.h"
+#include "recSup.h"
+#include "devSup.h"
+#include "int64outRecord.h"
+#include "epicsExport.h"
+
+/* Create the dset for devI64outSoft */
+static long init_record(int64outRecord *prec);
+static long write_int64out(int64outRecord *prec);
+struct {
+ long number;
+ DEVSUPFUN report;
+ DEVSUPFUN init;
+ DEVSUPFUN init_record;
+ DEVSUPFUN get_ioint_info;
+ DEVSUPFUN write_int64out;
+} devI64outSoft = {
+ 5,
+ NULL,
+ NULL,
+ init_record,
+ NULL,
+ write_int64out
+};
+epicsExportAddress(dset, devI64outSoft);
+
+static long init_record(int64outRecord *prec)
+{
+ return 0;
+}
+
+static long write_int64out(int64outRecord *prec)
+{
+ dbPutLink(&prec->out, DBR_INT64, &prec->val,1);
+ return 0;
+}
diff --git a/src/std/dev/devI64outSoftCallback.c b/src/std/dev/devI64outSoftCallback.c
new file mode 100644
index 000000000..bfb283523
--- /dev/null
+++ b/src/std/dev/devI64outSoftCallback.c
@@ -0,0 +1,69 @@
+/*************************************************************************\
+* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* Copyright (c) 2002 The Regents of the University of California, as
+* Operator of Los Alamos National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/*
+ * Original Author: Marty Kraimer
+ * Date: 04NOV2003
+ */
+
+#include
+#include
+#include
+
+#include "alarm.h"
+#include "dbDefs.h"
+#include "dbAccess.h"
+#include "recGbl.h"
+#include "recSup.h"
+#include "devSup.h"
+#include "int64outRecord.h"
+#include "epicsExport.h"
+
+/* Create the dset for devI64outSoftCallback */
+static long write_int64out(int64outRecord *prec);
+struct {
+ long number;
+ DEVSUPFUN report;
+ DEVSUPFUN init;
+ DEVSUPFUN init_record;
+ DEVSUPFUN get_ioint_info;
+ DEVSUPFUN write_int64out;
+} devI64outSoftCallback = {
+ 5,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ write_int64out
+};
+epicsExportAddress(dset, devI64outSoftCallback);
+
+static long write_int64out(int64outRecord *prec)
+{
+ struct link *plink = &prec->out;
+ long status;
+
+ if (prec->pact)
+ return 0;
+
+ if (plink->type != CA_LINK) {
+ status = dbPutLink(plink, DBR_INT64, &prec->val, 1);
+ return status;
+ }
+
+ status = dbCaPutLinkCallback(plink, DBR_INT64, &prec->val, 1,
+ dbCaCallbackProcess, plink);
+ if (status) {
+ recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM);
+ return status;
+ }
+
+ prec->pact = TRUE;
+ return 0;
+}
diff --git a/src/std/dev/devSoft.dbd b/src/std/dev/devSoft.dbd
index 1314bf540..2d7a64be3 100644
--- a/src/std/dev/devSoft.dbd
+++ b/src/std/dev/devSoft.dbd
@@ -9,6 +9,8 @@ device(bo,CONSTANT,devBoSoft,"Soft Channel")
device(calcout,CONSTANT,devCalcoutSoft,"Soft Channel")
device(event,CONSTANT,devEventSoft,"Soft Channel")
device(histogram,CONSTANT,devHistogramSoft,"Soft Channel")
+device(int64in,CONSTANT,devI64inSoft,"Soft Channel")
+device(int64out,CONSTANT,devI64outSoft,"Soft Channel")
device(longin,CONSTANT,devLiSoft,"Soft Channel")
device(longout,CONSTANT,devLoSoft,"Soft Channel")
device(lsi,CONSTANT,devLsiSoft,"Soft Channel")
@@ -37,6 +39,8 @@ device(ao,CONSTANT,devAoSoftCallback,"Async Soft Channel")
device(bi,CONSTANT,devBiSoftCallback,"Async Soft Channel")
device(bo,CONSTANT,devBoSoftCallback,"Async Soft Channel")
device(calcout,CONSTANT,devCalcoutSoftCallback,"Async Soft Channel")
+device(int64in,CONSTANT,devI64inSoftCallback,"Async Soft Channel")
+device(int64out,CONSTANT,devI64outSoftCallback,"Async Soft Channel")
device(longin,CONSTANT,devLiSoftCallback,"Async Soft Channel")
device(longout,CONSTANT,devLoSoftCallback,"Async Soft Channel")
device(lso,CONSTANT,devLsoSoftCallback,"Async Soft Channel")
diff --git a/src/std/rec/Makefile b/src/std/rec/Makefile
index 7515d769c..561058620 100644
--- a/src/std/rec/Makefile
+++ b/src/std/rec/Makefile
@@ -25,6 +25,8 @@ stdRecords += dfanoutRecord
stdRecords += eventRecord
stdRecords += fanoutRecord
stdRecords += histogramRecord
+stdRecords += int64inRecord
+stdRecords += int64outRecord
stdRecords += longinRecord
stdRecords += longoutRecord
stdRecords += lsiRecord
diff --git a/src/std/rec/compressRecord.dbd.pod b/src/std/rec/compressRecord.dbd.pod
index c1cb8cc29..265cdfe8a 100644
--- a/src/std/rec/compressRecord.dbd.pod
+++ b/src/std/rec/compressRecord.dbd.pod
@@ -97,7 +97,7 @@ recordtype(compress) {
}
field(BALG,DBF_MENU) {
prompt("Buffering Algorithm")
- promptgroup(GUI_ALARMS)
+ promptgroup("30 - Action")
special(SPC_RESET)
interest(1)
menu(bufferingALG)
diff --git a/src/std/rec/int64inRecord.c b/src/std/rec/int64inRecord.c
new file mode 100644
index 000000000..85063028d
--- /dev/null
+++ b/src/std/rec/int64inRecord.c
@@ -0,0 +1,416 @@
+/*************************************************************************\
+* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* Copyright (c) 2002 The Regents of the University of California, as
+* Operator of Los Alamos National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/* int64inRecord.c - Record Support Routines for int64in records */
+/*
+ * Original Author: Janet Anderson
+ * Date: 9/23/91
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "dbDefs.h"
+#include "epicsPrint.h"
+#include "alarm.h"
+#include "dbAccess.h"
+#include "dbEvent.h"
+#include "dbFldTypes.h"
+#include "devSup.h"
+#include "errMdef.h"
+#include "recSup.h"
+#include "recGbl.h"
+#include "menuYesNo.h"
+
+#define GEN_SIZE_OFFSET
+#include "int64inRecord.h"
+#undef GEN_SIZE_OFFSET
+#include "epicsExport.h"
+
+/* Hysterisis for alarm filtering: 1-1/e */
+#define THRESHOLD 0.6321
+/* Create RSET - Record Support Entry Table*/
+#define report NULL
+#define initialize NULL
+static long init_record(dbCommon *, int);
+static long process(dbCommon *);
+#define special NULL
+#define get_value NULL
+#define cvt_dbaddr NULL
+#define get_array_info NULL
+#define put_array_info NULL
+static long get_units(DBADDR *, char *);
+#define get_precision NULL
+#define get_enum_str NULL
+#define get_enum_strs NULL
+#define put_enum_str NULL
+static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
+static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
+
+rset int64inRSET={
+ RSETNUMBER,
+ report,
+ initialize,
+ init_record,
+ process,
+ special,
+ get_value,
+ cvt_dbaddr,
+ get_array_info,
+ put_array_info,
+ get_units,
+ get_precision,
+ get_enum_str,
+ get_enum_strs,
+ put_enum_str,
+ get_graphic_double,
+ get_control_double,
+ get_alarm_double
+};
+epicsExportAddress(rset,int64inRSET);
+
+
+struct int64indset { /* int64in input dset */
+ long number;
+ DEVSUPFUN dev_report;
+ DEVSUPFUN init;
+ DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
+ DEVSUPFUN get_ioint_info;
+ DEVSUPFUN read_int64in; /*returns: (-1,0)=>(failure,success)*/
+};
+static void checkAlarms(int64inRecord *prec, epicsTimeStamp *timeLast);
+static void monitor(int64inRecord *prec);
+static long readValue(int64inRecord *prec);
+
+
+static long init_record(dbCommon *pcommon, int pass)
+{
+ int64inRecord *prec = (int64inRecord*)pcommon;
+ struct int64indset *pdset;
+ long status;
+
+ if (pass==0) return(0);
+
+ /* int64in.siml must be a CONSTANT or a PV_LINK or a DB_LINK */
+ if (prec->siml.type == CONSTANT) {
+ recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
+ }
+
+ /* int64in.siol must be a CONSTANT or a PV_LINK or a DB_LINK */
+ if (prec->siol.type == CONSTANT) {
+ recGblInitConstantLink(&prec->siol,DBF_LONG,&prec->sval);
+ }
+
+ if(!(pdset = (struct int64indset *)(prec->dset))) {
+ recGblRecordError(S_dev_noDSET,(void *)prec,"int64in: init_record");
+ return(S_dev_noDSET);
+ }
+ /* must have read_int64in function defined */
+ if( (pdset->number < 5) || (pdset->read_int64in == NULL) ) {
+ recGblRecordError(S_dev_missingSup,(void *)prec,"int64in: init_record");
+ return(S_dev_missingSup);
+ }
+ if( pdset->init_record ) {
+ if((status=(*pdset->init_record)(prec))) return(status);
+ }
+ prec->mlst = prec->val;
+ prec->alst = prec->val;
+ prec->lalm = prec->val;
+ return(0);
+}
+
+static long process(dbCommon *pcommon)
+{
+ int64inRecord *prec = (int64inRecord*)pcommon;
+ struct int64indset *pdset = (struct int64indset *)(prec->dset);
+ long status;
+ unsigned char pact=prec->pact;
+ epicsTimeStamp timeLast;
+
+ if( (pdset==NULL) || (pdset->read_int64in==NULL) ) {
+ prec->pact=TRUE;
+ recGblRecordError(S_dev_missingSup,(void *)prec,"read_int64in");
+ return(S_dev_missingSup);
+ }
+ timeLast = prec->time;
+
+ status=readValue(prec); /* read the new value */
+ /* check if device support set pact */
+ if ( !pact && prec->pact ) return(0);
+ prec->pact = TRUE;
+
+ recGblGetTimeStamp(prec);
+ if (status==0) prec->udf = FALSE;
+
+ /* check for alarms */
+ checkAlarms(prec, &timeLast);
+ /* check event list */
+ monitor(prec);
+ /* process the forward scan link record */
+ recGblFwdLink(prec);
+
+ prec->pact=FALSE;
+ return(status);
+}
+
+#define indexof(field) int64inRecord##field
+
+static long get_units(DBADDR *paddr,char *units)
+{
+ int64inRecord *prec=(int64inRecord *)paddr->precord;
+
+ if(paddr->pfldDes->field_type == DBF_LONG) {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
+ return(0);
+}
+
+
+static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd)
+{
+ int64inRecord *prec=(int64inRecord *)paddr->precord;
+
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ case indexof(SVAL):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr,pgd);
+ }
+ return(0);
+}
+
+static long get_control_double(DBADDR *paddr, struct dbr_ctrlDouble *pcd)
+{
+ int64inRecord *prec=(int64inRecord *)paddr->precord;
+
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ case indexof(SVAL):
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ break;
+ default:
+ recGblGetControlDouble(paddr,pcd);
+ }
+ return(0);
+}
+
+static long get_alarm_double(DBADDR *paddr, struct dbr_alDouble *pad)
+{
+ int64inRecord *prec=(int64inRecord *)paddr->precord;
+
+ if(dbGetFieldIndex(paddr) == indexof(VAL)){
+ pad->upper_alarm_limit = prec->hihi;
+ pad->upper_warning_limit = prec->high;
+ pad->lower_warning_limit = prec->low;
+ pad->lower_alarm_limit = prec->lolo;
+ } else recGblGetAlarmDouble(paddr,pad);
+ return(0);
+}
+
+static void checkAlarms(int64inRecord *prec, epicsTimeStamp *timeLast)
+{
+ enum {
+ range_Lolo = 1,
+ range_Low,
+ range_Normal,
+ range_High,
+ range_Hihi
+ } alarmRange;
+ static const epicsEnum16 range_stat[] = {
+ SOFT_ALARM, LOLO_ALARM, LOW_ALARM,
+ NO_ALARM, HIGH_ALARM, HIHI_ALARM
+ };
+
+ double aftc, afvl;
+ epicsInt64 val, hyst, lalm;
+ epicsInt64 alev;
+ epicsEnum16 asev;
+
+ if (prec->udf) {
+ recGblSetSevr(prec, UDF_ALARM, prec->udfs);
+ prec->afvl = 0;
+ return;
+ }
+
+ val = prec->val;
+ hyst = prec->hyst;
+ lalm = prec->lalm;
+
+ /* check VAL against alarm limits */
+ if ((asev = prec->hhsv) &&
+ (val >= (alev = prec->hihi) ||
+ ((lalm == alev) && (val >= alev - hyst))))
+ alarmRange = range_Hihi;
+ else
+ if ((asev = prec->llsv) &&
+ (val <= (alev = prec->lolo) ||
+ ((lalm == alev) && (val <= alev + hyst))))
+ alarmRange = range_Lolo;
+ else
+ if ((asev = prec->hsv) &&
+ (val >= (alev = prec->high) ||
+ ((lalm == alev) && (val >= alev - hyst))))
+ alarmRange = range_High;
+ else
+ if ((asev = prec->lsv) &&
+ (val <= (alev = prec->low) ||
+ ((lalm == alev) && (val <= alev + hyst))))
+ alarmRange = range_Low;
+ else {
+ alev = val;
+ asev = NO_ALARM;
+ alarmRange = range_Normal;
+ }
+
+ aftc = prec->aftc;
+ afvl = 0;
+
+ if (aftc > 0) {
+ /* Apply level filtering */
+ afvl = prec->afvl;
+ if (afvl == 0) {
+ afvl = (double)alarmRange;
+ } else {
+ double t = epicsTimeDiffInSeconds(&prec->time, timeLast);
+ double alpha = aftc / (t + aftc);
+
+ /* The sign of afvl indicates whether the result should be
+ * rounded up or down. This gives the filter hysteresis.
+ * If afvl > 0 the floor() function rounds to a lower alarm
+ * level, otherwise to a higher.
+ */
+ afvl = alpha * afvl +
+ ((afvl > 0) ? (1 - alpha) : (alpha - 1)) * alarmRange;
+ if (afvl - floor(afvl) > THRESHOLD)
+ afvl = -afvl; /* reverse rounding */
+
+ alarmRange = abs((int)floor(afvl));
+ switch (alarmRange) {
+ case range_Hihi:
+ asev = prec->hhsv;
+ alev = prec->hihi;
+ break;
+ case range_High:
+ asev = prec->hsv;
+ alev = prec->high;
+ break;
+ case range_Normal:
+ asev = NO_ALARM;
+ break;
+ case range_Low:
+ asev = prec->lsv;
+ alev = prec->low;
+ break;
+ case range_Lolo:
+ asev = prec->llsv;
+ alev = prec->lolo;
+ break;
+ }
+ }
+ }
+ prec->afvl = afvl;
+
+ if (asev) {
+ /* Report alarm condition, store LALM for future HYST calculations */
+ if (recGblSetSevr(prec, range_stat[alarmRange], asev))
+ prec->lalm = alev;
+ } else {
+ /* No alarm condition, reset LALM */
+ prec->lalm = val;
+ }
+}
+
+/* DELTA calculates the absolute difference between its arguments
+ * expressed as an unsigned 32-bit integer */
+#define DELTA(last, val) \
+ ((epicsUInt32) ((last) > (val) ? (last) - (val) : (val) - (last)))
+
+static void monitor(int64inRecord *prec)
+{
+ unsigned short monitor_mask = recGblResetAlarms(prec);
+
+ if (prec->mdel < 0 ||
+ DELTA(prec->mlst, prec->val) > (epicsUInt32) prec->mdel) {
+ /* post events for value change */
+ monitor_mask |= DBE_VALUE;
+ /* update last value monitored */
+ prec->mlst = prec->val;
+ }
+
+ if (prec->adel < 0 ||
+ DELTA(prec->alst, prec->val) > (epicsUInt32) prec->adel) {
+ /* post events for archive value change */
+ monitor_mask |= DBE_LOG;
+ /* update last archive value monitored */
+ prec->alst = prec->val;
+ }
+
+ /* send out monitors connected to the value field */
+ if (monitor_mask)
+ db_post_events(prec, &prec->val, monitor_mask);
+}
+
+static long readValue(int64inRecord *prec)
+{
+ long status;
+ struct int64indset *pdset = (struct int64indset *) (prec->dset);
+
+ if (prec->pact == TRUE){
+ status=(*pdset->read_int64in)(prec);
+ return(status);
+ }
+
+ status=dbGetLink(&(prec->siml),DBR_USHORT, &(prec->simm),0,0);
+ if (status)
+ return(status);
+
+ if (prec->simm == menuYesNoNO){
+ status=(*pdset->read_int64in)(prec);
+ return(status);
+ }
+ if (prec->simm == menuYesNoYES){
+ status=dbGetLink(&(prec->siol),DBR_LONG,
+ &(prec->sval),0,0);
+
+ if (status==0) {
+ prec->val=prec->sval;
+ prec->udf=FALSE;
+ }
+ } else {
+ status=-1;
+ recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
+ return(status);
+ }
+ recGblSetSevr(prec,SIMM_ALARM,prec->sims);
+
+ return(status);
+}
diff --git a/src/std/rec/int64inRecord.dbd.pod b/src/std/rec/int64inRecord.dbd.pod
new file mode 100644
index 000000000..b85c68ae0
--- /dev/null
+++ b/src/std/rec/int64inRecord.dbd.pod
@@ -0,0 +1,528 @@
+#*************************************************************************
+# Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
+# National Laboratory.
+# Copyright (c) 2002 The Regents of the University of California, as
+# Operator of Los Alamos National Laboratory.
+# EPICS BASE is distributed subject to a Software License Agreement found
+# in file LICENSE that is included with this distribution.
+#*************************************************************************
+
+=title 64bit Integer Input Record (int64in)
+
+This record type is normally used to obtain an integer value of up to 64 bits
+from a hardware input.
+The record supports alarm limits, alarm filtering, graphics and control
+limits.
+
+=head2 Parameter Fields
+
+The record-specific fields are described below.
+
+=recordtype int64in
+
+=cut
+
+recordtype(int64in) {
+
+=head3 Input Specification
+
+These fields control where the record will read data from when it is processed:
+
+=fields DTYP, INP
+
+The DTYP field selects which device support layer should be responsible for
+providing input data to the record.
+The int64in device support layers provided by EPICS Base are documented in the
+L section.
+External support modules may provide additional device support for this record
+type.
+If not set explicitly, the DTYP value defaults to the first device support that
+is loaded for the record type, which will usually be the C support
+that comes with Base.
+
+The INP link field contains a database or channel access link or provides
+hardware address information that the device support uses to determine where the
+input data should come from.
+The format for the INP field value depends on the device support layer that is
+selected by the DTYP field.
+See L for a description of the various hardware
+address formats supported.
+
+=head3 Operator Display Parameters
+
+These parameters are used to present meaningful data to the operator.
+They do not affect the functioning of the record.
+
+=over
+
+=item *
+DESC is a string that is usually used to briefly describe the record.
+
+=item *
+EGU is a string of up to 16 characters naming the engineering units
+that the VAL field represents.
+
+=item *
+The HOPR and LOPR fields set the upper and lower display limits for the VAL,
+HIHI, HIGH, LOW, and LOLO fields.
+
+=back
+
+=fields DESC, EGU, HOPR, LOPR
+
+=head3 Alarm Limits
+
+The user configures limit alarms by putting numerical values into the HIHI,
+HIGH, LOW and LOLO fields, and by setting the associated alarm severity in the
+corresponding HHSV, HSV, LSV and LLSV menu fields.
+
+The HYST field controls hysteresis to prevent alarm chattering from an input
+signal that is close to one of the limits and suffers from significant readout
+noise.
+
+The AFTC field sets the time constant on a low-pass filter that delays the
+reporting of limit alarms until the signal has been within the alarm range for
+that number of seconds (the default AFTC value of zero retains the previous
+behavior).
+
+The LALM field is used by the record at run-time to implement the alarm limit
+functionality.
+
+=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, AFTC, LALM
+
+=head3 Monitor Parameters
+
+These parameters are used to determine when to send monitors placed on the VAL
+field.
+The monitors are sent when the current value exceeds the last transmitted value
+by the appropriate deadband.
+If these fields are set to zero, a monitor will be triggered every time the
+value changes; if set to -1, a monitor will be sent every time the record is
+processed.
+
+The ADEL field sets the deadband for archive monitors (C events), while
+the MDEL field controls value monitors (C events).
+
+The remaining fields are used by the record at run-time to implement the record
+monitoring deadband functionality.
+
+=fields ADEL, MDEL, ALST, MLST
+
+=cut
+
+ include "dbCommon.dbd"
+ field(VAL,DBF_INT64) {
+ prompt("Current value")
+ promptgroup("40 - Input")
+ asl(ASL0)
+ pp(TRUE)
+ }
+ field(INP,DBF_INLINK) {
+ prompt("Input Specification")
+ promptgroup("40 - Input")
+ interest(1)
+ }
+ field(EGU,DBF_STRING) {
+ prompt("Units name")
+ promptgroup("80 - Display")
+ interest(1)
+ size(16)
+ prop(YES)
+ }
+ field(HOPR,DBF_INT64) {
+ prompt("High Operating Range")
+ promptgroup("80 - Display")
+ interest(1)
+ prop(YES)
+ }
+ field(LOPR,DBF_INT64) {
+ prompt("Low Operating Range")
+ promptgroup("80 - Display")
+ interest(1)
+ prop(YES)
+ }
+ field(HIHI,DBF_INT64) {
+ prompt("Hihi Alarm Limit")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(LOLO,DBF_INT64) {
+ prompt("Lolo Alarm Limit")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(HIGH,DBF_INT64) {
+ prompt("High Alarm Limit")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(LOW,DBF_INT64) {
+ prompt("Low Alarm Limit")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(HHSV,DBF_MENU) {
+ prompt("Hihi Severity")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ menu(menuAlarmSevr)
+ }
+ field(LLSV,DBF_MENU) {
+ prompt("Lolo Severity")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ menu(menuAlarmSevr)
+ }
+ field(HSV,DBF_MENU) {
+ prompt("High Severity")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ menu(menuAlarmSevr)
+ }
+ field(LSV,DBF_MENU) {
+ prompt("Low Severity")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ menu(menuAlarmSevr)
+ }
+ field(HYST,DBF_INT64) {
+ prompt("Alarm Deadband")
+ promptgroup("70 - Alarm")
+ interest(1)
+ }
+ field(AFTC, DBF_DOUBLE) {
+ prompt("Alarm Filter Time Constant")
+ promptgroup("70 - Alarm")
+ interest(1)
+ }
+ field(AFVL, DBF_DOUBLE) {
+ prompt("Alarm Filter Value")
+ special(SPC_NOMOD)
+ interest(3)
+ }
+ field(ADEL,DBF_INT64) {
+ prompt("Archive Deadband")
+ promptgroup("80 - Display")
+ interest(1)
+ }
+ field(MDEL,DBF_INT64) {
+ prompt("Monitor Deadband")
+ promptgroup("80 - Display")
+ interest(1)
+ }
+ field(LALM,DBF_INT64) {
+ prompt("Last Value Alarmed")
+ special(SPC_NOMOD)
+ interest(3)
+ }
+ field(ALST,DBF_INT64) {
+ prompt("Last Value Archived")
+ special(SPC_NOMOD)
+ interest(3)
+ }
+ field(MLST,DBF_INT64) {
+ prompt("Last Val Monitored")
+ special(SPC_NOMOD)
+ interest(3)
+ }
+
+=head3 Simulation Mode
+
+The record provides several fields to support simulation of absent hardware.
+If the SIML field is set it is used to read a value into the SIMM field, which
+controls whether simulation is used or not:
+
+=over
+
+=item *
+SIMM must be zero (C) for the record to request a value from the device
+support.
+
+=item *
+If SIMM is C and the SIOL link field is set, a simulated value in
+engineering units is read using the link into the SVAL field, from where it will
+subsequently be copied into the VAL field.
+
+=back
+
+The SIMS field can be set to give the record an alarm severity while it is in
+simulation mode.
+
+=fields SIML, SIMM, SIOL, SVAL, SIMS
+
+=cut
+
+ field(SIOL,DBF_INLINK) {
+ prompt("Sim Input Specifctn")
+ promptgroup("90 - Simulate")
+ interest(1)
+ }
+ field(SVAL,DBF_INT64) {
+ prompt("Simulation Value")
+ }
+ field(SIML,DBF_INLINK) {
+ prompt("Sim Mode Location")
+ promptgroup("90 - Simulate")
+ interest(1)
+ }
+ field(SIMM,DBF_MENU) {
+ prompt("Simulation Mode")
+ interest(1)
+ menu(menuYesNo)
+ }
+ field(SIMS,DBF_MENU) {
+ prompt("Sim mode Alarm Svrty")
+ promptgroup("90 - Simulate")
+ interest(2)
+ menu(menuAlarmSevr)
+ }
+}
+
+=head2 Record Support
+
+=head3 Record Support Routines
+
+The following are the record support routines that would be of interest
+to an application developer.
+Other routines are the C, C,
+C and C routines, which are used to
+collect properties from the record for the complex DBR data structures.
+
+=head4 init_record
+
+This routine first initializes the simulation mode mechanism by setting SIMM
+if SIML is a constant, and setting SVAL if SIOL is a constant.
+
+It then checks if the device support and the device support's
+C routine are defined.
+If either one does not exist, an error message is issued
+and processing is terminated.
+
+If device support includes C, it is called.
+
+Finally, the deadband mechanisms for monitors and level alarms are
+initialized.
+
+=head4 process
+
+See next section.
+
+=head3 Record Processing
+
+Routine C implements the following algorithm:
+
+=over
+
+=item 1.
+
+Check to see that the appropriate device support module and its
+C routine are defined.
+If either one does not exist, an error message is issued and processing is
+terminated with the PACT field set to TRUE, effectively blocking the record
+to avoid error storms.
+
+=item 2.
+
+Determine the value:
+
+If PACT is TRUE, call the device support C routine and return.
+
+If PACT is FALSE, read the value, honoring simulation mode:
+
+=over
+
+=item * Get SIMM by reading the SIML link.
+
+=item * If SIMM is C,
+call the device support C routine and return.
+
+=item * If SIMM is C,
+read the simulated value into SVAL using the SIOL link,
+then copy the value into VAL and set UDF to 0 on success.
+
+=item * Raise an alarm for other values of SIMM.
+
+=item * Set the record to the severity configured in SIMS.
+
+=back
+
+=item 3.
+
+If PACT has been changed to TRUE, the device support signals asynchronous
+processing: its C output routine has started, but not
+completed reading the new value.
+In this case, the processing routine merely returns, leaving PACT TRUE.
+
+=item 4.
+
+Set PACT to TRUE. Get the processing time stamp. Set UDF to 0 if reading
+the value was successful.
+
+=item 5.
+
+Check UDF and level alarms: This routine checks to see if the record is
+undefined (UDF is TRUE) or if the new VAL causes the alarm status
+and severity to change. In the latter case, NSEV, NSTA and LALM are set.
+It also honors the alarm hysteresis factor (HYST): the value must change
+by at least HYST between level alarm status and severity changes.
+If AFTC is set, alarm level filtering is applied.
+
+=item 6.
+
+Check to see if monitors should be invoked:
+
+=over
+
+=item * Alarm monitors are posted if the alarm status or severity have
+changed.
+
+=item * Archive and value change monitors are posted if ADEL and MDEL
+conditions (see L) are met.
+
+=back
+
+=item 7.
+
+Scan (process) forward link if necessary, set PACT to FALSE, and return.
+
+=back
+
+=head2 Device Support
+
+=head3 Device Support Interface
+
+The record requires device support to provide an entry table (dset) which
+defines the following members:
+
+ typedef struct {
+ long number;
+ long (*report)(int level);
+ long (*init)(int after);
+ long (*init_record)(int64inRecord *prec);
+ long (*get_ioint_info)(int cmd, int64inRecord *prec, IOSCANPVT *piosl);
+ long (*read_int64in)(int64inRecord *prec);
+ } int64indset;
+
+The module must set C to at least 5, and provide a pointer to its
+C routine; the other function pointers may be C if their
+associated functionality is not required for this support layer.
+Most device supports also provide an C routine to configure the
+record instance and connect it to the hardware or driver support layer.
+
+The individual routines are described below.
+
+=head3 Device Support Routines
+
+=head4 long report(int level)
+
+This optional routine is called by the IOC command C and is passed the
+report level that was requested by the user.
+It should print a report on the state of the device support to stdout.
+The C parameter may be used to output increasingly more detailed
+information at higher levels, or to select different types of information with
+different levels.
+Level zero should print no more than a small summary.
+
+=head4 long init(int after)
+
+This optional routine is called twice at IOC initialization time.
+The first call happens before any of the C calls are made, with
+the integer parameter C set to 0.
+The second call happens after all of the C calls have been made,
+with C set to 1.
+
+=head4 long init_record(int64inRecord *prec)
+
+This optional routine is called by the record initialization code for each
+int64in record instance that has its DTYP field set to use this device support.
+It is normally used to check that the INP address is the expected type and that
+it points to a valid device; to allocate any record-specific buffer space and
+other memory; and to connect any communication channels needed for the
+C routine to work properly.
+
+=head4 long get_ioint_info(int cmd, int64inRecord *prec, IOSCANPVT *piosl)
+
+This optional routine is called whenever the record's SCAN field is being
+changed to or from the value C to find out which I/O Interrupt Scan
+list the record should be added to or deleted from.
+If this routine is not provided, it will not be possible to set the SCAN field
+to the value C at all.
+
+The C parameter is zero when the record is being added to the scan list,
+and one when it is being removed from the list.
+The routine must determine which interrupt source the record should be connected
+to, which it indicates by the scan list that it points the location at C<*piosl>
+to before returning.
+It can prevent the SCAN field from being changed at all by returning a non-zero
+value to its caller.
+
+In most cases the device support will create the I/O Interrupt Scan lists that
+it returns for itself, by calling C once for
+each separate interrupt source.
+That routine allocates memory and inializes the list, then passes back a pointer
+to the new list in the location at C<*piosl>.
+
+When the device support receives notification that the interrupt has occurred,
+it announces that to the IOC by calling C
+which will arrange for the appropriate records to be processed in a suitable
+thread.
+The C routine is safe to call from an interrupt service routine
+on embedded architectures (vxWorks and RTEMS).
+
+=head4 long read_int64in(int64inRecord *prec)
+
+This essential routine is called when the record wants a new value from the
+addressed device.
+It is responsible for performing (or at least initiating) a read operation, and
+(eventually) returning its value to the record.
+
+If the device may take more than a few microseconds to return the new value,
+this routine must never block (busy-wait), but use the asynchronous
+processing mechanism.
+In that case it signals the asynchronous operation by setting the record's
+PACT field to TRUE before it returns, having arranged for the record's
+C routine to be called later once the read operation is finished.
+When that happens, the C routine will be called again with
+PACT still set to TRUE; it should then set it to FALSE to indicate the read
+has completed, and return.
+
+A return value of zero indicates success, any other value indicates that an
+error occurred.
+
+=head3 Extended Device Support
+
+...
+
+=cut
+
+=head2 Device Support For Soft Records
+
+Two soft device support modules, Soft Channel and Soft Callback Channel, are
+provided for input records not related to actual hardware devices. The
+INP link type must be either a CONSTANT, DB_LINK, or CA_LINK.
+
+=head3 Soft Channel
+
+This module reads the value using the record's INP link.
+
+C calls C to read the value.
+
+=head3 Soft Callback Channel
+
+This module is like the previous except that it reads the value
+using asynchronous processing that will not complete until an asynchronous
+processing of the INP target record has completed.
+
+=cut
diff --git a/src/std/rec/int64outRecord.c b/src/std/rec/int64outRecord.c
new file mode 100644
index 000000000..ecbe52ce8
--- /dev/null
+++ b/src/std/rec/int64outRecord.c
@@ -0,0 +1,394 @@
+/*************************************************************************\
+* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
+* National Laboratory.
+* Copyright (c) 2002 The Regents of the University of California, as
+* Operator of Los Alamos National Laboratory.
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+/*
+ * Original Author: Janet Anderson
+ * Date: 9/23/91
+ */
+#include
+#include
+#include
+#include
+#include
+
+#include "dbDefs.h"
+#include "epicsPrint.h"
+#include "alarm.h"
+#include "dbAccess.h"
+#include "dbEvent.h"
+#include "dbFldTypes.h"
+#include "devSup.h"
+#include "errMdef.h"
+#include "recSup.h"
+#include "recGbl.h"
+#include "menuYesNo.h"
+#include "menuIvoa.h"
+#include "menuOmsl.h"
+
+#define GEN_SIZE_OFFSET
+#include "int64outRecord.h"
+#undef GEN_SIZE_OFFSET
+#include "epicsExport.h"
+
+/* Create RSET - Record Support Entry Table*/
+#define report NULL
+#define initialize NULL
+static long init_record(dbCommon *, int);
+static long process(dbCommon *);
+#define special NULL
+#define get_value NULL
+#define cvt_dbaddr NULL
+#define get_array_info NULL
+#define put_array_info NULL
+static long get_units(DBADDR *, char *);
+#define get_precision NULL
+#define get_enum_str NULL
+#define get_enum_strs NULL
+#define put_enum_str NULL
+static long get_graphic_double(DBADDR *, struct dbr_grDouble *);
+static long get_control_double(DBADDR *, struct dbr_ctrlDouble *);
+static long get_alarm_double(DBADDR *, struct dbr_alDouble *);
+
+rset int64outRSET={
+ RSETNUMBER,
+ report,
+ initialize,
+ init_record,
+ process,
+ special,
+ get_value,
+ cvt_dbaddr,
+ get_array_info,
+ put_array_info,
+ get_units,
+ get_precision,
+ get_enum_str,
+ get_enum_strs,
+ put_enum_str,
+ get_graphic_double,
+ get_control_double,
+ get_alarm_double
+};
+epicsExportAddress(rset,int64outRSET);
+
+
+struct int64outdset { /* int64out input dset */
+ long number;
+ DEVSUPFUN dev_report;
+ DEVSUPFUN init;
+ DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/
+ DEVSUPFUN get_ioint_info;
+ DEVSUPFUN write_int64out;/*(-1,0)=>(failure,success*/
+};
+static void checkAlarms(int64outRecord *prec);
+static void monitor(int64outRecord *prec);
+static long writeValue(int64outRecord *prec);
+static void convert(int64outRecord *prec, epicsInt64 value);
+
+
+static long init_record(dbCommon *pcommon, int pass)
+{
+ int64outRecord *prec = (int64outRecord*)pcommon;
+ struct int64outdset *pdset;
+ long status=0;
+
+ if (pass==0) return(0);
+ if (prec->siml.type == CONSTANT) {
+ recGblInitConstantLink(&prec->siml,DBF_USHORT,&prec->simm);
+ }
+ if(!(pdset = (struct int64outdset *)(prec->dset))) {
+ recGblRecordError(S_dev_noDSET,(void *)prec,"int64out: init_record");
+ return(S_dev_noDSET);
+ }
+ /* must have write_int64out functions defined */
+ if( (pdset->number < 5) || (pdset->write_int64out == NULL) ) {
+ recGblRecordError(S_dev_missingSup,(void *)prec,"int64out: init_record");
+ return(S_dev_missingSup);
+ }
+ if (prec->dol.type == CONSTANT) {
+ if(recGblInitConstantLink(&prec->dol,DBF_INT64,&prec->val))
+ prec->udf=FALSE;
+ }
+ if( pdset->init_record ) {
+ if((status=(*pdset->init_record)(prec))) return(status);
+ }
+ prec->mlst = prec->val;
+ prec->alst = prec->val;
+ prec->lalm = prec->val;
+ return(0);
+}
+
+static long process(dbCommon *pcommon)
+{
+ int64outRecord *prec = (int64outRecord*)pcommon;
+ struct int64outdset *pdset = (struct int64outdset *)(prec->dset);
+ long status=0;
+ epicsInt64 value;
+ unsigned char pact=prec->pact;
+
+ if( (pdset==NULL) || (pdset->write_int64out==NULL) ) {
+ prec->pact=TRUE;
+ recGblRecordError(S_dev_missingSup,(void *)prec,"write_int64out");
+ return(S_dev_missingSup);
+ }
+ if (!prec->pact) {
+ if((prec->dol.type != CONSTANT)
+ && (prec->omsl == menuOmslclosed_loop)) {
+ status = dbGetLink(&(prec->dol),DBR_INT64,
+ &value,0,0);
+ if (prec->dol.type!=CONSTANT && RTN_SUCCESS(status))
+ prec->udf=FALSE;
+ }
+ else {
+ value = prec->val;
+ }
+ if (!status) convert(prec,value);
+ }
+
+ /* check for alarms */
+ checkAlarms(prec);
+
+ if (prec->nsev < INVALID_ALARM )
+ status=writeValue(prec); /* write the new value */
+ else {
+ switch (prec->ivoa) {
+ case (menuIvoaContinue_normally) :
+ status=writeValue(prec); /* write the new value */
+ break;
+ case (menuIvoaDon_t_drive_outputs) :
+ break;
+ case (menuIvoaSet_output_to_IVOV) :
+ if(prec->pact == FALSE){
+ prec->val=prec->ivov;
+ }
+ status=writeValue(prec); /* write the new value */
+ break;
+ default :
+ status=-1;
+ recGblRecordError(S_db_badField,(void *)prec,
+ "int64out:process Illegal IVOA field");
+ }
+ }
+
+ /* check if device support set pact */
+ if ( !pact && prec->pact ) return(0);
+ prec->pact = TRUE;
+
+ recGblGetTimeStamp(prec);
+
+ /* check event list */
+ monitor(prec);
+
+ /* process the forward scan link record */
+ recGblFwdLink(prec);
+
+ prec->pact=FALSE;
+ return(status);
+}
+
+#define indexof(field) int64outRecord##field
+
+static long get_units(DBADDR *paddr,char *units)
+{
+ int64outRecord *prec=(int64outRecord *)paddr->precord;
+
+ if(paddr->pfldDes->field_type == DBF_INT64) {
+ strncpy(units,prec->egu,DB_UNITS_SIZE);
+ }
+ return(0);
+}
+
+static long get_graphic_double(DBADDR *paddr,struct dbr_grDouble *pgd)
+{
+ int64outRecord *prec=(int64outRecord *)paddr->precord;
+
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ pgd->upper_disp_limit = prec->hopr;
+ pgd->lower_disp_limit = prec->lopr;
+ break;
+ default:
+ recGblGetGraphicDouble(paddr,pgd);
+ }
+ return(0);
+}
+
+static long get_control_double(DBADDR *paddr,struct dbr_ctrlDouble *pcd)
+{
+ int64outRecord *prec=(int64outRecord *)paddr->precord;
+
+ switch (dbGetFieldIndex(paddr)) {
+ case indexof(VAL):
+ case indexof(HIHI):
+ case indexof(HIGH):
+ case indexof(LOW):
+ case indexof(LOLO):
+ case indexof(LALM):
+ case indexof(ALST):
+ case indexof(MLST):
+ /* do not change pre drvh/drvl behavior */
+ if(prec->drvh > prec->drvl) {
+ pcd->upper_ctrl_limit = prec->drvh;
+ pcd->lower_ctrl_limit = prec->drvl;
+ } else {
+ pcd->upper_ctrl_limit = prec->hopr;
+ pcd->lower_ctrl_limit = prec->lopr;
+ }
+ break;
+ default:
+ recGblGetControlDouble(paddr,pcd);
+ }
+ return(0);
+}
+
+static long get_alarm_double(DBADDR *paddr,struct dbr_alDouble *pad)
+{
+ int64outRecord *prec=(int64outRecord *)paddr->precord;
+
+ if(dbGetFieldIndex(paddr) == indexof(VAL)) {
+ pad->upper_alarm_limit = prec->hihi;
+ pad->upper_warning_limit = prec->high;
+ pad->lower_warning_limit = prec->low;
+ pad->lower_alarm_limit = prec->lolo;
+ } else recGblGetAlarmDouble(paddr,pad);
+ return(0);
+}
+
+static void checkAlarms(int64outRecord *prec)
+{
+ epicsInt64 val, hyst, lalm;
+ epicsInt64 alev;
+ epicsEnum16 asev;
+
+ if (prec->udf) {
+ recGblSetSevr(prec, UDF_ALARM, prec->udfs);
+ return;
+ }
+
+ val = prec->val;
+ hyst = prec->hyst;
+ lalm = prec->lalm;
+
+ /* alarm condition hihi */
+ asev = prec->hhsv;
+ alev = prec->hihi;
+ if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
+ if (recGblSetSevr(prec, HIHI_ALARM, asev))
+ prec->lalm = alev;
+ return;
+ }
+
+ /* alarm condition lolo */
+ asev = prec->llsv;
+ alev = prec->lolo;
+ if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
+ if (recGblSetSevr(prec, LOLO_ALARM, asev))
+ prec->lalm = alev;
+ return;
+ }
+
+ /* alarm condition high */
+ asev = prec->hsv;
+ alev = prec->high;
+ if (asev && (val >= alev || ((lalm == alev) && (val >= alev - hyst)))) {
+ if (recGblSetSevr(prec, HIGH_ALARM, asev))
+ prec->lalm = alev;
+ return;
+ }
+
+ /* alarm condition low */
+ asev = prec->lsv;
+ alev = prec->low;
+ if (asev && (val <= alev || ((lalm == alev) && (val <= alev + hyst)))) {
+ if (recGblSetSevr(prec, LOW_ALARM, asev))
+ prec->lalm = alev;
+ return;
+ }
+
+ /* we get here only if val is out of alarm by at least hyst */
+ prec->lalm = val;
+ return;
+}
+
+/* DELTA calculates the absolute difference between its arguments
+ * expressed as an unsigned 64-bit integer */
+#define DELTA(last, val) \
+ ((epicsUInt64) ((last) > (val) ? (last) - (val) : (val) - (last)))
+
+static void monitor(int64outRecord *prec)
+{
+ unsigned short monitor_mask = recGblResetAlarms(prec);
+
+ if (prec->mdel < 0 ||
+ DELTA(prec->mlst, prec->val) > (epicsUInt64) prec->mdel) {
+ /* post events for value change */
+ monitor_mask |= DBE_VALUE;
+ /* update last value monitored */
+ prec->mlst = prec->val;
+ }
+
+ if (prec->adel < 0 ||
+ DELTA(prec->alst, prec->val) > (epicsUInt64) prec->adel) {
+ /* post events for archive value change */
+ monitor_mask |= DBE_LOG;
+ /* update last archive value monitored */
+ prec->alst = prec->val;
+ }
+
+ /* send out monitors connected to the value field */
+ if (monitor_mask)
+ db_post_events(prec, &prec->val, monitor_mask);
+}
+
+static long writeValue(int64outRecord *prec)
+{
+ long status;
+ struct int64outdset *pdset = (struct int64outdset *) (prec->dset);
+
+ if (prec->pact == TRUE){
+ status=(*pdset->write_int64out)(prec);
+ return(status);
+ }
+
+ status=dbGetLink(&(prec->siml),DBR_USHORT,&(prec->simm),0,0);
+ if (!RTN_SUCCESS(status))
+ return(status);
+
+ if (prec->simm == menuYesNoNO){
+ status=(*pdset->write_int64out)(prec);
+ return(status);
+ }
+ if (prec->simm == menuYesNoYES){
+ status=dbPutLink(&prec->siol,DBR_INT64,&prec->val,1);
+ } else {
+ status=-1;
+ recGblSetSevr(prec,SOFT_ALARM,INVALID_ALARM);
+ return(status);
+ }
+ recGblSetSevr(prec,SIMM_ALARM,prec->sims);
+
+ return(status);
+}
+
+static void convert(int64outRecord *prec, epicsInt64 value)
+{
+ /* check drive limits */
+ if(prec->drvh > prec->drvl) {
+ if (value > prec->drvh) value = prec->drvh;
+ else if (value < prec->drvl) value = prec->drvl;
+ }
+ prec->val = value;
+}
diff --git a/src/std/rec/int64outRecord.dbd.pod b/src/std/rec/int64outRecord.dbd.pod
new file mode 100644
index 000000000..b489ada97
--- /dev/null
+++ b/src/std/rec/int64outRecord.dbd.pod
@@ -0,0 +1,596 @@
+#*************************************************************************
+# Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
+# National Laboratory.
+# Copyright (c) 2002 The Regents of the University of California, as
+# Operator of Los Alamos National Laboratory.
+# EPICS BASE is distributed subject to a Software License Agreement found
+# in file LICENSE that is included with this distribution.
+#*************************************************************************
+
+=title 64bit Integer Output Record (int64out)
+
+This record type is normally used to send an integer value of up to 64 bits
+to an output device.
+The record supports alarm, drive, graphics and control limits.
+
+=head2 Parameter Fields
+
+The record-specific fields are described below.
+
+=recordtype int64out
+
+=cut
+
+recordtype(int64out) {
+
+=head3 Output Value Determination
+
+These fields control how the record determines the value to be output when it
+gets processed:
+
+=fields OMSL, DOL, DRVH, DRVL, VAL
+
+The following steps are performed in order during record processing.
+
+=head4 Fetch Value
+
+The OMSL menu field is used to determine whether the DOL link field
+should be used during processing or not:
+
+=over
+
+=item *
+If OMSL is C the DOL link field is not used.
+The new output value is taken from the VAL field, which may have been set from
+elsewhere.
+
+=item *
+If OMSL is C the DOL link field is used to obtain a value.
+
+=back
+
+=head4 Drive Limits
+
+The output value is clipped to the range DRVL to DRVH inclusive, provided
+that DRVH > DRVL.
+The result is copied into the VAL field.
+
+=head3 Output Specification
+
+These fields control where the record will read data from when it is processed:
+
+=fields DTYP, OUT
+
+The DTYP field selects which device support layer should be responsible for
+writing output data.
+The int64out device support layers provided by EPICS Base are documented in the
+L section.
+External support modules may provide additional device support for this record
+type.
+If not set explicitly, the DTYP value defaults to the first device support that
+is loaded for the record type, which will usually be the C support
+that comes with Base.
+
+The OUT link field contains a database or channel access link or provides
+hardware address information that the device support uses to determine where the
+output data should be sent to.
+The format for the OUT field value depends on the device support layer that is
+selected by the DTYP field.
+See L for a description of the various hardware
+address formats supported.
+
+=head3 Operator Display Parameters
+
+These parameters are used to present meaningful data to the operator.
+They do not affect the functioning of the record.
+
+=over
+
+=item *
+DESC is a string that is usually used to briefly describe the record.
+
+=item *
+EGU is a string of up to 16 characters naming the engineering units
+that the VAL field represents.
+
+=item *
+The HOPR and LOPR fields set the upper and lower display limits for the VAL,
+HIHI, HIGH, LOW, and LOLO fields.
+
+=back
+
+=fields DESC, EGU, HOPR, LOPR
+
+=head3 Alarm Limits
+
+The user configures limit alarms by putting numerical values into the HIHI,
+HIGH, LOW and LOLO fields, and by setting the associated alarm severities
+in the corresponding HHSV, HSV, LSV and LLSV menu fields.
+
+The HYST field controls hysteresis to prevent alarm chattering from an input
+signal that is close to one of the limits and suffers from significant readout
+noise.
+
+The LALM field is used by the record at run-time to implement the alarm limit
+hysteresis functionality.
+
+=fields HIHI, HIGH, LOW, LOLO, HHSV, HSV, LSV, LLSV, HYST, LALM
+
+=head3 Monitor Parameters
+
+These parameters are used to determine when to send monitors placed on the VAL
+field.
+The monitors are sent when the current value exceeds the last transmitted value
+by the appropriate deadband.
+If these fields are set to zero, a monitor will be triggered every time the
+value changes; if set to -1, a monitor will be sent every time the record is
+processed.
+
+The ADEL field sets the deadband for archive monitors (C events), while
+the MDEL field controls value monitors (C events).
+
+The remaining fields are used by the record at run-time to implement the record
+monitoring deadband functionality.
+
+=fields ADEL, MDEL, ALST, MLST
+
+=cut
+
+ include "dbCommon.dbd"
+ field(VAL,DBF_INT64) {
+ prompt("Desired Output")
+ promptgroup("50 - Output")
+ asl(ASL0)
+ pp(TRUE)
+ }
+ field(OUT,DBF_OUTLINK) {
+ prompt("Output Specification")
+ promptgroup("50 - Output")
+ interest(1)
+ }
+ field(DOL,DBF_INLINK) {
+ prompt("Desired Output Loc")
+ promptgroup("40 - Input")
+ interest(1)
+ }
+ field(OMSL,DBF_MENU) {
+ prompt("Output Mode Select")
+ promptgroup("50 - Output")
+ interest(1)
+ menu(menuOmsl)
+ }
+ field(EGU,DBF_STRING) {
+ prompt("Units name")
+ promptgroup("80 - Display")
+ interest(1)
+ size(16)
+ prop(YES)
+ }
+ field(DRVH,DBF_INT64) {
+ prompt("Drive High Limit")
+ promptgroup("30 - Action")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(DRVL,DBF_INT64) {
+ prompt("Drive Low Limit")
+ promptgroup("30 - Action")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(HOPR,DBF_INT64) {
+ prompt("High Operating Range")
+ promptgroup("80 - Display")
+ interest(1)
+ prop(YES)
+ }
+ field(LOPR,DBF_INT64) {
+ prompt("Low Operating Range")
+ promptgroup("80 - Display")
+ interest(1)
+ prop(YES)
+ }
+ field(HIHI,DBF_INT64) {
+ prompt("Hihi Alarm Limit")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(LOLO,DBF_INT64) {
+ prompt("Lolo Alarm Limit")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(HIGH,DBF_INT64) {
+ prompt("High Alarm Limit")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(LOW,DBF_INT64) {
+ prompt("Low Alarm Limit")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ prop(YES)
+ }
+ field(HHSV,DBF_MENU) {
+ prompt("Hihi Severity")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ menu(menuAlarmSevr)
+ }
+ field(LLSV,DBF_MENU) {
+ prompt("Lolo Severity")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ menu(menuAlarmSevr)
+ }
+ field(HSV,DBF_MENU) {
+ prompt("High Severity")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ menu(menuAlarmSevr)
+ }
+ field(LSV,DBF_MENU) {
+ prompt("Low Severity")
+ promptgroup("70 - Alarm")
+ pp(TRUE)
+ interest(1)
+ menu(menuAlarmSevr)
+ }
+ field(HYST,DBF_INT64) {
+ prompt("Alarm Deadband")
+ promptgroup("70 - Alarm")
+ interest(1)
+ }
+ field(ADEL,DBF_INT64) {
+ prompt("Archive Deadband")
+ promptgroup("80 - Display")
+ interest(1)
+ }
+ field(MDEL,DBF_INT64) {
+ prompt("Monitor Deadband")
+ promptgroup("80 - Display")
+ interest(1)
+ }
+ field(LALM,DBF_INT64) {
+ prompt("Last Value Alarmed")
+ special(SPC_NOMOD)
+ interest(3)
+ }
+ field(ALST,DBF_INT64) {
+ prompt("Last Value Archived")
+ special(SPC_NOMOD)
+ interest(3)
+ }
+ field(MLST,DBF_INT64) {
+ prompt("Last Val Monitored")
+ special(SPC_NOMOD)
+ interest(3)
+ }
+
+=head3 Simulation Mode
+
+The record provides several fields to support simulation of absent hardware.
+If the SIML field is set it is used to read a value into the SIMM field,
+which controls whether simulation is used or not:
+
+=over
+
+=item *
+SIMM must be zero (C) for the record to write a value to the device
+support.
+
+=item *
+If SIMM is C and the SIOL link field is set, the value in engineering
+units is written using the link.
+
+=back
+
+The SIMS field can be set to give the record an alarm severity while it is in
+simulation mode.
+
+=fields SIML, SIMM, SIOL, SIMS
+
+=cut
+
+ field(SIOL,DBF_OUTLINK) {
+ prompt("Sim Output Specifctn")
+ promptgroup("90 - Simulate")
+ interest(1)
+ }
+ field(SIML,DBF_INLINK) {
+ prompt("Sim Mode Location")
+ promptgroup("90 - Simulate")
+ interest(1)
+ }
+ field(SIMM,DBF_MENU) {
+ prompt("Simulation Mode")
+ interest(1)
+ menu(menuYesNo)
+ }
+ field(SIMS,DBF_MENU) {
+ prompt("Sim mode Alarm Svrty")
+ promptgroup("90 - Simulate")
+ interest(2)
+ menu(menuAlarmSevr)
+ }
+
+=head3 Invalid Alarm Output Action
+
+Whenever an output record is put into INVALID alarm severity, IVOA specifies
+the action to take.
+
+=over
+
+=item C (default)
+
+Write the value. Same as if severity is lower than INVALID.
+
+=item C
+
+Do not write value.
+
+=item C
+
+Set VAL to IVOV, then write the value.
+
+=back
+
+=fields IVOA, IVOV
+
+=cut
+
+ field(IVOA,DBF_MENU) {
+ prompt("INVALID output action")
+ promptgroup("50 - Output")
+ interest(2)
+ menu(menuIvoa)
+ }
+ field(IVOV,DBF_INT64) {
+ prompt("INVALID output value")
+ promptgroup("50 - Output")
+ interest(2)
+ }
+}
+
+=head2 Record Support
+
+=head3 Record Support Routines
+
+The following are the record support routines that would be of interest
+to an application developer.
+Other routines are the C, C,
+C and C routines, which are used to
+collect properties from the record for the complex DBR data structures.
+
+=head4 init_record
+
+This routine first initializes the simulation mode mechanism by setting SIMM
+if SIML is a constant.
+
+It then checks if the device support and the device support's
+C routine are defined.
+If either one does not exist, an error message is issued
+and processing is terminated.
+
+If DOL is a constant, then VAL is initialized with its value and UDF is
+set to FALSE.
+
+If device support includes C, it is called.
+
+Finally, the deadband mechanisms for monitors and level alarms are
+initialized.
+
+=head4 process
+
+See next section.
+
+=head3 Record Processing
+
+Routine C implements the following algorithm:
+
+=over
+
+=item 1.
+
+Check to see that the appropriate device support module and its
+C routine are defined.
+If either one does not exist, an error message is issued and processing is
+terminated with the PACT field set to TRUE, effectively blocking the record
+to avoid error storms.
+
+=item 2.
+
+Check PACT. If PACT is FALSE, do the following:
+
+=over
+
+=item * Determine value, honoring closed loop mode:
+if DOL is not a CONSTANT and OMSL is CLOSED_LOOP then get value from DOL
+setting UDF to FALSE in case of success, else use the VAL field.
+
+=item * Call C:
+if drive limits are defined then force value to be within those limits.
+
+=back
+
+=item 3.
+
+Check UDF and level alarms: This routine checks to see if the record is
+undefined (UDF is TRUE) or if the new VAL causes the alarm status
+and severity to change. In the latter case, NSEV, NSTA and LALM are set.
+It also honors the alarm hysteresis factor (HYST): the value must change
+by at least HYST between level alarm status and severity changes.
+
+=item 4.
+
+Check severity and write the new value. See L
+for details on how invalid alarms affect output records.
+
+=item 5.
+
+If PACT has been changed to TRUE, the device support signals asynchronous
+processing: its C output routine has started, but not
+completed writing the new value.
+In this case, the processing routine merely returns, leaving PACT TRUE.
+
+=item 6.
+
+Check to see if monitors should be invoked:
+
+=over
+
+=item * Alarm monitors are posted if the alarm status or severity have
+changed.
+
+=item * Archive and value change monitors are posted if ADEL and MDEL
+conditions (see L) are met.
+
+=item * NSEV and NSTA are reset to 0.
+
+=back
+
+=item 7.
+
+Scan (process) forward link if necessary, set PACT to FALSE, and return.
+
+=back
+
+=head2 Device Support
+
+=head3 Device Support Interface
+
+The record requires device support to provide an entry table (dset) which
+defines the following members:
+
+ typedef struct {
+ long number;
+ long (*report)(int level);
+ long (*init)(int after);
+ long (*init_record)(int64outRecord *prec);
+ long (*get_ioint_info)(int cmd, int64outRecord *prec, IOSCANPVT *piosl);
+ long (*write_int64out)(int64outRecord *prec);
+ } int64outdset;
+
+The module must set C to at least 5, and provide a pointer to its
+C routine; the other function pointers may be C if their
+associated functionality is not required for this support layer.
+Most device supports also provide an C routine to configure the
+record instance and connect it to the hardware or driver support layer.
+
+The individual routines are described below.
+
+=head3 Device Support Routines
+
+=head4 long report(int level)
+
+This optional routine is called by the IOC command C and is passed the
+report level that was requested by the user.
+It should print a report on the state of the device support to stdout.
+The C parameter may be used to output increasingly more detailed
+information at higher levels, or to select different types of information with
+different levels.
+Level zero should print no more than a small summary.
+
+=head4 long init(int after)
+
+This optional routine is called twice at IOC initialization time.
+The first call happens before any of the C calls are made, with
+the integer parameter C set to 0.
+The second call happens after all of the C calls have been made,
+with C set to 1.
+
+=head4 long init_record(int64outRecord *prec)
+
+This optional routine is called by the record initialization code for each
+int64out record instance that has its DTYP field set to use this device support.
+It is normally used to check that the OUT address is the expected type and that
+it points to a valid device, to allocate any record-specific buffer space and
+other memory, and to connect any communication channels needed for the
+C routine to work properly.
+
+=head4 long get_ioint_info(int cmd, int64outRecord *prec, IOSCANPVT *piosl)
+
+This optional routine is called whenever the record's SCAN field is being
+changed to or from the value C to find out which I/O Interrupt Scan
+list the record should be added to or deleted from.
+If this routine is not provided, it will not be possible to set the SCAN field
+to the value C at all.
+
+The C parameter is zero when the record is being added to the scan list,
+and one when it is being removed from the list.
+The routine must determine which interrupt source the record should be connected
+to, which it indicates by the scan list that it points the location at C<*piosl>
+to before returning.
+It can prevent the SCAN field from being changed at all by returning a non-zero
+value to its caller.
+
+In most cases the device support will create the I/O Interrupt Scan lists that
+it returns for itself, by calling C once for
+each separate interrupt source.
+That routine allocates memory and inializes the list, then passes back a pointer
+to the new list in the location at C<*piosl>.
+
+When the device support receives notification that the interrupt has occurred,
+it announces that to the IOC by calling C
+which will arrange for the appropriate records to be processed in a suitable
+thread.
+The C routine is safe to call from an interrupt service routine
+on embedded architectures (vxWorks and RTEMS).
+
+=head4 long write_int64out(int64outRecord *prec)
+
+This essential routine is called when the record wants to write a new value
+to the addressed device.
+It is responsible for performing (or at least initiating) a write operation,
+using the value from the record's VAL field.
+
+If the device may take more than a few microseconds to accept the new value,
+this routine must never block (busy-wait), but use the asynchronous
+processing mechanism.
+In that case it signals the asynchronous operation by setting the record's
+PACT field to TRUE before it returns, having arranged for the record's
+C routine to be called later once the write operation is over.
+When that happens, the C routine will be called again with
+PACT still set to TRUE; it should then set it to FALSE to indicate the write
+has completed, and return.
+
+A return value of zero indicates success, any other value indicates that an
+error occurred.
+
+=head3 Extended Device Support
+
+...
+
+=cut
+
+=head2 Device Support For Soft Records
+
+Two soft device support modules, Soft Channel and Soft Callback Channel, are
+provided for output records not related to actual hardware devices. The
+OUT link type must be either a CONSTANT, DB_LINK, or CA_LINK.
+
+=head3 Soft Channel
+
+This module writes the current value using the record's VAL field.
+
+C calls C to write the current value.
+
+=head3 Soft Callback Channel
+
+This module is like the previous except that it writes the current value
+using asynchronous processing that will not complete until an asynchronous
+processing of the target record has completed.
+
+=cut
diff --git a/src/std/rec/test/Makefile b/src/std/rec/test/Makefile
index 90c7bab16..7e50f0ddf 100644
--- a/src/std/rec/test/Makefile
+++ b/src/std/rec/test/Makefile
@@ -32,6 +32,13 @@ testHarness_SRCS += arrayOpTest.c
TESTFILES += ../arrayOpTest.db
TESTS += arrayOpTest
+TESTPROD_HOST += recMiscTest
+recMiscTest_SRCS += recMiscTest.c
+recMiscTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp
+testHarness_SRCS += recMiscTest.c
+TESTFILES += ../recMiscTest.db
+TESTS += recMiscTest
+
TESTPROD_HOST += linkRetargetLinkTest
linkRetargetLinkTest_SRCS += linkRetargetLinkTest.c
linkRetargetLinkTest_SRCS += recTestIoc_registerRecordDeviceDriver.cpp
diff --git a/src/std/rec/test/epicsRunRecordTests.c b/src/std/rec/test/epicsRunRecordTests.c
index 8b1d30d59..dd56f3d6a 100644
--- a/src/std/rec/test/epicsRunRecordTests.c
+++ b/src/std/rec/test/epicsRunRecordTests.c
@@ -14,6 +14,7 @@
int analogMonitorTest(void);
int compressTest(void);
+int recMiscTest(void);
int arrayOpTest(void);
int asTest(void);
int linkRetargetLinkTest(void);
@@ -27,6 +28,8 @@ void epicsRunRecordTests(void)
runTest(compressTest);
+ runTest(recMiscTest);
+
runTest(arrayOpTest);
runTest(asTest);
diff --git a/src/std/rec/test/recMiscTest.c b/src/std/rec/test/recMiscTest.c
new file mode 100644
index 000000000..05de0e9d2
--- /dev/null
+++ b/src/std/rec/test/recMiscTest.c
@@ -0,0 +1,88 @@
+/*************************************************************************\
+* Copyright (c) 2017 Michael Davidsaver
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+#include
+
+#include "dbAccess.h"
+#include "errlog.h"
+#include "dbStaticLib.h"
+#include "dbUnitTest.h"
+#include "testMain.h"
+
+static
+void testint64BeforeInit(void)
+{
+ const char *S;
+ DBENTRY dbent;
+
+ /* check dbGet/PutString */
+
+ testDiag("In %s", EPICS_FUNCTION);
+
+ dbInitEntryFromRecord(testdbRecordPtr("out64"), &dbent);
+ if(dbFindField(&dbent, "VAL"))
+ testAbort("Failed to find out64.VAL");
+
+ S = dbGetString(&dbent);
+ testOk(S && strcmp(S, "0")==0, "initial value \"%s\"", S);
+
+ testOk1(dbPutString(&dbent, "0x12345678abcdef00")==0);
+
+ S = dbGetString(&dbent);
+ testOk(S && strcmp(S, "1311768467750121216")==0, "1311768467750121216 \"%s\"", S);
+
+ dbFinishEntry(&dbent);
+}
+
+static
+void testint64AfterInit(void)
+{
+ testDiag("In %s", EPICS_FUNCTION);
+
+ /* check dbGet/PutField and DB links */
+
+ testdbGetFieldEqual("in64", DBF_UINT64, 0llu);
+ testdbGetFieldEqual("out64", DBF_UINT64, 0x12345678abcdef00llu);
+
+ testdbPutFieldOk("out64.PROC", DBF_LONG, 1);
+
+ testdbGetFieldEqual("in64", DBF_UINT64, 0x12345678abcdef00llu);
+
+ testdbPutFieldOk("out64.VAL", DBF_UINT64, 0x22345678abcdef00llu);
+
+ testdbPutFieldOk("in64.PROC", DBF_LONG, 1);
+
+ testdbGetFieldEqual("in64", DBF_UINT64, 0x22345678abcdef00llu);
+}
+
+void recTestIoc_registerRecordDeviceDriver(struct dbBase *);
+
+MAIN(recMiscTest)
+{
+ testPlan(0);
+
+ testdbPrepare();
+
+ testdbReadDatabase("recTestIoc.dbd", NULL, NULL);
+
+ recTestIoc_registerRecordDeviceDriver(pdbbase);
+
+ testdbReadDatabase("recMiscTest.db", NULL, NULL);
+
+ testint64BeforeInit();
+
+ eltc(0);
+ testIocInitOk();
+ eltc(1);
+
+ testint64AfterInit();
+
+ testIocShutdownOk();
+
+ testdbCleanup();
+
+ return testDone();
+}
diff --git a/src/std/rec/test/recMiscTest.db b/src/std/rec/test/recMiscTest.db
new file mode 100644
index 000000000..46fc8ae11
--- /dev/null
+++ b/src/std/rec/test/recMiscTest.db
@@ -0,0 +1,10 @@
+
+# check int64in/out
+
+record(int64in, "in64") {
+ field(INP , "out64 NPP")
+}
+
+record(int64out, "out64") {
+ field(OUT , "in64 NPP")
+}
diff --git a/src/tools/DBD/Recfield.pm b/src/tools/DBD/Recfield.pm
index 73a98123c..89beb7be7 100644
--- a/src/tools/DBD/Recfield.pm
+++ b/src/tools/DBD/Recfield.pm
@@ -12,6 +12,8 @@ our %field_types = (
DBF_USHORT => $RXuintx,
DBF_LONG => $RXintx,
DBF_ULONG => $RXuintx,
+ DBF_INT64 => $RXintx,
+ DBF_UINT64 => $RXuintx,
DBF_FLOAT => $RXnum,
DBF_DOUBLE => $RXnum,
DBF_ENUM => qr/.*/,
@@ -317,6 +319,43 @@ sub toDeclaration {
}
+################################################################################
+
+package DBD::Recfield::DBF_INT64;
+
+use DBD::Base;
+@ISA = qw(DBD::Recfield);
+
+sub legal_value {
+ my ($this, $value) = @_;
+ $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe;
+ return ($value =~ m/^ $RXint $/x);
+}
+
+sub toDeclaration {
+ return shift->SUPER::toDeclaration("epicsInt64");
+}
+
+
+################################################################################
+
+package DBD::Recfield::DBF_UINT64;
+
+use DBD::Base;
+@ISA = qw(DBD::Recfield);
+
+sub legal_value {
+ my ($this, $value) = @_;
+ $value =~ s/^ ( $RXhex | $RXoct ) $/ oct($1) /xe;
+ return ($value =~ m/^ $RXuint $/x and
+ $value >= 0);
+}
+
+sub toDeclaration {
+ return shift->SUPER::toDeclaration("epicsUInt64");
+}
+
+
################################################################################
package DBD::Recfield::DBF_FLOAT;