diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | ctok.c | 47 | ||||
-rw-r--r-- | ctok.h | 38 | ||||
-rw-r--r-- | ctok_token.c | 70 | ||||
-rw-r--r-- | ctok_token.h | 69 | ||||
-rw-r--r-- | expr.c | 20 | ||||
-rw-r--r-- | obj-types.h | 5 | ||||
-rw-r--r-- | syslogd.c | 1 |
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 \ @@ -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; } @@ -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 */ @@ -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 @@ -3418,6 +3418,7 @@ static rsRetVal InitGlobalClasses(void) CHKiRet(wtiClassInit()); CHKiRet(wtpClassInit()); CHKiRet(queueClassInit()); + CHKiRet(ctok_tokenClassInit()); CHKiRet(ctokClassInit()); CHKiRet(exprClassInit()); |