Merge 3.16 (after 3.16.2-rc1) into 7.0
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbConstLink.h"
|
||||
#include "dbEvent.h"
|
||||
#include "recGbl.h"
|
||||
#include "devSup.h"
|
||||
#include "cantProceed.h"
|
||||
@@ -96,11 +97,15 @@ static long readLocked(struct link *pinp, void *dummy)
|
||||
|
||||
static long read_aai(aaiRecord *prec)
|
||||
{
|
||||
epicsUInt32 nord = prec->nord;
|
||||
struct link *pinp = prec->simm == menuYesNoYES ? &prec->siol : &prec->inp;
|
||||
long status = dbLinkDoLocked(pinp, readLocked, NULL);
|
||||
|
||||
if (status == S_db_noLSET)
|
||||
status = readLocked(pinp, NULL);
|
||||
|
||||
if (!status && nord != prec->nord)
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (c) 2002 Lawrence Berkeley Laboratory,The Control Systems
|
||||
* Group, Systems Engineering Department
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "alarm.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbAccess.h"
|
||||
#include "dbEvent.h"
|
||||
#include "recGbl.h"
|
||||
#include "devSup.h"
|
||||
#include "subArrayRecord.h"
|
||||
@@ -101,6 +102,7 @@ static long read_sa(subArrayRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct sart rt;
|
||||
epicsUInt32 nord = prec->nord;
|
||||
|
||||
rt.nRequest = prec->indx + prec->nelm;
|
||||
if (rt.nRequest > prec->malm)
|
||||
@@ -123,8 +125,12 @@ static long read_sa(subArrayRecord *prec)
|
||||
status = readLocked(&prec->inp, &rt);
|
||||
}
|
||||
|
||||
if (!status && rt.nRequest > 0)
|
||||
if (!status && rt.nRequest > 0) {
|
||||
subset(prec, rt.nRequest);
|
||||
|
||||
if (nord != prec->nord)
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
@@ -81,6 +81,7 @@ static long read_wf(waveformRecord *prec)
|
||||
{
|
||||
long status;
|
||||
struct wfrt rt;
|
||||
epicsUInt32 nord = prec->nord;
|
||||
|
||||
rt.nRequest = prec->nelm;
|
||||
rt.ptime = (dbLinkIsConstant(&prec->tsel) &&
|
||||
@@ -93,6 +94,8 @@ static long read_wf(waveformRecord *prec)
|
||||
if (!status && rt.nRequest > 0) {
|
||||
prec->nord = rt.nRequest;
|
||||
prec->udf = FALSE;
|
||||
if (nord != prec->nord)
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Copyright (c) 2016 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.
|
||||
# in file LICENSE that is included with this distribution.
|
||||
#*************************************************************************
|
||||
|
||||
# This is a Makefile fragment, see src/std/Makefile.
|
||||
@@ -13,6 +13,7 @@ DBD += links.dbd
|
||||
|
||||
dbRecStd_SRCS += lnkConst.c
|
||||
dbRecStd_SRCS += lnkCalc.c
|
||||
dbRecStd_SRCS += lnkState.c
|
||||
dbRecStd_SRCS += lnkDebug.c
|
||||
|
||||
HTMLS += links.html
|
||||
|
||||
|
||||
@@ -13,6 +13,12 @@ The following additional link types are available in this release:
|
||||
|
||||
=item * L<Calc|/"Calculation Link calc">
|
||||
|
||||
=item * L<dbState|/"dbState Link state">
|
||||
|
||||
=item * L<Debug|/"Debug Link debug">
|
||||
|
||||
=item * L<Trace|/"Trace Link trace">
|
||||
|
||||
=back
|
||||
|
||||
=head2 Using JSON Links
|
||||
@@ -31,15 +37,16 @@ database file syntax.
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
link(const, lnkConstIf)
|
||||
|
||||
=head3 Constant Link C<"const">
|
||||
|
||||
Constant links provide one or more values at link initalization time, but do not
|
||||
return any data when their C<getValue()> routine is called. Most record types
|
||||
support the use of constant links by calling C<recGblInitConstantLink()> at
|
||||
record initialization, which results in the constant value being loaded into the
|
||||
target field at that time.
|
||||
Constant links are input links that provide literal values at link initalization
|
||||
time, but do not return any data when their C<getValue()> routine is called.
|
||||
Most record types support the use of constant links on their input links by
|
||||
calling C<recGblInitConstantLink()> at record initialization, which results in
|
||||
the constant value being loaded into the target field at that time.
|
||||
|
||||
Note that for most record types (the C<printf> and C<calcout> records are the
|
||||
main exceptions) it is pointless to set an input link to a constant link at
|
||||
@@ -70,14 +77,35 @@ converted to the desired double value at initialization, for example:
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
link(calc, lnkCalcIf)
|
||||
|
||||
=head3 Calculation Link C<"calc">
|
||||
|
||||
Calculation links can perform simple mathematical expressions on scalar
|
||||
(double-precision floating-point) values obtained from other link types and
|
||||
return a single double-precision floating-point result. The expressions are
|
||||
evaluated by the EPICS Calc engine, and up to 12 inputs can be provided.
|
||||
A calculation link is an input link that can evaluate mathematical expressions
|
||||
on scalar (double-precision floating-point) values obtained from up to 12 child
|
||||
input links, and returns a double-precision floating-point result. The
|
||||
expression is evaluated by the EPICS Calc engine, and the result is returned as
|
||||
the value of the link.
|
||||
|
||||
Two additional expressions may also be provided and are evaluated to determine
|
||||
whether the record owning the link should be placed in alarm state. In both
|
||||
cases the result of the main calculation is available to these expressions as
|
||||
C<VAL> (attempts to assign to C<VAL> inside either expression will have no
|
||||
lasting effect). If the C<major> expression evaluates to a non-zero value the
|
||||
record will be placed in C<LINK/MAJOR> alarm. If not and the C<minor> expression
|
||||
evaluates to non-zero the record will be placed in C<LINK/MINOR> alarm state.
|
||||
|
||||
A calculation link can also be an output link, with the scalar output value
|
||||
being converted to a double and provided to the expression as C<VAL>. Up to 12
|
||||
additional input links can also be read and provided to the expression as above.
|
||||
The result of the calculation is forwarded to a child output link specified in
|
||||
the link's C<out> parameter.
|
||||
|
||||
For an output link the main expression is actually optional; if not provided the
|
||||
converted value will be forwarded to the output link unchanged. The two alarm
|
||||
expressions may still be used to put the output link into alarm state as
|
||||
described above.
|
||||
|
||||
=head4 Parameters
|
||||
|
||||
@@ -88,6 +116,7 @@ The link address is a JSON map with the following keys:
|
||||
=item expr
|
||||
|
||||
The primary expression to be evaluated, given as a string.
|
||||
This is optional for output links, required for input links.
|
||||
|
||||
=item major
|
||||
|
||||
@@ -104,6 +133,12 @@ to the inputs C<A>, C<B>, C<C>, ... C<L>. Each input argument may be either a
|
||||
numeric literal or an embedded JSON link inside C<{}> braces. The same input
|
||||
values are provided to the two alarm expressions as to the primary expression.
|
||||
|
||||
=item out
|
||||
|
||||
A JSON link inside C<{}> braces which specifies the destination of C<putValue>
|
||||
operations after any expressions have been evaluated.
|
||||
This key is required for output links, not used by input links.
|
||||
|
||||
=item units
|
||||
|
||||
An optional string specifying the engineering units for the result of the
|
||||
@@ -129,3 +164,72 @@ atomically with the value of the input argument.
|
||||
{calc: {expr:"A*B", args:[{db:"record.VAL"}, 1.5], prec:3}}
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
link(state, lnkStateIf)
|
||||
|
||||
=head3 dbState Link C<"state">
|
||||
|
||||
A dbState link is one that gets or puts a boolean value from/to a named global
|
||||
flag as implemented by the dbState facility in C<dbstate.h>. The link type can
|
||||
invert the sense of the dbState flag during the get or put if desired.
|
||||
|
||||
The value of the named flag is read or written at the time of the link I/O
|
||||
operation. When reading a flag, the value returned by the link will be zero or
|
||||
one converted to the requested data type. When writing to a flag the boolean
|
||||
value of the data written is determined in the originating data type. All
|
||||
strings are regarded as true other than C<""> and C<"0"> which are both false.
|
||||
|
||||
A link can be configured to invert the sense of the flag data by putting an
|
||||
exclamation mark C<!> before the first character of the flag's name in the link
|
||||
address.
|
||||
|
||||
These dbState flags can be accessed from the IOC Shell with various dbState
|
||||
commands, and are also used by the C<"sync"> Channel-Access server-side filter
|
||||
mechanism.
|
||||
|
||||
=head4 Parameters
|
||||
|
||||
The link takes a single parameter which must be a string, providing the name of
|
||||
the dbState object, with an optional leading C<!> character to indicate that the
|
||||
flag's value should be inverted. The dbState object will be created when the
|
||||
link is initialized if it doesn't already exist.
|
||||
|
||||
=head4 Examples
|
||||
|
||||
{state:"redBeam"}
|
||||
{state:"!simEnable"}
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
link(debug, lnkDebugIf)
|
||||
variable(lnkDebug_debug, int)
|
||||
|
||||
=head3 Debug Link C<"debug">
|
||||
|
||||
The debug link type exists to enable debugging of other link types; it provides
|
||||
no functionality itself other than to turn on the debug flag for the child link
|
||||
that is its only parameter and pass all link operations down to that link.
|
||||
|
||||
=head4 Example
|
||||
|
||||
{debug:{state:"redBeam"}}
|
||||
|
||||
=cut
|
||||
|
||||
|
||||
link(trace, lnkTraceIf)
|
||||
|
||||
=head3 Trace Link C<"trace">
|
||||
|
||||
The trace link type is a relative of the debug link type that also traces the
|
||||
operation of its child link. At creation it turns on the debug flag of its child
|
||||
link, then it prints the method arguments and return values of all link
|
||||
operations before / after passing control down to the child link.
|
||||
|
||||
=head4 Example
|
||||
|
||||
{trace:{state:"redBeam"}}
|
||||
|
||||
=cut
|
||||
|
||||
@@ -6,13 +6,9 @@
|
||||
\*************************************************************************/
|
||||
/* lnkCalc.c */
|
||||
|
||||
/* Current usage
|
||||
* {calc:{expr:"A", args:[{...}, ...]}}
|
||||
/* Usage
|
||||
* {calc:{expr:"A*B", args:[{...}, ...], units:"mm"}}
|
||||
* First link in 'args' is 'A', second is 'B', and so forth.
|
||||
*
|
||||
* TODO:
|
||||
* Support setting individual input links instead of the args list.
|
||||
* {calc:{expr:"K", K:{...}}}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -26,6 +22,7 @@
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsString.h"
|
||||
#include "epicsTypes.h"
|
||||
#include "epicsTime.h"
|
||||
#include "dbAccessDefs.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbConvertFast.h"
|
||||
@@ -40,15 +37,14 @@
|
||||
|
||||
typedef long (*FASTCONVERT)();
|
||||
|
||||
#define IFDEBUG(n) if(clink->jlink.debug)
|
||||
|
||||
typedef struct calc_link {
|
||||
jlink jlink; /* embedded object */
|
||||
int nArgs;
|
||||
short dbfType;
|
||||
enum {
|
||||
ps_init,
|
||||
ps_expr, ps_major, ps_minor,
|
||||
ps_args,
|
||||
ps_args, ps_out,
|
||||
ps_prec,
|
||||
ps_units,
|
||||
ps_time,
|
||||
@@ -66,7 +62,9 @@ typedef struct calc_link {
|
||||
char *units;
|
||||
short tinp;
|
||||
struct link inp[CALCPERFORM_NARGS];
|
||||
struct link out;
|
||||
double arg[CALCPERFORM_NARGS];
|
||||
epicsTimeStamp time;
|
||||
double val;
|
||||
} calc_link;
|
||||
|
||||
@@ -77,19 +75,25 @@ static lset lnkCalc_lset;
|
||||
|
||||
static jlink* lnkCalc_alloc(short dbfType)
|
||||
{
|
||||
calc_link *clink = calloc(1, sizeof(struct calc_link));
|
||||
calc_link *clink;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_alloc()\n");
|
||||
if (dbfType == DBF_FWDLINK) {
|
||||
errlogPrintf("lnkCalc: No support for forward links\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clink = calloc(1, sizeof(struct calc_link));
|
||||
if (!clink) {
|
||||
errlogPrintf("lnkCalc: calloc() failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clink->nArgs = 0;
|
||||
clink->dbfType = dbfType;
|
||||
clink->pstate = ps_init;
|
||||
clink->prec = 15; /* standard value for a double */
|
||||
clink->tinp = -1;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_alloc -> calc@%p\n", clink);
|
||||
|
||||
return &clink->jlink;
|
||||
}
|
||||
|
||||
@@ -98,12 +102,11 @@ static void lnkCalc_free(jlink *pjlink)
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
int i;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_free(calc@%p)\n", clink);
|
||||
|
||||
for (i = 0; i < clink->nArgs; i++)
|
||||
dbJLinkFree(clink->inp[i].value.json.jlink);
|
||||
|
||||
dbJLinkFree(clink->out.value.json.jlink);
|
||||
|
||||
free(clink->expr);
|
||||
free(clink->major);
|
||||
free(clink->minor);
|
||||
@@ -118,9 +121,6 @@ static jlif_result lnkCalc_integer(jlink *pjlink, long long num)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_integer(calc@%p, %lld)\n", clink, num);
|
||||
|
||||
if (clink->pstate == ps_prec) {
|
||||
clink->prec = num;
|
||||
return jlif_continue;
|
||||
@@ -146,9 +146,6 @@ static jlif_result lnkCalc_double(jlink *pjlink, double num)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_double(calc@%p, %g)\n", clink, num);
|
||||
|
||||
if (clink->pstate != ps_args) {
|
||||
return jlif_stop;
|
||||
errlogPrintf("lnkCalc: Unexpected double %g\n", num);
|
||||
@@ -171,9 +168,6 @@ static jlif_result lnkCalc_string(jlink *pjlink, const char *val, size_t len)
|
||||
char *inbuf, *postbuf;
|
||||
short err;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_string(calc@%p, \"%.*s\")\n", clink, (int) len, val);
|
||||
|
||||
if (clink->pstate == ps_units) {
|
||||
clink->units = epicsStrnDup(val, len);
|
||||
return jlif_continue;
|
||||
@@ -181,7 +175,8 @@ static jlif_result lnkCalc_string(jlink *pjlink, const char *val, size_t len)
|
||||
|
||||
if (clink->pstate == ps_time) {
|
||||
char tinp;
|
||||
if (len != 1 || (tinp = toupper(val[0])) < 'A' || tinp > 'L') {
|
||||
|
||||
if (len != 1 || (tinp = toupper((int) val[0])) < 'A' || tinp > 'L') {
|
||||
errlogPrintf("lnkCalc: Bad 'time' parameter \"%.*s\"\n", (int) len, val);
|
||||
return jlif_stop;
|
||||
}
|
||||
@@ -234,11 +229,10 @@ static jlif_key_result lnkCalc_start_map(jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_start_map(calc@%p)\n", clink);
|
||||
|
||||
if (clink->pstate == ps_args)
|
||||
return jlif_key_child_link;
|
||||
return jlif_key_child_inlink;
|
||||
if (clink->pstate == ps_out)
|
||||
return jlif_key_child_outlink;
|
||||
|
||||
if (clink->pstate != ps_init) {
|
||||
errlogPrintf("lnkCalc: Unexpected map\n");
|
||||
@@ -252,10 +246,21 @@ static jlif_result lnkCalc_map_key(jlink *pjlink, const char *key, size_t len)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_map_key(calc@%p, \"%.*s\")\n", pjlink, (int) len, key);
|
||||
/* FIXME: These errors messages are wrong when a key is duplicated.
|
||||
* The key is known, we just don't allow it more than once.
|
||||
*/
|
||||
|
||||
if (len == 4) {
|
||||
if (len == 3) {
|
||||
if (!strncmp(key, "out", len) &&
|
||||
clink->dbfType == DBF_OUTLINK &&
|
||||
clink->out.type == 0)
|
||||
clink->pstate = ps_out;
|
||||
else {
|
||||
errlogPrintf("lnkCalc: Unknown key \"%.3s\"\n", key);
|
||||
return jlif_stop;
|
||||
}
|
||||
}
|
||||
else if (len == 4) {
|
||||
if (!strncmp(key, "expr", len) && !clink->post_expr)
|
||||
clink->pstate = ps_expr;
|
||||
else if (!strncmp(key, "args", len) && !clink->nArgs)
|
||||
@@ -293,13 +298,16 @@ static jlif_result lnkCalc_end_map(jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_end_map(calc@%p)\n", clink);
|
||||
|
||||
if (clink->pstate == ps_error)
|
||||
return jlif_stop;
|
||||
else if (!clink->post_expr) {
|
||||
errlogPrintf("lnkCalc: no expression ('expr' key)\n");
|
||||
else if (clink->dbfType == DBF_INLINK &&
|
||||
!clink->post_expr) {
|
||||
errlogPrintf("lnkCalc: No expression ('expr' key)\n");
|
||||
return jlif_stop;
|
||||
}
|
||||
else if (clink->dbfType == DBF_OUTLINK &&
|
||||
clink->out.type != JSON_LINK) {
|
||||
errlogPrintf("lnkCalc: No output link ('out' key)\n");
|
||||
return jlif_stop;
|
||||
}
|
||||
|
||||
@@ -310,9 +318,6 @@ static jlif_result lnkCalc_start_array(jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_start_array(calc@%p)\n", clink);
|
||||
|
||||
if (clink->pstate != ps_args) {
|
||||
errlogPrintf("lnkCalc: Unexpected array\n");
|
||||
return jlif_stop;
|
||||
@@ -325,9 +330,6 @@ static jlif_result lnkCalc_end_array(jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_end_array(calc@%p)\n", clink);
|
||||
|
||||
if (clink->pstate == ps_error)
|
||||
return jlif_stop;
|
||||
|
||||
@@ -339,15 +341,27 @@ static void lnkCalc_end_child(jlink *parent, jlink *child)
|
||||
calc_link *clink = CONTAINER(parent, struct calc_link, jlink);
|
||||
struct link *plink;
|
||||
|
||||
if (clink->nArgs == CALCPERFORM_NARGS) {
|
||||
dbJLinkFree(child);
|
||||
errlogPrintf("lnkCalc: Too many input args, limit is %d\n",
|
||||
CALCPERFORM_NARGS);
|
||||
if (clink->pstate == ps_args) {
|
||||
if (clink->nArgs == CALCPERFORM_NARGS) {
|
||||
errlogPrintf("lnkCalc: Too many input args, limit is %d\n",
|
||||
CALCPERFORM_NARGS);
|
||||
goto errOut;
|
||||
}
|
||||
|
||||
plink = &clink->inp[clink->nArgs++];
|
||||
}
|
||||
else if (clink->pstate == ps_out) {
|
||||
plink = &clink->out;
|
||||
}
|
||||
else {
|
||||
errlogPrintf("lnkCalc: Unexpected child link, parser state = %d\n",
|
||||
clink->pstate);
|
||||
errOut:
|
||||
clink->pstate = ps_error;
|
||||
dbJLinkFree(child);
|
||||
return;
|
||||
}
|
||||
|
||||
plink = &clink->inp[clink->nArgs++];
|
||||
plink->type = JSON_LINK;
|
||||
plink->value.json.string = NULL;
|
||||
plink->value.json.jlink = child;
|
||||
@@ -355,11 +369,6 @@ static void lnkCalc_end_child(jlink *parent, jlink *child)
|
||||
|
||||
static struct lset* lnkCalc_get_lset(const jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_get_lset(calc@%p)\n", pjlink);
|
||||
|
||||
return &lnkCalc_lset;
|
||||
}
|
||||
|
||||
@@ -368,9 +377,6 @@ static void lnkCalc_report(const jlink *pjlink, int level, int indent)
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
int i;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_report(calc@%p)\n", clink);
|
||||
|
||||
printf("%*s'calc': \"%s\" = %.*g %s\n", indent, "",
|
||||
clink->expr, clink->prec, clink->val,
|
||||
clink->units ? clink->units : "");
|
||||
@@ -388,9 +394,13 @@ static void lnkCalc_report(const jlink *pjlink, int level, int indent)
|
||||
printf("%*s Minor expression: \"%s\"\n", indent, "",
|
||||
clink->minor);
|
||||
|
||||
if (clink->tinp >= 0 && clink->tinp < clink->nArgs)
|
||||
printf("%*s Timestamp input \"%c\"\n", indent, "",
|
||||
clink->tinp + 'A');
|
||||
if (clink->tinp >= 0) {
|
||||
char timeStr[40];
|
||||
epicsTimeToStrftime(timeStr, 40, "%Y-%m-%d %H:%M:%S.%09f",
|
||||
&clink->time);
|
||||
printf("%*s Timestamp input %c: %s\n", indent, "",
|
||||
clink->tinp + 'A', timeStr);
|
||||
}
|
||||
|
||||
for (i = 0; i < clink->nArgs; i++) {
|
||||
struct link *plink = &clink->inp[i];
|
||||
@@ -403,17 +413,20 @@ static void lnkCalc_report(const jlink *pjlink, int level, int indent)
|
||||
if (child)
|
||||
dbJLinkReport(child, level - 1, indent + 4);
|
||||
}
|
||||
|
||||
if (clink->out.type == JSON_LINK) {
|
||||
printf("%*s Output:\n", indent, "");
|
||||
|
||||
dbJLinkReport(clink->out.value.json.jlink, level - 1, indent + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long lnkCalc_map_children(jlink *pjlink, jlink_map_fn rtn, void *ctx)
|
||||
static long lnkCalc_map_children(jlink *pjlink, jlink_map_fn rtn, void *ctx)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
int i;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_map_children(calc@%p)\n", clink);
|
||||
|
||||
for (i = 0; i < clink->nArgs; i++) {
|
||||
struct link *child = &clink->inp[i];
|
||||
long status = dbJLinkMapChildren(child, rtn, ctx);
|
||||
@@ -421,6 +434,10 @@ long lnkCalc_map_children(jlink *pjlink, jlink_map_fn rtn, void *ctx)
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clink->out.type == JSON_LINK) {
|
||||
return dbJLinkMapChildren(&clink->out, rtn, ctx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -432,9 +449,6 @@ static void lnkCalc_open(struct link *plink)
|
||||
struct calc_link, jlink);
|
||||
int i;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_open(calc@%p)\n", clink);
|
||||
|
||||
for (i = 0; i < clink->nArgs; i++) {
|
||||
struct link *child = &clink->inp[i];
|
||||
|
||||
@@ -442,6 +456,10 @@ static void lnkCalc_open(struct link *plink)
|
||||
dbJLinkInit(child);
|
||||
dbLoadLink(child, DBR_DOUBLE, &clink->arg[i]);
|
||||
}
|
||||
|
||||
if (clink->out.type == JSON_LINK) {
|
||||
dbJLinkInit(&clink->out);
|
||||
}
|
||||
}
|
||||
|
||||
static void lnkCalc_remove(struct dbLocker *locker, struct link *plink)
|
||||
@@ -450,15 +468,16 @@ static void lnkCalc_remove(struct dbLocker *locker, struct link *plink)
|
||||
struct calc_link, jlink);
|
||||
int i;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_remove(calc@%p)\n", clink);
|
||||
|
||||
for (i = 0; i < clink->nArgs; i++) {
|
||||
struct link *child = &clink->inp[i];
|
||||
|
||||
dbRemoveLink(locker, child);
|
||||
}
|
||||
|
||||
if (clink->out.type == JSON_LINK) {
|
||||
dbRemoveLink(locker, &clink->out);
|
||||
}
|
||||
|
||||
free(clink->expr);
|
||||
free(clink->major);
|
||||
free(clink->minor);
|
||||
@@ -477,9 +496,6 @@ static int lnkCalc_isConn(const struct link *plink)
|
||||
int connected = 1;
|
||||
int i;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_isConn(calc@%p)\n", clink);
|
||||
|
||||
for (i = 0; i < clink->nArgs; i++) {
|
||||
struct link *child = &clink->inp[i];
|
||||
|
||||
@@ -488,37 +504,24 @@ static int lnkCalc_isConn(const struct link *plink)
|
||||
connected = 0;
|
||||
}
|
||||
|
||||
if (clink->out.type == JSON_LINK) {
|
||||
struct link *child = &clink->out;
|
||||
|
||||
if (dbLinkIsVolatile(child) &&
|
||||
!dbIsLinkConnected(child))
|
||||
connected = 0;
|
||||
}
|
||||
|
||||
return connected;
|
||||
}
|
||||
|
||||
static int lnkCalc_getDBFtype(const struct link *plink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10) {
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
|
||||
printf("lnkCalc_getDBFtype(calc@%p)\n", clink);
|
||||
}
|
||||
|
||||
return DBF_DOUBLE;
|
||||
}
|
||||
|
||||
static long lnkCalc_getElements(const struct link *plink, long *nelements)
|
||||
{
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10) {
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
|
||||
printf("lnkCalc_getElements(calc@%p, (%ld))\n",
|
||||
clink, *nelements);
|
||||
}
|
||||
|
||||
*nelements = 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -551,23 +554,22 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
long status;
|
||||
FASTCONVERT conv = dbFastPutConvertRoutine[DBR_DOUBLE][dbrType];
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_getValue(calc@%p, %d, ...)\n",
|
||||
clink, dbrType);
|
||||
|
||||
/* Any link errors will trigger a LINK/INVALID alarm in the child link */
|
||||
for (i = 0; i < clink->nArgs; i++) {
|
||||
struct link *child = &clink->inp[i];
|
||||
long nReq = 1;
|
||||
|
||||
if (i == clink->tinp &&
|
||||
dbLinkIsConstant(&prec->tsel) &&
|
||||
prec->tse == epicsTimeEventDeviceTime) {
|
||||
struct lcvt vt = {&clink->arg[i], &prec->time};
|
||||
if (i == clink->tinp) {
|
||||
struct lcvt vt = {&clink->arg[i], &clink->time};
|
||||
|
||||
status = dbLinkDoLocked(child, readLocked, &vt);
|
||||
if (status == S_db_noLSET)
|
||||
status = readLocked(child, &vt);
|
||||
|
||||
if (dbLinkIsConstant(&prec->tsel) &&
|
||||
prec->tse == epicsTimeEventDeviceTime) {
|
||||
prec->time = clink->time;
|
||||
}
|
||||
}
|
||||
else
|
||||
dbGetLink(child, DBR_DOUBLE, &clink->arg[i], NULL, &nReq);
|
||||
@@ -599,7 +601,7 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
}
|
||||
}
|
||||
|
||||
if (!status && clink->post_minor) {
|
||||
if (!status && !clink->sevr && clink->post_minor) {
|
||||
double alval = clink->val;
|
||||
|
||||
status = calcPerform(clink->arg, &alval, clink->post_minor);
|
||||
@@ -613,14 +615,79 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
return status;
|
||||
}
|
||||
|
||||
static long lnkCalc_putValue(struct link *plink, short dbrType,
|
||||
const void *pbuffer, long nRequest)
|
||||
{
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
dbCommon *prec = plink->precord;
|
||||
int i;
|
||||
long status;
|
||||
FASTCONVERT conv = dbFastGetConvertRoutine[dbrType][DBR_DOUBLE];
|
||||
|
||||
/* Any link errors will trigger a LINK/INVALID alarm in the child link */
|
||||
for (i = 0; i < clink->nArgs; i++) {
|
||||
struct link *child = &clink->inp[i];
|
||||
long nReq = 1;
|
||||
|
||||
if (i == clink->tinp) {
|
||||
struct lcvt vt = {&clink->arg[i], &clink->time};
|
||||
|
||||
status = dbLinkDoLocked(child, readLocked, &vt);
|
||||
if (status == S_db_noLSET)
|
||||
status = readLocked(child, &vt);
|
||||
|
||||
if (dbLinkIsConstant(&prec->tsel) &&
|
||||
prec->tse == epicsTimeEventDeviceTime) {
|
||||
prec->time = clink->time;
|
||||
}
|
||||
}
|
||||
else
|
||||
dbGetLink(child, DBR_DOUBLE, &clink->arg[i], NULL, &nReq);
|
||||
}
|
||||
clink->stat = 0;
|
||||
clink->sevr = 0;
|
||||
|
||||
/* Get the value being output as VAL */
|
||||
status = conv(pbuffer, &clink->val, NULL);
|
||||
|
||||
if (!status && clink->post_expr)
|
||||
status = calcPerform(clink->arg, &clink->val, clink->post_expr);
|
||||
|
||||
if (!status && clink->post_major) {
|
||||
double alval = clink->val;
|
||||
|
||||
status = calcPerform(clink->arg, &alval, clink->post_major);
|
||||
if (!status && alval) {
|
||||
clink->stat = LINK_ALARM;
|
||||
clink->sevr = MAJOR_ALARM;
|
||||
recGblSetSevr(prec, clink->stat, clink->sevr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!status && !clink->sevr && clink->post_minor) {
|
||||
double alval = clink->val;
|
||||
|
||||
status = calcPerform(clink->arg, &alval, clink->post_minor);
|
||||
if (!status && alval) {
|
||||
clink->stat = LINK_ALARM;
|
||||
clink->sevr = MINOR_ALARM;
|
||||
recGblSetSevr(prec, clink->stat, clink->sevr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!status) {
|
||||
status = dbPutLink(&clink->out, DBR_DOUBLE, &clink->val, 1);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static long lnkCalc_getPrecision(const struct link *plink, short *precision)
|
||||
{
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_getPrecision(calc@%p)\n", clink);
|
||||
|
||||
*precision = clink->prec;
|
||||
return 0;
|
||||
}
|
||||
@@ -630,9 +697,6 @@ static long lnkCalc_getUnits(const struct link *plink, char *units, int len)
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_getUnits(calc@%p)\n", clink);
|
||||
|
||||
if (clink->units) {
|
||||
strncpy(units, clink->units, --len);
|
||||
units[len] = '\0';
|
||||
@@ -648,9 +712,6 @@ static long lnkCalc_getAlarm(const struct link *plink, epicsEnum16 *status,
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_getAlarm(calc@%p)\n", clink);
|
||||
|
||||
if (status)
|
||||
*status = clink->stat;
|
||||
if (severity)
|
||||
@@ -659,6 +720,19 @@ static long lnkCalc_getAlarm(const struct link *plink, epicsEnum16 *status,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long lnkCalc_getTimestamp(const struct link *plink, epicsTimeStamp *pstamp)
|
||||
{
|
||||
calc_link *clink = CONTAINER(plink->value.json.jlink,
|
||||
struct calc_link, jlink);
|
||||
|
||||
if (clink->tinp >= 0) {
|
||||
*pstamp = clink->time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static long doLocked(struct link *plink, dbLinkUserCallback rtn, void *priv)
|
||||
{
|
||||
return rtn(plink, priv);
|
||||
@@ -675,8 +749,8 @@ static lset lnkCalc_lset = {
|
||||
lnkCalc_getValue,
|
||||
NULL, NULL, NULL,
|
||||
lnkCalc_getPrecision, lnkCalc_getUnits,
|
||||
lnkCalc_getAlarm, NULL,
|
||||
NULL, NULL,
|
||||
lnkCalc_getAlarm, lnkCalc_getTimestamp,
|
||||
lnkCalc_putValue, NULL,
|
||||
NULL, doLocked
|
||||
};
|
||||
|
||||
@@ -686,6 +760,6 @@ static jlif lnkCalcIf = {
|
||||
lnkCalc_start_map, lnkCalc_map_key, lnkCalc_end_map,
|
||||
lnkCalc_start_array, lnkCalc_end_array,
|
||||
lnkCalc_end_child, lnkCalc_get_lset,
|
||||
lnkCalc_report, lnkCalc_map_children
|
||||
lnkCalc_report, lnkCalc_map_children, NULL
|
||||
};
|
||||
epicsExportAddress(jlif, lnkCalcIf);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2016 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.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* lnkConst.c */
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
#include "epicsExport.h"
|
||||
|
||||
|
||||
#define IFDEBUG(n) if (clink->jlink.debug)
|
||||
|
||||
typedef long (*FASTCONVERT)();
|
||||
|
||||
typedef struct const_link {
|
||||
@@ -48,18 +46,23 @@ static lset lnkConst_lset;
|
||||
|
||||
static jlink* lnkConst_alloc(short dbfType)
|
||||
{
|
||||
const_link *clink = calloc(1, sizeof(*clink));
|
||||
const_link *clink;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_alloc()\n");
|
||||
if (dbfType != DBF_INLINK) {
|
||||
errlogPrintf("lnkConst: Only works with input links\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clink = calloc(1, sizeof(*clink));
|
||||
if (!clink) {
|
||||
errlogPrintf("lnkConst: calloc() failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
clink->type = s0;
|
||||
clink->nElems = 0;
|
||||
clink->value.pmem = NULL;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_alloc -> const@%p\n", clink);
|
||||
|
||||
return &clink->jlink;
|
||||
}
|
||||
|
||||
@@ -67,9 +70,6 @@ static void lnkConst_free(jlink *pjlink)
|
||||
{
|
||||
const_link *clink = CONTAINER(pjlink, const_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_free(const@%p) type=%d\n", pjlink, clink->type);
|
||||
|
||||
switch (clink->type) {
|
||||
int i;
|
||||
case ac40:
|
||||
@@ -95,16 +95,13 @@ static jlif_result lnkConst_integer(jlink *pjlink, long long num)
|
||||
const_link *clink = CONTAINER(pjlink, const_link, jlink);
|
||||
int newElems = clink->nElems + 1;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_integer(const@%p, %lld)\n", pjlink, num);
|
||||
|
||||
switch (clink->type) {
|
||||
void *buf;
|
||||
|
||||
case s0:
|
||||
clink->type = si64;
|
||||
clink->value.scalar_integer = num;
|
||||
IFDEBUG(12)
|
||||
if (pjlink->debug)
|
||||
printf(" si64 := %lld\n", num);
|
||||
break;
|
||||
|
||||
@@ -118,7 +115,7 @@ static jlif_result lnkConst_integer(jlink *pjlink, long long num)
|
||||
|
||||
clink->value.pmem = buf;
|
||||
clink->value.pintegers[clink->nElems] = num;
|
||||
IFDEBUG(12)
|
||||
if (pjlink->debug)
|
||||
printf(" ai64 += %lld\n", num);
|
||||
break;
|
||||
|
||||
@@ -129,7 +126,7 @@ static jlif_result lnkConst_integer(jlink *pjlink, long long num)
|
||||
|
||||
clink->value.pmem = buf;
|
||||
clink->value.pdoubles[clink->nElems] = num;
|
||||
IFDEBUG(12)
|
||||
if (pjlink->debug)
|
||||
printf(" af64 += %lld\n", num);
|
||||
break;
|
||||
|
||||
@@ -146,10 +143,6 @@ static jlif_result lnkConst_integer(jlink *pjlink, long long num)
|
||||
|
||||
static jlif_result lnkConst_boolean(jlink *pjlink, int val)
|
||||
{
|
||||
const_link *clink = CONTAINER(pjlink, const_link, jlink);
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_boolean(const@%p, %d)\n", pjlink, val);
|
||||
|
||||
return lnkConst_integer(pjlink, val);
|
||||
}
|
||||
|
||||
@@ -158,9 +151,6 @@ static jlif_result lnkConst_double(jlink *pjlink, double num)
|
||||
const_link *clink = CONTAINER(pjlink, const_link, jlink);
|
||||
int newElems = clink->nElems + 1;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_double(const@%p, %g)\n", pjlink, num);
|
||||
|
||||
switch (clink->type) {
|
||||
epicsFloat64 *f64buf;
|
||||
int i;
|
||||
@@ -212,9 +202,6 @@ static jlif_result lnkConst_string(jlink *pjlink, const char *val, size_t len)
|
||||
const_link *clink = CONTAINER(pjlink, const_link, jlink);
|
||||
int newElems = clink->nElems + 1;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_string(const@%p, \"%.*s\")\n", clink, (int) len, val);
|
||||
|
||||
switch (clink->type) {
|
||||
char **vec, *str;
|
||||
|
||||
@@ -262,9 +249,6 @@ static jlif_result lnkConst_start_array(jlink *pjlink)
|
||||
{
|
||||
const_link *clink = CONTAINER(pjlink, const_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_start_array(const@%p)\n", pjlink);
|
||||
|
||||
if (clink->type != s0) {
|
||||
errlogPrintf("lnkConst: Embedded array value\n");
|
||||
return jlif_stop;
|
||||
@@ -276,21 +260,11 @@ static jlif_result lnkConst_start_array(jlink *pjlink)
|
||||
|
||||
static jlif_result lnkConst_end_array(jlink *pjlink)
|
||||
{
|
||||
const_link *clink = CONTAINER(pjlink, const_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_end_array(const@%p)\n", pjlink);
|
||||
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static struct lset* lnkConst_get_lset(const jlink *pjlink)
|
||||
{
|
||||
const_link *clink = CONTAINER(pjlink, const_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_get_lset(const@%p)\n", pjlink);
|
||||
|
||||
return &lnkConst_lset;
|
||||
}
|
||||
|
||||
@@ -318,9 +292,6 @@ static void lnkConst_report(const jlink *pjlink, int level, int indent)
|
||||
};
|
||||
const char * const dtype = type_names[clink->type & 3];
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_report(const@%p)\n", clink);
|
||||
|
||||
if (clink->type > a0) {
|
||||
const char * const plural = clink->nElems > 1 ? "s" : "";
|
||||
|
||||
@@ -382,11 +353,6 @@ static void lnkConst_report(const jlink *pjlink, int level, int indent)
|
||||
|
||||
static void lnkConst_remove(struct dbLocker *locker, struct link *plink)
|
||||
{
|
||||
const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_remove(const@%p)\n", clink);
|
||||
|
||||
lnkConst_free(plink->value.json.jlink);
|
||||
}
|
||||
|
||||
@@ -395,55 +361,51 @@ static long lnkConst_loadScalar(struct link *plink, short dbrType, void *pbuffer
|
||||
const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink);
|
||||
long status;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_loadScalar(const@%p, %d, %p)\n",
|
||||
clink, dbrType, pbuffer);
|
||||
|
||||
switch (clink->type) {
|
||||
case si64:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" si64 %lld\n", clink->value.scalar_integer);
|
||||
status = dbFastPutConvertRoutine[DBF_INT64][dbrType]
|
||||
(&clink->value.scalar_integer, pbuffer, NULL);
|
||||
break;
|
||||
|
||||
case sf64:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" sf64 %g\n", clink->value.scalar_double);
|
||||
status = dbFastPutConvertRoutine[DBF_DOUBLE][dbrType]
|
||||
(&clink->value.scalar_double, pbuffer, NULL);
|
||||
break;
|
||||
|
||||
case sc40:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" sc40 '%s'\n", clink->value.scalar_string);
|
||||
status = dbFastPutConvertRoutine[DBF_STRING][dbrType]
|
||||
(clink->value.scalar_string, pbuffer, NULL);
|
||||
break;
|
||||
|
||||
case ai64:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" ai64 [%lld, ...]\n", clink->value.pintegers[0]);
|
||||
status = dbFastPutConvertRoutine[DBF_INT64][dbrType]
|
||||
(clink->value.pintegers, pbuffer, NULL);
|
||||
break;
|
||||
|
||||
case af64:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" af64 [%g, ...]\n", clink->value.pdoubles[0]);
|
||||
status = dbFastPutConvertRoutine[DBF_DOUBLE][dbrType]
|
||||
(clink->value.pdoubles, pbuffer, NULL);
|
||||
break;
|
||||
|
||||
case ac40:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" ac40 ['%s', ...]\n", clink->value.pstrings[0]);
|
||||
status = dbFastPutConvertRoutine[DBF_STRING][dbrType]
|
||||
(clink->value.pstrings[0], pbuffer, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" Bad type %d\n", clink->type);
|
||||
status = S_db_badField;
|
||||
break;
|
||||
@@ -458,27 +420,23 @@ static long lnkConst_loadLS(struct link *plink, char *pbuffer, epicsUInt32 size,
|
||||
const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink);
|
||||
const char *pstr;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_loadLS(const@%p, %p, %d, %d)\n",
|
||||
clink, pbuffer, size, *plen);
|
||||
|
||||
if(!size) return 0;
|
||||
|
||||
switch (clink->type) {
|
||||
case sc40:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" sc40 '%s'\n", clink->value.scalar_string);
|
||||
pstr = clink->value.scalar_string;
|
||||
break;
|
||||
|
||||
case ac40:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" ac40 ['%s', ...]\n", clink->value.pstrings[0]);
|
||||
pstr = clink->value.pstrings[0];
|
||||
break;
|
||||
|
||||
default:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" Bad type %d\n", clink->type);
|
||||
return S_db_badField;
|
||||
}
|
||||
@@ -499,10 +457,6 @@ static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer,
|
||||
FASTCONVERT conv;
|
||||
long status;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_loadArray(const@%p, %d, %p, (%ld))\n",
|
||||
clink, dbrType, pbuffer, *pnReq);
|
||||
|
||||
if (nElems > *pnReq)
|
||||
nElems = *pnReq;
|
||||
|
||||
@@ -510,28 +464,28 @@ static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer,
|
||||
int i;
|
||||
|
||||
case si64:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" si64 %lld\n", clink->value.scalar_integer);
|
||||
status = dbFastPutConvertRoutine[DBF_INT64][dbrType]
|
||||
(&clink->value.scalar_integer, pdest, NULL);
|
||||
break;
|
||||
|
||||
case sf64:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" sf64 %g\n", clink->value.scalar_double);
|
||||
status = dbFastPutConvertRoutine[DBF_DOUBLE][dbrType]
|
||||
(&clink->value.scalar_double, pdest, NULL);
|
||||
break;
|
||||
|
||||
case sc40:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" sc40 '%s'\n", clink->value.scalar_string);
|
||||
status = dbFastPutConvertRoutine[DBF_STRING][dbrType]
|
||||
(clink->value.scalar_string, pbuffer, NULL);
|
||||
break;
|
||||
|
||||
case ai64:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" ai64 [%lld, ...]\n", clink->value.pintegers[0]);
|
||||
conv = dbFastPutConvertRoutine[DBF_INT64][dbrType];
|
||||
for (i = 0; i < nElems; i++) {
|
||||
@@ -542,7 +496,7 @@ static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer,
|
||||
break;
|
||||
|
||||
case af64:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" af64 [%g, ...]\n", clink->value.pdoubles[0]);
|
||||
conv = dbFastPutConvertRoutine[DBF_DOUBLE][dbrType];
|
||||
for (i = 0; i < nElems; i++) {
|
||||
@@ -553,7 +507,7 @@ static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer,
|
||||
break;
|
||||
|
||||
case ac40:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" ac40 ['%s', ...]\n", clink->value.pstrings[0]);
|
||||
conv = dbFastPutConvertRoutine[DBF_STRING][dbrType];
|
||||
for (i = 0; i < nElems; i++) {
|
||||
@@ -564,7 +518,7 @@ static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer,
|
||||
break;
|
||||
|
||||
default:
|
||||
IFDEBUG(12)
|
||||
if (clink->jlink.debug)
|
||||
printf(" Bad type %d\n", clink->type);
|
||||
status = S_db_badField;
|
||||
}
|
||||
@@ -574,12 +528,6 @@ static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer,
|
||||
|
||||
static long lnkConst_getNelements(const struct link *plink, long *nelements)
|
||||
{
|
||||
const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_getNelements(const@%p, (%ld))\n",
|
||||
plink->value.json.jlink, *nelements);
|
||||
|
||||
*nelements = 0;
|
||||
return 0;
|
||||
}
|
||||
@@ -587,13 +535,6 @@ static long lnkConst_getNelements(const struct link *plink, long *nelements)
|
||||
static long lnkConst_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
long *pnRequest)
|
||||
{
|
||||
const_link *clink = CONTAINER(plink->value.json.jlink, const_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_getValue(const@%p, %d, %p, ... (%ld))\n",
|
||||
plink->value.json.jlink, dbrType, pbuffer,
|
||||
pnRequest ? *pnRequest : 0);
|
||||
|
||||
if (pnRequest)
|
||||
*pnRequest = 0;
|
||||
return 0;
|
||||
@@ -626,7 +567,6 @@ static jlif lnkConstIf = {
|
||||
NULL, NULL, NULL,
|
||||
lnkConst_start_array, lnkConst_end_array,
|
||||
NULL, lnkConst_get_lset,
|
||||
lnkConst_report, NULL
|
||||
lnkConst_report, NULL, NULL
|
||||
};
|
||||
epicsExportAddress(jlif, lnkConstIf);
|
||||
|
||||
|
||||
1045
modules/database/src/std/link/lnkDebug.c
Normal file
1045
modules/database/src/std/link/lnkDebug.c
Normal file
File diff suppressed because it is too large
Load Diff
230
modules/database/src/std/link/lnkState.c
Normal file
230
modules/database/src/std/link/lnkState.c
Normal file
@@ -0,0 +1,230 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2017 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.
|
||||
\*************************************************************************/
|
||||
/* lnkState.c */
|
||||
|
||||
/* Usage:
|
||||
* {state:green}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "dbDefs.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsString.h"
|
||||
#include "epicsTypes.h"
|
||||
#include "dbAccessDefs.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbConvertFast.h"
|
||||
#include "dbLink.h"
|
||||
#include "dbJLink.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "dbStaticPvt.h"
|
||||
#include "dbState.h"
|
||||
#include "recGbl.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
|
||||
typedef long (*FASTCONVERT)();
|
||||
|
||||
typedef struct state_link {
|
||||
jlink jlink; /* embedded object */
|
||||
char *name;
|
||||
short val;
|
||||
short invert;
|
||||
dbStateId state;
|
||||
} state_link;
|
||||
|
||||
static lset lnkState_lset;
|
||||
|
||||
|
||||
/*************************** jlif Routines **************************/
|
||||
|
||||
static jlink* lnkState_alloc(short dbfType)
|
||||
{
|
||||
state_link *slink;
|
||||
|
||||
if (dbfType == DBF_FWDLINK) {
|
||||
errlogPrintf("lnkState: DBF_FWDLINK not supported\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
slink = calloc(1, sizeof(struct state_link));
|
||||
if (!slink) {
|
||||
errlogPrintf("lnkState: calloc() failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
slink->name = NULL;
|
||||
slink->state = NULL;
|
||||
slink->invert = 0;
|
||||
slink->val = 0;
|
||||
|
||||
return &slink->jlink;
|
||||
}
|
||||
|
||||
static void lnkState_free(jlink *pjlink)
|
||||
{
|
||||
state_link *slink = CONTAINER(pjlink, struct state_link, jlink);
|
||||
|
||||
free(slink->name);
|
||||
free(slink);
|
||||
}
|
||||
|
||||
static jlif_result lnkState_string(jlink *pjlink, const char *val, size_t len)
|
||||
{
|
||||
state_link *slink = CONTAINER(pjlink, struct state_link, jlink);
|
||||
|
||||
if (len > 1 && val[0] == '!') {
|
||||
slink->invert = 1;
|
||||
val++; len--;
|
||||
}
|
||||
|
||||
slink->name = epicsStrnDup(val, len);
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static struct lset* lnkState_get_lset(const jlink *pjlink)
|
||||
{
|
||||
return &lnkState_lset;
|
||||
}
|
||||
|
||||
static void lnkState_report(const jlink *pjlink, int level, int indent)
|
||||
{
|
||||
state_link *slink = CONTAINER(pjlink, struct state_link, jlink);
|
||||
|
||||
printf("%*s'state': \"%s\" = %s%s\n", indent, "",
|
||||
slink->name, slink->invert ? "! " : "", slink->val ? "TRUE" : "FALSE");
|
||||
}
|
||||
|
||||
/*************************** lset Routines **************************/
|
||||
|
||||
static void lnkState_open(struct link *plink)
|
||||
{
|
||||
state_link *slink = CONTAINER(plink->value.json.jlink,
|
||||
struct state_link, jlink);
|
||||
|
||||
slink->state = dbStateCreate(slink->name);
|
||||
}
|
||||
|
||||
static void lnkState_remove(struct dbLocker *locker, struct link *plink)
|
||||
{
|
||||
state_link *slink = CONTAINER(plink->value.json.jlink,
|
||||
struct state_link, jlink);
|
||||
|
||||
free(slink->name);
|
||||
free(slink);
|
||||
|
||||
plink->value.json.jlink = NULL;
|
||||
}
|
||||
|
||||
static int lnkState_getDBFtype(const struct link *plink)
|
||||
{
|
||||
return DBF_SHORT;
|
||||
}
|
||||
|
||||
static long lnkState_getElements(const struct link *plink, long *nelements)
|
||||
{
|
||||
*nelements = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long lnkState_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
long *pnRequest)
|
||||
{
|
||||
state_link *slink = CONTAINER(plink->value.json.jlink,
|
||||
struct state_link, jlink);
|
||||
FASTCONVERT conv = dbFastPutConvertRoutine[DBR_SHORT][dbrType];
|
||||
|
||||
slink->val = slink->invert ^ dbStateGet(slink->state);
|
||||
return conv(&slink->val, pbuffer, NULL);
|
||||
}
|
||||
|
||||
static long lnkState_putValue(struct link *plink, short dbrType,
|
||||
const void *pbuffer, long nRequest)
|
||||
{
|
||||
state_link *slink = CONTAINER(plink->value.json.jlink,
|
||||
struct state_link, jlink);
|
||||
short val;
|
||||
const char *pstr;
|
||||
|
||||
if (nRequest == 0)
|
||||
return 0;
|
||||
|
||||
switch(dbrType) {
|
||||
case DBR_CHAR:
|
||||
case DBR_UCHAR:
|
||||
val = !! *(const epicsInt8 *) pbuffer;
|
||||
break;
|
||||
|
||||
case DBR_SHORT:
|
||||
case DBR_USHORT:
|
||||
val = !! *(const epicsInt16 *) pbuffer;
|
||||
break;
|
||||
|
||||
case DBR_LONG:
|
||||
case DBR_ULONG:
|
||||
val = !! *(const epicsInt32 *) pbuffer;
|
||||
break;
|
||||
|
||||
case DBR_INT64:
|
||||
case DBR_UINT64:
|
||||
val = !! *(const epicsInt64 *) pbuffer;
|
||||
break;
|
||||
|
||||
case DBR_FLOAT:
|
||||
val = !! *(const epicsFloat32 *) pbuffer;
|
||||
break;
|
||||
|
||||
case DBR_DOUBLE:
|
||||
val = !! *(const epicsFloat64 *) pbuffer;
|
||||
break;
|
||||
|
||||
case DBR_STRING: /* Only "" and "0" are FALSE */
|
||||
pstr = (const char *) pbuffer;
|
||||
val = (pstr[0] != 0) && ((pstr[0] != '0') || (pstr[1] != 0));
|
||||
break;
|
||||
|
||||
default:
|
||||
return S_db_badDbrtype;
|
||||
}
|
||||
slink->val = val;
|
||||
|
||||
val ^= slink->invert;
|
||||
(val ? dbStateSet : dbStateClear)(slink->state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************* Interface Tables *************************/
|
||||
|
||||
static lset lnkState_lset = {
|
||||
0, 0, /* not constant, always connected */
|
||||
lnkState_open, lnkState_remove,
|
||||
NULL, NULL, NULL,
|
||||
NULL, lnkState_getDBFtype, lnkState_getElements,
|
||||
lnkState_getValue,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
lnkState_putValue, NULL,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
static jlif lnkStateIf = {
|
||||
"state", lnkState_alloc, lnkState_free,
|
||||
NULL, NULL, NULL, NULL, lnkState_string,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, lnkState_get_lset,
|
||||
lnkState_report, NULL, NULL
|
||||
};
|
||||
epicsExportAddress(jlif, lnkStateIf);
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2002 Southeastern Universities Research Association, as
|
||||
* Operator of Thomas Jefferson National Accelerator Facility.
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/* recAai.c */
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* Original Author: Dave Barker
|
||||
*
|
||||
* C E B A F
|
||||
*
|
||||
*
|
||||
* Continuous Electron Beam Accelerator Facility
|
||||
* Newport News, Virginia, USA.
|
||||
*
|
||||
@@ -225,10 +225,14 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
static long put_array_info(DBADDR *paddr, long nNew)
|
||||
{
|
||||
aaiRecord *prec = (aaiRecord *)paddr->precord;
|
||||
epicsUInt32 nord = prec->nord;
|
||||
|
||||
prec->nord = nNew;
|
||||
if (prec->nord > prec->nelm)
|
||||
prec->nord = prec->nelm;
|
||||
|
||||
if (nord != prec->nord)
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -241,7 +245,7 @@ static long get_units(DBADDR *paddr, char *units)
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
|
||||
break;
|
||||
break;
|
||||
case indexof(HOPR):
|
||||
case indexof(LOPR):
|
||||
strncpy(units,prec->egu,DB_UNITS_SIZE);
|
||||
@@ -336,33 +340,22 @@ static void monitor(aaiRecord *prec)
|
||||
static long readValue(aaiRecord *prec)
|
||||
{
|
||||
struct aaidset *pdset = (struct aaidset *) prec->dset;
|
||||
long status = 0;
|
||||
long status;
|
||||
|
||||
if (!prec->pact) {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm, &prec->simm, &prec->siml);
|
||||
if (status) return status;
|
||||
}
|
||||
/* NB: Device support must post updates to NORD */
|
||||
|
||||
switch (prec->simm) {
|
||||
case menuYesNoNO:
|
||||
status = pdset->read_aai(prec);
|
||||
break;
|
||||
if (prec->pact)
|
||||
goto do_read;
|
||||
|
||||
case menuYesNoYES: {
|
||||
status = recGblGetSimm((dbCommon *)prec, &prec->sscn, &prec->oldsimm,
|
||||
&prec->simm, &prec->siml);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (prec->simm == menuYesNoYES) {
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
/* Device suport is responsible for buffer
|
||||
which might be read-only so we may not be
|
||||
allowed to call dbGetLink on it.
|
||||
Maybe also device support has an advanced
|
||||
simulation mode.
|
||||
Thus call device now.
|
||||
|
||||
Reading through SIOL is handled in Soft Channel Device Support
|
||||
*/
|
||||
status = pdset->read_aai(prec);
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
if (prec->sdly >= 0) {
|
||||
CALLBACK *pvt = prec->simpvt;
|
||||
if (!pvt) {
|
||||
pvt = calloc(1, sizeof(CALLBACK)); /* very lazy allocation of callback structure */
|
||||
@@ -370,14 +363,14 @@ static long readValue(aaiRecord *prec)
|
||||
}
|
||||
if (pvt) callbackRequestProcessCallbackDelayed(pvt, prec->prio, prec, prec->sdly);
|
||||
prec->pact = TRUE;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
else if (prec->simm != menuYesNoNO) {
|
||||
recGblSetSevr(prec, SOFT_ALARM, INVALID_ALARM);
|
||||
status = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
do_read:
|
||||
return pdset->read_aai(prec);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2002 Southeastern Universities Research Association, as
|
||||
* Operator of Thomas Jefferson National Accelerator Facility.
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
/* recAao.c */
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* Original Author: Dave Barker
|
||||
*
|
||||
* C E B A F
|
||||
*
|
||||
*
|
||||
* Continuous Electron Beam Accelerator Facility
|
||||
* Newport News, Virginia, USA.
|
||||
*
|
||||
@@ -225,10 +225,14 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
static long put_array_info(DBADDR *paddr, long nNew)
|
||||
{
|
||||
aaoRecord *prec = (aaoRecord *)paddr->precord;
|
||||
epicsUInt32 nord = prec->nord;
|
||||
|
||||
prec->nord = nNew;
|
||||
if (prec->nord > prec->nelm)
|
||||
prec->nord = prec->nelm;
|
||||
|
||||
if (nord != prec->nord)
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -241,7 +245,7 @@ static long get_units(DBADDR *paddr, char *units)
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
|
||||
break;
|
||||
break;
|
||||
case indexof(HOPR):
|
||||
case indexof(LOPR):
|
||||
strncpy(units,prec->egu,DB_UNITS_SIZE);
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
* 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.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Original Author: Bob Dalesio
|
||||
* Date: 7-14-89
|
||||
* Date: 7-14-89
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -439,12 +439,16 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
static long put_array_info(DBADDR *paddr, long nNew)
|
||||
{
|
||||
compressRecord *prec = (compressRecord *) paddr->precord;
|
||||
epicsUInt32 nuse = prec->nuse;
|
||||
|
||||
if (prec->balg == bufferingALG_FIFO)
|
||||
prec->off = (prec->off + nNew) % prec->nsam;
|
||||
prec->nuse += nNew;
|
||||
if (prec->nuse > prec->nsam)
|
||||
prec->nuse = prec->nsam;
|
||||
|
||||
if (nuse != prec->nuse)
|
||||
db_post_events(prec, &prec->nuse, DBE_VALUE | DBE_LOG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
* Copyright (c) 2002 Lawrence Berkeley Laboratory,The Control Systems
|
||||
* Group, Systems Engineering Department
|
||||
* 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.
|
||||
\*************************************************************************/
|
||||
|
||||
/* recSubArray.c - Record Support Routines for SubArray records
|
||||
/* recSubArray.c - Record Support Routines for SubArray records
|
||||
*
|
||||
*
|
||||
* Author: Carl Lionberger
|
||||
* Date: 090293
|
||||
*
|
||||
* NOTES:
|
||||
* Derived from waveform record.
|
||||
* Derived from waveform record.
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
*/
|
||||
@@ -126,7 +126,7 @@ static long init_record(struct dbCommon *pcommon, int pass)
|
||||
}
|
||||
|
||||
if (pdset->init_record)
|
||||
return (*pdset->init_record)(prec);
|
||||
return pdset->init_record(prec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -194,11 +194,14 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
static long put_array_info(DBADDR *paddr, long nNew)
|
||||
{
|
||||
subArrayRecord *prec = (subArrayRecord *) paddr->precord;
|
||||
epicsUInt32 nord = prec->nord;
|
||||
|
||||
if (nNew > prec->malm)
|
||||
nNew = prec->malm;
|
||||
prec->nord = nNew;
|
||||
if (prec->nord > prec->malm)
|
||||
prec->nord = prec->malm;
|
||||
|
||||
if (nord != prec->nord)
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -211,7 +214,7 @@ static long get_units(DBADDR *paddr, char *units)
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
|
||||
break;
|
||||
break;
|
||||
case indexof(HOPR):
|
||||
case indexof(LOPR):
|
||||
strncpy(units,prec->egu,DB_UNITS_SIZE);
|
||||
@@ -321,4 +324,3 @@ static long readValue(subArrayRecord *prec)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* 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.
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/* recWaveform.c - Record Support Routines for Waveform records */
|
||||
@@ -205,12 +205,14 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset)
|
||||
static long put_array_info(DBADDR *paddr, long nNew)
|
||||
{
|
||||
waveformRecord *prec = (waveformRecord *) paddr->precord;
|
||||
epicsUInt32 nord = prec->nord;
|
||||
|
||||
prec->nord = nNew;
|
||||
if (prec->nord > prec->nelm)
|
||||
prec->nord = prec->nelm;
|
||||
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
if (nord != prec->nord)
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -223,7 +225,7 @@ static long get_units(DBADDR *paddr, char *units)
|
||||
switch (dbGetFieldIndex(paddr)) {
|
||||
case indexof(VAL):
|
||||
if (prec->ftvl == DBF_STRING || prec->ftvl == DBF_ENUM)
|
||||
break;
|
||||
break;
|
||||
case indexof(HOPR):
|
||||
case indexof(LOPR):
|
||||
strncpy(units,prec->egu,DB_UNITS_SIZE);
|
||||
@@ -346,15 +348,18 @@ static long readValue(waveformRecord *prec)
|
||||
|
||||
case menuYesNoYES: {
|
||||
long nRequest = prec->nelm;
|
||||
epicsUInt32 nord = prec->nord;
|
||||
|
||||
recGblSetSevr(prec, SIMM_ALARM, prec->sims);
|
||||
if (prec->pact || (prec->sdly < 0.)) {
|
||||
status = dbGetLink(&prec->siol, prec->ftvl, prec->bptr, 0, &nRequest);
|
||||
if (status == 0) prec->udf = FALSE;
|
||||
/* nord set only for db links: needed for old db_access */
|
||||
if (status == 0)
|
||||
prec->udf = FALSE;
|
||||
|
||||
if (!dbLinkIsConstant(&prec->siol)) {
|
||||
prec->nord = nRequest;
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
if (nord != prec->nord)
|
||||
db_post_events(prec, &prec->nord, DBE_VALUE | DBE_LOG);
|
||||
}
|
||||
prec->pact = FALSE;
|
||||
} else { /* !prec->pact && delay >= 0. */
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
|
||||
if $running_under_some_shell;
|
||||
#!/usr/bin/env perl
|
||||
#*************************************************************************
|
||||
# Copyright (c) 2010 UChicago Argonne LLC, as Operator of Argonne
|
||||
# National Laboratory.
|
||||
|
||||
Reference in New Issue
Block a user