aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2009-04-27 19:03:11 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2009-04-27 19:03:11 +0400
commitb9baa0d48da843d73926fff54b36846a778d9474 (patch)
tree7904fe31f4d6d9aa9cba1776c7ea3153933b0301
parentc1723b27e05334a43d1443a125023ba556f54117 (diff)
downloadrspamd-b9baa0d48da843d73926fff54b36846a778d9474.tar.gz
rspamd-b9baa0d48da843d73926fff54b36846a778d9474.zip
* Add expression parser utility
* Temporaly switch off expression optimizer as it should be reworked
-rw-r--r--CMakeLists.txt13
-rw-r--r--src/expressions.c2
-rw-r--r--src/plugins/regexp.c20
-rw-r--r--utils/expression_parser.c50
4 files changed, 69 insertions, 16 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e1e0c7ba2..3b89b265b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -330,10 +330,14 @@ SET(TESTDEPENDS src/mem_pool.c
src/statfile.c)
SET(UTILSSRC utils/url_extracter.c)
+SET(EXPRSRC utils/expression_parser.c)
SET(UTILSDEPENDS src/mem_pool.c
src/hash.c
src/url.c
+ src/fuzzy.c
+ src/expressions.c
+ src/message.c
src/util.c)
LIST(LENGTH PLUGINSSRC RSPAMD_MODULES_NUM)
@@ -414,6 +418,15 @@ ENDIF(LIBUTIL_LIBRARY)
TARGET_LINK_LIBRARIES(utils/url-extracter ${GLIB2_LIBRARIES})
TARGET_LINK_LIBRARIES(utils/url-extracter ${GMIME2_LIBRARIES})
+ADD_EXECUTABLE(utils/expression-parser ${UTILSDEPENDS} ${CONTRIBSRC} ${EXPRSRC})
+SET_TARGET_PROPERTIES(utils/expression-parser PROPERTIES LINKER_LANGUAGE C)
+TARGET_LINK_LIBRARIES(utils/expression-parser m)
+IF(LIBUTIL_LIBRARY)
+ TARGET_LINK_LIBRARIES(utils/expression-parser util)
+ENDIF(LIBUTIL_LIBRARY)
+TARGET_LINK_LIBRARIES(utils/expression-parser ${GLIB2_LIBRARIES})
+TARGET_LINK_LIBRARIES(utils/expression-parser ${GMIME2_LIBRARIES})
+
INSTALL(PROGRAMS rspamd-${RSPAMD_VERSION} DESTINATION bin RENAME rspamd)
INSTALL(PROGRAMS rspamc.pl DESTINATION bin RENAME rspamc)
IF(ENABLE_PERL MATCHES "ON")
diff --git a/src/expressions.c b/src/expressions.c
index e656cc433..200c1abd3 100644
--- a/src/expressions.c
+++ b/src/expressions.c
@@ -382,7 +382,7 @@ parse_expression (memory_pool_t *pool, char *line)
case READ_REGEXP_FLAGS:
if (!is_regexp_flag (*p) || *(p + 1) == '\0') {
if (c != p) {
- if (is_regexp_flag (*p) && *(p + 1) == '\0') {
+ if ((is_regexp_flag (*p) || *p == '/') && *(p + 1) == '\0') {
p ++;
}
str = memory_pool_alloc (pool, p - c + 2);
diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c
index 622c06c83..d21baf494 100644
--- a/src/plugins/regexp.c
+++ b/src/plugins/regexp.c
@@ -369,17 +369,17 @@ optimize_regexp_expression (struct expression **e, GQueue *stack, gboolean res)
msg_debug ("optimize_regexp_expression: found '!' operator, inversing result");
res = !res;
it = it->next;
- *e = it;
+ *e = it->next;
continue;
}
else if (it->content.operation == '&' && res == FALSE) {
msg_debug ("optimize_regexp_expression: found '&' and previous expression is false");
- *e = it;
+ *e = it->next;
ret = TRUE;
}
else if (it->content.operation == '|' && res == TRUE) {
msg_debug ("optimize_regexp_expression: found '|' and previous expression is true");
- *e = it;
+ *e = it->next;
ret = TRUE;
}
break;
@@ -400,7 +400,6 @@ process_regexp_expression (struct expression *expr, struct worker_task *task)
gsize cur, op1, op2;
struct expression *it = expr;
struct rspamd_regexp *re;
- gboolean try_optimize = TRUE;
stack = g_queue_new ();
@@ -409,21 +408,13 @@ process_regexp_expression (struct expression *expr, struct worker_task *task)
/* Find corresponding symbol */
cur = process_regexp ((struct rspamd_regexp *)it->content.operand, task);
msg_debug ("process_regexp_expression: regexp %s found", cur ? "is" : "is not");
- if (try_optimize) {
- try_optimize = optimize_regexp_expression (&it, stack, cur);
- } else {
- g_queue_push_head (stack, GSIZE_TO_POINTER (cur));
- }
+ g_queue_push_head (stack, GSIZE_TO_POINTER (cur));
} else if (it->type == EXPR_FUNCTION) {
cur = (gsize)call_expression_function ((struct expression_function *)it->content.operand, task);
msg_debug ("process_regexp_expression: function %s returned %s", ((struct expression_function *)it->content.operand)->name,
cur ? "true" : "false");
- if (try_optimize) {
- try_optimize = optimize_regexp_expression (&it, stack, cur);
- } else {
- g_queue_push_head (stack, GSIZE_TO_POINTER (cur));
- }
+ g_queue_push_head (stack, GSIZE_TO_POINTER (cur));
} else if (it->type == EXPR_REGEXP) {
/* Compile regexp if it is not parsed */
if (it->content.operand == NULL) {
@@ -445,7 +436,6 @@ process_regexp_expression (struct expression *expr, struct worker_task *task)
g_queue_free (stack);
return FALSE;
}
- try_optimize = TRUE;
switch (it->content.operation) {
case '!':
op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack));
diff --git a/utils/expression_parser.c b/utils/expression_parser.c
new file mode 100644
index 000000000..fa0237f3a
--- /dev/null
+++ b/utils/expression_parser.c
@@ -0,0 +1,50 @@
+#include "../src/config.h"
+#include "../src/main.h"
+#include "../src/cfg_file.h"
+#include "../src/expressions.h"
+
+int
+main (int argc, char **argv)
+{
+ memory_pool_t *pool;
+ struct expression *cur;
+ char *line, *outstr;
+ int r, s;
+ char buf[BUFSIZ];
+
+ pool = memory_pool_new (memory_pool_get_size ());
+
+ line = fgets (buf, sizeof (buf), stdin);
+ while (line) {
+ s = strlen (line);
+ if (buf[s - 1] == '\n') {
+ buf[s - 1] = '\0';
+ }
+ if (buf[s - 2] == '\r') {
+ buf[s - 2] = '\0';
+ }
+
+ r = 0;
+ cur = parse_expression (pool, line);
+ s = strlen (line) * 4;
+ outstr = memory_pool_alloc (pool, s);
+ while (cur) {
+ if (cur->type == EXPR_REGEXP) {
+ r += snprintf (outstr + r, s - r, "OP:%s ", (char *)cur->content.operand);
+ } else if (cur->type == EXPR_STR) {
+ r += snprintf (outstr + r, s - r, "S:%s ", (char *)cur->content.operand);
+
+ } else if (cur->type == EXPR_FUNCTION) {
+ r += snprintf (outstr + r, s - r, "F:%s ", ((struct expression_function *)cur->content.operand)->name);
+ }
+ else {
+ r += snprintf (outstr + r, s - r, "O:%c ", cur->content.operation);
+ }
+ cur = cur->next;
+ }
+ printf ("Parsed expression: '%s' -> '%s'\n", line, outstr);
+ line = fgets (buf, sizeof (buf), stdin);
+ }
+
+ memory_pool_delete (pool);
+}