summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--ctok.c47
-rw-r--r--ctok.h38
-rw-r--r--ctok_token.c70
-rw-r--r--ctok_token.h69
-rw-r--r--expr.c20
-rw-r--r--obj-types.h5
-rw-r--r--syslogd.c1
8 files changed, 210 insertions, 42 deletions
diff --git a/Makefile.am b/Makefile.am
index d6e50d8f..a0e61210 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -45,6 +45,8 @@ rsyslogd_SOURCES = \
expr.h \
ctok.c \
ctok.h \
+ ctok_token.c \
+ ctok_token.h \
conf.c \
conf.h \
omshell.c \
diff --git a/ctok.c b/ctok.c
index 6557b3fa..eca6daa5 100644
--- a/ctok.c
+++ b/ctok.c
@@ -323,20 +323,57 @@ finalize_it:
}
-/* Get the next token from the input stream. This parses the next token and
+/* Unget a token. The token ungotten will be returned the next time
+ * ctokGetToken() is called. Only one token can be ungotten at a time.
+ * If a second token is ungotten, the first is lost. This is considered
+ * a programming error.
+ * rgerhards, 2008-02-20
+ */
+rsRetVal
+ctokUngetToken(ctok_t *pThis, ctok_token_t *pToken)
+{
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pThis, ctok);
+ ASSERT(pToken != NULL);
+ ASSERT(pThis->pUngotToken == NULL);
+
+ pThis->pUngotToken = pToken;
+
+ RETiRet;
+}
+
+
+/* Get the *next* token from the input stream. This parses the next token and
* ignores any whitespace in between. End of stream is communicated via iRet.
+ * The returned token must either be destructed by the caller OR being passed
+ * back to ctokUngetToken().
* rgerhards, 2008-02-19
*/
rsRetVal
-ctokGetNextToken(ctok_t *pThis, ctok_token_t *pToken)
+ctokGetToken(ctok_t *pThis, ctok_token_t **ppToken)
{
DEFiRet;
+ ctok_token_t *pToken;
uchar c;
uchar szWord[128];
ISOBJ_TYPE_assert(pThis, ctok);
ASSERT(pToken != NULL);
+ /* first check if we have an ungotten token and, if so, provide that
+ * one back (without any parsing). -- rgerhards, 2008-02-20
+ */
+ if(pThis->pUngotToken != NULL) {
+ *ppToken = pThis->pUngotToken;
+ pThis->pUngotToken = NULL;
+ FINALIZE;
+ }
+
+ /* setup the stage - create our token */
+ CHKiRet(ctok_tokenConstruct(&pToken));
+ CHKiRet(ctok_tokenConstructFinalize(pToken));
+
CHKiRet(ctokSkipWhitespaceFromStream(pThis));
CHKiRet(ctokGetCharFromStream(pThis, &c)); /* read a charater */
@@ -429,9 +466,15 @@ ctokGetNextToken(ctok_t *pThis, ctok_token_t *pToken)
break;
}
+ *ppToken = pToken;
RUNLOG_VAR("%d", pToken->tok);
finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pToken != NULL)
+ ctok_tokenDestruct(&pToken);
+ }
+
RETiRet;
}
diff --git a/ctok.h b/ctok.h
index 1cddb68b..26dae5f1 100644
--- a/ctok.h
+++ b/ctok.h
@@ -24,45 +24,14 @@
#include "obj.h"
#include "stringbuf.h"
-
-/* the tokens... I use numbers below so that the tokens can be easier
- * identified in debug output. */
-typedef struct {
- enum {
- ctok_INVALID = 0,
- ctok_OR = 1,
- ctok_AND = 2,
- ctok_PLUS = 3,
- ctok_MINUS = 4,
- ctok_TIMES = 5, /* "*" */
- ctok_DIV = 6,
- ctok_MOD = 7,
- ctok_NOT = 8,
- ctok_RPAREN = 9,
- ctok_LPAREN = 10,
- ctok_COMMA = 11,
- ctok_SYSVAR = 12,
- ctok_MSGVAR = 13,
- ctok_SIMPSTR = 14,
- ctok_TPLSTR = 15,
- ctok_CMP_EQ = 16,
- ctok_CMP_NEQ = 17,
- ctok_CMP_LT = 18,
- ctok_CMP_GT = 19,
- ctok_CMP_LTEQ = 20,
- ctok_CMP_GTEQ = 21,
- ctok_NUMBER = 22,
- ctok_FUNCTION = 23
- } tok;
- rsCStrObj *pstrVal;
- int64 intVal;
-} ctok_token_t;
+#include "ctok_token.h"
/* the ctokession object */
typedef struct ctok_s {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
uchar *pp; /* this points to the next unread character, it is a reminescent of pp in
the config parser code ;) */
+ ctok_token_t *pUngotToken; /* buffer for ctokUngetToken(), NULL if not set */
} ctok_t;
@@ -71,7 +40,8 @@ rsRetVal ctokConstruct(ctok_t **ppThis);
rsRetVal ctokConstructFinalize(ctok_t __attribute__((unused)) *pThis);
rsRetVal ctokDestruct(ctok_t **ppThis);
rsRetVal ctokGetpp(ctok_t *pThis, uchar **pp);
-rsRetVal ctokGetNextToken(ctok_t *pThis, ctok_token_t *pToken);
+rsRetVal ctokGetToken(ctok_t *pThis, ctok_token_t **ppToken);
+rsRetVal ctokUngetToken(ctok_t *pThis, ctok_token_t *pToken);
PROTOTYPEObjClassInit(ctok);
PROTOTYPEpropSetMeth(ctok, pp, uchar*);
diff --git a/ctok_token.c b/ctok_token.c
new file mode 100644
index 00000000..a8bd9d97
--- /dev/null
+++ b/ctok_token.c
@@ -0,0 +1,70 @@
+/* ctok_token - implements the token_t class.
+ *
+ * Module begun 2008-02-20 by Rainer Gerhards
+ *
+ * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include <strings.h>
+#include <assert.h>
+
+#include "rsyslog.h"
+#include "template.h"
+#include "ctok_token.h"
+
+/* static data */
+DEFobjStaticHelpers
+
+
+/* Standard-Constructor
+ */
+BEGINobjConstruct(ctok_token) /* be sure to specify the object type also in END macro! */
+ENDobjConstruct(ctok_token)
+
+
+/* ConstructionFinalizer
+ * rgerhards, 2008-01-09
+ */
+rsRetVal ctok_tokenConstructFinalize(ctok_token_t __attribute__((unused)) *pThis)
+{
+ DEFiRet;
+ RETiRet;
+}
+
+
+/* destructor for the ctok object */
+BEGINobjDestruct(ctok_token) /* be sure to specify the object type also in END and CODESTART macros! */
+CODESTARTobjDestruct(ctok_token)
+ if(pThis->pstrVal != NULL) {
+ rsCStrDestruct(pThis->pstrVal);
+ }
+ENDobjDestruct(ctok_token)
+
+
+
+BEGINObjClassInit(ctok_token, 1) /* class, version */
+ OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, ctok_tokenConstructFinalize);
+ENDObjClassInit(ctok_token)
+
+/* vi:set ai:
+ */
diff --git a/ctok_token.h b/ctok_token.h
new file mode 100644
index 00000000..45aeb017
--- /dev/null
+++ b/ctok_token.h
@@ -0,0 +1,69 @@
+/* The ctok_token object
+ *
+ * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#ifndef INCLUDED_CTOK_TOKEN_H
+#define INCLUDED_CTOK_TOKEN_H
+
+#include "obj.h"
+#include "stringbuf.h"
+
+/* the tokens... I use numbers below so that the tokens can be easier
+ * identified in debug output. */
+typedef struct {
+ BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ enum {
+ ctok_INVALID = 0,
+ ctok_OR = 1,
+ ctok_AND = 2,
+ ctok_PLUS = 3,
+ ctok_MINUS = 4,
+ ctok_TIMES = 5, /* "*" */
+ ctok_DIV = 6,
+ ctok_MOD = 7,
+ ctok_NOT = 8,
+ ctok_RPAREN = 9,
+ ctok_LPAREN = 10,
+ ctok_COMMA = 11,
+ ctok_SYSVAR = 12,
+ ctok_MSGVAR = 13,
+ ctok_SIMPSTR = 14,
+ ctok_TPLSTR = 15,
+ ctok_CMP_EQ = 16,
+ ctok_CMP_NEQ = 17,
+ ctok_CMP_LT = 18,
+ ctok_CMP_GT = 19,
+ ctok_CMP_LTEQ = 20,
+ ctok_CMP_GTEQ = 21,
+ ctok_NUMBER = 22,
+ ctok_FUNCTION = 23
+ } tok;
+ rsCStrObj *pstrVal;
+ int64 intVal;
+} ctok_token_t;
+
+
+/* prototypes */
+rsRetVal ctok_tokenConstruct(ctok_token_t **ppThis);
+rsRetVal ctok_tokenConstructFinalize(ctok_token_t __attribute__((unused)) *pThis);
+rsRetVal ctok_tokenDestruct(ctok_token_t **ppThis);
+PROTOTYPEObjClassInit(ctok_token);
+
+#endif /* #ifndef INCLUDED_CTOK_TOKEN_H */
diff --git a/expr.c b/expr.c
index 5aada596..b059dac7 100644
--- a/expr.c
+++ b/expr.c
@@ -72,15 +72,15 @@ static rsRetVal
terminal(expr_t *pThis, ctok_t *ctok)
{
DEFiRet;
- ctok_token_t token;
+ ctok_token_t *pToken;
RUNLOG_STR("terminal");
ISOBJ_TYPE_assert(pThis, expr);
ISOBJ_TYPE_assert(ctok, ctok);
- CHKiRet(ctokGetNextToken(ctok, &token));
+ CHKiRet(ctokGetToken(ctok, &pToken));
- switch(token.tok) {
+ switch(pToken->tok) {
case ctok_SIMPSTR:
break;
default:
@@ -127,11 +127,23 @@ static rsRetVal
val(expr_t *pThis, ctok_t *ctok)
{
DEFiRet;
+ ctok_token_t *pToken;
RUNLOG_STR("val");
ISOBJ_TYPE_assert(pThis, expr);
ISOBJ_TYPE_assert(ctok, ctok);
+ CHKiRet(ctokGetToken(ctok, &pToken));
+ if(pToken->tok == ctok_PLUS || pToken->tok == ctok_MINUS) {
+ /* TODO: fill structure */
+ dbgprintf("plus/minus\n");
+ CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */
+ CHKiRet(ctokGetToken(ctok, &pToken)); /* get next one */
+ } else {
+ /* we could not process the token, so push it back */
+ CHKiRet(ctokUngetToken(ctok, pToken));
+ }
+
CHKiRet(term(pThis, ctok));
finalize_it:
@@ -207,7 +219,6 @@ rsRetVal exprConstructFinalize(expr_t *pThis)
ISOBJ_TYPE_assert(pThis, expr);
-finalize_it:
RETiRet;
}
@@ -230,6 +241,7 @@ exprEval(expr_t *pThis, msg_t *pMsg)
DEFiRet;
ISOBJ_TYPE_assert(pThis, expr);
+ ISOBJ_TYPE_assert(pMsg, msg);
RETiRet;
}
diff --git a/obj-types.h b/obj-types.h
index f63eb49e..d3722070 100644
--- a/obj-types.h
+++ b/obj-types.h
@@ -63,9 +63,10 @@ typedef enum { /* IDs of known object "types/classes" */
OBJwti = 4,
OBJqueue = 5,
OBJctok = 6,
- OBJexpr = 7 /* remeber to UPDATE OBJ_NUM_IDS (below) if you add one! */
+ OBJctok_token = 7,
+ OBJexpr = 8 /* remeber to UPDATE OBJ_NUM_IDS (below) if you add one! */
} objID_t;
-#define OBJ_NUM_IDS 8
+#define OBJ_NUM_IDS 9
typedef enum { /* IDs of base methods supported by all objects - used for jump table, so
* they must start at zero and be incremented. -- rgerahrds, 2008-01-04
diff --git a/syslogd.c b/syslogd.c
index d3ad9fbd..40581d54 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -3418,6 +3418,7 @@ static rsRetVal InitGlobalClasses(void)
CHKiRet(wtiClassInit());
CHKiRet(wtpClassInit());
CHKiRet(queueClassInit());
+ CHKiRet(ctok_tokenClassInit());
CHKiRet(ctokClassInit());
CHKiRet(exprClassInit());