summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-09-04 10:50:07 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-09-04 10:50:07 +0200
commit0bf6991bf6c155ff43c394c284e23dfe6b0fc53f (patch)
treeb1132d38b757ebf146864872a0223f926b61a3f0
parent07527fbd38dbed4ed1708fe558ad34b1ebf9e48c (diff)
downloadrsyslog-0bf6991bf6c155ff43c394c284e23dfe6b0fc53f.tar.gz
rsyslog-0bf6991bf6c155ff43c394c284e23dfe6b0fc53f.tar.bz2
rsyslog-0bf6991bf6c155ff43c394c284e23dfe6b0fc53f.zip
new ruleengine: first code for stmt handling
-rw-r--r--grammar/grammar.y54
-rw-r--r--grammar/lexer.l1
-rw-r--r--grammar/rainerscript.c54
-rw-r--r--grammar/rainerscript.h22
4 files changed, 110 insertions, 21 deletions
diff --git a/grammar/grammar.y b/grammar/grammar.y
index ac0be30b..9051028a 100644
--- a/grammar/grammar.y
+++ b/grammar/grammar.y
@@ -9,7 +9,7 @@
* cases. So while we hope that cfsysline support can be dropped some time in
* the future, we will probably keep these useful constructs.
*
- * Copyright 2011 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2011-2012 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@@ -48,6 +48,7 @@ extern int yyerror(char*);
es_str_t *estr;
enum cnfobjType objType;
struct cnfobj *obj;
+ struct cnfstmt *stmt;
struct nvlst *nvlst;
struct objlst *objlst;
struct cnfactlst *actlst;
@@ -75,6 +76,7 @@ extern int yyerror(char*);
%token <s> BSD_HOST_SELECTOR
%token IF
%token THEN
+%token ELSE
%token OR
%token AND
%token NOT
@@ -100,6 +102,7 @@ extern int yyerror(char*);
%type <actlst> block
*/
%type <expr> expr
+%type <stmt> stmt block script
/*
%type <rule> rule
%type <rule> scriptfilt
@@ -112,15 +115,9 @@ extern int yyerror(char*);
%left '*' '/' '%'
%nonassoc UMINUS NOT
-/*%expect 3*/
-/* these shift/reduce conflicts are created by the CFSYSLINE construct, which we
- * unfortunately can not avoid. The problem is that CFSYSLINE can occur both in
- * global context as well as within an action. It's not permitted somewhere else,
- * but this is suficient for conflicts. The "dangling else" built-in resolution
- * works well to solve this issue, so we accept it (it's a wonder that our
- * old style grammar doesn't work at all, so we better do not complain...).
- * Use "bison -v grammar.y" if more conflicts arise and check grammar.output for
- * were exactly these conflicts exits.
+%expect 1 /* dangling else */
+/* If more erors show up, Use "bison -v grammar.y" if more conflicts arise and
+ * check grammar.output for were exactly these conflicts exits.
*/
%%
/* note: we use left recursion below, because that saves stack space AND
@@ -129,7 +126,8 @@ extern int yyerror(char*);
*/
conf: /* empty (to end recursion) */
| conf obj { cnfDoObj($2); }
- | conf stmt { dbgprintf("RRRR: top-level stmt"); }
+ | conf stmt { dbgprintf("RRRR: top-level stmt:\n");
+ cnfstmtPrint($2, 0); }
| conf BSD_TAG_SELECTOR { cnfDoBSDTag($2); }
| conf BSD_HOST_SELECTOR { cnfDoBSDHost($2); }
obj: BEGINOBJ nvlst ENDOBJ { $$ = cnfobjNew($1, $2); }
@@ -146,15 +144,31 @@ constant: BEGIN_CONSTANT nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_CONSTANT, $2); }
nvlst: { $$ = NULL; }
| nvlst nv { $2->next = $1; $$ = $2; }
nv: NAME '=' VALUE { $$ = nvlstNew($1, $3); }
-script: stmt { dbgprintf("RRRR: root stmt\n"); }
- | script stmt { dbgprintf("RRRR: stmt in list\n"); }
-stmt: s_act { dbgprintf("RRRR: have s_act\n"); }
- | STOP { dbgprintf("RRRR: have STOP\n"); }
- | IF expr THEN block { dbgprintf("RRRR: have s_if \n"); }
- | PRIFILT block { dbgprintf("RRRR: have s_prifilt\n"); }
- | PROPFILT block { dbgprintf("RRRR: have s_propfilt\n"); }
-block: stmt { dbgprintf("RRRR: have block:stmt\n"); }
- | '{' script '}' { dbgprintf("RRRR: have block:script\n"); }
+script: stmt { $$ = $1; dbgprintf("RRRR: root stmt\n"); }
+ | script stmt { $2->next = $1; $$ = $2; dbgprintf("RRRR: stmt in list\n"); }
+stmt: s_act { $$ = cnfstmtNew(S_ACT); dbgprintf("RRRR: have s_act\n"); }
+ | STOP { $$ = cnfstmtNew(S_STOP);
+ dbgprintf("RRRR: have STOP\n"); }
+ | IF expr THEN block { $$ = cnfstmtNew(S_IF);
+ $$->d.cond.expr = $2;
+ $$->d.cond.t_then = $4;
+ $$->d.cond.t_else = NULL;
+ dbgprintf("RRRR: have s_if \n"); }
+ | IF expr THEN block ELSE block { $$ = cnfstmtNew(S_IF);
+ $$->d.cond.expr = $2;
+ $$->d.cond.t_then = $4;
+ $$->d.cond.t_else = $6;
+ dbgprintf("RRRR: have s_if \n"); }
+ | PRIFILT block { $$ = cnfstmtNew(S_PRIFILT);
+ $$->d.cond.expr = $1;
+ $$->d.cond.t_then = $2;
+ dbgprintf("RRRR: have s_prifilt\n"); }
+ | PROPFILT block { $$ = cnfstmtNew(S_PROPFILT);
+ $$->d.cond.expr = $1;
+ $$->d.cond.t_then = $2;
+ dbgprintf("RRRR: have s_propfilt\n"); }
+block: stmt { $$ = $1; dbgprintf("RRRR: have block:stmt\n"); }
+ | '{' script '}' { $$ = $2; dbgprintf("RRRR: have block:script\n"); }
/*
rule: PRIFILT actlst { $$ = cnfruleNew(CNFFILT_PRI, $2); $$->filt.s = $1; }
| PROPFILT actlst { $$ = cnfruleNew(CNFFILT_PROP, $2); $$->filt.s = $1; }
diff --git a/grammar/lexer.l b/grammar/lexer.l
index 8e74bde7..d603c449 100644
--- a/grammar/lexer.l
+++ b/grammar/lexer.l
@@ -138,6 +138,7 @@ int fileno(FILE *stream);
* to tell us the real source line.
*/
"stop" { dbgprintf("STOP\n"); return STOP; }
+"else" { dbgprintf("STOP\n"); return ELSE; }
"preprocfilelinenumber(" { BEGIN LINENO; }
<LINENO>[0-9]+ { yylineno = atoi(yytext) - 1; }
<LINENO>")" { BEGIN INITIAL; }
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index 33630a76..0d236c1e 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -107,7 +107,6 @@ objlstNew(struct cnfobj *o)
lst->next = NULL;
lst->obj = o;
}
-dbgprintf("AAAA: creating new objlst\n");
cnfobjPrint(o);
return lst;
@@ -1497,6 +1496,48 @@ cnfexprPrint(struct cnfexpr *expr, int indent)
break;
}
}
+void
+cnfstmtPrint(struct cnfstmt *stmt, int indent)
+{
+ //dbgprintf("stmt %p, indent %d, type '%c'\n", expr, indent, expr->nodetype);
+ switch(stmt->nodetype) {
+ case S_STOP:
+ doIndent(indent); dbgprintf("STOP\n");
+ break;
+ case S_ACT:
+ doIndent(indent); dbgprintf("ACTION %p\n", stmt->d.act);
+ break;
+ case S_IF:
+ doIndent(indent); dbgprintf("IF\n");
+ cnfexprPrint(stmt->d.cond.expr, indent+1);
+ doIndent(indent); dbgprintf("THEN\n");
+ cnfstmtPrint(stmt->d.cond.t_then, indent+1);
+ if(stmt->d.cond.t_else != NULL) {
+ doIndent(indent); dbgprintf("ELSE\n");
+ cnfstmtPrint(stmt->d.cond.t_else, indent+1);
+ }
+ doIndent(indent); dbgprintf("END IF\n");
+ break;
+ case S_PRIFILT:
+ doIndent(indent); dbgprintf("PRIFILT\n");
+ cnfexprPrint(stmt->d.cond.expr, indent+1);
+ doIndent(indent); dbgprintf("THEN\n");
+ cnfstmtPrint(stmt->d.cond.t_then, indent+1);
+ doIndent(indent); dbgprintf("END PRIFILT\n");
+ break;
+ case S_PROPFILT:
+ doIndent(indent); dbgprintf("PROPFILT\n");
+ cnfexprPrint(stmt->d.cond.expr, indent+1);
+ doIndent(indent); dbgprintf("THEN\n");
+ cnfstmtPrint(stmt->d.cond.t_then, indent+1);
+ doIndent(indent); dbgprintf("END PROPFILT\n");
+ break;
+ default:
+ dbgprintf("error: unknown stmt type %u\n",
+ (unsigned) stmt->nodetype);
+ break;
+ }
+}
struct cnfnumval*
cnfnumvalNew(long long val)
@@ -1531,6 +1572,17 @@ cnfvarNew(char *name)
return var;
}
+struct cnfstmt *
+cnfstmtNew(unsigned s_type)
+{
+ struct cnfstmt* cnfstmt;
+ if((cnfstmt = malloc(sizeof(struct cnfstmt))) != NULL) {
+ cnfstmt->nodetype = s_type;
+ cnfstmt->next = NULL;
+ }
+ return cnfstmt;
+}
+
struct cnfrule *
cnfruleNew(enum cnfFiltType filttype, struct cnfactlst *actlst)
{
diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h
index 4c625cd8..3238b7fe 100644
--- a/grammar/rainerscript.h
+++ b/grammar/rainerscript.h
@@ -118,7 +118,14 @@ struct cnfactlst {
* R - rule
* S - string
* V - var
+ * ... plus the S_* #define's below:
*/
+#define S_STOP 4000
+#define S_PRIFILT 4001
+#define S_PROPFILT 4002
+#define S_IF 4003
+#define S_ACT 4004
+
enum cnfFiltType { CNFFILT_NONE, CNFFILT_PRI, CNFFILT_PROP, CNFFILT_SCRIPT };
static inline char*
cnfFiltType2str(enum cnfFiltType filttype)
@@ -147,6 +154,19 @@ struct cnfrule {
struct cnfactlst *actlst;
};
+struct cnfstmt { /* base statement, for simple types */
+ unsigned nodetype;
+ struct cnfstmt *next;
+ union {
+ struct {
+ struct cnfexpr *expr;
+ struct cnfstmt *t_then;
+ struct cnfstmt *t_else;
+ } cond;
+ struct action_s *act;
+ } d;
+};
+
struct cnfexpr {
unsigned nodetype;
struct cnfexpr *l;
@@ -273,6 +293,8 @@ void cnfparamsPrint(struct cnfparamblk *params, struct cnfparamvals *vals);
void varDelete(struct var *v);
void cnfparamvalsDestruct(struct cnfparamvals *paramvals, struct cnfparamblk *blk);
void cnfcfsyslinelstDestruct(struct cnfcfsyslinelst *cfslst);
+struct cnfstmt * cnfstmtNew(unsigned s_type);
+void cnfstmtPrint(struct cnfstmt *stmt, int indent);
rsRetVal initRainerscript(void);
/* debug helper */