diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-03-17 14:13:45 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-03-17 14:13:45 +0000 |
commit | fb236b262fab5adb864b2766910a80590c12611a (patch) | |
tree | 50b9a28dd9b79402cc6937b488229391b3b11674 | |
parent | 2020bd22fff005ac5ba32dda3b4f848f3027640c (diff) | |
download | rspamd-fb236b262fab5adb864b2766910a80590c12611a.tar.gz rspamd-fb236b262fab5adb864b2766910a80590c12611a.zip |
[Feature] Save operation node for expressions atoms
-rw-r--r-- | src/libutil/expression.c | 51 | ||||
-rw-r--r-- | src/libutil/expression.h | 29 |
2 files changed, 62 insertions, 18 deletions
diff --git a/src/libutil/expression.c b/src/libutil/expression.c index 2bbc5fa3b..782ad2371 100644 --- a/src/libutil/expression.c +++ b/src/libutil/expression.c @@ -27,21 +27,6 @@ #define MIN_RESORT_EVALS 50 #define MAX_RESORT_EVALS 150 -enum rspamd_expression_op { - OP_INVALID = 0, - OP_PLUS, /* || or + */ - OP_MULT, /* && or * */ - OP_OR, /* || or | */ - OP_AND, /* && or & */ - OP_NOT, /* ! */ - OP_LT, /* < */ - OP_GT, /* > */ - OP_LE, /* <= */ - OP_GE, /* >= */ - OP_OBRACE, /* ( */ - OP_CBRACE /* ) */ -}; - enum rspamd_expression_elt_type { ELT_OP = 0, ELT_ATOM, @@ -372,12 +357,19 @@ rspamd_ast_add_node (GPtrArray *operands, struct rspamd_expression_elt *op, /* Unary operator */ res = g_node_new (op); a1 = rspamd_expr_stack_elt_pop (operands); - g_node_append (res, a1); + if (a1 == NULL) { g_set_error (err, rspamd_expr_quark(), EINVAL, "no operand to " "unary '%s' operation", rspamd_expr_op_to_str (op->p.op)); return FALSE; } + + g_node_append (res, a1); + test_elt = a1->data; + + if (test_elt->type == ELT_ATOM) { + test_elt->p.atom->parent = res; + } } else { /* For binary operators we might want to examine chains */ @@ -404,6 +396,7 @@ rspamd_ast_add_node (GPtrArray *operands, struct rspamd_expression_elt *op, rspamd_expr_stack_elt_push (operands, a1); return TRUE; } + /* Now test a2 */ test = a2; test_elt = test->data; @@ -419,6 +412,16 @@ rspamd_ast_add_node (GPtrArray *operands, struct rspamd_expression_elt *op, res = g_node_new (op); g_node_append (res, a1); g_node_append (res, a2); + + test_elt = a1->data; + if (test_elt->type == ELT_ATOM) { + test_elt->p.atom->parent = res; + } + + test_elt = a2->data; + if (test_elt->type == ELT_ATOM) { + test_elt->p.atom->parent = res; + } } /* Push back resulting node to the stack */ @@ -1139,3 +1142,19 @@ rspamd_expression_atom_foreach (struct rspamd_expression *expr, g_node_traverse (expr->ast, G_POST_ORDER, G_TRAVERSE_ALL, -1, rspamd_ast_atom_traverse, &data); } + +gboolean +rspamd_expression_node_is_op (GNode *node, enum rspamd_expression_op op) +{ + struct rspamd_expression_elt *elt; + + g_assert (node != NULL); + + elt = node->data; + + if (elt->type == ELT_OP && elt->p.op == op) { + return TRUE; + } + + return FALSE; +} diff --git a/src/libutil/expression.h b/src/libutil/expression.h index 97cbfec4b..82c0c60c1 100644 --- a/src/libutil/expression.h +++ b/src/libutil/expression.h @@ -24,19 +24,36 @@ #define RSPAMD_EXPRESSION_FLAG_NOOPT (1 << 0) +enum rspamd_expression_op { + OP_INVALID = 0, + OP_PLUS, /* || or + */ + OP_MULT, /* && or * */ + OP_OR, /* || or | */ + OP_AND, /* && or & */ + OP_NOT, /* ! */ + OP_LT, /* < */ + OP_GT, /* > */ + OP_LE, /* <= */ + OP_GE, /* >= */ + OP_OBRACE, /* ( */ + OP_CBRACE /* ) */ +}; + typedef struct rspamd_expression_atom_s { + /* Parent node */ + GNode *parent; /* Opaque userdata */ gpointer data; /* String representation of atom */ const gchar *str; /* Length of the string representation of atom */ gsize len; - /* Relative priority */ - gint priority; /* Average execution time (in ticks) */ gdouble avg_ticks; /* Amount of positive triggers */ guint hits; + /* Relative priority */ + gint priority; } rspamd_expression_atom_t; struct rspamd_atom_subr { @@ -101,4 +118,12 @@ typedef void (*rspamd_expression_atom_foreach_cb) (const rspamd_ftok_t *atom, void rspamd_expression_atom_foreach (struct rspamd_expression *expr, rspamd_expression_atom_foreach_cb cb, gpointer cbdata); +/** + * Checks if a specified node in AST is the specified operation + * @param node AST node packed in GNode container + * @param op operation to check + * @return TRUE if node is operation node and is exactly the specified option + */ +gboolean rspamd_expression_node_is_op (GNode *node, enum rspamd_expression_op op); + #endif /* SRC_LIBUTIL_EXPRESSION_H_ */ |