return res;
}
-static gint
+static gdouble
rspamd_composite_process_single_symbol (struct composites_data *cd,
const gchar *sym, struct rspamd_symbol_result **pms)
{
struct rspamd_symbol_result *ms = NULL;
- gint rc = 0;
+ gdouble rc = 0;
struct rspamd_composite *ncomp;
if ((ms = g_hash_table_lookup (cd->metric_res->symbols, sym)) == NULL) {
RSPAMD_EXPRESSION_FLAG_NOOPT, cd);
clrbit (cd->checked, cd->composite->id * 2);
- if (rc) {
+ if (rc != 0) {
setbit (cd->checked, ncomp->id * 2 + 1);
ms = g_hash_table_lookup (cd->metric_res->symbols, sym);
}
/*
* XXX: in case of cyclic references this would return 0
*/
- rc = isset (cd->checked, ncomp->id * 2 + 1);
+ if (isset (cd->checked, ncomp->id * 2 + 1)) {
+ ms = g_hash_table_lookup (cd->metric_res->symbols, sym);
+ }
}
}
}
- else {
- rc = 1;
+
+ if (ms) {
+ if (ms->score == 0) {
+ rc = 0.001; /* Distinguish from 0 */
+ }
+ else {
+ rc = ms->score;
+ }
}
*pms = ms;
struct rspamd_symbol *sdef;
GHashTableIter it;
gpointer k, v;
- gint rc = 0;
+ gdouble rc = 0;
if (isset (cd->checked, cd->composite->id * 2)) {
/* We have already checked this composite, so just return its value */
- rc = isset (cd->checked, cd->composite->id * 2 + 1);
+ if (isset (cd->checked, cd->composite->id * 2 + 1)) {
+ ms = g_hash_table_lookup (cd->metric_res->symbols, sym);
+ }
+
+ if (ms) {
+ if (ms->score == 0) {
+ rc = 0.001; /* Distinguish from 0 */
+ }
+ else {
+ rc = ms->score;
+ }
+ }
+
return rc;
}
rc = rspamd_composite_process_single_symbol (cd, sym, &ms);
}
- if (rc && ms) {
+ if (rc != 0 && ms) {
/*
* At this point we know that we need to do something about this symbol,
* however, we don't know whether we need to delete it unfortunately,
union {
rspamd_expression_atom_t *atom;
enum rspamd_expression_op op;
- struct {
- gint val;
- gint op_idx;
- } lim;
+ gdouble lim;
} p;
+
gint flags;
- gdouble value;
gint priority;
+ gdouble value;
};
struct rspamd_expression {
}
memset (&elt, 0, sizeof (elt));
- num_re = rspamd_regexp_cache_create (NULL, "/^\\d+(?:\\s+|[)]|$)/", NULL, NULL);
+ num_re = rspamd_regexp_cache_create (NULL,
+ "/^(?:[+-]?([0-9]*[.])?[0-9]+)(?:\\s+|[)]|$)/", NULL, NULL);
p = line;
c = line;
}
break;
case PARSE_LIM:
- if (g_ascii_isdigit (*p) && p != end - 1) {
+ if ((g_ascii_isdigit (*p) || *p == '-' || *p == '.')
+ && p < end - 1) {
p ++;
}
else {
if (p - c > 0) {
elt.type = ELT_LIMIT;
- elt.p.lim.val = strtoul (c, NULL, 10);
+ elt.p.lim = strtod (c, NULL);
g_array_append_val (e->expressions, elt);
rspamd_expr_stack_elt_push (operand_stack,
g_node_new (rspamd_expr_dup_elt (pool, &elt)));
break;
case ELT_LIMIT:
- acc = elt->p.lim.val;
+ acc = elt->p.lim;
break;
case ELT_OP:
g_assert (node->children != NULL);
celt = node->parent->children->data;
if (celt->type == ELT_LIMIT) {
- lim = celt->p.lim.val;
+ lim = celt->p.lim;
}
}
/* Save limit if we've found it */
if (celt->type == ELT_LIMIT) {
- lim = celt->p.lim.val;
+ lim = celt->p.lim;
continue;
}
(int)elt->p.atom->len, elt->p.atom->str);
}
else if (elt->type == ELT_LIMIT) {
- rspamd_printf_gstring (res, "%d", elt->p.lim.val);
+ rspamd_printf_gstring (res, "%f", elt->p.lim);
}
else {
op_str = rspamd_expr_op_to_str (elt->p.op);