summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ctok.c4
-rw-r--r--ctok_token.h9
-rw-r--r--doc/expression.html2
-rw-r--r--vmop.h25
4 files changed, 36 insertions, 4 deletions
diff --git a/ctok.c b/ctok.c
index 3d0b55f7..b0c24b9b 100644
--- a/ctok.c
+++ b/ctok.c
@@ -484,6 +484,10 @@ ctokGetToken(ctok_t *pThis, ctok_token_t **ppToken)
pToken->tok = ctok_OR;
} else if(!strcasecmp((char*)szWord, "not")) {
pToken->tok = ctok_NOT;
+ } else if(!strcasecmp((char*)szWord, "contains")) {
+ pToken->tok = ctok_CMP_CONTAINS;
+ } else if(!strcasecmp((char*)szWord, "startswith")) {
+ pToken->tok = ctok_CMP_STARTSWITH;
} else if(!strcasecmp((char*)szWord, "then")) {
pToken->tok = ctok_THEN;
} else {
diff --git a/ctok_token.h b/ctok_token.h
index ccde6325..66be42b6 100644
--- a/ctok_token.h
+++ b/ctok_token.h
@@ -26,7 +26,10 @@
#include "stringbuf.h"
/* the tokens... I use numbers below so that the tokens can be easier
- * identified in debug output. */
+ * identified in debug output. These ID's are also partly resused as opcodes.
+ * As such, they should be kept below 1,000 so that they do not interfer
+ * with the rest of the opcodes.
+ */
typedef struct {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
enum {
@@ -54,7 +57,9 @@ typedef struct {
ctok_CMP_LT = 102,
ctok_CMP_GT = 103,
ctok_CMP_LTEQ = 104,
- ctok_CMP_GTEQ = 105, /* end compare operations */
+ ctok_CMP_CONTAINS = 105,
+ ctok_CMP_STARTSWITH = 106,
+ ctok_CMP_GTEQ = 107, /* end compare operations */
} tok;
rsCStrObj *pstrVal;
int64 intVal;
diff --git a/doc/expression.html b/doc/expression.html
index 6298b74a..58401a1b 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;=" <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/vmop.h b/vmop.h
index 319232a0..031d03e4 100644
--- a/vmop.h
+++ b/vmop.h
@@ -22,10 +22,33 @@
#ifndef INCLUDED_VMOP_H
#define INCLUDED_VMOP_H
+#include "ctok_token.h"
+
/* machine instructions types */
typedef enum { /* do NOT start at 0 to detect uninitialized types after calloc() */
opcode_INVALID = 0,
- opcode_PUSH = 1
+ /* for simplicity of debugging and reading dumps, we use the same IDs
+ * that the tokenizer uses where this applicable.
+ */
+ opcode_OR = ctok_OR,
+ opcode_AND = ctok_AND,
+ opcode_PLUS = ctok_PLUS,
+ opcode_MINUS = ctok_MINUS,
+ opcode_TIMES = ctok_TIMES, /* "*" */
+ opcode_DIV = ctok_DIV,
+ opcode_MOD = ctok_MOD,
+ opcode_NOT = ctok_NOT,
+ opcode_CMP_EQ = ctok_CMP_EQ, /* all compare operations must be in a row */
+ opcode_CMP_NEQ = ctok_CMP_NEQ,
+ opcode_CMP_LT = ctok_CMP_LT,
+ opcode_CMP_GT = ctok_CMP_GT,
+ opcode_CMP_LTEQ = ctok_CMP_LTEQ,
+ opcode_CMP_CONTAINS = ctok_CMP_CONTAINS,
+ opcode_CMP_STARTSWITH = ctok_CMP_STARTSWITH,
+ opcode_CMP_GTEQ = ctok_CMP_GTEQ, /* end compare operations */
+ /* here we start our own codes */
+ opcode_PUSH = 1000, /* requires var operand */
+ opcode_POP = 1001, /* requires var operand to receive result */
} opcode_t;
/* the vmop object */