diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2011-06-26 17:09:24 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2011-06-26 17:09:24 +0200 |
commit | e08d2ff08e4cff4bec38878e084fee7666caaaf2 (patch) | |
tree | ce71db48fcc7062dbe38a117faa69e4a53ba37e7 /filter/filter.c | |
parent | 35f8c731ea29bd534c74b2d0de089d5683ebcd8d (diff) |
Adds filter clist operation.
Diffstat (limited to 'filter/filter.c')
-rw-r--r-- | filter/filter.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/filter/filter.c b/filter/filter.c index b8044293..913bd086 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -279,7 +279,7 @@ clist_match_set(struct adata *clist, struct f_tree *set) } static struct adata * -clist_del_matching(struct linpool *pool, struct adata *clist, struct f_tree *set) +clist_filter(struct linpool *pool, struct adata *clist, struct f_tree *set, int pos) { if (!clist) return NULL; @@ -294,7 +294,7 @@ clist_del_matching(struct linpool *pool, struct adata *clist, struct f_tree *set while (l < end) { v.val.i = *l++; - if (!find_tree(set, v)) + if (pos == !!find_tree(set, v)) /* pos && find_tree || !pos && !find_tree */ *k++ = v.val.i; } @@ -945,7 +945,7 @@ interpret(struct f_inst *what) runtime("Can't add/delete to non-clist"); struct f_val dummy; - u16 op = what->aux; + int arg_set = 0; i = 0; if ((v2.type == T_PAIR) || (v2.type == T_QUAD)) @@ -955,17 +955,35 @@ interpret(struct f_inst *what) else if (v2.type == T_IP) i = ipa_to_u32(v2.val.px.ip); #endif - else if ((v2.type == T_SET) && (op == 'd') && clist_set_type(v2.val.t, &dummy)) - op = 'D'; + else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy)) + arg_set = 1; else runtime("Can't add/delete non-pair"); res.type = T_CLIST; - switch (op) { - case 'a': res.val.ad = int_set_add(f_pool, v1.val.ad, i); break; - case 'd': res.val.ad = int_set_del(f_pool, v1.val.ad, i); break; - case 'D': res.val.ad = clist_del_matching(f_pool, v1.val.ad, v2.val.t); break; - default: bug("unknown Ca operation"); + switch (what->aux) + { + case 'a': + if (arg_set) + runtime("Can't add set"); + res.val.ad = int_set_add(f_pool, v1.val.ad, i); + break; + + case 'd': + if (!arg_set) + res.val.ad = int_set_del(f_pool, v1.val.ad, i); + else + res.val.ad = clist_filter(f_pool, v1.val.ad, v2.val.t, 0); + break; + + case 'f': + if (!arg_set) + runtime("Can't filter pair"); + res.val.ad = clist_filter(f_pool, v1.val.ad, v2.val.t, 1); + break; + + default: + bug("unknown Ca operation"); } break; |