]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Save operation node for expressions atoms
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 17 Mar 2016 14:13:45 +0000 (14:13 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 17 Mar 2016 14:13:45 +0000 (14:13 +0000)
src/libutil/expression.c
src/libutil/expression.h

index 2bbc5fa3b04665816e34dc8380a72ce64e3d3c7e..782ad2371de0081f1d9b129af6435808e4fc0367 100644 (file)
 #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;
+}
index 97cbfec4bed209250dac07cff2b68622db77a265..82c0c60c15c92907c45075174b298ac7ba650c52 100644 (file)
 
 #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_ */