summaryrefslogtreecommitdiffstats
path: root/grammar/rainerscript.c
diff options
context:
space:
mode:
Diffstat (limited to 'grammar/rainerscript.c')
-rw-r--r--grammar/rainerscript.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index b03e7c12..a4cf90bd 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -38,6 +38,7 @@
#include "rainerscript.h"
#include "conf.h"
#include "parserif.h"
+#include "parse.h"
#include "rsconf.h"
#include "grammar.h"
#include "queue.h"
@@ -144,6 +145,116 @@ getFIOPName(unsigned iFIOP)
return pRet;
}
+
+/* This function takes the filter part of a property
+ * based filter and decodes it. It processes the line up to the beginning
+ * of the action part.
+ */
+static rsRetVal
+DecodePropFilter(uchar *pline, struct cnfstmt *stmt)
+{
+ rsParsObj *pPars = NULL;
+ cstr_t *pCSCompOp = NULL;
+ cstr_t *pCSPropName = NULL;
+ int iOffset; /* for compare operations */
+ DEFiRet;
+
+ ASSERT(pline != NULL);
+
+ DBGPRINTF("Decoding property-based filter '%s'\n", pline);
+
+ /* create parser object starting with line string without leading colon */
+ if((iRet = rsParsConstructFromSz(&pPars, pline+1)) != RS_RET_OK) {
+ parser_errmsg("error %d constructing parser object", iRet);
+ ABORT_FINALIZE(iRet);
+ }
+
+ /* read property */
+ iRet = parsDelimCStr(pPars, &pCSPropName, ',', 1, 1, 1);
+ if(iRet != RS_RET_OK) {
+ parser_errmsg("error %d parsing filter property", iRet);
+ rsParsDestruct(pPars);
+ ABORT_FINALIZE(iRet);
+ }
+ iRet = propNameToID(pCSPropName, &stmt->d.s_propfilt.propID);
+ if(iRet != RS_RET_OK) {
+ parser_errmsg("invalid property name '%s' in filter",
+ cstrGetSzStrNoNULL(pCSPropName));
+ rsParsDestruct(pPars);
+ ABORT_FINALIZE(iRet);
+ }
+ if(stmt->d.s_propfilt.propID == PROP_CEE) {
+ /* in CEE case, we need to preserve the actual property name */
+ if((stmt->d.s_propfilt.propName =
+ es_newStrFromBuf((char*)cstrGetSzStrNoNULL(pCSPropName)+2, cstrLen(pCSPropName)-2)) == NULL) {
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ }
+
+ /* read operation */
+ iRet = parsDelimCStr(pPars, &pCSCompOp, ',', 1, 1, 1);
+ if(iRet != RS_RET_OK) {
+ parser_errmsg("error %d compare operation property - ignoring selector", iRet);
+ rsParsDestruct(pPars);
+ ABORT_FINALIZE(iRet);
+ }
+
+ /* we now first check if the condition is to be negated. To do so, we first
+ * must make sure we have at least one char in the param and then check the
+ * first one.
+ * rgerhards, 2005-09-26
+ */
+ if(rsCStrLen(pCSCompOp) > 0) {
+ if(*rsCStrGetBufBeg(pCSCompOp) == '!') {
+ stmt->d.s_propfilt.isNegated = 1;
+ iOffset = 1; /* ignore '!' */
+ } else {
+ stmt->d.s_propfilt.isNegated = 0;
+ iOffset = 0;
+ }
+ } else {
+ stmt->d.s_propfilt.isNegated = 0;
+ iOffset = 0;
+ }
+
+ if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "contains", 8)) {
+ stmt->d.s_propfilt.operation = FIOP_CONTAINS;
+ } else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "isequal", 7)) {
+ stmt->d.s_propfilt.operation = FIOP_ISEQUAL;
+ } else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "isempty", 7)) {
+ stmt->d.s_propfilt.operation = FIOP_ISEMPTY;
+ } else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "startswith", 10)) {
+ stmt->d.s_propfilt.operation = FIOP_STARTSWITH;
+ } else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (unsigned char*) "regex", 5)) {
+ stmt->d.s_propfilt.operation = FIOP_REGEX;
+ } else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (unsigned char*) "ereregex", 8)) {
+ stmt->d.s_propfilt.operation = FIOP_EREREGEX;
+ } else {
+ parser_errmsg("error: invalid compare operation '%s'",
+ (char*) rsCStrGetSzStrNoNULL(pCSCompOp));
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+
+ if(stmt->d.s_propfilt.operation != FIOP_ISEMPTY) {
+ /* read compare value */
+ iRet = parsQuotedCStr(pPars, &stmt->d.s_propfilt.pCSCompValue);
+ if(iRet != RS_RET_OK) {
+ parser_errmsg("error %d compare value property", iRet);
+ rsParsDestruct(pPars);
+ ABORT_FINALIZE(iRet);
+ }
+ }
+
+finalize_it:
+ if(pPars != NULL)
+ rsParsDestruct(pPars);
+ if(pCSCompOp != NULL)
+ rsCStrDestruct(&pCSCompOp);
+ if(pCSPropName != NULL)
+ cstrDestruct(&pCSPropName);
+ RETiRet;
+}
+
static void
prifiltInvert(struct funcData_prifilt *prifilt)
{
@@ -1091,7 +1202,11 @@ var2Number(struct var *r, int *bSuccess)
n = es_str2num(r->d.estr, bSuccess);
} else {
if(r->datatype == 'J') {
+#ifdef HAVE_JSON_OBJECT_NEW_INT64
+ n = (r->d.json == NULL) ? 0 : json_object_get_int64(r->d.json);
+#else /* HAVE_JSON_OBJECT_NEW_INT64 */
n = (r->d.json == NULL) ? 0 : json_object_get_int(r->d.json);
+#endif /* HAVE_JSON_OBJECT_NEW_INT64 */
} else {
n = r->d.n;
}
@@ -1476,6 +1591,19 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
ret->d.n = 1;
ret->datatype = 'N';
break;
+ case CNFFUNC_LOOKUP:
+dbgprintf("DDDD: executing lookup\n");
+ ret->datatype = 'S';
+ if(func->funcdata == NULL) {
+ ret->d.estr = es_newStrFromCStr("TABLE-NOT-FOUND", sizeof("TABLE-NOT-FOUND")-1);
+ break;
+ }
+ cnfexprEval(func->expr[1], &r[1], usrptr);
+ str = (char*) var2CString(&r[1], &bMustFree);
+ ret->d.estr = lookupKey_estr(func->funcdata, (uchar*)str);
+ if(bMustFree) free(str);
+ if(r[1].datatype == 'S') es_deleteStr(r[1].d.estr);
+ break;
default:
if(Debug) {
fname = es_str2cstr(func->fname, NULL);
@@ -2580,6 +2708,7 @@ cnfstmtNewPROPFILT(char *propfilt, struct cnfstmt *t_then)
cnfstmt->d.s_propfilt.pCSCompValue = NULL;
if(DecodePropFilter((uchar*)propfilt, cnfstmt) != RS_RET_OK) {
cnfstmt->nodetype = S_NOP; /* disable action! */
+ cnfstmtDestructLst(t_then); /* we do no longer need this */
}
}
return cnfstmt;
@@ -3243,6 +3372,13 @@ funcName2ID(es_str_t *fname, unsigned short nParams)
return CNFFUNC_INVALID;
}
return CNFFUNC_PRIFILT;
+ } else if(!es_strbufcmp(fname, (unsigned char*)"lookup", sizeof("lookup") - 1)) {
+ if(nParams != 2) {
+ parser_errmsg("number of parameters for lookup() must be two "
+ "but is %d.", nParams);
+ return CNFFUNC_INVALID;
+ }
+ return CNFFUNC_LOOKUP;
} else {
return CNFFUNC_INVALID;
}
@@ -3307,6 +3443,30 @@ finalize_it:
}
+static inline rsRetVal
+initFunc_lookup(struct cnffunc *func)
+{
+ uchar *cstr = NULL;
+ DEFiRet;
+
+ func->funcdata = NULL;
+ if(func->expr[0]->nodetype != 'S') {
+ parser_errmsg("table name (param 1) of lookup() must be a constant string");
+ FINALIZE;
+ }
+
+ cstr = (uchar*)es_str2cstr(((struct cnfstringval*) func->expr[0])->estr, NULL);
+ if((func->funcdata = lookupFindTable(cstr)) == NULL) {
+ parser_errmsg("lookup table '%s' not found", cstr);
+ FINALIZE;
+ }
+
+finalize_it:
+ free(cstr);
+ RETiRet;
+}
+
+
struct cnffunc *
cnffuncNew(es_str_t *fname, struct cnffparamlst* paramlst)
{
@@ -3344,6 +3504,9 @@ cnffuncNew(es_str_t *fname, struct cnffparamlst* paramlst)
case CNFFUNC_PRIFILT:
initFunc_prifilt(func);
break;
+ case CNFFUNC_LOOKUP:
+ initFunc_lookup(func);
+ break;
default:break;
}
}