Subject: |
[Merge] lp:~epics-core/epics-base/printf-record into lp:epics-base |
From: |
Andrew Johnson <[email protected]> |
To: |
[email protected] |
Date: |
Mon, 10 Dec 2012 21:22:20 -0000 |
Andrew Johnson has proposed merging lp:~epics-core/epics-base/printf-record into lp:epics-base.
Requested reviews:
EPICS Core Developers (epics-core)
For more details, see:
https://code.launchpad.net/~epics-core/epics-base/printf-record/+merge/139098
This branch adds three new record types and associated device support to Base:
* printf: A string conversion record, plus device support for Soft Channel, Async Soft Channel and stdio device types.
* lsi: A long string input record, plus device support for Soft Channel input.
* lso: A long string output record, plus device support for Soft Channel, Async Soft Channel and stdio device types.
--
https://code.launchpad.net/~epics-core/epics-base/printf-record/+merge/139098
Your team EPICS Core Developers is requested to review the proposed merge of lp:~epics-core/epics-base/printf-record into lp:epics-base.
=== modified file 'src/ioc/db/Makefile'
--- src/ioc/db/Makefile 2012-06-21 20:27:32 +0000
+++ src/ioc/db/Makefile 2012-12-10 21:21:25 +0000
@@ -47,6 +47,7 @@
menuGlobal_DBD += menuIvoa.dbd
menuGlobal_DBD += menuOmsl.dbd
menuGlobal_DBD += menuPini.dbd
+menuGlobal_DBD += menuPost.dbd
menuGlobal_DBD += menuPriority.dbd
menuGlobal_DBD += menuScan.dbd
menuGlobal_DBD += menuYesNo.dbd
=== modified file 'src/ioc/db/dbAccess.c'
--- src/ioc/db/dbAccess.c 2012-10-29 06:20:56 +0000
+++ src/ioc/db/dbAccess.c 2012-12-10 21:21:25 +0000
@@ -583,10 +583,8 @@
{
DBENTRY dbEntry;
dbFldDes *pflddes;
- struct rset *prset;
long status = 0;
- long no_elements = 1;
- short dbfType, dbrType, field_size;
+ short dbfType;
if (!pname || !*pname || !pdbbase)
return S_db_notFound;
@@ -601,48 +599,49 @@
status = dbGetAttributePart(&dbEntry, &pname);
if (status) goto finish;
+ pflddes = dbEntry.pflddes;
+ dbfType = pflddes->field_type;
+
paddr->precord = dbEntry.precnode->precord;
paddr->pfield = dbEntry.pfield;
- pflddes = dbEntry.pflddes;
-
- dbfType = pflddes->field_type;
- dbrType = mapDBFToDBR[dbfType];
- field_size = pflddes->size;
-
+ paddr->pfldDes = pflddes;
+ paddr->no_elements = 1;
+ paddr->field_type = dbfType;
+ paddr->field_size = pflddes->size;
+ paddr->special = pflddes->special;
+ paddr->dbr_field_type = mapDBFToDBR[dbfType];
+
+ if (paddr->special == SPC_DBADDR) {
+ struct rset *prset = dbGetRset(paddr);
+
+ /* Let record type modify paddr */
+ if (prset && prset->cvt_dbaddr) {
+ status = prset->cvt_dbaddr(paddr);
+ if (status)
+ goto finish;
+ dbfType = paddr->field_type;
+ }
+ }
+
+ /* Handle field modifiers */
if (*pname++ == '$') {
/* Some field types can be accessed as char arrays */
if (dbfType == DBF_STRING) {
- dbfType = DBF_CHAR;
- dbrType = DBR_CHAR;
- no_elements = field_size;
- field_size = 1;
+ paddr->no_elements = paddr->field_size;
+ paddr->field_type = DBF_CHAR;
+ paddr->field_size = 1;
+ paddr->dbr_field_type = DBR_CHAR;
} else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
/* Clients see a char array, but keep original dbfType */
- dbrType = DBR_CHAR;
- no_elements = PVNAME_STRINGSZ + 12;
- field_size = 1;
+ paddr->no_elements = PVNAME_STRINGSZ + 12;
+ paddr->field_size = 1;
+ paddr->dbr_field_type = DBR_CHAR;
} else {
status = S_dbLib_fieldNotFound;
goto finish;
}
}
- paddr->pfldDes = pflddes;
- paddr->field_type = dbfType;
- paddr->dbr_field_type = dbrType;
- paddr->field_size = field_size;
- paddr->special = pflddes->special;
- paddr->no_elements = no_elements;
-
- if ((paddr->special == SPC_DBADDR) &&
- (prset = dbGetRset(paddr)) &&
- prset->cvt_dbaddr)
- /* cvt_dbaddr routine may change any of these elements of paddr:
- * pfield, no_elements, element_offset, field_type,
- * dbr_field_type, field_size, and/or special.
- */
- status = prset->cvt_dbaddr(paddr);
-
finish:
dbFinishEntry(&dbEntry);
return status;
@@ -817,7 +816,7 @@
/* check for array */
if ((!pfl || pfl->type == dbfl_type_rec) &&
- paddr->special == SPC_DBADDR &&
+ paddr->pfldDes->special == SPC_DBADDR &&
no_elements > 1 &&
(prset = dbGetRset(paddr)) &&
prset->get_array_info) {
@@ -1171,7 +1170,7 @@
struct rset *prset = dbGetRset(paddr);
long offset = 0;
- if (paddr->special == SPC_DBADDR &&
+ if (paddr->pfldDes->special == SPC_DBADDR &&
prset && prset->get_array_info) {
long dummy;
@@ -1184,7 +1183,7 @@
/* update array info */
if (!status &&
- paddr->special == SPC_DBADDR &&
+ paddr->pfldDes->special == SPC_DBADDR &&
prset && prset->put_array_info) {
status = prset->put_array_info(paddr, nRequest);
}
=== modified file 'src/ioc/db/dbLink.c'
--- src/ioc/db/dbLink.c 2012-07-07 20:54:31 +0000
+++ src/ioc/db/dbLink.c 2012-12-10 21:21:25 +0000
@@ -649,3 +649,62 @@
}
}
+/* Helper functions for long string support */
+
+long dbLoadLinkLS(struct link *plink, char *pbuffer, epicsUInt32 size,
+ epicsUInt32 *plen)
+{
+ if (plink->type == CONSTANT &&
+ plink->value.constantStr) {
+ strncpy(pbuffer, plink->value.constantStr, --size);
+ pbuffer[size] = 0;
+ *plen = strlen(pbuffer) + 1;
+ return 0;
+ }
+
+ return S_db_notFound;
+}
+
+long dbGetLinkLS(struct link *plink, char *pbuffer, epicsUInt32 size,
+ epicsUInt32 *plen)
+{
+ int dtyp = dbGetLinkDBFtype(plink);
+ long len = size;
+ long status;
+
+ if (dtyp < 0) /* Not connected */
+ return 0;
+
+ if (dtyp == DBR_CHAR || dtyp == DBF_UCHAR) {
+ status = dbGetLink(plink, dtyp, pbuffer, 0, &len);
+ }
+ else if (size >= MAX_STRING_SIZE)
+ status = dbGetLink(plink, DBR_STRING, pbuffer, 0, 0);
+ else {
+ /* pbuffer is too small to fetch using DBR_STRING */
+ char tmp[MAX_STRING_SIZE];
+
+ status = dbGetLink(plink, DBR_STRING, tmp, 0, 0);
+ if (!status)
+ strncpy(pbuffer, tmp, len - 1);
+ }
+ if (!status) {
+ pbuffer[--len] = 0;
+ *plen = strlen(pbuffer) + 1;
+ }
+ return status;
+}
+
+long dbPutLinkLS(struct link *plink, char *pbuffer, epicsUInt32 len)
+{
+ int dtyp = dbGetLinkDBFtype(plink);
+
+ if (dtyp < 0)
+ return 0; /* Not connected */
+
+ if (dtyp == DBR_CHAR || dtyp == DBF_UCHAR)
+ return dbPutLink(plink, dtyp, pbuffer, len);
+
+ return dbPutLink(plink, DBR_STRING, pbuffer, 1);
+}
+
=== modified file 'src/ioc/db/dbLink.h'
--- src/ioc/db/dbLink.h 2012-08-08 18:38:21 +0000
+++ src/ioc/db/dbLink.h 2012-12-10 21:21:25 +0000
@@ -81,6 +81,13 @@
const void *pbuffer, long nRequest);
epicsShareFunc void dbScanFwdLink(struct link *plink);
+epicsShareFunc long dbLoadLinkLS(struct link *plink, char *pbuffer,
+ epicsUInt32 size, epicsUInt32 *plen);
+epicsShareFunc long dbGetLinkLS(struct link *plink, char *pbuffer,
+ epicsUInt32 buffer_size, epicsUInt32 *plen);
+epicsShareFunc long dbPutLinkLS(struct link *plink, char *pbuffer,
+ epicsUInt32 len);
+
#ifdef __cplusplus
}
#endif
=== added file 'src/ioc/db/menuPost.dbd'
--- src/ioc/db/menuPost.dbd 1970-01-01 00:00:00 +0000
+++ src/ioc/db/menuPost.dbd 2012-12-10 21:21:25 +0000
@@ -0,0 +1,11 @@
+#*************************************************************************
+# Copyright (c) 2012 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.
+#*************************************************************************
+
+menu(menuPost) {
+ choice(menuPost_OnChange, "On Change")
+ choice(menuPost_Always, "Always")
+}
=== modified file 'src/std/dev/Makefile'
--- src/std/dev/Makefile 2012-07-11 23:07:23 +0000
+++ src/std/dev/Makefile 2012-12-10 21:21:25 +0000
@@ -30,6 +30,8 @@
dbRecStd_SRCS += devHistogramSoft.c
dbRecStd_SRCS += devLiSoft.c
dbRecStd_SRCS += devLoSoft.c
+dbRecStd_SRCS += devLsiSoft.c
+dbRecStd_SRCS += devLsoSoft.c
dbRecStd_SRCS += devMbbiDirectSoft.c
dbRecStd_SRCS += devMbbiDirectSoftRaw.c
dbRecStd_SRCS += devMbbiSoft.c
@@ -38,6 +40,7 @@
dbRecStd_SRCS += devMbboDirectSoftRaw.c
dbRecStd_SRCS += devMbboSoft.c
dbRecStd_SRCS += devMbboSoftRaw.c
+dbRecStd_SRCS += devPrintfSoft.c
dbRecStd_SRCS += devSASoft.c
dbRecStd_SRCS += devSiSoft.c
dbRecStd_SRCS += devSoSoft.c
@@ -55,12 +58,14 @@
dbRecStd_SRCS += devBoSoftCallback.c
dbRecStd_SRCS += devCalcoutSoftCallback.c
dbRecStd_SRCS += devLoSoftCallback.c
+dbRecStd_SRCS += devLsoSoftCallback.c
dbRecStd_SRCS += devMbboSoftCallback.c
dbRecStd_SRCS += devMbboDirectSoftCallback.c
+dbRecStd_SRCS += devPrintfSoftCallback.c
dbRecStd_SRCS += devSoSoftCallback.c
dbRecStd_SRCS += devTimestamp.c
-dbRecStd_SRCS += devSoStdio.c
+dbRecStd_SRCS += devStdio.c
dbRecStd_SRCS += asSubRecordFunctions.c
=== added file 'src/std/dev/devLsiSoft.c'
--- src/std/dev/devLsiSoft.c 1970-01-01 00:00:00 +0000
+++ src/std/dev/devLsiSoft.c 2012-12-10 21:21:25 +0000
@@ -0,0 +1,42 @@
+/*************************************************************************\
+* Copyright (c) 2012 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.
+\*************************************************************************/
+
+/* Long String Input soft device support
+ *
+ * Author: Andrew Johnson
+ * Date: 2012-11-28
+ */
+
+#include "dbAccess.h"
+#include "epicsTime.h"
+#include "link.h"
+#include "lsiRecord.h"
+#include "epicsExport.h"
+
+static long init_record(lsiRecord *prec)
+{
+ dbLoadLinkLS(&prec->inp, prec->val, prec->sizv, &prec->len);
+
+ return 0;
+}
+
+static long read_string(lsiRecord *prec)
+{
+ long status = dbGetLinkLS(&prec->inp, prec->val, prec->sizv, &prec->len);
+
+ if (!status &&
+ prec->tsel.type == CONSTANT &&
+ prec->tse == epicsTimeEventDeviceTime)
+ dbGetTimeStamp(&prec->inp, &prec->time);
+
+ return status;
+}
+
+lsidset devLsiSoft = {
+ 5, NULL, NULL, init_record, NULL, read_string
+};
+epicsExportAddress(dset, devLsiSoft);
=== added file 'src/std/dev/devLsoSoft.c'
--- src/std/dev/devLsoSoft.c 1970-01-01 00:00:00 +0000
+++ src/std/dev/devLsoSoft.c 2012-12-10 21:21:25 +0000
@@ -0,0 +1,26 @@
+/*************************************************************************\
+* Copyright (c) 2012 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.
+\*************************************************************************/
+
+/* Long String Output soft device support
+ *
+ * Author: Andrew Johnson
+ * Date: 2012-11-29
+ */
+
+#include "dbAccess.h"
+#include "lsoRecord.h"
+#include "epicsExport.h"
+
+static long write_string(lsoRecord *prec)
+{
+ return dbPutLinkLS(&prec->out, prec->val, prec->len);
+}
+
+lsodset devLsoSoft = {
+ 5, NULL, NULL, NULL, NULL, write_string
+};
+epicsExportAddress(dset, devLsoSoft);
=== added file 'src/std/dev/devLsoSoftCallback.c'
--- src/std/dev/devLsoSoftCallback.c 1970-01-01 00:00:00 +0000
+++ src/std/dev/devLsoSoftCallback.c 2012-12-10 21:21:25 +0000
@@ -0,0 +1,51 @@
+/*************************************************************************\
+* Copyright (c) 2012 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.
+\*************************************************************************/
+/* $Revision-Id$ */
+/*
+ * Author: Andrew Johnson
+ * Date: 30 Nov 2012
+ */
+
+#include "alarm.h"
+#include "dbAccess.h"
+#include "recGbl.h"
+#include "lsoRecord.h"
+#include "epicsExport.h"
+
+static long write_string(lsoRecord *prec)
+{
+ struct link *plink = &prec->out;
+ int dtyp = dbGetLinkDBFtype(plink);
+ long len = prec->len;
+ long status;
+
+ if (prec->pact || dtyp < 0)
+ return 0;
+
+ if (dtyp != DBR_CHAR && dtyp != DBF_UCHAR) {
+ dtyp = DBR_STRING;
+ len = 1;
+ }
+
+ if (plink->type != CA_LINK)
+ return dbPutLink(plink, dtyp, prec->val, len);
+
+ status = dbCaPutLinkCallback(plink, dtyp, prec->val, len,
+ dbCaCallbackProcess, plink);
+ if (status) {
+ recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM);
+ return status;
+ }
+
+ prec->pact = TRUE;
+ return 0;
+}
+
+lsodset devLsoSoftCallback = {
+ 5, NULL, NULL, NULL, NULL, write_string
+};
+epicsExportAddress(dset, devLsoSoftCallback);
=== added file 'src/std/dev/devPrintfSoft.c'
--- src/std/dev/devPrintfSoft.c 1970-01-01 00:00:00 +0000
+++ src/std/dev/devPrintfSoft.c 2012-12-10 21:21:25 +0000
@@ -0,0 +1,26 @@
+/*************************************************************************\
+* Copyright (c) 2012 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.
+\*************************************************************************/
+/* $Revision-Id$ */
+/*
+ * Author: Andrew Johnson
+ * Date: 28 Sept 2012
+ */
+
+#include "dbAccess.h"
+#include "printfRecord.h"
+#include "epicsExport.h"
+
+static long write_string(printfRecord *prec)
+{
+ return dbPutLinkLS(&prec->out, prec->val, prec->len);
+}
+
+printfdset devPrintfSoft = {
+ 5, NULL, NULL, NULL, NULL, write_string
+};
+epicsExportAddress(dset, devPrintfSoft);
+
=== added file 'src/std/dev/devPrintfSoftCallback.c'
--- src/std/dev/devPrintfSoftCallback.c 1970-01-01 00:00:00 +0000
+++ src/std/dev/devPrintfSoftCallback.c 2012-12-10 21:21:25 +0000
@@ -0,0 +1,51 @@
+/*************************************************************************\
+* Copyright (c) 2012 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.
+\*************************************************************************/
+/* $Revision-Id$ */
+/*
+ * Author: Andrew Johnson
+ * Date: 28 Sept 2012
+ */
+
+#include "alarm.h"
+#include "dbAccess.h"
+#include "recGbl.h"
+#include "printfRecord.h"
+#include "epicsExport.h"
+
+static long write_string(printfRecord *prec)
+{
+ struct link *plink = &prec->out;
+ int dtyp = dbGetLinkDBFtype(plink);
+ long len = prec->len;
+ long status;
+
+ if (prec->pact || dtyp < 0)
+ return 0;
+
+ if (dtyp != DBR_CHAR && dtyp != DBF_UCHAR) {
+ dtyp = DBR_STRING;
+ len = 1;
+ }
+
+ if (plink->type != CA_LINK)
+ return dbPutLink(plink, dtyp, prec->val, len);
+
+ status = dbCaPutLinkCallback(plink, dtyp, prec->val, len,
+ dbCaCallbackProcess, plink);
+ if (status) {
+ recGblSetSevr(prec, LINK_ALARM, INVALID_ALARM);
+ return status;
+ }
+
+ prec->pact = TRUE;
+ return 0;
+}
+
+printfdset devPrintfSoftCallback = {
+ 5, NULL, NULL, NULL, NULL, write_string
+};
+epicsExportAddress(dset, devPrintfSoftCallback);
=== removed file 'src/std/dev/devSoStdio.c'
--- src/std/dev/devSoStdio.c 2012-07-18 21:45:23 +0000
+++ src/std/dev/devSoStdio.c 1970-01-01 00:00:00 +0000
@@ -1,108 +0,0 @@
-/*************************************************************************\
-* Copyright (c) 2008 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.
-\*************************************************************************/
-
-/* $Revision-Id$ */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "dbCommon.h"
-#include "devSup.h"
-#include "errlog.h"
-#include "recGbl.h"
-#include "recSup.h"
-#include "stringoutRecord.h"
-#include "epicsExport.h"
-
-typedef int (*PRINTFFUNC)(const char *fmt, ...);
-
-static int stderrPrintf(const char *fmt, ...);
-static int logPrintf(const char *fmt, ...);
-
-
-static struct outStream {
- const char *name;
- PRINTFFUNC print;
-} outStreams[] = {
- {"stdout", printf},
- {"stderr", stderrPrintf},
- {"errlog", logPrintf},
- {NULL, NULL}
-};
-
-static int stderrPrintf(const char *fmt, ...) {
- va_list pvar;
- int retval;
-
- va_start(pvar, fmt);
- retval = vfprintf(stderr, fmt, pvar);
- va_end (pvar);
-
- return retval;
-}
-
-static int logPrintf(const char *fmt, ...) {
- va_list pvar;
- int retval;
-
- va_start(pvar, fmt);
- retval = errlogVprintf(fmt, pvar);
- va_end (pvar);
-
- return retval;
-}
-
-static long add(dbCommon *pcommon) {
- stringoutRecord *prec = (stringoutRecord *) pcommon;
- struct outStream *pstream;
-
- if (prec->out.type != INST_IO)
- return S_dev_badOutType;
-
- for (pstream = outStreams; pstream->name; ++pstream) {
- if (strcmp(prec->out.value.instio.string, pstream->name) == 0) {
- prec->dpvt = pstream;
- return 0;
- }
- }
- prec->dpvt = NULL;
- return -1;
-}
-
-static long del(dbCommon *pcommon) {
- stringoutRecord *prec = (stringoutRecord *) pcommon;
-
- prec->dpvt = NULL;
- return 0;
-}
-
-static struct dsxt dsxtSoStdio = {
- add, del
-};
-
-static long init(int pass)
-{
- if (pass == 0) devExtend(&dsxtSoStdio);
- return 0;
-}
-
-static long write_string(stringoutRecord *prec)
-{
- struct outStream *pstream = (struct outStream *)prec->dpvt;
- if (pstream)
- pstream->print("%s\n", prec->val);
- return 0;
-}
-
-/* Create the dset for devSoStdio */
-static struct {
- dset common;
- DEVSUPFUN write;
-} devSoStdio = {
- {5, NULL, init, NULL, NULL}, write_string
-};
-epicsExportAddress(dset, devSoStdio);
=== modified file 'src/std/dev/devSoft.dbd'
--- src/std/dev/devSoft.dbd 2012-07-11 23:07:23 +0000
+++ src/std/dev/devSoft.dbd 2012-12-10 21:21:25 +0000
@@ -9,10 +9,13 @@
device(histogram,CONSTANT,devHistogramSoft,"Soft Channel")
device(longin,CONSTANT,devLiSoft,"Soft Channel")
device(longout,CONSTANT,devLoSoft,"Soft Channel")
+device(lsi,CONSTANT,devLsiSoft,"Soft Channel")
+device(lso,CONSTANT,devLsoSoft,"Soft Channel")
device(mbbi,CONSTANT,devMbbiSoft,"Soft Channel")
device(mbbiDirect,CONSTANT,devMbbiDirectSoft,"Soft Channel")
device(mbbo,CONSTANT,devMbboSoft,"Soft Channel")
device(mbboDirect,CONSTANT,devMbboDirectSoft,"Soft Channel")
+device(printf,CONSTANT,devPrintfSoft,"Soft Channel")
device(stringin,CONSTANT,devSiSoft,"Soft Channel")
device(stringout,CONSTANT,devSoSoft,"Soft Channel")
device(subArray,CONSTANT,devSASoft,"Soft Channel")
@@ -34,10 +37,12 @@
device(calcout,CONSTANT,devCalcoutSoftCallback,"Async Soft Channel")
device(longin,CONSTANT,devLiSoftCallback,"Async Soft Channel")
device(longout,CONSTANT,devLoSoftCallback,"Async Soft Channel")
+device(lso,CONSTANT,devLsoSoftCallback,"Async Soft Channel")
device(mbbi,CONSTANT,devMbbiSoftCallback,"Async Soft Channel")
device(mbbiDirect,CONSTANT,devMbbiDirectSoftCallback,"Async Soft Channel")
device(mbbo,CONSTANT,devMbboSoftCallback,"Async Soft Channel")
device(mbboDirect,CONSTANT,devMbboDirectSoftCallback,"Async Soft Channel")
+device(printf,CONSTANT,devPrintfSoftCallback,"Async Soft Channel")
device(stringin,CONSTANT,devSiSoftCallback,"Async Soft Channel")
device(stringout,CONSTANT,devSoSoftCallback,"Async Soft Channel")
@@ -49,6 +54,8 @@
device(longin, INST_IO,devLiGeneralTime,"General Time")
device(stringin,INST_IO,devSiGeneralTime,"General Time")
+device(lso,INST_IO,devLsoStdio,"stdio")
+device(printf,INST_IO,devPrintfStdio,"stdio")
device(stringout,INST_IO,devSoStdio,"stdio")
device(bi, INST_IO, devBiDbState, "Db State")
=== added file 'src/std/dev/devStdio.c'
--- src/std/dev/devStdio.c 1970-01-01 00:00:00 +0000
+++ src/std/dev/devStdio.c 2012-12-10 21:21:25 +0000
@@ -0,0 +1,212 @@
+/*************************************************************************\
+* Copyright (c) 2008 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.
+\*************************************************************************/
+
+/* $Revision-Id$ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "dbCommon.h"
+#include "devSup.h"
+#include "errlog.h"
+#include "recGbl.h"
+#include "recSup.h"
+#include "lsoRecord.h"
+#include "printfRecord.h"
+#include "stringoutRecord.h"
+#include "epicsExport.h"
+
+typedef int (*PRINTFFUNC)(const char *fmt, ...);
+
+static int stderrPrintf(const char *fmt, ...);
+static int logPrintf(const char *fmt, ...);
+
+
+static struct outStream {
+ const char *name;
+ PRINTFFUNC print;
+} outStreams[] = {
+ {"stdout", printf},
+ {"stderr", stderrPrintf},
+ {"errlog", logPrintf},
+ {NULL, NULL}
+};
+
+static int stderrPrintf(const char *fmt, ...) {
+ va_list pvar;
+ int retval;
+
+ va_start(pvar, fmt);
+ retval = vfprintf(stderr, fmt, pvar);
+ va_end (pvar);
+
+ return retval;
+}
+
+static int logPrintf(const char *fmt, ...) {
+ va_list pvar;
+ int retval;
+
+ va_start(pvar, fmt);
+ retval = errlogVprintf(fmt, pvar);
+ va_end (pvar);
+
+ return retval;
+}
+
+
+/* lso device support */
+
+static long add_lso(dbCommon *pcommon) {
+ lsoRecord *prec = (lsoRecord *) pcommon;
+ struct outStream *pstream;
+
+ if (prec->out.type != INST_IO)
+ return S_dev_badOutType;
+
+ for (pstream = outStreams; pstream->name; ++pstream) {
+ if (strcmp(prec->out.value.instio.string, pstream->name) == 0) {
+ prec->dpvt = pstream;
+ return 0;
+ }
+ }
+ prec->dpvt = NULL;
+ return -1;
+}
+
+static long del_lso(dbCommon *pcommon) {
+ lsoRecord *prec = (lsoRecord *) pcommon;
+
+ prec->dpvt = NULL;
+ return 0;
+}
+
+static struct dsxt dsxtLsoStdio = {
+ add_lso, del_lso
+};
+
+static long init_lso(int pass)
+{
+ if (pass == 0) devExtend(&dsxtLsoStdio);
+ return 0;
+}
+
+static long write_lso(lsoRecord *prec)
+{
+ struct outStream *pstream = (struct outStream *)prec->dpvt;
+ if (pstream)
+ pstream->print("%s\n", prec->val);
+ return 0;
+}
+
+lsodset devLsoStdio = {
+ 5, NULL, init_lso, NULL, NULL, write_lso
+};
+epicsExportAddress(dset, devLsoStdio);
+
+
+/* printf device support */
+
+static long add_printf(dbCommon *pcommon) {
+ printfRecord *prec = (printfRecord *) pcommon;
+ struct outStream *pstream;
+
+ if (prec->out.type != INST_IO)
+ return S_dev_badOutType;
+
+ for (pstream = outStreams; pstream->name; ++pstream) {
+ if (strcmp(prec->out.value.instio.string, pstream->name) == 0) {
+ prec->dpvt = pstream;
+ return 0;
+ }
+ }
+ prec->dpvt = NULL;
+ return -1;
+}
+
+static long del_printf(dbCommon *pcommon) {
+ printfRecord *prec = (printfRecord *) pcommon;
+
+ prec->dpvt = NULL;
+ return 0;
+}
+
+static struct dsxt dsxtPrintfStdio = {
+ add_printf, del_printf
+};
+
+static long init_printf(int pass)
+{
+ if (pass == 0) devExtend(&dsxtPrintfStdio);
+ return 0;
+}
+
+static long write_printf(printfRecord *prec)
+{
+ struct outStream *pstream = (struct outStream *)prec->dpvt;
+ if (pstream)
+ pstream->print("%s\n", prec->val);
+ return 0;
+}
+
+printfdset devPrintfStdio = {
+ 5, NULL, init_printf, NULL, NULL, write_printf
+};
+epicsExportAddress(dset, devPrintfStdio);
+
+
+/* stringout device support */
+
+static long add_stringout(dbCommon *pcommon) {
+ stringoutRecord *prec = (stringoutRecord *) pcommon;
+ struct outStream *pstream;
+
+ if (prec->out.type != INST_IO)
+ return S_dev_badOutType;
+
+ for (pstream = outStreams; pstream->name; ++pstream) {
+ if (strcmp(prec->out.value.instio.string, pstream->name) == 0) {
+ prec->dpvt = pstream;
+ return 0;
+ }
+ }
+ prec->dpvt = NULL;
+ return -1;
+}
+
+static long del_stringout(dbCommon *pcommon) {
+ stringoutRecord *prec = (stringoutRecord *) pcommon;
+
+ prec->dpvt = NULL;
+ return 0;
+}
+
+static struct dsxt dsxtSoStdio = {
+ add_stringout, del_stringout
+};
+
+static long init_stringout(int pass)
+{
+ if (pass == 0) devExtend(&dsxtSoStdio);
+ return 0;
+}
+
+static long write_stringout(stringoutRecord *prec)
+{
+ struct outStream *pstream = (struct outStream *)prec->dpvt;
+ if (pstream)
+ pstream->print("%s\n", prec->val);
+ return 0;
+}
+
+static struct {
+ dset common;
+ DEVSUPFUN write;
+} devSoStdio = {
+ {5, NULL, init_stringout, NULL, NULL}, write_stringout
+};
+epicsExportAddress(dset, devSoStdio);
=== modified file 'src/std/rec/Makefile'
--- src/std/rec/Makefile 2011-11-14 23:42:50 +0000
+++ src/std/rec/Makefile 2012-12-10 21:21:25 +0000
@@ -11,67 +11,43 @@
SRC_DIRS += $(STDDIR)/rec
-DBDINC += aaiRecord
-DBDINC += aaoRecord
-DBDINC += aiRecord
-DBDINC += aoRecord
-DBDINC += aSubRecord
-DBDINC += biRecord
-DBDINC += boRecord
-DBDINC += calcRecord
-DBDINC += calcoutRecord
-DBDINC += compressRecord
-DBDINC += dfanoutRecord
-DBDINC += eventRecord
-DBDINC += fanoutRecord
-DBDINC += histogramRecord
-DBDINC += longinRecord
-DBDINC += longoutRecord
-DBDINC += mbbiRecord
-DBDINC += mbbiDirectRecord
-DBDINC += mbboRecord
-DBDINC += mbboDirectRecord
-DBDINC += permissiveRecord
-DBDINC += selRecord
-DBDINC += seqRecord
-DBDINC += stateRecord
-DBDINC += stringinRecord
-DBDINC += stringoutRecord
-DBDINC += subRecord
-DBDINC += subArrayRecord
-DBDINC += waveformRecord
+stdRecords += aaiRecord
+stdRecords += aaoRecord
+stdRecords += aiRecord
+stdRecords += aoRecord
+stdRecords += aSubRecord
+stdRecords += biRecord
+stdRecords += boRecord
+stdRecords += calcRecord
+stdRecords += calcoutRecord
+stdRecords += compressRecord
+stdRecords += dfanoutRecord
+stdRecords += eventRecord
+stdRecords += fanoutRecord
+stdRecords += histogramRecord
+stdRecords += longinRecord
+stdRecords += longoutRecord
+stdRecords += lsiRecord
+stdRecords += lsoRecord
+stdRecords += mbbiRecord
+stdRecords += mbbiDirectRecord
+stdRecords += mbboRecord
+stdRecords += mbboDirectRecord
+stdRecords += permissiveRecord
+stdRecords += printfRecord
+stdRecords += selRecord
+stdRecords += seqRecord
+stdRecords += stateRecord
+stdRecords += stringinRecord
+stdRecords += stringoutRecord
+stdRecords += subRecord
+stdRecords += subArrayRecord
+stdRecords += waveformRecord
+DBDINC += $(stdRecords)
DBD += stdRecords.dbd
-stdRecords_DBD = $(patsubst %,%.dbd,$(DBDINC))
+stdRecords_DBD = $(patsubst %,%.dbd,$(stdRecords))
-dbRecStd_SRCS += aaiRecord.c
-dbRecStd_SRCS += aaoRecord.c
-dbRecStd_SRCS += aiRecord.c
-dbRecStd_SRCS += aoRecord.c
-dbRecStd_SRCS += aSubRecord.c
-dbRecStd_SRCS += biRecord.c
-dbRecStd_SRCS += boRecord.c
-dbRecStd_SRCS += calcRecord.c
-dbRecStd_SRCS += calcoutRecord.c
-dbRecStd_SRCS += compressRecord.c
-dbRecStd_SRCS += dfanoutRecord.c
-dbRecStd_SRCS += eventRecord.c
-dbRecStd_SRCS += fanoutRecord.c
-dbRecStd_SRCS += histogramRecord.c
-dbRecStd_SRCS += longinRecord.c
-dbRecStd_SRCS += longoutRecord.c
-dbRecStd_SRCS += mbbiRecord.c
-dbRecStd_SRCS += mbbiDirectRecord.c
-dbRecStd_SRCS += mbboRecord.c
-dbRecStd_SRCS += mbboDirectRecord.c
-dbRecStd_SRCS += permissiveRecord.c
-dbRecStd_SRCS += selRecord.c
-dbRecStd_SRCS += seqRecord.c
-dbRecStd_SRCS += stateRecord.c
-dbRecStd_SRCS += stringinRecord.c
-dbRecStd_SRCS += stringoutRecord.c
-dbRecStd_SRCS += subRecord.c
-dbRecStd_SRCS += subArrayRecord.c
-dbRecStd_SRCS += waveformRecord.c
+dbRecStd_SRCS += $(patsubst %,%.c,$(stdRecords))
=== modified file 'src/std/rec/RULES'
--- src/std/rec/RULES 2011-02-27 00:24:51 +0000
+++ src/std/rec/RULES 2012-12-10 21:21:25 +0000
@@ -9,7 +9,7 @@
# This is a Makefile fragment, see src/std/Makefile.
-$(COMMON_DIR)/stdRecords.dbd:
+$(COMMON_DIR)/stdRecords.dbd: ../rec/Makefile
$(RM) $@
$(PERL) $(TOOLS)/makeIncludeDbd.pl $(stdRecords_DBD) $@
=== added file 'src/std/rec/lsiRecord.c'
--- src/std/rec/lsiRecord.c 1970-01-01 00:00:00 +0000
+++ src/std/rec/lsiRecord.c 2012-12-10 21:21:25 +0000
@@ -0,0 +1,284 @@
+/*************************************************************************\
+* Copyright (c) 2012 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.
+\*************************************************************************/
+
+/* Long String Input record type */
+/*
+ * Author: Andrew Johnson
+ * Date: 2012-11-27
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "dbDefs.h"
+#include "errlog.h"
+#include "alarm.h"
+#include "cantProceed.h"
+#include "dbAccess.h"
+#include "dbEvent.h"
+#include "dbFldTypes.h"
+#include "errMdef.h"
+#include "menuPost.h"
+#include "menuYesNo.h"
+#include "recSup.h"
+#include "recGbl.h"
+#include "special.h"
+#define GEN_SIZE_OFFSET
+#include "lsiRecord.h"
+#undef GEN_SIZE_OFFSET
+#include "epicsExport.h"
+
+static void monitor(lsiRecord *);
+static long readValue(lsiRecord *);
+
+static long init_record(lsiRecord *prec, int pass)
+{
+ lsidset *pdset;
+
+ if (pass == 0) {
+ size_t sizv = prec->sizv;
+
+ if (sizv < 16) {
+ sizv = 16; /* Enforce a minimum size for the VAL field */
+ prec->sizv = sizv;
+ }
+
+ prec->val = callocMustSucceed(1, sizv, "lsi::init_record");
+ prec->len = 0;
+ prec->oval = callocMustSucceed(1, sizv, "lsi::init_record");
+ prec->olen = 0;
+ return 0;
+ }
+
+ dbLoadLink(&prec->siml, DBF_USHORT, &prec->simm);
+
+ pdset = (lsidset *) prec->dset;
+ if (!pdset) {
+ recGblRecordError(S_dev_noDSET, prec, "lsi: init_record");
+ return S_dev_noDSET;
+ }
+
+ /* must have a read_string function */
+ if (pdset->number < 5 || !pdset->read_string) {
+ recGblRecordError(S_dev_missingSup, prec, "lsi: init_record");
+ return S_dev_missingSup;
+ }
+
+ if (pdset->init_record) {
+ long status = pdset->init_record(prec);
+
+ if (status)
+ return status;
+ }
+
+ if (prec->len) {
+ strcpy(prec->oval, prec->val);
+ prec->olen = prec->len;
+ prec->udf = FALSE;
+ }
+
+ return 0;
+}
+
+static long process(lsiRecord *prec)
+{
+ int pact = prec->pact;
+ lsidset *pdset = (lsidset *) prec->dset;
+ long status = 0;
+
+ if (!pdset || !pdset->read_string) {
+ prec->pact = TRUE;
+ recGblRecordError(S_dev_missingSup, prec, "lsi: read_string");
+ return S_dev_missingSup;
+ }
+
+ status = readValue(prec); /* read the new value */
+ if (!pact && prec->pact)
+ return 0;
+
+ prec->pact = TRUE;
+ recGblGetTimeStamp(prec);
+
+ monitor(prec);
+
+ /* Wrap up */
+ recGblFwdLink(prec);
+ prec->pact = FALSE;
+ return status;
+}
+
+static long cvt_dbaddr(DBADDR *paddr)
+{
+ lsiRecord *prec = (lsiRecord *) paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+
+ if (fieldIndex == lsiRecordVAL) {
+ paddr->pfield = prec->val;
+ paddr->special = SPC_MOD;
+ }
+ else if (fieldIndex == lsiRecordOVAL) {
+ paddr->pfield = prec->oval;
+ paddr->special = SPC_NOMOD;
+ }
+ else {
+ errlogPrintf("lsiRecord::cvt_dbaddr called for %s.%s\n",
+ prec->name, paddr->pfldDes->name);
+ return -1;
+ }
+
+ paddr->no_elements = 1;
+ paddr->field_type = DBF_STRING;
+ paddr->dbr_field_type = DBF_STRING;
+ paddr->field_size = prec->sizv;
+ return 0;
+}
+
+static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
+{
+ lsiRecord *prec = (lsiRecord *) paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+
+ if (fieldIndex == lsiRecordVAL)
+ *no_elements = prec->len;
+ else if (fieldIndex == lsiRecordOVAL)
+ *no_elements = prec->olen;
+ else
+ return -1;
+
+ *offset = 0;
+ return 0;
+}
+
+static long put_array_info(DBADDR *paddr, long nNew)
+{
+ lsiRecord *prec = (lsiRecord *) paddr->precord;
+
+ if (nNew == prec->sizv)
+ --nNew; /* truncated string */
+ prec->val[nNew] = 0; /* ensure data is terminated */
+
+ return 0;
+}
+
+static long special(DBADDR *paddr, int after)
+{
+ lsiRecord *prec = (lsiRecord *) paddr->precord;
+
+ if (!after)
+ return 0;
+
+ /* We set prec->len here and not in put_array_info()
+ * because that does not get called if the put was
+ * done using a DBR_STRING type.
+ */
+ prec->len = strlen(prec->val) + 1;
+ db_post_events(prec, &prec->len, DBE_VALUE | DBE_LOG);
+
+ return 0;
+}
+
+static void monitor(lsiRecord *prec)
+{
+ epicsUInt16 events = recGblResetAlarms(prec);
+
+ if (prec->len != prec->olen ||
+ memcmp(prec->oval, prec->val, prec->len)) {
+ events |= DBE_VALUE | DBE_LOG;
+ memcpy(prec->oval, prec->val, prec->len);
+ }
+
+ if (prec->len != prec->olen) {
+ prec->olen = prec->len;
+ db_post_events(prec, &prec->len, DBE_VALUE | DBE_LOG);
+ }
+
+ if (prec->mpst == menuPost_Always)
+ events |= DBE_VALUE;
+ if (prec->apst == menuPost_Always)
+ events |= DBE_LOG;
+
+ if (events)
+ db_post_events(prec, prec->val, events);
+}
+
+static long readValue(lsiRecord *prec)
+{
+ long status;
+ lsidset *pdset = (lsidset *) prec->dset;
+
+ if (prec->pact)
+ goto read;
+
+ status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0);
+ if (status)
+ return status;
+
+ switch (prec->simm) {
+ case menuYesNoNO:
+read:
+ status = pdset->read_string(prec);
+ break;
+
+ case menuYesNoYES:
+ recGblSetSevr(prec, SIMM_ALARM, prec->sims);
+ status = dbGetLinkLS(&prec->siol, prec->val, prec->sizv, &prec->len);
+ break;
+
+ default:
+ recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
+ status = -1;
+ }
+
+ if (!status)
+ prec->udf = FALSE;
+
+ return status;
+}
+
+
+/* Create Record Support Entry Table*/
+
+#define report NULL
+#define initialize NULL
+/* init_record */
+/* process */
+/* special */
+#define get_value NULL
+/* cvt_dbaddr */
+/* get_array_info */
+/* put_array_info */
+#define get_units NULL
+#define get_precision NULL
+#define get_enum_str NULL
+#define get_enum_strs NULL
+#define put_enum_str NULL
+#define get_graphic_double NULL
+#define get_control_double NULL
+#define get_alarm_double NULL
+
+rset lsiRSET = {
+ 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, lsiRSET);
=== added file 'src/std/rec/lsiRecord.dbd'
--- src/std/rec/lsiRecord.dbd 1970-01-01 00:00:00 +0000
+++ src/std/rec/lsiRecord.dbd 2012-12-10 21:21:25 +0000
@@ -0,0 +1,88 @@
+#*************************************************************************
+# Copyright (c) 2012 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.
+#*************************************************************************
+
+recordtype(lsi) {
+ include "dbCommon.dbd"
+ %#include "devSup.h"
+ %
+ %/* Declare Device Support Entry Table */
+ %typedef struct lsidset {
+ % long number;
+ % DEVSUPFUN report;
+ % DEVSUPFUN init;
+ % DEVSUPFUN init_record;
+ % DEVSUPFUN get_ioint_info;
+ % DEVSUPFUN read_string;
+ %} lsidset;
+ %
+ field(VAL,DBF_NOACCESS) {
+ prompt("Current Value")
+ asl(ASL0)
+ pp(TRUE)
+ special(SPC_DBADDR)
+ extra("char *val")
+ }
+ field(OVAL,DBF_NOACCESS) {
+ prompt("Old Value")
+ special(SPC_DBADDR)
+ interest(3)
+ extra("char *oval")
+ }
+ field(SIZV,DBF_USHORT) {
+ prompt("Size of buffers")
+ promptgroup(GUI_OUTPUT)
+ special(SPC_NOMOD)
+ interest(1)
+ initial("41")
+ }
+ field(LEN,DBF_ULONG) {
+ prompt("Length of VAL")
+ special(SPC_NOMOD)
+ }
+ field(OLEN,DBF_ULONG) {
+ prompt("Length of OVAL")
+ special(SPC_NOMOD)
+ }
+ field(INP,DBF_INLINK) {
+ prompt("Input Specification")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(MPST,DBF_MENU) {
+ prompt("Post Value Monitors")
+ promptgroup(GUI_DISPLAY)
+ interest(1)
+ menu(menuPost)
+ }
+ field(APST,DBF_MENU) {
+ prompt("Post Archive Monitors")
+ promptgroup(GUI_DISPLAY)
+ interest(1)
+ menu(menuPost)
+ }
+ field(SIML,DBF_INLINK) {
+ prompt("Simulation Mode Link")
+ promptgroup(GUI_INPUTS)
+ interest(2)
+ }
+ field(SIMM,DBF_MENU) {
+ prompt("Simulation Mode")
+ interest(2)
+ menu(menuYesNo)
+ }
+ field(SIMS,DBF_MENU) {
+ prompt("Simulation Mode Severity")
+ promptgroup(GUI_INPUTS)
+ interest(2)
+ menu(menuAlarmSevr)
+ }
+ field(SIOL,DBF_INLINK) {
+ prompt("Sim Input Specifctn")
+ promptgroup(GUI_INPUTS)
+ interest(2)
+ }
+}
=== added file 'src/std/rec/lsoRecord.c'
--- src/std/rec/lsoRecord.c 1970-01-01 00:00:00 +0000
+++ src/std/rec/lsoRecord.c 2012-12-10 21:21:25 +0000
@@ -0,0 +1,322 @@
+/*************************************************************************\
+* Copyright (c) 2012 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.
+\*************************************************************************/
+
+/* Long String Output record type */
+/*
+ * Author: Andrew Johnson
+ * Date: 2012-11-28
+ */
+
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "dbDefs.h"
+#include "errlog.h"
+#include "alarm.h"
+#include "cantProceed.h"
+#include "dbAccess.h"
+#include "dbEvent.h"
+#include "dbFldTypes.h"
+#include "devSup.h"
+#include "errMdef.h"
+#include "menuIvoa.h"
+#include "menuOmsl.h"
+#include "menuPost.h"
+#include "menuYesNo.h"
+#include "recSup.h"
+#include "recGbl.h"
+#include "special.h"
+#define GEN_SIZE_OFFSET
+#include "lsoRecord.h"
+#undef GEN_SIZE_OFFSET
+#include "epicsExport.h"
+
+static void monitor(lsoRecord *);
+static long writeValue(lsoRecord *);
+
+static long init_record(lsoRecord *prec, int pass)
+{
+ lsodset *pdset;
+
+ if (pass == 0) {
+ size_t sizv = prec->sizv;
+
+ if (sizv < 16) {
+ sizv = 16; /* Enforce a minimum size for the VAL field */
+ prec->sizv = sizv;
+ }
+
+ prec->val = callocMustSucceed(1, sizv, "lso::init_record");
+ prec->len = 0;
+ prec->oval = callocMustSucceed(1, sizv, "lso::init_record");
+ prec->olen = 0;
+ return 0;
+ }
+
+ dbLoadLink(&prec->siml, DBF_USHORT, &prec->simm);
+
+ pdset = (lsodset *) prec->dset;
+ if (!pdset) {
+ recGblRecordError(S_dev_noDSET, prec, "lso: init_record");
+ return S_dev_noDSET;
+ }
+
+ /* must have a write_string function defined */
+ if (pdset->number < 5 || !pdset->write_string) {
+ recGblRecordError(S_dev_missingSup, prec, "lso: init_record");
+ return S_dev_missingSup;
+ }
+
+ dbLoadLinkLS(&prec->dol, prec->val, prec->sizv, &prec->len);
+
+ if (pdset->init_record) {
+ long status = pdset->init_record(prec);
+
+ if (status)
+ return status;
+ }
+
+ if (prec->len) {
+ strcpy(prec->oval, prec->val);
+ prec->olen = prec->len;
+ prec->udf = FALSE;
+ }
+
+ return 0;
+}
+
+static long process(lsoRecord *prec)
+{
+ int pact = prec->pact;
+ lsodset *pdset = (lsodset *) prec->dset;
+ long status = 0;
+
+ if (!pdset || !pdset->write_string) {
+ prec->pact = TRUE;
+ recGblRecordError(S_dev_missingSup, prec, "lso: write_string");
+ return S_dev_missingSup;
+ }
+
+ if (!pact && prec->omsl == menuOmslclosed_loop)
+ if (!dbGetLinkLS(&prec->dol, prec->val, prec->sizv, &prec->len))
+ prec->udf = FALSE;
+
+ if (prec->udf)
+ recGblSetSevr(prec, UDF_ALARM, INVALID_ALARM);
+
+ 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) {
+ size_t size = prec->sizv - 1;
+
+ strncpy(prec->val, prec->ivov, size);
+ prec->val[size] = 0;
+ prec->len = strlen(prec->val) + 1;
+ }
+ status = writeValue(prec); /* write the new value */
+ break;
+
+ default:
+ status = -1;
+ recGblRecordError(S_db_badField, prec,
+ "lso:process Bad IVOA choice");
+ }
+ }
+
+ /* Asynchronous if device support set pact */
+ if (!pact && prec->pact)
+ return status;
+
+ prec->pact = TRUE;
+ recGblGetTimeStamp(prec);
+
+ monitor(prec);
+
+ /* Wrap up */
+ recGblFwdLink(prec);
+ prec->pact = FALSE;
+ return status;
+}
+
+static long cvt_dbaddr(DBADDR *paddr)
+{
+ lsoRecord *prec = (lsoRecord *) paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+
+ if (fieldIndex == lsoRecordVAL) {
+ paddr->pfield = prec->val;
+ paddr->special = SPC_MOD;
+ }
+ else if (fieldIndex == lsoRecordOVAL) {
+ paddr->pfield = prec->oval;
+ paddr->special = SPC_NOMOD;
+ }
+ else {
+ errlogPrintf("lsoRecord::cvt_dbaddr called for %s.%s\n",
+ prec->name, paddr->pfldDes->name);
+ return -1;
+ }
+
+ paddr->no_elements = 1;
+ paddr->field_type = DBF_STRING;
+ paddr->dbr_field_type = DBF_STRING;
+ paddr->field_size = prec->sizv;
+ return 0;
+}
+
+static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
+{
+ lsoRecord *prec = (lsoRecord *) paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+
+ if (fieldIndex == lsoRecordVAL)
+ *no_elements = prec->len;
+ else if (fieldIndex == lsoRecordOVAL)
+ *no_elements = prec->olen;
+ else
+ return -1;
+
+ *offset = 0;
+ return 0;
+}
+
+static long put_array_info(DBADDR *paddr, long nNew)
+{
+ lsoRecord *prec = (lsoRecord *) paddr->precord;
+
+ if (nNew == prec->sizv)
+ --nNew; /* truncated string */
+ prec->val[nNew] = 0; /* ensure data is terminated */
+
+ return 0;
+}
+
+static long special(DBADDR *paddr, int after)
+{
+ lsoRecord *prec = (lsoRecord *) paddr->precord;
+
+ if (!after)
+ return 0;
+
+ /* We set prec->len here and not in put_array_info()
+ * because that does not get called if the put was
+ * done using a DBR_STRING type.
+ */
+ prec->len = strlen(prec->val) + 1;
+ db_post_events(prec, &prec->len, DBE_VALUE | DBE_LOG);
+
+ return 0;
+}
+
+static void monitor(lsoRecord *prec)
+{
+ epicsUInt16 events = recGblResetAlarms(prec);
+
+ if (prec->len != prec->olen ||
+ memcmp(prec->oval, prec->val, prec->len)) {
+ events |= DBE_VALUE | DBE_LOG;
+ memcpy(prec->oval, prec->val, prec->len);
+ }
+
+ if (prec->len != prec->olen) {
+ prec->olen = prec->len;
+ db_post_events(prec, &prec->len, DBE_VALUE | DBE_LOG);
+ }
+
+ if (prec->mpst == menuPost_Always)
+ events |= DBE_VALUE;
+ if (prec->apst == menuPost_Always)
+ events |= DBE_LOG;
+
+ if (events)
+ db_post_events(prec, prec->val, events);
+}
+
+static long writeValue(lsoRecord *prec)
+{
+ long status;
+ lsodset *pdset = (lsodset *) prec->dset;
+
+ if (prec->pact)
+ goto write;
+
+ status = dbGetLink(&prec->siml, DBR_USHORT, &prec->simm, 0, 0);
+ if (status)
+ return(status);
+
+ switch (prec->simm) {
+ case menuYesNoNO:
+write:
+ status = pdset->write_string(prec);
+ break;
+
+ case menuYesNoYES:
+ recGblSetSevr(prec, SIMM_ALARM, prec->sims);
+ status = dbPutLink(&prec->siol,DBR_STRING, prec->val,1);
+ break;
+
+ default:
+ recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
+ status = -1;
+ }
+
+ return status;
+}
+
+/* Create Record Support Entry Table*/
+
+#define report NULL
+#define initialize NULL
+/* init_record */
+/* process */
+/* special */
+#define get_value NULL
+/* cvt_dbaddr */
+/* get_array_info */
+/* put_array_info */
+#define get_units NULL
+#define get_precision NULL
+#define get_enum_str NULL
+#define get_enum_strs NULL
+#define put_enum_str NULL
+#define get_graphic_double NULL
+#define get_control_double NULL
+#define get_alarm_double NULL
+
+rset lsoRSET = {
+ 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, lsoRSET);
=== added file 'src/std/rec/lsoRecord.dbd'
--- src/std/rec/lsoRecord.dbd 1970-01-01 00:00:00 +0000
+++ src/std/rec/lsoRecord.dbd 2012-12-10 21:21:25 +0000
@@ -0,0 +1,112 @@
+#*************************************************************************
+# Copyright (c) 2012 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.
+#*************************************************************************
+
+recordtype(lso) {
+ include "dbCommon.dbd"
+ %#include "devSup.h"
+ %
+ %/* Declare Device Support Entry Table */
+ %typedef struct lsodset {
+ % long number;
+ % DEVSUPFUN report;
+ % DEVSUPFUN init;
+ % DEVSUPFUN init_record;
+ % DEVSUPFUN get_ioint_info;
+ % DEVSUPFUN write_string;
+ %} lsodset;
+ %
+ field(VAL,DBF_NOACCESS) {
+ prompt("Current Value")
+ asl(ASL0)
+ pp(TRUE)
+ special(SPC_DBADDR)
+ extra("char *val")
+ }
+ field(OVAL,DBF_NOACCESS) {
+ prompt("Previous Value")
+ special(SPC_DBADDR)
+ interest(3)
+ extra("char *oval")
+ }
+ field(SIZV,DBF_USHORT) {
+ prompt("Size of buffers")
+ promptgroup(GUI_OUTPUT)
+ special(SPC_NOMOD)
+ interest(1)
+ initial("41")
+ }
+ field(LEN,DBF_ULONG) {
+ prompt("Length of VAL")
+ special(SPC_NOMOD)
+ }
+ field(OLEN,DBF_ULONG) {
+ prompt("Length of OVAL")
+ special(SPC_NOMOD)
+ interest(3)
+ }
+ field(DOL,DBF_INLINK) {
+ prompt("Desired Output Link")
+ promptgroup(GUI_OUTPUT)
+ interest(1)
+ }
+ field(IVOA,DBF_MENU) {
+ prompt("INVALID Output Action")
+ promptgroup(GUI_OUTPUT)
+ interest(2)
+ menu(menuIvoa)
+ }
+ field(IVOV,DBF_STRING) {
+ prompt("INVALID Output Value")
+ promptgroup(GUI_OUTPUT)
+ interest(2)
+ size(40)
+ }
+ field(OMSL,DBF_MENU) {
+ prompt("Output Mode Select")
+ promptgroup(GUI_OUTPUT)
+ interest(1)
+ menu(menuOmsl)
+ }
+ field(OUT,DBF_OUTLINK) {
+ prompt("Output Specification")
+ promptgroup(GUI_OUTPUT)
+ interest(1)
+ }
+ field(MPST,DBF_MENU) {
+ prompt("Post Value Monitors")
+ promptgroup(GUI_DISPLAY)
+ interest(1)
+ menu(menuPost)
+ }
+ field(APST,DBF_MENU) {
+ prompt("Post Archive Monitors")
+ promptgroup(GUI_DISPLAY)
+ interest(1)
+ menu(menuPost)
+ }
+ field(SIML,DBF_INLINK) {
+ prompt("Sim Mode link")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(SIMM,DBF_MENU) {
+ prompt("Simulation Mode")
+ interest(1)
+ menu(menuYesNo)
+ }
+ field(SIMS,DBF_MENU) {
+ prompt("Sim mode Alarm Svrty")
+ promptgroup(GUI_INPUTS)
+ interest(2)
+ menu(menuAlarmSevr)
+ }
+ field(SIOL,DBF_OUTLINK) {
+ prompt("Sim Output Specifctn")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+}
=== added file 'src/std/rec/printfRecord.c'
--- src/std/rec/printfRecord.c 1970-01-01 00:00:00 +0000
+++ src/std/rec/printfRecord.c 2012-12-10 21:21:25 +0000
@@ -0,0 +1,438 @@
+/*************************************************************************\
+* Copyright (c) 2012 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.
+\*************************************************************************/
+
+/* Printf record type */
+/*
+ * Author: Andrew Johnson
+ * Date: 2012-09-18
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+#include "dbDefs.h"
+#include "errlog.h"
+#include "alarm.h"
+#include "cantProceed.h"
+#include "dbAccess.h"
+#include "dbEvent.h"
+#include "dbFldTypes.h"
+#include "epicsMath.h"
+#include "epicsStdio.h"
+#include "errMdef.h"
+#include "recSup.h"
+#include "recGbl.h"
+#include "special.h"
+#define GEN_SIZE_OFFSET
+#include "printfRecord.h"
+#undef GEN_SIZE_OFFSET
+#include "epicsExport.h"
+
+
+/* Flag bits */
+#define F_CHAR 1
+#define F_SHORT 2
+#define F_LONG 4
+#define F_LEFT 8
+#define F_BADFMT 0x10
+#define F_BADLNK 0x20
+#define F_BAD (F_BADFMT | F_BADLNK)
+
+#define GET_PRINT(VALTYPE, DBRTYPE) \
+ VALTYPE val; \
+ int ok; \
+\
+ if (plink->type == CONSTANT) \
+ ok = recGblInitConstantLink(plink++, DBRTYPE, &val); \
+ else \
+ ok = ! dbGetLink(plink++, DBRTYPE, &val, 0, 0); \
+ if (ok) \
+ added = epicsSnprintf(pval, vspace + 1, format, val); \
+ else \
+ flags |= F_BADLNK
+
+static void doPrintf(printfRecord *prec)
+{
+ const char *pfmt = prec->fmt;
+ DBLINK *plink = &prec->inp0;
+ int linkn = 0;
+ char *pval = prec->val;
+ int vspace = prec->sizv - 1;
+ int ch;
+
+ while (vspace > 0 && (ch = *pfmt++)) {
+ if (ch != '%') {
+ /* Copy literal strings directly into prec->val */
+ *pval++ = ch;
+ --vspace;
+ }
+ else {
+ char format[20];
+ char *pformat = format;
+ int width = 0;
+ int precision = 0;
+ int *pnum = &width;
+ int flags = 0;
+ int added = 0;
+ int cont = 1;
+
+ /* The format directive parsing here is not comprehensive,
+ * in most cases we just copy each directive into format[]
+ * and get epicsSnprintf() do all the work. We do replace
+ * all variable-length field width or precision '*' chars
+ * with an integer read from the next input link, and we
+ * also convert %ls (long string) directives ourself, so
+ * we need to know the width, precision and justification.
+ */
+
+ *pformat++ = ch; /* '%' */
+ while (cont && (ch = *pfmt++)) {
+ *pformat++ = ch;
+ switch (ch) {
+ case '+': case ' ': case '#':
+ break;
+ case '-':
+ flags |= F_LEFT;
+ break;
+ case '.':
+ pnum = &precision;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ *pnum = *pnum * 10 + ch - '0';
+ break;
+ case '*':
+ if (*pnum) {
+ flags |= F_BADFMT;
+ }
+ else if (linkn++ < PRINTF_NLINKS) {
+ epicsInt16 i;
+ int ok;
+
+ if (plink->type == CONSTANT)
+ ok = recGblInitConstantLink(plink++, DBR_SHORT, &i);
+ else
+ ok = ! dbGetLink(plink++, DBR_SHORT, &i, 0, 0);
+ if (ok) {
+ *pnum = i;
+ added = epicsSnprintf(--pformat, 6, "%d", i);
+ pformat += added;
+ }
+ else /* No more LNKn fields */
+ flags |= F_BADLNK;
+ }
+ else
+ flags |= F_BADLNK;
+ break;
+ case 'h':
+ if (flags & F_SHORT)
+ flags = (flags & ~F_SHORT) | F_CHAR;
+ else
+ flags |= F_SHORT;
+ break;
+ case 'l':
+ flags |= F_LONG;
+ break;
+ default:
+ if (strchr("diouxXeEfFgGcs%", ch) == NULL)
+ flags |= F_BADFMT;
+ cont = 0;
+ break;
+ }
+ }
+ if (!ch) /* End of format string */
+ break;
+
+ if (flags & F_BAD)
+ goto bad_format;
+
+ *pformat = 0; /* Terminate our format string */
+
+ if (width < 0) {
+ width = -width;
+ flags |= F_LEFT;
+ }
+ if (precision < 0)
+ precision = 0;
+
+ if (ch == '%') {
+ added = epicsSnprintf(pval, vspace + 1, format);
+ }
+ else if (linkn++ >= PRINTF_NLINKS) {
+ /* No more LNKn fields */
+ flags |= F_BADLNK;
+ }
+ else
+ switch (ch) { /* Conversion character */
+ case 'c': case 'd': case 'i':
+ if (ch == 'c' || flags & F_CHAR) {
+ GET_PRINT(epicsInt8, DBR_CHAR);
+ }
+ else if (flags & F_SHORT) {
+ GET_PRINT(epicsInt16, DBR_SHORT);
+ }
+ else { /* F_LONG has no real effect */
+ GET_PRINT(epicsInt32, DBR_LONG);
+ }
+ break;
+
+ case 'o': case 'x': case 'X': case 'u':
+ if (flags & F_CHAR) {
+ GET_PRINT(epicsUInt8, DBR_UCHAR);
+ }
+ else if (flags & F_SHORT) {
+ GET_PRINT(epicsUInt16, DBR_USHORT);
+ }
+ else { /* F_LONG has no real effect */
+ GET_PRINT(epicsUInt32, DBR_ULONG);
+ }
+ break;
+
+ case 'e': case 'E':
+ case 'f': case 'F':
+ case 'g': case 'G':
+ if (flags & F_SHORT) {
+ GET_PRINT(epicsFloat32, DBR_FLOAT);
+ }
+ else {
+ GET_PRINT(epicsFloat64, DBR_DOUBLE);
+ }
+ break;
+
+ case 's':
+ if (flags & F_LONG && plink->type != CONSTANT) {
+ long n = vspace + 1;
+
+ if (precision && n > precision)
+ n = precision + 1;
+ /* If set, precision is the maximum number of
+ * characters to be printed from the string.
+ * It does not limit the field width however.
+ */
+ if (dbGetLink(plink++, DBR_CHAR, pval, 0, &n))
+ flags |= F_BADLNK;
+ else {
+ int padding;
+
+ /* Terminate string and measure its length */
+ pval[n] = 0;
+ added = strlen(pval);
+ padding = width - added;
+
+ if (padding > 0) {
+ if (flags & F_LEFT) {
+ /* add spaces on RHS */
+ if (width > vspace)
+ padding = vspace - added;
+ memset(pval + added, ' ', padding);
+ }
+ else {
+ /* insert spaces on LHS */
+ int trunc = width - vspace;
+
+ if (trunc < added) {
+ added -= trunc;
+ memmove(pval + padding, pval, added);
+ }
+ else {
+ padding = vspace;
+ added = 0;
+ }
+ memset(pval, ' ', padding);
+ }
+ added += padding;
+ }
+ }
+ }
+ else {
+ char val[MAX_STRING_SIZE];
+ int ok;
+
+ if (plink->type == CONSTANT)
+ ok = recGblInitConstantLink(plink++, DBR_STRING, val);
+ else
+ ok = ! dbGetLink(plink++, DBR_STRING, val, 0, 0);
+ if (ok)
+ added = epicsSnprintf(pval, vspace + 1, format, val);
+ else
+ flags |= F_BADLNK;
+ }
+ break;
+
+ default:
+ errlogPrintf("printfRecord: Unexpected conversion '%s'\n",
+ format);
+ flags |= F_BADFMT;
+ break;
+ }
+
+ if (flags & F_BAD) {
+ bad_format:
+ added = epicsSnprintf(pval, vspace + 1, "%s",
+ flags & F_BADLNK ? prec->ivls : format);
+ }
+
+ if (added <= vspace) {
+ pval += added;
+ vspace -= added;
+ }
+ else {
+ /* Output was truncated */
+ pval += vspace;
+ vspace = 0;
+ }
+ }
+ }
+ *pval++ = 0; /* Terminate the VAL string */
+ prec->len = pval - prec->val;
+}
+
+
+static long init_record(printfRecord *prec, int pass)
+{
+ printfdset *pdset;
+
+ if (pass == 0) {
+ size_t sizv = prec->sizv;
+
+ if (sizv < 16) {
+ sizv = 16; /* Enforce a minimum size for the VAL field */
+ prec->sizv = sizv;
+ }
+
+ prec->val = callocMustSucceed(1, sizv, "printf::init_record");
+ prec->len = 0;
+ return 0;
+ }
+
+ pdset = (printfdset *) prec->dset;
+ if (!pdset)
+ return 0; /* Device support is optional */
+
+ if (pdset->number < 5) {
+ recGblRecordError(S_dev_missingSup, prec, "printf::init_record");
+ return S_dev_missingSup;
+ }
+
+ if (pdset->init_record) {
+ long status = pdset->init_record(prec);
+ if (status)
+ return status;
+ }
+
+ return 0;
+}
+
+static long process(printfRecord *prec)
+{
+ int pact = prec->pact;
+ printfdset *pdset;
+ long status = 0;
+ epicsUInt16 events;
+
+ if (!pact) {
+ doPrintf(prec);
+
+ prec->udf = FALSE;
+ recGblGetTimeStamp(prec);
+ }
+
+ /* Call device support */
+ pdset = (printfdset *) prec->dset;
+ if (pdset &&
+ pdset->number >= 5 &&
+ pdset->write_string) {
+ status = pdset->write_string(prec);
+
+ /* Asynchronous if device support set pact */
+ if (!pact && prec->pact)
+ return status;
+ }
+
+ prec->pact = TRUE;
+
+ /* Post monitor */
+ events = recGblResetAlarms(prec);
+ db_post_events(prec, prec->val, events | DBE_VALUE | DBE_LOG);
+ db_post_events(prec, &prec->len, events | DBE_VALUE | DBE_LOG);
+
+ /* Wrap up */
+ recGblFwdLink(prec);
+ prec->pact = FALSE;
+ return status;
+}
+
+static long cvt_dbaddr(DBADDR *paddr)
+{
+ printfRecord *prec = (printfRecord *)paddr->precord;
+ int fieldIndex = dbGetFieldIndex(paddr);
+
+ if (fieldIndex == printfRecordVAL) {
+ paddr->pfield = prec->val;
+ paddr->no_elements = 1;
+ paddr->field_type = DBF_STRING;
+ paddr->dbr_field_type = DBF_STRING;
+ paddr->field_size = prec->sizv;
+ }
+ else
+ errlogPrintf("printfRecord::cvt_dbaddr called for %s.%s\n",
+ prec->name, paddr->pfldDes->name);
+ return 0;
+}
+
+static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
+{
+ printfRecord *prec = (printfRecord *) paddr->precord;
+
+ *no_elements = prec->len;
+ *offset = 0;
+ return 0;
+}
+
+
+/* Create Record Support Entry Table */
+
+#define report NULL
+#define initialize NULL
+/* init_record */
+/* process */
+#define special NULL
+#define get_value NULL
+/* cvt_dbaddr */
+/* get_array_info */
+#define put_array_info NULL
+#define get_units NULL
+#define get_precision NULL
+#define get_enum_str NULL
+#define get_enum_strs NULL
+#define put_enum_str NULL
+#define get_graphic_double NULL
+#define get_control_double NULL
+#define get_alarm_double NULL
+
+rset printfRSET = {
+ 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, printfRSET);
+
=== added file 'src/std/rec/printfRecord.dbd'
--- src/std/rec/printfRecord.dbd 1970-01-01 00:00:00 +0000
+++ src/std/rec/printfRecord.dbd 2012-12-10 21:21:25 +0000
@@ -0,0 +1,109 @@
+#*************************************************************************
+# Copyright (c) 2012 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.
+#*************************************************************************
+
+recordtype(printf) {
+ include "dbCommon.dbd"
+ %#include "devSup.h"
+ %
+ %/* Declare Device Support Entry Table */
+ %typedef struct printfdset {
+ % long number;
+ % DEVSUPFUN report;
+ % DEVSUPFUN init;
+ % DEVSUPFUN init_record;
+ % DEVSUPFUN get_ioint_info;
+ % DEVSUPFUN write_string;
+ %} printfdset;
+ %
+ field(VAL,DBF_NOACCESS) {
+ prompt("Result")
+ asl(ASL0)
+ pp(TRUE)
+ special(SPC_DBADDR)
+ extra("char *val")
+ }
+ field(SIZV,DBF_USHORT) {
+ prompt("Size of VAL buffer")
+ promptgroup(GUI_OUTPUT)
+ special(SPC_NOMOD)
+ interest(1)
+ initial("41")
+ }
+ field(LEN,DBF_ULONG) {
+ prompt("Length of VAL")
+ special(SPC_NOMOD)
+ }
+ field(OUT,DBF_OUTLINK) {
+ prompt("Output Specification")
+ promptgroup(GUI_OUTPUT)
+ interest(1)
+ }
+ field(FMT,DBF_STRING) {
+ prompt("Format String")
+ promptgroup(GUI_CALC)
+ pp(TRUE)
+ size(81)
+ }
+ field(IVLS,DBF_STRING) {
+ prompt("Invalid Link String")
+ promptgroup(GUI_CALC)
+ size(16)
+ initial("LNK")
+ }
+ field(INP0,DBF_INLINK) {
+ prompt("Input 0")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(INP1,DBF_INLINK) {
+ prompt("Input 1")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(INP2,DBF_INLINK) {
+ prompt("Input 2")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(INP3,DBF_INLINK) {
+ prompt("Input 3")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(INP4,DBF_INLINK) {
+ prompt("Input 4")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(INP5,DBF_INLINK) {
+ prompt("Input 5")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(INP6,DBF_INLINK) {
+ prompt("Input 6")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(INP7,DBF_INLINK) {
+ prompt("Input 7")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(INP8,DBF_INLINK) {
+ prompt("Input 8")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ field(INP9,DBF_INLINK) {
+ prompt("Input 9")
+ promptgroup(GUI_INPUTS)
+ interest(1)
+ }
+ %/* Number of INPx fields defined */
+ %#define PRINTF_NLINKS 10
+}
- Navigate by Date:
- Prev:
Re: [Merge] lp:~anj/epics-base/udf-severity into lp:epics-base Ben Franksen
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
<2012>
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: [Merge] lp:~anj/epics-base/udf-severity into lp:epics-base Ben Franksen
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
<2012>
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|