static rspamd_expression_atom_t * rspamd_mime_expr_parse (const gchar *line, gsize len,
rspamd_mempool_t *pool, gpointer ud, GError **err);
-static gdouble rspamd_mime_expr_process (gpointer input, rspamd_expression_atom_t *atom);
+static gdouble rspamd_mime_expr_process (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom);
static gint rspamd_mime_expr_priority (rspamd_expression_atom_t *atom);
static void rspamd_mime_expr_destroy (rspamd_expression_atom_t *atom);
}
static gdouble
-rspamd_mime_expr_process (gpointer input, rspamd_expression_atom_t *atom)
+rspamd_mime_expr_process (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom)
{
- struct rspamd_task *task = input;
+ struct rspamd_task *task = process_data->task;
struct rspamd_mime_atom *mime_atom;
lua_State *L;
gdouble ret = 0;
return;
}
- rc = rspamd_process_expression (comp->expr,
- RSPAMD_EXPRESSION_FLAG_NOOPT, cd);
+ struct rspamd_expr_process_data process_data;
+ memset (&process_data, 0, sizeof process_data);
+
+ process_data.flags = RSPAMD_EXPRESSION_FLAG_NOOPT;
+ process_data.cd = cd;
+
+ rc = rspamd_process_expression (comp->expr, &process_data);
/* Checked bit */
setbit (cd->checked, comp->id * 2);
}
static gdouble
-rspamd_ast_process_node (struct rspamd_expression *expr, gint flags, GNode *node,
- gpointer data, GPtrArray *track)
+rspamd_ast_process_node (struct rspamd_expression *expr, GNode *node,
+ struct rspamd_expr_process_data *process_data)
{
struct rspamd_expression_elt *elt, *celt, *parelt = NULL;
GNode *cld;
t1 = rspamd_get_ticks (TRUE);
}
- elt->value = expr->subr->process (data, elt->p.atom);
+ elt->value = expr->subr->process (process_data, elt->p.atom);
if (fabs (elt->value) > 1e-9) {
elt->p.atom->hits ++;
- if (track) {
- g_ptr_array_add (track, elt->p.atom);
+ if (process_data->trace) {
+ g_ptr_array_add (process_data->trace, elt->p.atom);
}
}
continue;
}
- val = rspamd_ast_process_node (expr, flags, cld, data, track);
+ val = rspamd_ast_process_node (expr, cld, process_data);
if (isnan (acc)) {
acc = rspamd_ast_do_op (elt, val, 0, lim, TRUE);
acc = rspamd_ast_do_op (elt, val, acc, lim, FALSE);
}
- if (!(flags & RSPAMD_EXPRESSION_FLAG_NOOPT)) {
+ if (!(process_data->flags & RSPAMD_EXPRESSION_FLAG_NOOPT)) {
if (rspamd_ast_node_done (elt, parelt, acc, lim)) {
return acc;
}
}
gdouble
-rspamd_process_expression_track (struct rspamd_expression *expr, gint flags,
- gpointer data, GPtrArray *track)
+rspamd_process_expression_track (struct rspamd_expression *expr, struct rspamd_expr_process_data *process_data)
{
gdouble ret = 0;
/* Ensure that stack is empty at this point */
g_assert (expr->expression_stack->len == 0);
- ret = rspamd_ast_process_node (expr, flags, expr->ast, data, track);
+ ret = rspamd_ast_process_node (expr, expr->ast, process_data);
/* Cleanup */
g_node_traverse (expr->ast, G_IN_ORDER, G_TRAVERSE_ALL, -1,
}
gdouble
-rspamd_process_expression (struct rspamd_expression *expr, gint flags,
- gpointer data)
+rspamd_process_expression (struct rspamd_expression *expr, struct rspamd_expr_process_data *process_data)
{
- return rspamd_process_expression_track (expr, flags, data, NULL);
+ return rspamd_process_expression_track (expr, process_data);
}
static gboolean
gint priority;
} rspamd_expression_atom_t;
+struct rspamd_expr_process_data {
+ /* Current Lua state to run atom processing */
+ struct lua_State *L;
+ /* Parameter of lua-function processing atom*/
+ gint stack_item;
+ gint flags;
+ /* != NULL if trace is collected */
+ GPtrArray *trace;
+ struct composites_data *cd;
+ struct rspamd_task *task;
+};
+
struct rspamd_atom_subr {
/* Parses atom from string and returns atom structure */
rspamd_expression_atom_t * (*parse)(const gchar *line, gsize len,
rspamd_mempool_t *pool, gpointer ud, GError **err);
/* Process atom via the opaque pointer (e.g. struct rspamd_task *) */
- gdouble (*process) (gpointer input, rspamd_expression_atom_t *atom);
+ gdouble (*process) (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom);
/* Calculates the relative priority of the expression */
gint (*priority) (rspamd_expression_atom_t *atom);
void (*destroy) (rspamd_expression_atom_t *atom);
* @param data opaque data pointer for all the atoms
* @return the value of expression
*/
-gdouble rspamd_process_expression (struct rspamd_expression *expr, gint flags,
- gpointer data);
+gdouble rspamd_process_expression (struct rspamd_expression *expr,
+ struct rspamd_expr_process_data *process_data);
/**
* Process the expression and return its value using atom 'process' functions with the specified data pointer.
* @param track pointer array to atoms tracking
* @return the value of expression
*/
-gdouble rspamd_process_expression_track (struct rspamd_expression *expr, gint flags,
- gpointer data, GPtrArray *track);
+gdouble rspamd_process_expression_track (struct rspamd_expression *expr,
+ struct rspamd_expr_process_data *process_data);
/**
* Shows string representation of an expression
static rspamd_expression_atom_t * lua_atom_parse (const gchar *line, gsize len,
rspamd_mempool_t *pool, gpointer ud, GError **err);
-static gdouble lua_atom_process (gpointer input, rspamd_expression_atom_t *atom);
+static gdouble lua_atom_process (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom);
static const struct rspamd_atom_subr lua_atom_subr = {
.parse = lua_atom_parse,
}
static gdouble
-lua_atom_process (gpointer input, rspamd_expression_atom_t *atom)
+lua_atom_process (struct rspamd_expr_process_data *process_data, rspamd_expression_atom_t *atom)
{
struct lua_expression *e = (struct lua_expression *)atom->data;
gdouble ret = 0;
- lua_rawgeti (e->L, LUA_REGISTRYINDEX, e->process_idx);
- lua_pushlstring (e->L, atom->str, atom->len);
- lua_pushvalue (e->L, GPOINTER_TO_INT (input));
+ lua_rawgeti (process_data->L, LUA_REGISTRYINDEX, e->process_idx);
+ lua_pushlstring (process_data->L, atom->str, atom->len);
+ lua_pushvalue (process_data->L, process_data->stack_item);
- if (lua_pcall (e->L, 2, 1, 0) != 0) {
- msg_info ("callback call failed: %s", lua_tostring (e->L, -1));
- lua_pop (e->L, 1);
+ if (lua_pcall (process_data->L, 2, 1, 0) != 0) {
+ msg_info ("callback call failed: %s", lua_tostring (process_data->L, -1));
+ lua_pop (process_data->L, 1);
}
else {
- ret = lua_tonumber (e->L, -1);
- lua_pop (e->L, 1);
+ ret = lua_tonumber (process_data->L, -1);
+ lua_pop (process_data->L, 1);
}
return ret;
gdouble res;
gint flags = 0;
+ struct rspamd_expr_process_data process_data;
+ memset (&process_data, 0, sizeof process_data);
+ process_data.L = L;
+ process_data.stack_item = 2;
+
if (lua_gettop (L) >= 3) {
- flags = lua_tonumber (L, 3);
+ process_data.flags = flags;
}
- res = rspamd_process_expression (e->expr, flags, GINT_TO_POINTER (2));
+ res = rspamd_process_expression (e->expr, &process_data);
lua_pushnumber (L, res);
rspamd_expression_atom_t *atom;
gint res;
guint i;
- gint flags = 0;
- GPtrArray *trace;
+ struct rspamd_expr_process_data process_data;
+ memset (&process_data, 0, sizeof process_data);
+
+ process_data.L = L;
+ /*
+ * stack:1 - self
+ * stack:2 - data, see process_traced() definition for details
+ */
+ process_data.stack_item = 2;
if (lua_gettop (L) >= 3) {
- flags = lua_tonumber (L, 3);
+ process_data.flags = lua_tonumber (L, 3);
}
- trace = g_ptr_array_sized_new (32);
- res = rspamd_process_expression_track (e->expr, flags, GINT_TO_POINTER (2),
- trace);
+ process_data.trace = g_ptr_array_sized_new (32);
+
+ res = rspamd_process_expression_track (e->expr, &process_data);
lua_pushnumber (L, res);
- lua_createtable (L, trace->len, 0);
+ lua_createtable (L, process_data.trace->len, 0);
- for (i = 0; i < trace->len; i ++) {
- atom = g_ptr_array_index (trace, i);
+ for (i = 0; i < process_data.trace->len; i ++) {
+ atom = g_ptr_array_index (process_data.trace, i);
lua_pushlstring (L, atom->str, atom->len);
lua_rawseti (L, -2, i + 1);
}
- g_ptr_array_free (trace, TRUE);
+ g_ptr_array_free (process_data.trace, TRUE);
return 2;
}
else {
/* Process expression */
if (item->expr) {
- res = rspamd_process_expression (item->expr, 0, task);
+ struct rspamd_expr_process_data process_data;
+ memset (&process_data, 0, sizeof process_data);
+
+ process_data.task = task;
+
+ res = rspamd_process_expression (item->expr, &process_data);
}
else {
msg_warn_task ("FIXME: %s symbol is broken with new expressions",