diff --git a/src/std/dev/Makefile b/src/std/dev/Makefile index 3ee4e7608..2a037ea42 100644 --- a/src/std/dev/Makefile +++ b/src/std/dev/Makefile @@ -38,6 +38,7 @@ dbRecStd_SRCS += devMbboDirectSoft.c 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 @@ -57,9 +58,11 @@ dbRecStd_SRCS += devCalcoutSoftCallback.c dbRecStd_SRCS += devLoSoftCallback.c dbRecStd_SRCS += devMbboSoftCallback.c dbRecStd_SRCS += devMbboDirectSoftCallback.c +dbRecStd_SRCS += devPrintfSoftCallback.c dbRecStd_SRCS += devSoSoftCallback.c dbRecStd_SRCS += devTimestamp.c +dbRecStd_SRCS += devPrintfStdio.c dbRecStd_SRCS += devSoStdio.c dbRecStd_SRCS += asSubRecordFunctions.c diff --git a/src/std/dev/devPrintfSoft.c b/src/std/dev/devPrintfSoft.c new file mode 100644 index 000000000..f88db01ec --- /dev/null +++ b/src/std/dev/devPrintfSoft.c @@ -0,0 +1,35 @@ +/*************************************************************************\ +* 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, size_t len) +{ + struct link *plink = &prec->out; + int dtyp = dbGetLinkDBFtype(plink); + + if (dtyp < 0) + return 0; /* Not connected */ + + if (dtyp == DBR_CHAR || dtyp == DBF_UCHAR) + return dbPutLink(plink, dtyp, prec->val, len); + + return dbPutLink(plink, DBR_STRING, prec->val, 1); +} + +printfdset devPrintfSoft = { + 5, NULL, NULL, NULL, NULL, write_string +}; +epicsExportAddress(dset, devPrintfSoft); + diff --git a/src/std/dev/devPrintfSoftCallback.c b/src/std/dev/devPrintfSoftCallback.c new file mode 100644 index 000000000..09eb2494d --- /dev/null +++ b/src/std/dev/devPrintfSoftCallback.c @@ -0,0 +1,50 @@ +/*************************************************************************\ +* 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, size_t len) +{ + struct link *plink = &prec->out; + int dtyp = dbGetLinkDBFtype(plink); + 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); diff --git a/src/std/dev/devPrintfStdio.c b/src/std/dev/devPrintfStdio.c new file mode 100644 index 000000000..b109c750f --- /dev/null +++ b/src/std/dev/devPrintfStdio.c @@ -0,0 +1,105 @@ +/*************************************************************************\ +* 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$ */ + +#include +#include + +#include "dbCommon.h" +#include "devSup.h" +#include "errlog.h" +#include "recGbl.h" +#include "recSup.h" +#include "printfRecord.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) { + 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(dbCommon *pcommon) { + printfRecord *prec = (printfRecord *) 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(printfRecord *prec, size_t len) +{ + struct outStream *pstream = (struct outStream *)prec->dpvt; + if (pstream) + pstream->print("%s\n", prec->val); + return 0; +} + +/* Create the dset for devSoStdio */ +printfdset devPrintfStdio = { + 5, NULL, init, NULL, NULL, write_string +}; +epicsExportAddress(dset, devPrintfStdio); diff --git a/src/std/dev/devSoft.dbd b/src/std/dev/devSoft.dbd index 9072245ca..da2f21ad4 100644 --- a/src/std/dev/devSoft.dbd +++ b/src/std/dev/devSoft.dbd @@ -13,6 +13,7 @@ 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") @@ -38,6 +39,7 @@ 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 +51,7 @@ device(bo, INST_IO,devBoGeneralTime,"General Time") device(longin, INST_IO,devLiGeneralTime,"General Time") device(stringin,INST_IO,devSiGeneralTime,"General Time") +device(printf,INST_IO,devPrintfStdio,"stdio") device(stringout,INST_IO,devSoStdio,"stdio") device(bi, INST_IO, devBiDbState, "Db State")