diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2012-10-01 10:29:38 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2012-10-01 10:29:38 +0200 |
commit | c0ccd3ff253401ce2081a5d2042f50af35b07233 (patch) | |
tree | 0c828480a8d8b2fa507edc83e7727d913ee426a1 /grammar | |
parent | cdbeb9d75a9a79c1f5941f748af540ab13425cf1 (diff) | |
download | rsyslog-c0ccd3ff253401ce2081a5d2042f50af35b07233.tar.gz rsyslog-c0ccd3ff253401ce2081a5d2042f50af35b07233.tar.xz rsyslog-c0ccd3ff253401ce2081a5d2042f50af35b07233.zip |
implement string arrays for config objects
as a tester, imudp now supports binding to multiple options
based on a string array
Diffstat (limited to 'grammar')
-rw-r--r-- | grammar/grammar.y | 9 | ||||
-rw-r--r-- | grammar/rainerscript.c | 147 | ||||
-rw-r--r-- | grammar/rainerscript.h | 11 |
3 files changed, 134 insertions, 33 deletions
diff --git a/grammar/grammar.y b/grammar/grammar.y index 89fd2289..10d832c3 100644 --- a/grammar/grammar.y +++ b/grammar/grammar.y @@ -94,8 +94,7 @@ extern int yyerror(char*); %token CMP_STARTSWITH %token CMP_STARTSWITHI -%type <estr> value -%type <nvlst> nv nvlst +%type <nvlst> nv nvlst value %type <obj> obj property constant %type <objlst> propconst %type <expr> expr @@ -141,9 +140,9 @@ property: BEGIN_PROPERTY nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_PROPERTY, $2); } constant: BEGIN_CONSTANT nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_CONSTANT, $2); } nvlst: { $$ = NULL; } | nvlst nv { $2->next = $1; $$ = $2; } -nv: NAME '=' value { $$ = nvlstNew($1, $3); } -value: STRING { $$ = $1; } - | array { dbgprintf("DDDD: value array\n"); } +nv: NAME '=' value { $$ = nvlstSetName($3, $1); } +value: STRING { $$ = nvlstNewStr($1); } + | array { $$ = nvlstNewArray($1); } script: stmt { $$ = $1; } | script stmt { $$ = scriptAddStmt($1, $2); } stmt: actlst { $$ = $1; } diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c index d77721b8..6f9310db 100644 --- a/grammar/rainerscript.c +++ b/grammar/rainerscript.c @@ -51,6 +51,9 @@ DEFobjCurrIf(regexp) void cnfexprOptimize(struct cnfexpr *expr); static void cnfstmtOptimizePRIFilt(struct cnfstmt *stmt); +static void cnfarrayPrint(struct cnfarray *ar, int indent); +static void cnfarrayContentDestruct(struct cnfarray *ar); +static struct cnfarray* cnfarrayDup(struct cnfarray *old); char* getFIOPName(unsigned iFIOP) @@ -206,13 +209,12 @@ objlstPrint(struct objlst *lst) } struct nvlst* -nvlstNew(es_str_t *name, es_str_t *value) +nvlstNewStr(es_str_t *value) { struct nvlst *lst; if((lst = malloc(sizeof(struct nvlst))) != NULL) { lst->next = NULL; - lst->name = name; lst->val.datatype = 'S'; lst->val.d.estr = value; lst->bUsed = 0; @@ -221,6 +223,28 @@ nvlstNew(es_str_t *name, es_str_t *value) return lst; } +struct nvlst* +nvlstNewArray(struct cnfarray *ar) +{ + struct nvlst *lst; + + if((lst = malloc(sizeof(struct nvlst))) != NULL) { + lst->next = NULL; + lst->val.datatype = 'A'; + lst->val.d.ar = ar; + lst->bUsed = 0; + } + + return lst; +} + +struct nvlst* +nvlstSetName(struct nvlst *lst, es_str_t *name) +{ + lst->name = name; + return lst; +} + void nvlstDestruct(struct nvlst *lst) { @@ -230,8 +254,7 @@ nvlstDestruct(struct nvlst *lst) toDel = lst; lst = lst->next; es_deleteStr(toDel->name); - if(toDel->val.datatype == 'S') - es_deleteStr(toDel->val.d.estr); + varDelete(&toDel->val); free(toDel); } } @@ -243,11 +266,21 @@ nvlstPrint(struct nvlst *lst) dbgprintf("nvlst %p:\n", lst); while(lst != NULL) { name = es_str2cstr(lst->name, NULL); - // TODO: support for non-string types - value = es_str2cstr(lst->val.d.estr, NULL); - dbgprintf("\tname: '%s', value '%s'\n", name, value); + switch(lst->val.datatype) { + case 'A': + dbgprintf("\tname: '%s':\n", name); + cnfarrayPrint(lst->val.d.ar, 5); + break; + case 'S': + value = es_str2cstr(lst->val.d.estr, NULL); + dbgprintf("\tname: '%s', value '%s'\n", name, value); + free(value); + break; + default:dbgprintf("nvlstPrint: unknown type '%c' [%d]\n", + lst->val.datatype, lst->val.datatype); + break; + } free(name); - free(value); lst = lst->next; } } @@ -566,6 +599,7 @@ doGetWord(struct nvlst *valnode, struct cnfparamdescr *param, es_size_t i; int r = 1; unsigned char *c; + val->val.datatype = 'S'; val->val.d.estr = es_newStr(32); c = es_getBufAddr(valnode->val.d.estr); @@ -574,7 +608,7 @@ doGetWord(struct nvlst *valnode, struct cnfparamdescr *param, } if(i != es_strlen(valnode->val.d.estr)) { parser_errmsg("parameter '%s' contains whitespace, which is not " - "permitted - data after first whitespace ignored", + "permitted", param->name); r = 0; } @@ -582,6 +616,30 @@ doGetWord(struct nvlst *valnode, struct cnfparamdescr *param, } static inline int +doGetArray(struct nvlst *valnode, struct cnfparamdescr *param, + struct cnfparamvals *val) +{ + int r = 1; + + switch(valnode->val.datatype) { + case 'S': + /* a constant string is assumed to be a single-element array */ + val->val.datatype = 'A'; + val->val.d.ar = cnfarrayNew(es_strdup(valnode->val.d.estr)); + break; + case 'A': + val->val.datatype = 'A'; + val->val.d.ar = cnfarrayDup(valnode->val.d.ar); + break; + default:parser_errmsg("parameter '%s' must be an array, but is a " + "different datatype", param->name); + r = 0; + break; + } + return r; +} + +static inline int doGetChar(struct nvlst *valnode, struct cnfparamdescr *param, struct cnfparamvals *val) { @@ -607,8 +665,15 @@ nvlstGetParam(struct nvlst *valnode, struct cnfparamdescr *param, uchar *cstr; int r; - dbgprintf("XXXX: in nvlstGetParam, name '%s', type %d, valnode->bUsed %d\n", + DBGPRINTF("nvlstGetParam: name '%s', type %d, valnode->bUsed %d\n", param->name, (int) param->type, valnode->bUsed); + if(valnode->val.datatype != 'S' && param->type != eCmdHdlrArray) { + parser_errmsg("parameter '%s' is not a string, which is not " + "permitted", + param->name); + r = 0; + goto done; + } valnode->bUsed = 1; val->bUsed = 1; switch(param->type) { @@ -664,6 +729,9 @@ nvlstGetParam(struct nvlst *valnode, struct cnfparamdescr *param, val->val.d.estr = es_strdup(valnode->val.d.estr); r = 1; break; + case eCmdHdlrArray: + r = doGetArray(valnode, param, val); + break; case eCmdHdlrGoneAway: parser_errmsg("parameter '%s' is no longer supported", param->name); @@ -674,7 +742,7 @@ nvlstGetParam(struct nvlst *valnode, struct cnfparamdescr *param, r = 0; break; } - return r; +done: return r; } @@ -751,6 +819,9 @@ cnfparamsPrint(struct cnfparamblk *params, struct cnfparamvals *vals) dbgprintf(" '%s'", cstr); free(cstr); break; + case 'A': + cnfarrayPrint(vals[i].val.d.ar, 0); + break; case 'N': dbgprintf("%lld", vals[i].val.d.n); break; @@ -1544,11 +1615,10 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr) //--------------------------------------------------------- -static inline void -cnfarrayDestruct(struct cnfarray *ar) +static void +cnfarrayContentDestruct(struct cnfarray *ar) { unsigned short i; - for(i = 0 ; i < ar->nmemb ; ++i) { es_deleteStr(ar->arr[i]); } @@ -1620,7 +1690,7 @@ cnfexprDestruct(struct cnfexpr *expr) cnffuncDestruct((struct cnffunc*)expr); break; case S_ARRAY: - cnfarrayDestruct((struct cnfarray*)expr); + cnfarrayContentDestruct((struct cnfarray*)expr); break; default:break; } @@ -1665,6 +1735,17 @@ pmaskPrint(uchar *pmask, int indent) dbgprintf("\n"); } +static void +cnfarrayPrint(struct cnfarray *ar, int indent) +{ + int i; + doIndent(indent); dbgprintf("ARRAY:\n"); + for(i = 0 ; i < ar->nmemb ; ++i) { + doIndent(indent+1); + cstrPrint("string '", ar->arr[i]); + dbgprintf("'\n"); + } +} void cnfexprPrint(struct cnfexpr *expr, int indent) @@ -1757,13 +1838,7 @@ cnfexprPrint(struct cnfexpr *expr, int indent) dbgprintf("'\n"); break; case S_ARRAY: -dbgprintf("DDDD: %d members\n", ((struct cnfarray*)expr)->nmemb); - doIndent(indent); dbgprintf("ARRAY:\n"); - for(i = 0 ; i < ((struct cnfarray*)expr)->nmemb ; ++i) { - doIndent(indent+1); - cstrPrint("string '", ((struct cnfarray*)expr)->arr[i]); - dbgprintf("'\n"); - } + cnfarrayPrint((struct cnfarray*)expr, indent); break; case 'N': doIndent(indent); @@ -1924,7 +1999,6 @@ cnfarrayNew(es_str_t *val) done: return ar; } -/* creates array AND adds first element to it */ struct cnfarray* cnfarrayAdd(struct cnfarray *ar, es_str_t *val) { @@ -1940,6 +2014,19 @@ cnfarrayAdd(struct cnfarray *ar, es_str_t *val) done: return ar; } +/* duplicate an array (deep copy) */ +static struct cnfarray* +cnfarrayDup(struct cnfarray *old) +{ + int i; + struct cnfarray *ar; + ar = cnfarrayNew(es_strdup(old->arr[0])); + for(i = 1 ; i < old->nmemb ; ++i) { + cnfarrayAdd(ar, es_strdup(old->arr[i])); + } + return ar; +} + struct cnfvar* cnfvarNew(char *name) { @@ -2647,8 +2734,16 @@ cnfDoInclude(char *name) void varDelete(struct var *v) { - if(v->datatype == 'S') + switch(v->datatype) { + case 'S': es_deleteStr(v->d.estr); + break; + case 'A': + cnfarrayContentDestruct(v->d.ar); + free(v->d.ar); + break; + default:break; + } } void @@ -2656,7 +2751,9 @@ cnfparamvalsDestruct(struct cnfparamvals *paramvals, struct cnfparamblk *blk) { int i; for(i = 0 ; i < blk->nParams ; ++i) { - varDelete(¶mvals[i].val); + if(paramvals[i].bUsed) { + varDelete(¶mvals[i].val); + } } free(paramvals); } diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h index 974f2160..314f8434 100644 --- a/grammar/rainerscript.h +++ b/grammar/rainerscript.h @@ -74,11 +74,13 @@ enum cnfactType { CNFACT_V2, CNFACT_LEGACY }; struct var { union { es_str_t *estr; - struct cnfexpr *expr; + struct cnfarray *ar; long long n; struct json_object *json; } d; - char datatype; /* 'N' number, 'S' string, 'E' expression, 'J' JSON */ + char datatype; /* 'N' number, 'S' string, 'J' JSON, 'A' array + * Note: 'A' is only supported during config phase + */ }; struct cnfobj { @@ -284,7 +286,9 @@ void readConfFile(FILE *fp, es_str_t **str); struct objlst* objlstNew(struct cnfobj *obj); void objlstDestruct(struct objlst *lst); void objlstPrint(struct objlst *lst); -struct nvlst* nvlstNew(es_str_t *name, es_str_t *value); +struct nvlst* nvlstNewArray(struct cnfarray *ar); +struct nvlst* nvlstNewStr(es_str_t *value); +struct nvlst* nvlstSetName(struct nvlst *lst, es_str_t *name); void nvlstDestruct(struct nvlst *lst); void nvlstPrint(struct nvlst *lst); void nvlstChkUnused(struct nvlst *lst); @@ -323,6 +327,7 @@ struct cnfstmt * cnfstmtNewUnset(char *var); void cnfstmtDestruct(struct cnfstmt *root); void cnfstmtOptimize(struct cnfstmt *root); struct cnfarray* cnfarrayNew(es_str_t *val); +//struct cnfarray* cnfarrayDup(struct cnfarray *old); struct cnfarray* cnfarrayAdd(struct cnfarray *ar, es_str_t *val); char* getFIOPName(unsigned iFIOP); rsRetVal initRainerscript(void); |