ioc/db: add optional "tagged" plugin configuration (sets integer tag and any value in one step)

This commit is contained in:
Ralph Lange
2014-08-28 11:23:22 -07:00
parent 8604d4643a
commit bc1cd15852
2 changed files with 92 additions and 40 deletions

View File

@@ -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;
}

View File

@@ -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}