summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/expression.html2
-rw-r--r--expr.c20
-rw-r--r--obj-types.h20
-rw-r--r--obj.c2
-rw-r--r--obj.h1
-rw-r--r--vmop.c8
-rw-r--r--vmop.h1
-rw-r--r--vmprg.c43
-rw-r--r--vmprg.h4
9 files changed, 89 insertions, 12 deletions
diff --git a/doc/expression.html b/doc/expression.html
index 58401a1b..2b601e86 100644
--- a/doc/expression.html
+++ b/doc/expression.html
@@ -11,7 +11,7 @@ far, they are supported for filtering messages.</p><p>C-like comments (/* some c
<h2>Formal Definition</h2>
<p>Below is the formal definition of expression format (in ABNF, RFC 2234):<br>
-</p><pre>if_stmt := "if" expr "then" # an aid, not part of expression itself<br><br>expr := e_and *("or" e_and)<br>e_and := e_cmp *("and" e_cmp)<br>e_cmp := val 0*1(cmp_op val)<br>val := ["+" / "-"] term *(("+" / "-") term)<br>term := factor *(("*" / "/" / "%") factor)<br>factor := ["not"] terminal<br>terminal := var / constant / function / "(" expr ")"<br>function := name "(" *("," expr) ")"<br>var := "$" varname<br>varname := msgvar / sysvar<br>msgvar := name<br>sysvar := "$" name<br>name := alpha *(alnum)<br>constant := string / number<br>string := simpstr / tplstr ; tplstr will be implemented in next phase<br>simpstr := "'" *char "'" ; use your imagination for char ;)<br>tplstr := '"' template '"' ; not initially implemented<br>number := 1*digit ; 0nn = octal, 0xnn = hex, nn = decimal<br>cmp_op := "==" / "!=" / "&lt;&gt;" / "&lt;" / "&gt;" / "&lt;=" / "&gt;=" / "contains" / "startswith"<br>digit := %x30-39<br>alpha := "a" ... "z" # all letters<br>alnum :* alpha / digit / "_"<br></pre>
+</p><pre>if_stmt := "if" expr "then" # an aid, not part of expression itself<br><br>expr := e_and *("or" e_and)<br>e_and := e_cmp *("and" e_cmp)<br>e_cmp := val 0*1(cmp_op val)<br>val := term *(("+" / "-") term)<br>term := factor *(("*" / "/" / "%") factor)<br>factor := ["not"] terminal<br>terminal := var / constant / function / "(" expr ")"<br>function := name "(" *("," expr) ")"<br>var := "$" varname<br>varname := msgvar / sysvar<br>msgvar := name<br>sysvar := "$" name<br>name := alpha *(alnum)<br>constant := string / number<br>string := simpstr / tplstr ; tplstr will be implemented in next phase<br>simpstr := "'" *char "'" ; use your imagination for char ;)<br>tplstr := '"' template '"' ; not initially implemented<br>number := ["-"] 1*digit ; 0nn = octal, 0xnn = hex, nn = decimal<br>cmp_op := "==" / "!=" / "&lt;&gt;" / "&lt;" / "&gt;" / "&lt;=" / "&gt;=" / "contains" / "startswith"<br>digit := %x30-39<br>alpha := "a" ... "z" # all letters<br>alnum :* alpha / digit / "_"<br></pre>
<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
[<a href="manual.html">manual index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p>
<p><font size="2">This documentation is part of the
diff --git a/expr.c b/expr.c
index cdf123e2..e9df1a3f 100644
--- a/expr.c
+++ b/expr.c
@@ -163,6 +163,7 @@ val(expr_t *pThis, ctok_t *ctok)
/* TODO: this must be a loop! */
dbgprintf("plus/minus\n");
CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */
+ // vm: +/-???
CHKiRet(ctokGetToken(ctok, &pToken)); /* get next one */
} else {
/* we could not process the token, so push it back */
@@ -170,7 +171,6 @@ val(expr_t *pThis, ctok_t *ctok)
}
CHKiRet(term(pThis, ctok));
- // vm: +/-
finalize_it:
RETiRet;
@@ -192,10 +192,9 @@ e_cmp(expr_t *pThis, ctok_t *ctok)
CHKiRet(ctokGetToken(ctok, &pToken));
if(ctok_tokenIsCmpOp(pToken)) {
dbgoprint((obj_t*) pThis, "cmp\n");
- /* fill structure */
- CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */
CHKiRet(val(pThis, ctok));
- // vm: cmpop
+ CHKiRet(vmprgAddVarOperation(pThis->pVmprg, (opcode_t) pToken->tok, NULL)); /* add to program */
+ CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */
} else {
/* we could not process the token, so push it back */
CHKiRet(ctokUngetToken(ctok, pToken));
@@ -225,7 +224,7 @@ e_and(expr_t *pThis, ctok_t *ctok)
/* fill structure */
CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */
CHKiRet(e_cmp(pThis, ctok));
- // VM: and
+ CHKiRet(vmprgAddVarOperation(pThis->pVmprg, opcode_AND, NULL)); /* add to program */
CHKiRet(ctokGetToken(ctok, &pToken));
}
@@ -257,7 +256,7 @@ expr(expr_t *pThis, ctok_t *ctok)
dbgoprint((obj_t*) pThis, "found OR\n");
CHKiRet(ctok_tokenDestruct(&pToken)); /* no longer needed */
CHKiRet(e_and(pThis, ctok));
- // VM: or
+ CHKiRet(vmprgAddVarOperation(pThis->pVmprg, opcode_OR, NULL)); /* add to program */
CHKiRet(ctokGetToken(ctok, &pToken));
}
@@ -298,7 +297,8 @@ rsRetVal exprConstructFinalize(expr_t *pThis)
/* destructor for the expr object */
BEGINobjDestruct(expr) /* be sure to specify the object type also in END and CODESTART macros! */
CODESTARTobjDestruct(expr)
- /* ... then free resources */
+ if(pThis->pVmprg != NULL)
+ vmprgDestruct(&pThis->pVmprg);
ENDobjDestruct(expr)
@@ -352,8 +352,14 @@ exprParse(expr_t *pThis, ctok_t *ctok)
ISOBJ_TYPE_assert(pThis, expr);
ISOBJ_TYPE_assert(ctok, ctok);
+ /* first, we need to make sure we have a program where we can add to what we parse... */
+ CHKiRet(vmprgConstruct(&pThis->pVmprg));
+ CHKiRet(vmprgConstructFinalize(pThis->pVmprg));
+
+ /* happy parsing... */
CHKiRet(expr(pThis, ctok));
dbgoprint((obj_t*) pThis, "successfully parsed/created expression\n");
+vmprgDebugPrint(pThis->pVmprg);
finalize_it:
RETiRet;
diff --git a/obj-types.h b/obj-types.h
index a473060d..6fce1f8f 100644
--- a/obj-types.h
+++ b/obj-types.h
@@ -231,5 +231,25 @@ finalize_it: \
}
+/* this defines the debug print entry point. DebugPrint is optional. If
+ * it is provided, the object should output some meaningful information
+ * via the debug system.
+ * rgerhards, 2008-02-20
+ */
+#define PROTOTYPEObjDebugPrint(obj) rsRetVal obj##DebugPrint(obj##_t *pThis)
+#define BEGINobjDebugPrint(obj) \
+ rsRetVal obj##DebugPrint(obj##_t *pThis) \
+ { \
+ DEFiRet; \
+
+#define CODESTARTobjDebugPrint(obj) \
+ ASSERT(pThis != NULL); \
+ ISOBJ_TYPE_assert(pThis, obj); \
+
+#define ENDobjDebugPrint(obj) \
+ RETiRet; \
+ }
+
+
#endif /* #ifndef OBJ_TYPES_H_INCLUDED */
diff --git a/obj.c b/obj.c
index 093fa008..417ca4ca 100644
--- a/obj.c
+++ b/obj.c
@@ -1,5 +1,3 @@
-// TODO: we need to be called when the derived object is destructed!!!!
-
/* obj.c
*
* This file implements a generic object "class". All other classes can
diff --git a/obj.h b/obj.h
index 229bcd7b..516202ef 100644
--- a/obj.h
+++ b/obj.h
@@ -82,6 +82,7 @@
#define objDestruct(pThis) (((obj_t*) (pThis))->pObjInfo->objMethods[objMethod_DESTRUCT])(&pThis)
#define objSerialize(pThis) (((obj_t*) (pThis))->pObjInfo->objMethods[objMethod_SERIALIZE])
#define objGetSeverity(pThis, piSever) (((obj_t*) (pThis))->pObjInfo->objMethods[objMethod_GETSEVERITY])(pThis, piSever)
+#define objDebugPrint(pThis) (((obj_t*) (pThis))->pObjInfo->objMethods[objMethod_DEBUGPRINT])(pThis)
#define OBJSetMethodHandler(methodID, pHdlr) \
CHKiRet(objInfoSetMethod(pObjInfoOBJ, methodID, (rsRetVal (*)(void*)) pHdlr))
diff --git a/vmop.c b/vmop.c
index 460347bd..705a8a12 100644
--- a/vmop.c
+++ b/vmop.c
@@ -58,6 +58,13 @@ CODESTARTobjDestruct(vmop)
ENDobjDestruct(vmop)
+/* destructor for the vmop object */
+BEGINobjDebugPrint(vmop) /* be sure to specify the object type also in END and CODESTART macros! */
+CODESTARTobjDebugPrint(vmop)
+ dbgoprint((obj_t*) pThis, "operation: %d, next %p\n", (int) pThis->opcode, pThis->pNext);
+ENDobjDebugPrint(vmop)
+
+
/* set operand (variant case)
* rgerhards, 2008-02-20
*/
@@ -90,6 +97,7 @@ vmopSetOpcode(vmop_t *pThis, opcode_t opcode)
* rgerhards, 2008-02-19
*/
BEGINObjClassInit(vmop, 1) /* class, version */
+ OBJSetMethodHandler(objMethod_DEBUGPRINT, vmopDebugPrint);
OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, vmopConstructFinalize);
ENDObjClassInit(vmop)
diff --git a/vmop.h b/vmop.h
index 2500fd78..4bf066b5 100644
--- a/vmop.h
+++ b/vmop.h
@@ -70,5 +70,6 @@ rsRetVal vmopDestruct(vmop_t **ppThis);
rsRetVal vmopSetOpcode(vmop_t *pThis, opcode_t opcode);
rsRetVal vmopSetVar(vmop_t *pThis, var_t *pVar);
PROTOTYPEObjClassInit(vmop);
+PROTOTYPEObjDebugPrint(vmop);
#endif /* #ifndef INCLUDED_VMOP_H */
diff --git a/vmprg.c b/vmprg.c
index 44b403f8..d8795b3b 100644
--- a/vmprg.c
+++ b/vmprg.c
@@ -65,13 +65,53 @@ CODESTARTobjDestruct(vmprg)
ENDobjDestruct(vmprg)
+/* destructor for the vmop object */
+BEGINobjDebugPrint(vmprg) /* be sure to specify the object type also in END and CODESTART macros! */
+ vmop_t *pOp;
+CODESTARTobjDebugPrint(vmprg)
+ dbgoprint((obj_t*) pThis, "program contents:\n");
+ for(pOp = pThis->vmopRoot ; pOp != NULL ; pOp = pOp->pNext) {
+ vmopDebugPrint(pOp);
+ }
+ENDobjDebugPrint(vmprg)
+
+
+/* this is a shortcut for high-level callers. It creates a new vmop, sets its
+ * parameters and adds it to the program - all in one big step. If there is no
+ * var associated with this operation, the caller can simply supply NULL as
+ * pVar.
+ */
+rsRetVal
+vmprgAddVarOperation(vmprg_t *pThis, opcode_t opcode, var_t *pVar)
+{
+ DEFiRet;
+ vmop_t *pOp;
+
+ ISOBJ_TYPE_assert(pThis, vmprg);
+
+ /* construct and fill vmop */
+ CHKiRet(vmopConstruct(&pOp));
+ CHKiRet(vmopConstructFinalize(pOp));
+ CHKiRet(vmopConstructFinalize(pOp));
+ CHKiRet(vmopSetOpcode(pOp, opcode));
+ if(pVar != NULL)
+ CHKiRet(vmopSetVar(pOp, pVar));
+
+ /* and add it to the program */
+ CHKiRet(vmprgAddOperation(pThis, pOp));
+
+finalize_it:
+ RETiRet;
+}
+
+
/* add an operation (instruction) to the end of the current program. This
* function is expected to be called while creating the program, but never
* again after this is done and it is being executed. Results are undefined if
* it is called after execution.
*/
rsRetVal
-addOperation(vmprg_t *pThis, vmop_t *pOp)
+vmprgAddOperation(vmprg_t *pThis, vmop_t *pOp)
{
DEFiRet;
@@ -94,6 +134,7 @@ addOperation(vmprg_t *pThis, vmop_t *pOp)
* rgerhards, 2008-02-19
*/
BEGINObjClassInit(vmprg, 1) /* class, version */
+ OBJSetMethodHandler(objMethod_DEBUGPRINT, vmprgDebugPrint);
OBJSetMethodHandler(objMethod_CONSTRUCTION_FINALIZER, vmprgConstructFinalize);
ENDObjClassInit(vmprg)
diff --git a/vmprg.h b/vmprg.h
index 9b278360..a2ddf1ba 100644
--- a/vmprg.h
+++ b/vmprg.h
@@ -51,7 +51,9 @@ typedef struct vmprg_s {
rsRetVal vmprgConstruct(vmprg_t **ppThis);
rsRetVal vmprgConstructFinalize(vmprg_t __attribute__((unused)) *pThis);
rsRetVal vmprgDestruct(vmprg_t **ppThis);
-rsRetVal addOperation(vmprg_t *pThis, vmop_t *pOp);
+rsRetVal vmprgAddOperation(vmprg_t *pThis, vmop_t *pOp);
+rsRetVal vmprgAddVarOperation(vmprg_t *pThis, opcode_t opcode, var_t *pVar);
PROTOTYPEObjClassInit(vmprg);
+PROTOTYPEObjDebugPrint(vmprg);
#endif /* #ifndef INCLUDED_VMPRG_H */