lnkState: Add support for inverting the flag data
Determine the truthiness of put data in its original data type. Adjust the link documentation to cover these changes.
This commit is contained in:
@@ -137,12 +137,18 @@ link(state, lnkStateIf)
|
||||
=head3 dbState Link C<"state">
|
||||
|
||||
A dbState link is one that reads or writes a boolean value from/to a named
|
||||
global flag as implemented by the dbState facility in C<dbstate.h>.
|
||||
global flag as implemented by the dbState facility in C<dbstate.h>. The link
|
||||
type can invert the sense of the dbState flag if desired.
|
||||
|
||||
The value of the named flag is read or written at the time of the link I/O
|
||||
operation. The boolean flag data is represented as a C<DBF_LONG> that can only
|
||||
hold the values zero or one; putting any non-zero numeric value to a link sets
|
||||
the boolean flag value, putting a zero value clears it.
|
||||
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
|
||||
@@ -150,11 +156,14 @@ mechanism.
|
||||
|
||||
=head4 Parameters
|
||||
|
||||
The link address must be a string providing the name of the dbState object,
|
||||
which will be created when the link is initialized if it doesn't already exist.
|
||||
The link address must be a string providing the name of the dbState object, with
|
||||
an optional leading C<!> charater to indicate 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 Example
|
||||
=head4 Examples
|
||||
|
||||
{state:"redBeam"}
|
||||
{state:"!simEnable"}
|
||||
|
||||
=cut
|
||||
|
||||
@@ -40,7 +40,8 @@ typedef long (*FASTCONVERT)();
|
||||
typedef struct state_link {
|
||||
jlink jlink; /* embedded object */
|
||||
char *name;
|
||||
int val;
|
||||
short val;
|
||||
short invert;
|
||||
dbStateId state;
|
||||
} state_link;
|
||||
|
||||
@@ -58,6 +59,7 @@ static jlink* lnkState_alloc(short dbfType)
|
||||
|
||||
slink->name = NULL;
|
||||
slink->state = NULL;
|
||||
slink->invert = 0;
|
||||
slink->val = 0;
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -84,6 +86,11 @@ static jlif_result lnkState_string(jlink *pjlink, const char *val, size_t len)
|
||||
IFDEBUG(10)
|
||||
printf("lnkState_string(state@%p, \"%.*s\")\n", slink, (int) len, val);
|
||||
|
||||
if (len > 1 && val[0] == '!') {
|
||||
slink->invert = 1;
|
||||
val++; len--;
|
||||
}
|
||||
|
||||
slink->name = epicsStrnDup(val, len);
|
||||
return jlif_continue;
|
||||
}
|
||||
@@ -105,8 +112,8 @@ static void lnkState_report(const jlink *pjlink, int level, int indent)
|
||||
IFDEBUG(10)
|
||||
printf("lnkState_report(state@%p)\n", slink);
|
||||
|
||||
printf("%*s'state': \"%s\" = %d\n", indent, "",
|
||||
slink->name, slink->val);
|
||||
printf("%*s'state': \"%s\" = %s%s\n", indent, "",
|
||||
slink->name, slink->invert ? "! " : "", slink->val ? "TRUE" : "FALSE");
|
||||
}
|
||||
|
||||
/*************************** lset Routines **************************/
|
||||
@@ -155,7 +162,7 @@ static int lnkState_getDBFtype(const struct link *plink)
|
||||
IFDEBUG(10)
|
||||
printf("lnkState_getDBFtype(state@%p)\n", slink);
|
||||
|
||||
return DBF_LONG;
|
||||
return DBF_SHORT;
|
||||
}
|
||||
|
||||
static long lnkState_getElements(const struct link *plink, long *nelements)
|
||||
@@ -177,13 +184,15 @@ static long lnkState_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
state_link *slink = CONTAINER(plink->value.json.jlink,
|
||||
struct state_link, jlink);
|
||||
long status;
|
||||
FASTCONVERT conv = dbFastPutConvertRoutine[DBR_LONG][dbrType];
|
||||
short flag;
|
||||
FASTCONVERT conv = dbFastPutConvertRoutine[DBR_SHORT][dbrType];
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkState_getValue(state@%p, %d, ...)\n",
|
||||
slink, dbrType);
|
||||
|
||||
slink->val = dbStateGet(slink->state);
|
||||
flag = dbStateGet(slink->state);
|
||||
slink->val = slink->invert ^ flag;
|
||||
status = conv(&slink->val, pbuffer, NULL);
|
||||
|
||||
return status;
|
||||
@@ -194,20 +203,59 @@ static long lnkState_putValue(struct link *plink, short dbrType,
|
||||
{
|
||||
state_link *slink = CONTAINER(plink->value.json.jlink,
|
||||
struct state_link, jlink);
|
||||
long status;
|
||||
FASTCONVERT conv = dbFastPutConvertRoutine[dbrType][DBR_LONG];
|
||||
short val;
|
||||
const char *pstr;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkState_getValue(state@%p, %d, ...)\n",
|
||||
printf("lnkState_putValue(state@%p, %d, ...)\n",
|
||||
slink, dbrType);
|
||||
|
||||
if (nRequest == 0)
|
||||
return 0;
|
||||
|
||||
status = conv(pbuffer, &slink->val, NULL);
|
||||
(slink->val ? dbStateSet : dbStateClear)(slink->state);
|
||||
switch(dbrType) {
|
||||
case DBR_CHAR:
|
||||
case DBR_UCHAR:
|
||||
val = !! *(const epicsInt8 *) pbuffer;
|
||||
break;
|
||||
|
||||
return status;
|
||||
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 *************************/
|
||||
|
||||
Reference in New Issue
Block a user