From b9baa0d48da843d73926fff54b36846a778d9474 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 27 Apr 2009 19:03:11 +0400 Subject: [PATCH] * Add expression parser utility * Temporaly switch off expression optimizer as it should be reworked --- CMakeLists.txt | 13 ++++++++++ src/expressions.c | 2 +- src/plugins/regexp.c | 20 ++++------------ utils/expression_parser.c | 50 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 utils/expression_parser.c 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); +} -- 2.39.5