#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,
/* 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 */
rspamd_expr_stack_elt_push (operands, a1);
return TRUE;
}
+
/* Now test a2 */
test = a2;
test_elt = test->data;
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 */
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;
+}
#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 {
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_ */