summaryrefslogtreecommitdiffstats
path: root/grammar
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2011-07-03 13:10:37 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2011-07-03 13:10:37 +0200
commit1cdab4d2b548a0db54b5a2c5404f3f78e012113e (patch)
tree8b827e5bc63e61da3a57e71cc495326d8fbf462e /grammar
parent62e95c10ba84871fd5ad97fccd75664b07620013 (diff)
downloadrsyslog-1cdab4d2b548a0db54b5a2c5404f3f78e012113e.tar.gz
rsyslog-1cdab4d2b548a0db54b5a2c5404f3f78e012113e.tar.xz
rsyslog-1cdab4d2b548a0db54b5a2c5404f3f78e012113e.zip
milestone: support for action list added to grammar
Diffstat (limited to 'grammar')
-rw-r--r--grammar/rscript.l4
-rw-r--r--grammar/rscript.y33
-rw-r--r--grammar/utils.c117
-rw-r--r--grammar/utils.h22
4 files changed, 163 insertions, 13 deletions
diff --git a/grammar/rscript.l b/grammar/rscript.l
index ccc39a2f..750a3e81 100644
--- a/grammar/rscript.l
+++ b/grammar/rscript.l
@@ -105,8 +105,8 @@ static int preCommentState;
<INOBJ>. { printf("INOBJ: invalid char '%s'\n", yytext); }
/* CFSYSLINE is valid in all modes */
-\$[a-z]+.*$ { yylval.s = yytext; return CFSYSLINE; }
-<INOBJ>\$[a-z]+.*$ { yylval.s = yytext; return CFSYSLINE; }
+\$[a-z]+.*$ { yylval.s = strdup(yytext); return CFSYSLINE; }
+<INOBJ>\$[a-z]+.*$ { yylval.s = strdup(yytext); return CFSYSLINE; }
\#.*\n /* skip comments in input */
[\n\t ] /* drop whitespace */
diff --git a/grammar/rscript.y b/grammar/rscript.y
index 5bd8f0f9..15348e4d 100644
--- a/grammar/rscript.y
+++ b/grammar/rscript.y
@@ -12,6 +12,7 @@
enum cnfobjType objType;
struct cnfobj *obj;
struct nvlst *nvlst;
+ struct cnfactlst *actlst;
}
%token <estr> NAME
@@ -26,9 +27,20 @@
%type <nvlst> nv nvlst
%type <obj> obj
-%type <s> actlst
-%type <s> act
+%type <actlst> actlst
+%type <actlst> act
+
+%expect 2
+/* two 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 rscript.y" if more conflicts arise and check rscript.out for
+ * were exactly these conflicts exits.
+ */
%%
conf: /* empty (to end recursion) */
| obj conf
@@ -50,15 +62,20 @@ nvlst: { $$ = NULL; }
| nvlst nv { $2->next = $1; $$ = $2; }
nv: NAME '=' VALUE { $$ = nvlstNew($1, $3); }
-rule: PRIFILT actlst { printf("PRIFILT: %s\n", $1); free($1); }
+rule: PRIFILT actlst { printf("PRIFILT: %s\n", $1); free($1);
+ $2 = cnfactlstReverse($2);
+ cnfactlstPrint($2); }
| PROPFILT actlst
-actlst: act { printf("action (end actlst) %s\n", $1);$$=$1; }
- | actlst '&' act { printf("in actionlist %s\n", $3); }
-act: BEGIN_ACTION nvlst ENDOBJ { $$ = "obj"; }
+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); }
+
+act: BEGIN_ACTION nvlst ENDOBJ { $$ = cnfactlstNew(CNFACT_V2, $2, NULL); }
| LEGACY_ACTION { printf("legacy action: '%s'\n", $1);
- /*free($1);*/
- $$ = $1;}
+ $$ = cnfactlstNew(CNFACT_LEGACY, NULL, $1); }
%%
int yyerror(char *s)
diff --git a/grammar/utils.c b/grammar/utils.c
index a505704f..28e1a04a 100644
--- a/grammar/utils.c
+++ b/grammar/utils.c
@@ -74,7 +74,6 @@ nvlstDestruct(struct nvlst *lst)
}
}
-
void
nvlstPrint(struct nvlst *lst)
{
@@ -119,14 +118,126 @@ cnfobjPrint(struct cnfobj *o)
nvlstPrint(o->nvlst);
}
+
+struct cnfactlst*
+cnfactlstNew(enum cnfactType actType, struct nvlst *lst, char *actLine)
+{
+ struct cnfactlst *actlst;
+
+ if((actlst = malloc(sizeof(struct cnfactlst))) != NULL) {
+ actlst->next = NULL;
+ actlst->syslines = NULL;
+ actlst->actType = actType;
+ if(actType == CNFACT_V2)
+ actlst->data.lst = lst;
+ else
+ actlst->data.legActLine = actLine;
+ }
+ return actlst;
+}
+
+struct cnfactlst*
+cnfactlstAddSysline(struct cnfactlst* actlst, char *line)
+{
+ struct cnfcfsyslinelst *cflst;
+
+ if((cflst = malloc(sizeof(struct cnfcfsyslinelst))) != NULL) {
+ cflst->next = NULL;
+ cflst->line = line;
+ if(actlst->syslines == NULL) {
+ actlst->syslines = cflst;
+ } else {
+ cflst->next = actlst->syslines;
+ actlst->syslines = cflst;
+ }
+ }
+ return actlst;
+}
+
+void
+cnfactlstDestruct(struct cnfactlst *actlst)
+{
+ struct cnfactlst *toDel;
+
+ while(actlst != NULL) {
+ toDel = actlst;
+ actlst = actlst->next;
+ if(toDel->actType == CNFACT_V2)
+ nvlstDestruct(toDel->data.lst);
+ else
+ free(toDel->data.legActLine);
+ free(toDel);
+ }
+
+}
+
+static inline struct cnfcfsyslinelst*
+cnfcfsyslinelstReverse(struct cnfcfsyslinelst *lst)
+{
+ struct cnfcfsyslinelst *curr, *prev;
+
+ if(lst == NULL)
+ return;
+ prev = lst;
+ lst = lst->next;
+ prev->next = NULL;
+ while(lst != NULL) {
+ curr = lst;
+ lst = lst->next;
+ curr->next = prev;
+ prev = curr;
+ }
+ return prev;
+}
+
+struct cnfactlst*
+cnfactlstReverse(struct cnfactlst *actlst)
+{
+ struct cnfactlst *curr, *prev;
+
+ prev = actlst;
+ actlst = actlst->next;
+ prev->next = NULL;
+ while(actlst != NULL) {
+ curr = actlst;
+ actlst = actlst->next;
+ curr->syslines = cnfcfsyslinelstReverse(curr->syslines);
+ curr->next = prev;
+ prev = curr;
+ }
+ return prev;
+}
+
+void
+cnfactlstPrint(struct cnfactlst *actlst)
+{
+ struct cnfcfsyslinelst *cflst;
+
+ printf("---------- cnfactlst %p:\n", actlst);
+ while(actlst != NULL) {
+ if(actlst->actType == CNFACT_V2) {
+ printf("V2 action type: ");
+ nvlstPrint(actlst->data.lst);
+ } else {
+ printf("legacy action line: '%s'\n",
+ actlst->data.legActLine);
+ }
+ for( cflst = actlst->syslines
+ ; cflst != NULL ; cflst = cflst->next) {
+ printf("cfsysline: '%s'\n", cflst->line);
+ }
+ actlst = actlst->next;
+ }
+ printf("----------\n");
+}
+
/* debug helper */
void
cstrPrint(char *text, es_str_t *estr)
{
char *str;
- printf("in cstrPrint, estr %p\n", estr);
str = es_str2cstr(estr, NULL);
- printf("2: in cstrPrint, estr %p\n", estr);
printf("%s%s", text, str);
free(str);
}
+
diff --git a/grammar/utils.h b/grammar/utils.h
index 66b05647..2a6ba10a 100644
--- a/grammar/utils.h
+++ b/grammar/utils.h
@@ -30,6 +30,8 @@ cnfobjType2str(enum cnfobjType ot)
}
}
+enum cnfactType { CNFACT_V2, CNFACT_LEGACY };
+
struct cnfobj {
enum cnfobjType objType;
struct nvlst *nvlst;
@@ -41,6 +43,21 @@ struct nvlst {
es_str_t *value;
};
+struct cnfcfsyslinelst {
+ struct cnfcfsyslinelst *next;
+ char *line;
+};
+
+struct cnfactlst {
+ struct cnfactlst *next;
+ struct cnfcfsyslinelst *syslines;
+ enum cnfactType actType;
+ union {
+ struct nvlst *lst;
+ char *legActLine;
+ } data;
+};
+
void readConfFile(FILE *fp, es_str_t **str);
struct nvlst* nvlstNew(es_str_t *name, es_str_t *value);
@@ -49,6 +66,11 @@ void nvlstPrint(struct nvlst *lst);
struct cnfobj* cnfobjNew(enum cnfobjType objType, struct nvlst *lst);
void cnfobjDestruct(struct cnfobj *o);
void cnfobjPrint(struct cnfobj *o);
+struct cnfactlst* cnfactlstNew(enum cnfactType actType, struct nvlst *lst, char *actLine);
+void cnfactlstDestruct(struct cnfactlst *actlst);
+void cnfactlstPrint(struct cnfactlst *actlst);
+struct cnfactlst* cnfactlstAddSysline(struct cnfactlst* actlst, char *line);
+struct cnfactlst* cnfactlstReverse(struct cnfactlst *actlst);
/* debug helper */
void cstrPrint(char *text, es_str_t *estr);