From bc1cd1585291fe11a74c480bf59ffcf79fbd1cd6 Mon Sep 17 00:00:00 2001 From: Ralph Lange Date: Thu, 28 Aug 2014 11:23:22 -0700 Subject: [PATCH] ioc/db: add optional "tagged" plugin configuration (sets integer tag and any value in one step) --- src/ioc/db/chfPlugin.c | 60 +++++++++++++++++++++-------------- src/ioc/db/chfPlugin.h | 72 ++++++++++++++++++++++++++++++++---------- 2 files changed, 92 insertions(+), 40 deletions(-) diff --git a/src/ioc/db/chfPlugin.c b/src/ioc/db/chfPlugin.c index 0cf4f367f..bcc6a2efe 100644 --- a/src/ioc/db/chfPlugin.c +++ b/src/ioc/db/chfPlugin.c @@ -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 + * Author: Ralph Lange */ /* 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; } diff --git a/src/ioc/db/chfPlugin.h b/src/ioc/db/chfPlugin.h index 47d3055c4..eabaa7ac3 100644 --- a/src/ioc/db/chfPlugin.h +++ b/src/ioc/db/chfPlugin.h @@ -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 + * Author: Ralph Lange */ /* 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}