summaryrefslogtreecommitdiffstats
path: root/grammar
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-09-18 12:58:33 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-09-18 12:58:33 +0200
commit66929c7c1b37719b94d11a56b44fcfb23052237c (patch)
treef462f45b812220bdadef0517be550b96fa9eb98c /grammar
parentb76a00dd20b0941a9096d17c491ab1277a2b6fd1 (diff)
downloadrsyslog-66929c7c1b37719b94d11a56b44fcfb23052237c.tar.gz
rsyslog-66929c7c1b37719b94d11a56b44fcfb23052237c.tar.xz
rsyslog-66929c7c1b37719b94d11a56b44fcfb23052237c.zip
new ruleengine: implement native JSON in RainerScript
Diffstat (limited to 'grammar')
-rw-r--r--grammar/rainerscript.c54
-rw-r--r--grammar/rainerscript.h3
2 files changed, 48 insertions, 9 deletions
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index 05d489a3..e7299e62 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -738,12 +738,14 @@ done:
* try to convert it to one. The semantics from es_str2num()
* are used (bSuccess tells if the conversion went well or not).
*/
-static inline long long
+static long long
var2Number(struct var *r, int *bSuccess)
{
long long n;
if(r->datatype == 'S') {
n = es_str2num(r->d.estr, bSuccess);
+ } else if(r->datatype == 'J') {
+ n = (r->d.json == NULL) ? 0 : json_object_get_int(r->d.json);
} else {
n = r->d.n;
if(bSuccess)
@@ -757,12 +759,27 @@ var2Number(struct var *r, int *bSuccess)
static inline es_str_t *
var2String(struct var *r, int *bMustFree)
{
+ es_str_t *estr;
+ char *cstr;
+ rs_size_t lenstr;
if(r->datatype == 'N') {
*bMustFree = 1;
- return es_newStrFromNumber(r->d.n);
+ estr = es_newStrFromNumber(r->d.n);
+ } else if(r->datatype == 'J') {
+ *bMustFree = 1;
+ if(r->d.json == NULL) {
+ cstr = "",
+ lenstr = 0;
+ } else {
+ cstr = (char*)json_object_get_string(r->d.json);
+ lenstr = strlen(cstr);
+ }
+ estr = es_newStrFromCStr(cstr, lenstr);
+ } else {
+ *bMustFree = 0;
+ estr = r->d.estr;
}
- *bMustFree = 0;
- return r->d.estr;
+ return estr;
}
/* Perform a function call. This has been moved out of cnfExprEval in order
@@ -873,6 +890,27 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
}
}
+static inline void
+evalVar(struct cnfvar *var, void *usrptr, struct var *ret)
+{
+ rsRetVal localRet;
+ es_str_t *estr;
+ struct json_object *json;
+
+ if(var->name[0] == '$' && var->name[1] == '!') {
+ /* TODO: unify string libs */
+ estr = es_newStrFromBuf(var->name+1, strlen(var->name)-1);
+ localRet = msgGetCEEPropJSON((msg_t*)usrptr, estr, &json);
+ es_deleteStr(estr);
+ ret->datatype = 'J';
+ ret->d.json = (localRet == RS_RET_OK) ? json : NULL;
+ } else {
+ ret->datatype = 'S';
+ ret->d.estr = cnfGetVar(var->name, usrptr);
+ }
+
+}
+
#define FREE_BOTH_RET \
if(r.datatype == 'S') es_deleteStr(r.d.estr); \
if(l.datatype == 'S') es_deleteStr(l.d.estr)
@@ -1186,8 +1224,7 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
ret->d.estr = es_strdup(((struct cnfstringval*)expr)->estr);
break;
case 'V':
- ret->datatype = 'S';
- ret->d.estr = cnfGetVar(((struct cnfvar*)expr)->name, usrptr);
+ evalVar((struct cnfvar*)expr, usrptr, ret);
break;
case '&':
/* TODO: think about optimization, should be possible ;) */
@@ -1430,6 +1467,7 @@ cnfexprPrint(struct cnfexpr *expr, int indent)
cnfexprPrint(func->expr[i], indent+1);
}
break;
+ case '&':
case '+':
case '-':
case '*':
@@ -1443,8 +1481,8 @@ cnfexprPrint(struct cnfexpr *expr, int indent)
cnfexprPrint(expr->r, indent+1);
break;
default:
- dbgprintf("error: unknown nodetype %u\n",
- (unsigned) expr->nodetype);
+ dbgprintf("error: unknown nodetype %u['%c']\n",
+ (unsigned) expr->nodetype, (char) expr->nodetype);
break;
}
}
diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h
index 51d96e51..f01b1d79 100644
--- a/grammar/rainerscript.h
+++ b/grammar/rainerscript.h
@@ -72,8 +72,9 @@ struct var {
es_str_t *estr;
struct cnfexpr *expr;
long long n;
+ struct json_object *json;
} d;
- char datatype; /* 'N' number, 'S' string, 'E' expression */
+ char datatype; /* 'N' number, 'S' string, 'E' expression, 'J' JSON */
};
struct cnfobj {