ioc/db: add optional "tagged" plugin configuration (sets integer tag and any value in one step)
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2010 Brookhaven National Laboratory.
|
||||
* Copyright (c) 2010 Helmholtz-Zentrum Berlin
|
||||
* fuer Materialien und Energie GmbH.
|
||||
* für Materialien und Energie GmbH.
|
||||
* Copyright (c) 2014 ITER Organization.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author: Ralph Lange <Ralph.Lange@bessy.de>
|
||||
* Author: Ralph Lange <Ralph.Lange@gmx.de>
|
||||
*/
|
||||
|
||||
/* Based on the linkoptions utility by Michael Davidsaver (BNL) */
|
||||
@@ -84,19 +85,19 @@ store_integer_value(const chfPluginArgDef *opt, char *user, epicsInt32 val)
|
||||
|
||||
switch (opt->optType) {
|
||||
case chfPluginArgInt32:
|
||||
ival = (epicsInt32 *) ((char *)user + opt->offset);
|
||||
ival = (epicsInt32 *) ((char *)user + opt->dataOffset);
|
||||
*ival = val;
|
||||
break;
|
||||
case chfPluginArgBoolean:
|
||||
sval = user + opt->offset;
|
||||
sval = user + opt->dataOffset;
|
||||
*sval = !!val;
|
||||
break;
|
||||
case chfPluginArgDouble:
|
||||
dval = (double*) (user + opt->offset);
|
||||
dval = (double*) (user + opt->dataOffset);
|
||||
*dval = val;
|
||||
break;
|
||||
case chfPluginArgString:
|
||||
sval = user + opt->offset;
|
||||
sval = user + opt->dataOffset;
|
||||
ret = sprintf(buff, "%ld", (long)val);
|
||||
if (ret < 0 || (unsigned) ret > opt->size - 1) {
|
||||
return -1;
|
||||
@@ -105,7 +106,7 @@ store_integer_value(const chfPluginArgDef *opt, char *user, epicsInt32 val)
|
||||
sval[opt->size-1]='\0';
|
||||
break;
|
||||
case chfPluginArgEnum:
|
||||
eval = (int*) (user + opt->offset);
|
||||
eval = (int*) (user + opt->dataOffset);
|
||||
for (emap = opt->enums; emap && emap->name; emap++) {
|
||||
if (val == emap->value) {
|
||||
*eval = val;
|
||||
@@ -143,19 +144,19 @@ static int store_boolean_value(const chfPluginArgDef *opt, char *user, int val)
|
||||
|
||||
switch (opt->optType) {
|
||||
case chfPluginArgInt32:
|
||||
ival = (epicsInt32 *) (user + opt->offset);
|
||||
ival = (epicsInt32 *) (user + opt->dataOffset);
|
||||
*ival = val;
|
||||
break;
|
||||
case chfPluginArgBoolean:
|
||||
sval = user + opt->offset;
|
||||
sval = user + opt->dataOffset;
|
||||
*sval = val;
|
||||
break;
|
||||
case chfPluginArgDouble:
|
||||
dval = (double*) (user + opt->offset);
|
||||
dval = (double*) (user + opt->dataOffset);
|
||||
*dval = !!val;
|
||||
break;
|
||||
case chfPluginArgString:
|
||||
sval = user + opt->offset;
|
||||
sval = user + opt->dataOffset;
|
||||
if ((unsigned) (val ? 4 : 5) > opt->size - 1) {
|
||||
return -1;
|
||||
}
|
||||
@@ -196,24 +197,24 @@ store_double_value(const chfPluginArgDef *opt, void *vuser, double val)
|
||||
if (val < INT_MIN || val > INT_MAX) {
|
||||
return -1;
|
||||
}
|
||||
ival = (epicsInt32 *) (user + opt->offset);
|
||||
ival = (epicsInt32 *) (user + opt->dataOffset);
|
||||
*ival = (epicsInt32) val;
|
||||
break;
|
||||
case chfPluginArgBoolean:
|
||||
sval = user + opt->offset;
|
||||
sval = user + opt->dataOffset;
|
||||
*sval = !!val;
|
||||
break;
|
||||
case chfPluginArgDouble:
|
||||
dval = (double*) (user + opt->offset);
|
||||
dval = (double*) (user + opt->dataOffset);
|
||||
*dval = val;
|
||||
break;
|
||||
case chfPluginArgString:
|
||||
sval = user + opt->offset;
|
||||
sval = user + opt->dataOffset;
|
||||
if (opt->size <= 8) { /* Play it safe: 3 exp + 2 sign + 'e' + '.' */
|
||||
return -1;
|
||||
}
|
||||
i = epicsSnprintf(sval, opt->size, "%.*g", (int) opt->size - 7, val);
|
||||
if (i >= opt->size) {
|
||||
if (i < 0 || (unsigned) i >= opt->size) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
@@ -252,11 +253,11 @@ store_string_value(const chfPluginArgDef *opt, char *user, const char *val,
|
||||
|
||||
switch (opt->optType) {
|
||||
case chfPluginArgInt32:
|
||||
ival = (epicsInt32 *) (user + opt->offset);
|
||||
ival = (epicsInt32 *) (user + opt->dataOffset);
|
||||
return epicsParseInt32(val, ival, 0, &end);
|
||||
|
||||
case chfPluginArgBoolean:
|
||||
sval = user + opt->offset;
|
||||
sval = user + opt->dataOffset;
|
||||
if (epicsStrnCaseCmp(val, "true", len) == 0) {
|
||||
*sval = 1;
|
||||
} else if (epicsStrnCaseCmp(val, "false", len) == 0) {
|
||||
@@ -270,17 +271,17 @@ store_string_value(const chfPluginArgDef *opt, char *user, const char *val,
|
||||
}
|
||||
break;
|
||||
case chfPluginArgDouble:
|
||||
dval = (double*) (user + opt->offset);
|
||||
dval = (double*) (user + opt->dataOffset);
|
||||
return epicsParseDouble(val, dval, &end);
|
||||
|
||||
case chfPluginArgString:
|
||||
i = opt->size-1 < len ? opt->size-1 : len;
|
||||
sval = user + opt->offset;
|
||||
i = opt->size-1 < len ? opt->size-1 : (int) len;
|
||||
sval = user + opt->dataOffset;
|
||||
strncpy(sval, val, i);
|
||||
sval[i] = '\0';
|
||||
break;
|
||||
case chfPluginArgEnum:
|
||||
eval = (int*) (user + opt->offset);
|
||||
eval = (int*) (user + opt->dataOffset);
|
||||
for (emap = opt->enums; emap && emap->name; emap++) {
|
||||
if (strncmp(emap->name, val, len) == 0) {
|
||||
*eval = emap->value;
|
||||
@@ -455,8 +456,10 @@ parse_map_key(chFilter *filter, const char *key, size_t stringLen)
|
||||
{
|
||||
const chfPluginArgDef *cur;
|
||||
const chfPluginArgDef *opts = ((chfPlugin*)filter->plug->puser)->opts;
|
||||
chfFilter *f = (chfFilter*)filter->puser;
|
||||
chfFilter *f = (chfFilter*)filter->puser;
|
||||
int *tag;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
f->nextParam = -1;
|
||||
for(cur = opts, i = 0; cur && cur->name; cur++, i++) {
|
||||
@@ -470,6 +473,17 @@ parse_map_key(chFilter *filter, const char *key, size_t stringLen)
|
||||
}
|
||||
|
||||
f->found[i/32] |= 1<<(i%32);
|
||||
/* For tagged parameters:
|
||||
* set tag to this choice, and mark all other choices as found */
|
||||
if (opts[i].tagged) {
|
||||
tag = (int*) ((char*) f->puser + opts[i].tagOffset);
|
||||
*tag = opts[i].choice;
|
||||
for (cur = opts, j = 0; cur && cur->name; cur++, j++) {
|
||||
if (cur->tagged && cur->tagOffset == opts[i].tagOffset) {
|
||||
f->found[j/32] |= 1<<(j%32);
|
||||
}
|
||||
}
|
||||
}
|
||||
return parse_continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2010 Brookhaven National Laboratory.
|
||||
* Copyright (c) 2010 Helmholtz-Zentrum Berlin
|
||||
* fuer Materialien und Energie GmbH.
|
||||
* für Materialien und Energie GmbH.
|
||||
* Copyright (c) 2014 ITER Organization.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
|
||||
/*
|
||||
* Author: Ralph Lange <Ralph.Lange@bessy.de>
|
||||
* Author: Ralph Lange <Ralph.Lange@gmx.de>
|
||||
*/
|
||||
|
||||
/* Based on the linkoptions utility by Michael Davidsaver (BNL) */
|
||||
@@ -44,10 +45,11 @@ struct db_field_log;
|
||||
*
|
||||
* typedef struct myStruct {
|
||||
* ... other stuff
|
||||
* char mode;
|
||||
* epicsInt32 ival;
|
||||
* double dval;
|
||||
* double dval;
|
||||
* epicsInt32 ival2;
|
||||
* int enumval;
|
||||
* int enumval;
|
||||
* char strval[20];
|
||||
* char boolval;
|
||||
* } myStruct;
|
||||
@@ -57,18 +59,22 @@ struct db_field_log;
|
||||
*
|
||||
* static const
|
||||
* chfPluginDef myStructDef[] = {
|
||||
* chfInt32 (myStruct, ival, "Integer" , 0, 0),
|
||||
* chfInt32 (myStruct, ival2, "Second" , 1, 0),
|
||||
* chfDouble(myStruct, dval, "Double" , 1, 0),
|
||||
* chfString(myStruct, strval , "String" , 1, 0),
|
||||
* chfEnum (myStruct, enumval, "Color" , 1, 0, colorEnum),
|
||||
* chfBoolean(myStruct, boolval, "Bool" , 1, 0),
|
||||
* chfTagInt32(myStruct, ival, "Integer" , ival2, 3, 0, 0),
|
||||
* chfInt32 (myStruct, ival2, "Second" , 1, 0),
|
||||
* chfDouble (myStruct, dval, "Double" , 1, 0),
|
||||
* chfString (myStruct, strval , "String" , 1, 0),
|
||||
* chfEnum (myStruct, enumval, "Color" , 1, 0, colorEnum),
|
||||
* chfBoolean (myStruct, boolval, "Bool" , 1, 0),
|
||||
* chfPluginEnd
|
||||
* };
|
||||
*
|
||||
* Note: The 4th argument specifies the parameter to be required (1) or optional (0),
|
||||
* the 5th whether converting to the required type is allowed (1), or
|
||||
* type mismatches are an error (0).
|
||||
* Note: The "Tag" version has two additional arguments. the 4th arg specifies the tag
|
||||
* field (integer type) inside the structure to be set, the 5th arg specifies the
|
||||
* value to set the tag field to. Arguments 6 and 7 specify "required" and
|
||||
* "conversion" as described above.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -231,25 +237,57 @@ typedef struct chfPluginArgDef {
|
||||
chfPluginArg optType;
|
||||
unsigned int required:1;
|
||||
unsigned int convert:1;
|
||||
epicsUInt32 offset;
|
||||
epicsUInt32 size;
|
||||
unsigned int tagged:1;
|
||||
epicsUInt32 tagOffset;
|
||||
epicsUInt32 choice;
|
||||
epicsUInt32 dataOffset;
|
||||
epicsUInt32 size;
|
||||
const chfPluginEnumType *enums;
|
||||
} chfPluginArgDef;
|
||||
|
||||
/* Simple arguments */
|
||||
|
||||
#define chfInt32(Struct, Member, Name, Req, Conv) \
|
||||
{Name, chfPluginArgInt32, Req, Conv, OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
{Name, chfPluginArgInt32, Req, Conv, 0, 0, 0, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
|
||||
#define chfBoolean(Struct, Member, Name, Req, Conv) \
|
||||
{Name, chfPluginArgBoolean, Req, Conv, OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
{Name, chfPluginArgBoolean, Req, Conv, 0, 0, 0, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
|
||||
#define chfDouble(Struct, Member, Name, Req, Conv) \
|
||||
{Name, chfPluginArgDouble, Req, Conv, OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
{Name, chfPluginArgDouble, Req, Conv, 0, 0, 0, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
|
||||
#define chfString(Struct, Member, Name, Req, Conv) \
|
||||
{Name, chfPluginArgString, Req, Conv, OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
{Name, chfPluginArgString, Req, Conv, 0, 0, 0, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
|
||||
#define chfEnum(Struct, Member, Name, Req, Conv, Enums) \
|
||||
{Name, chfPluginArgEnum, Req, Conv, OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), Enums}
|
||||
{Name, chfPluginArgEnum, Req, Conv, 0, 0, 0, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), Enums}
|
||||
|
||||
/* Tagged arguments */
|
||||
|
||||
#define chfTagInt32(Struct, Member, Name, Tag, Choice, Req, Conv) \
|
||||
{Name, chfPluginArgInt32, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
|
||||
#define chfTagBoolean(Struct, Member, Name, Tag, Choice, Req, Conv) \
|
||||
{Name, chfPluginArgBoolean, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
|
||||
#define chfTagDouble(Struct, Member, Name, Tag, Choice, Req, Conv) \
|
||||
{Name, chfPluginArgDouble, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
|
||||
#define chfTagString(Struct, Member, Name, Tag, Choice, Req, Conv) \
|
||||
{Name, chfPluginArgString, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), NULL}
|
||||
|
||||
#define chfTagEnum(Struct, Member, Name, Tag, Choice, Req, Conv, Enums) \
|
||||
{Name, chfPluginArgEnum, Req, Conv, 1, OFFSET(Struct, Tag), Choice, \
|
||||
OFFSET(Struct, Member), sizeof( ((Struct*)0)->Member ), Enums}
|
||||
|
||||
#define chfPluginArgEnd {0}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user