summaryrefslogtreecommitdiffstats
path: root/grammar
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2011-07-04 15:31:09 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2011-07-04 15:31:09 +0200
commitbffa39ab9539c0e26dbbfb450f42de93638292e1 (patch)
treea410a02bcd931fc5668fa1b4ab6595c561ee7c08 /grammar
parent11f50cfe836ec104b4167e7c6c5d207a4d8fe081 (diff)
downloadrsyslog-bffa39ab9539c0e26dbbfb450f42de93638292e1.tar.gz
rsyslog-bffa39ab9539c0e26dbbfb450f42de93638292e1.tar.xz
rsyslog-bffa39ab9539c0e26dbbfb450f42de93638292e1.zip
milstone: top-level grammer now ready for integration (but script detail still missing)
Diffstat (limited to 'grammar')
-rw-r--r--grammar/debian.conf10
-rw-r--r--grammar/rscript.l13
-rw-r--r--grammar/rscript.y73
-rw-r--r--grammar/utils.c42
-rw-r--r--grammar/utils.h30
5 files changed, 118 insertions, 50 deletions
diff --git a/grammar/debian.conf b/grammar/debian.conf
index 166cde52..ff7708c5 100644
--- a/grammar/debian.conf
+++ b/grammar/debian.conf
@@ -118,5 +118,15 @@ daemon.*;mail.*;\
news.err;\
*.=debug;*.=info;\
*.=notice;*.=warn |/dev/xconsole
+$cfs 21
+$cfs 22
+$cfs 23
# samples added to get full "flavor" of what we need to support...
:msg, contains, "error" /var/log/somelog
+$cfs 11
+$cfs 12
+$cfs 13
+module()
+$cfs 1
+$cfs 2
+$cfs 3
diff --git a/grammar/rscript.l b/grammar/rscript.l
index 6472ca13..68f4d406 100644
--- a/grammar/rscript.l
+++ b/grammar/rscript.l
@@ -94,8 +94,7 @@ char *currfn; /* name of currently processed file */
* to tell us the real source line.
*/
"preprocfilelinenumber(" { BEGIN LINENO; }
-<LINENO>[0-9]+ { printf("linno was %d, set to %d\n", yylineno, atoi(yytext) -1);
- yylineno = atoi(yytext) - 1; }
+<LINENO>[0-9]+ { yylineno = atoi(yytext) - 1; }
<LINENO>")" { BEGIN INITIAL; }
<LINENO>.|\n
/* $IncludeConfig must be detected as part of CFSYSLINE, because this is
@@ -116,18 +115,18 @@ char *currfn; /* name of currently processed file */
BEGIN INOBJ; return BEGINOBJ; }
"action"[ \n\t]*"(" { BEGIN INOBJ; return BEGIN_ACTION; }
^[ \t]*:\$?[a-z]+[ ]*,[ ]*!?[a-z]+[ ]*,[ ]*\".*\" {
- printf("PROP-FILT: '%s'\n", yytext);
- return PROPFILT;
- }
+ yylval.s = strdup(yytext); return PROPFILT; }
-^[ \t]*[,\*a-z]+\.[,!=;\.\*a-z]+ { printf("token prifilt '%s'\n", yytext); yylval.s = strdup(yytext); return PRIFILT; }
+^[ \t]*[,\*a-z]+\.[,!=;\.\*a-z]+ { yylval.s = strdup(yytext); return PRIFILT; }
"*" |
\-\/[^*][^\n]* |
\/[^*][^\n]* |
:[a-z0-9]+:[^\n]* |
[\|\.\-\@~][^\n]+ |
-[a-z0-9_][a-z0-9_\-\+]* { yylval.s = strdup(yytext); printf("LEGA ACT: '%s'\n", yytext);return LEGACY_ACTION; }
+[a-z0-9_][a-z0-9_\-\+]* { yylval.s = strdup(yytext);
+ // printf("lex: LEGA ACT: '%s'\n", yytext);
+ return LEGACY_ACTION; }
<INOBJ>")" { BEGIN INITIAL; return ENDOBJ; }
<INOBJ>[a-z][a-z0-9_\.]* { yylval.estr = es_newStrFromCStr(yytext, yyleng);
return NAME; }
diff --git a/grammar/rscript.y b/grammar/rscript.y
index 8dc00620..aaf133eb 100644
--- a/grammar/rscript.y
+++ b/grammar/rscript.y
@@ -16,6 +16,7 @@ extern int yylineno;
struct nvlst *nvlst;
struct cnfactlst *actlst;
struct cnfexpr *expr;
+ struct cnfrule *rule;
}
%token <estr> NAME
@@ -55,6 +56,8 @@ extern int yylineno;
%type <s> cfsysline
%type <actlst> block
%type <expr> expr
+%type <rule> rule
+%type <rule> scriptfilt
%left AND OR
%left CMP_EQ CMP_NE CMP_LE CMP_GE CMP_LT CMP_GT CMP_CONTAINS CMP_CONTAINSI CMP_STARTSWITH CMP_STARTSWITHI
@@ -73,60 +76,54 @@ extern int yylineno;
* were exactly these conflicts exits.
*/
%%
+/* note: we use left recursion below, because that saves stack space AND
+ * offers the right sequence so that we can submit the top-layer objects
+ * one by one.
+ */
conf: /* empty (to end recursion) */
- | obj conf
- | rule conf { printf("RULE processed, back in main\n"); }
- | cfsysline conf { printf("cfsysline: %s\n", $1); }
- | BSD_TAG_SELECTOR conf { printf("BSD tag '%s'\n", $1); }
- | BSD_HOST_SELECTOR conf { printf("BSD host '%s'\n", $1); }
-
-obj: BEGINOBJ nvlst ENDOBJ { $$ = cnfobjNew($1, $2);
- cnfobjPrint($$);
- cnfobjDestruct($$);
- }
- | BEGIN_ACTION nvlst ENDOBJ { struct cnfobj *t = cnfobjNew(CNFOBJ_ACTION, $2);
- cnfobjPrint(t);
- cnfobjDestruct(t);
- printf("XXXX: this is an new-style action!\n");
- }
-cfsysline: CFSYSLINE { printf("XXXX: processing CFSYSLINE: %s\n", $1);$$ = $1 }
+ | conf obj { printf("global:config: ");
+ cnfobjPrint($2); cnfobjDestruct($2); }
+ | conf rule { printf("global:rule processed\n");
+ cnfrulePrint($2); }
+ | conf cfsysline { printf("global:cfsysline: %s\n", $2); }
+ | conf BSD_TAG_SELECTOR { printf("global:BSD tag '%s'\n", $2); }
+ | conf BSD_HOST_SELECTOR { printf("global:BSD host '%s'\n", $2); }
+
+obj: BEGINOBJ nvlst ENDOBJ { $$ = cnfobjNew($1, $2); }
+ | BEGIN_ACTION nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_ACTION, $2); }
+cfsysline: CFSYSLINE { $$ = $1 }
nvlst: { $$ = NULL; }
| nvlst nv { $2->next = $1; $$ = $2; }
nv: NAME '=' VALUE { $$ = nvlstNew($1, $3); }
-rule: PRIFILT actlst { printf("PRIFILT: %s\n", $1); free($1);
- $2 = cnfactlstReverse($2);
- cnfactlstPrint($2); }
- | PROPFILT actlst { printf("PROPFILT: %s\n", $1); free($1);
- $2 = cnfactlstReverse($2);
- cnfactlstPrint($2); }
- | scriptfilt
-
-scriptfilt: IF expr THEN actlst { printf("if filter detected, expr:\n"); cnfexprPrint($2,0);
- struct exprret r;
- cnfexprEval($2, &r);
- printf("eval result: %lld\n", r.d.n);
+rule: PRIFILT actlst { $$ = cnfruleNew(CNFFILT_PRI, $2); $$->filt.s = $1; }
+ | PROPFILT actlst { $$ = cnfruleNew(CNFFILT_PROP, $2); $$->filt.s = $1; }
+ | scriptfilt { $$ = $1; }
+
+scriptfilt: IF expr THEN actlst { $$ = cnfruleNew(CNFFILT_SCRIPT, $4);
+ $$->filt.expr = $2;
+ //struct exprret r;
+ //cnfexprEval($2, &r);
+ // printf("eval result: %lld\n", r.d.n);
}
/* note: we can do some limited block-structuring with the v6 engine. In that case,
* we must not support additonal filters inside the blocks, so they must consist of
* "act", only. We can implement that via the "&" actlist logic.
*/
-block: actlst
- | block actlst
+block: actlst { $$ = $1; }
+ | block actlst { $2->next = $1; $$ = $2; }
/* v7: | actlst
v7: | block rule */
-actlst: act { printf("action (end actlst)\n");$$=$1; }
- | actlst '&' act { printf("in actionlist \n");
- $3->next = $1; $$ = $3; }
- | actlst cfsysline { printf("in actionlist/CFSYSLINE: %s\n", $2);
- $$ = cnfactlstAddSysline($1, $2); }
+actlst: act { $$=$1; }
+ | actlst '&' act { $3->next = $1; $$ = $3; }
+ | actlst cfsysline { $$ = cnfactlstAddSysline($1, $2); }
| '{' block '}' { $$ = $2; }
act: BEGIN_ACTION nvlst ENDOBJ { $$ = cnfactlstNew(CNFACT_V2, $2, NULL); }
- | LEGACY_ACTION { printf("legacy action: '%s'\n", $1);
+ | LEGACY_ACTION { //printf("legacy action: '%s'\n", $1);
$$ = cnfactlstNew(CNFACT_LEGACY, NULL, $1); }
expr: expr AND expr { $$ = cnfexprNew(AND, $1, $3); }
@@ -147,8 +144,8 @@ expr: expr AND expr { $$ = cnfexprNew(AND, $1, $3); }
| expr '*' expr { $$ = cnfexprNew('*', $1, $3); }
| expr '/' expr { $$ = cnfexprNew('/', $1, $3); }
| expr '%' expr { $$ = cnfexprNew('%', $1, $3); }
- | '(' expr ')' { $$ = $2; printf("( expr)\n"); }
- | '-' expr %prec UMINUS { printf("uminus\n"); $$ = cnfexprNew('M', NULL, $2); }
+ | '(' expr ')' { $$ = $2; }
+ | '-' expr %prec UMINUS { $$ = cnfexprNew('M', NULL, $2); }
| NUMBER { $$ = (struct cnfexpr*) cnfnumvalNew($1); }
| STRING { $$ = (struct cnfexpr*) cnfstringvalNew($1); }
| VAR { printf("variables not yet implemented!\n"); }
diff --git a/grammar/utils.c b/grammar/utils.c
index f25977d5..b04274c1 100644
--- a/grammar/utils.c
+++ b/grammar/utils.c
@@ -187,7 +187,6 @@ static inline struct cnfcfsyslinelst*
cnfcfsyslinelstReverse(struct cnfcfsyslinelst *lst)
{
struct cnfcfsyslinelst *curr, *prev;
-printf("syslinerevers on %p\n", lst);
if(lst == NULL)
return NULL;
prev = NULL;
@@ -207,6 +206,7 @@ cnfactlstReverse(struct cnfactlst *actlst)
prev = NULL;
while(actlst != NULL) {
+ //printf("reversing: %s\n", actlst->data.legActLine);
curr = actlst;
actlst = actlst->next;
curr->syslines = cnfcfsyslinelstReverse(curr->syslines);
@@ -221,8 +221,8 @@ cnfactlstPrint(struct cnfactlst *actlst)
{
struct cnfcfsyslinelst *cflst;
- printf("---------- cnfactlst %p:\n", actlst);
while(actlst != NULL) {
+ printf("aclst %p: ", actlst);
if(actlst->actType == CNFACT_V2) {
printf("V2 action type: ");
nvlstPrint(actlst->data.lst);
@@ -232,11 +232,10 @@ cnfactlstPrint(struct cnfactlst *actlst)
}
for( cflst = actlst->syslines
; cflst != NULL ; cflst = cflst->next) {
- printf("cfsysline: '%s'\n", cflst->line);
+ printf("action:cfsysline: '%s'\n", cflst->line);
}
actlst = actlst->next;
}
- printf("----------\n");
}
struct cnfexpr*
@@ -305,7 +304,7 @@ cnfexprEval(struct cnfexpr *expr, struct exprret *ret)
{
struct exprret r, l; /* memory for subexpression results */
- printf("eval expr %p, type '%c'(%u)\n", expr, expr->nodetype, expr->nodetype);
+ //printf("eval expr %p, type '%c'(%u)\n", expr, expr->nodetype, expr->nodetype);
switch(expr->nodetype) {
case CMP_EQ:
COMP_NUM_BINOP(==);
@@ -523,6 +522,39 @@ cnfstringvalNew(es_str_t *estr)
return strval;
}
+struct cnfrule *
+cnfruleNew(enum cnfFiltType filttype, struct cnfactlst *actlst)
+{
+ struct cnfrule* cnfrule;
+ if((cnfrule = malloc(sizeof(struct cnfrule))) != NULL) {
+ cnfrule->nodetype = 'R';
+ cnfrule->filttype = filttype;
+ cnfrule->actlst = cnfactlstReverse(actlst);
+ }
+ return cnfrule;
+}
+
+void
+cnfrulePrint(struct cnfrule *rule)
+{
+ printf("------ start rule %p:\n", rule);
+ printf("%s: ", cnfFiltType2str(rule->filttype));
+ switch(rule->filttype) {
+ case CNFFILT_NONE:
+ break;
+ case CNFFILT_PRI:
+ case CNFFILT_PROP:
+ printf("%s\n", rule->filt.s);
+ break;
+ case CNFFILT_SCRIPT:
+ printf("\n");
+ cnfexprPrint(rule->filt.expr, 0);
+ break;
+ }
+ cnfactlstPrint(rule->actlst);
+ printf("------ end rule %p\n", rule);
+}
+
/* debug helper */
void
cstrPrint(char *text, es_str_t *estr)
diff --git a/grammar/utils.h b/grammar/utils.h
index f52bc1e0..9dfac5b1 100644
--- a/grammar/utils.h
+++ b/grammar/utils.h
@@ -61,6 +61,34 @@ struct cnfactlst {
/* the following structures support expressions, and may (very much later
* be the sole foundation for the AST.
*/
+enum cnfFiltType { CNFFILT_NONE, CNFFILT_PRI, CNFFILT_PROP, CNFFILT_SCRIPT };
+static inline char*
+cnfFiltType2str(enum cnfFiltType filttype)
+{
+ switch(filttype) {
+ case CNFFILT_NONE:
+ return("filter:none");
+ case CNFFILT_PRI:
+ return("filter:pri");
+ case CNFFILT_PROP:
+ return("filter:prop");
+ case CNFFILT_SCRIPT:
+ return("filter:script");
+ }
+ return("error:invalid_filter_type"); /* should never be reached */
+}
+
+
+struct cnfrule {
+ unsigned nodetype;
+ enum cnfFiltType filttype;
+ union {
+ char *s;
+ struct cnfexpr *expr;
+ } filt;
+ struct cnfactlst *actlst;
+};
+
struct cnfexpr {
unsigned nodetype;
struct cnfexpr *l;
@@ -110,6 +138,8 @@ void cnfexprPrint(struct cnfexpr *expr, int indent);
void cnfexprEval(struct cnfexpr *expr, struct exprret *ret);
struct cnfnumval* cnfnumvalNew(long long val);
struct cnfstringval* cnfstringvalNew(es_str_t *estr);
+struct cnfrule * cnfruleNew(enum cnfFiltType filttype, struct cnfactlst *actlst);
+void cnfrulePrint(struct cnfrule *rule);
/* debug helper */
void cstrPrint(char *text, es_str_t *estr);