summaryrefslogtreecommitdiffstats
path: root/grammar
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-10-01 10:29:38 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-10-01 10:29:38 +0200
commitc0ccd3ff253401ce2081a5d2042f50af35b07233 (patch)
tree0c828480a8d8b2fa507edc83e7727d913ee426a1 /grammar
parentcdbeb9d75a9a79c1f5941f748af540ab13425cf1 (diff)
downloadrsyslog-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.y9
-rw-r--r--grammar/rainerscript.c147
-rw-r--r--grammar/rainerscript.h11
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(&paramvals[i].val);
+ if(paramvals[i].bUsed) {
+ varDelete(&paramvals[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);