summaryrefslogtreecommitdiffstats
path: root/vm.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2008-02-25 13:27:10 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2008-02-25 13:27:10 +0000
commit5ebc0db1a6d4c75ce9c26449ef2a2e3d7b340e10 (patch)
treed9f34f80e487d70da9c764f7c050086eceaff5bf /vm.c
parenta24cee11b718603fbc681e4a7a23f50c8d785ad7 (diff)
downloadrsyslog-5ebc0db1a6d4c75ce9c26449ef2a2e3d7b340e10.tar.gz
rsyslog-5ebc0db1a6d4c75ce9c26449ef2a2e3d7b340e10.tar.xz
rsyslog-5ebc0db1a6d4c75ce9c26449ef2a2e3d7b340e10.zip
- added PUSHMSGVAR operation
- included expression support in filter module (and it works ;))
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c73
1 files changed, 70 insertions, 3 deletions
diff --git a/vm.c b/vm.c
index 76f06328..389a3cd1 100644
--- a/vm.c
+++ b/vm.c
@@ -219,11 +219,41 @@ ENDop(UNARY_MINUS)
BEGINop(PUSHCONSTANT) /* remember to set the instruction also in the ENDop macro! */
+ var_t *pVarDup; /* we need to duplicate the var, as we need to hand it over */
CODESTARTop(PUSHCONSTANT)
- vmstk.Push(pThis->pStk, pOp->operand.pVar);
+ CHKiRet(var.Duplicate(pOp->operand.pVar, &pVarDup));
+ vmstk.Push(pThis->pStk, pVarDup);
+finalize_it:
ENDop(PUSHCONSTANT)
+BEGINop(PUSHMSGVAR) /* remember to set the instruction also in the ENDop macro! */
+ var_t *pVal; /* the value to push */
+ cstr_t *pstrVal;
+CODESTARTop(PUSHMSGVAR)
+ if(pThis->pMsg == NULL) {
+ /* TODO: flag an error message! As a work-around, we permit
+ * execution to continue here with an empty string
+ */
+ /* TODO: create a method in var to create a string var? */
+ CHKiRet(var.Construct(&pVal));
+ CHKiRet(var.ConstructFinalize(pVal));
+ CHKiRet(rsCStrConstructFromszStr(&pstrVal, (uchar*)""));
+ CHKiRet(var.SetString(pVal, pstrVal));
+ } else {
+ /* we have a message, so pull value from there */
+var.DebugPrint(pOp->operand.pVar);
+ CHKiRet(msgGetMsgVar(pThis->pMsg, pOp->operand.pVar->val.pStr, &pVal));
+ }
+
+ /* if we reach this point, we have a valid pVal and can push it */
+ vmstk.Push(pThis->pStk, pVal);
+RUNLOG_STR("msgvar:");
+var.DebugPrint(pVal);
+finalize_it:
+ENDop(PUSHMSGVAR)
+
+
/* ------------------------------ end instruction set implementation ------------------------------ */
@@ -292,6 +322,7 @@ execProg(vm_t *pThis, vmprg_t *pProg)
// TODO: implement: doOP(CMP_STARTSWITH);
doOP(NOT);
doOP(PUSHCONSTANT);
+ doOP(PUSHMSGVAR);
doOP(PLUS);
doOP(MINUS);
doOP(TIMES);
@@ -317,6 +348,41 @@ finalize_it:
}
+/* Set the current message object for the VM. It *is* valid to set a
+ * NULL message object, what simply means there is none. Message
+ * objects are properly reference counted.
+ */
+static rsRetVal
+SetMsg(vm_t *pThis, msg_t *pMsg)
+{
+ DEFiRet;
+ if(pThis->pMsg != NULL) {
+ msgDestruct(&pThis->pMsg);
+ }
+
+ if(pMsg != NULL) {
+ pThis->pMsg = MsgAddRef(pMsg);
+ }
+
+ RETiRet;
+}
+
+
+/* Pop a var from the stack and return it to caller. The variable type is not
+ * changed, it is taken from the stack as is. This functionality is
+ * partly needed. We may (or may not ;)) be able to remove it once we have
+ * full RainerScript support. -- rgerhards, 2008-02-25
+ */
+static rsRetVal
+PopVarFromStack(vm_t *pThis, var_t **ppVar)
+{
+ DEFiRet;
+ CHKiRet(vmstk.Pop(pThis->pStk, ppVar));
+finalize_it:
+ RETiRet;
+}
+
+
/* Pop a boolean from the stack and return it to caller. This functionality is
* partly needed. We may (or may not ;)) be able to remove it once we have
* full RainerScript support. -- rgerhards, 2008-02-25
@@ -325,13 +391,12 @@ static rsRetVal
PopBoolFromStack(vm_t *pThis, var_t **ppVar)
{
DEFiRet;
-
CHKiRet(vmstk.PopBool(pThis->pStk, ppVar));
-
finalize_it:
RETiRet;
}
+
/* queryInterface function
* rgerhards, 2008-02-21
*/
@@ -354,6 +419,8 @@ CODESTARTobjQueryInterface(vm)
pIf->DebugPrint = vmDebugPrint;
pIf->ExecProg = execProg;
pIf->PopBoolFromStack = PopBoolFromStack;
+ pIf->PopVarFromStack = PopVarFromStack;
+ pIf->SetMsg = SetMsg;
finalize_it:
ENDobjQueryInterface(vm)