summaryrefslogtreecommitdiffstats
path: root/src/segtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/segtree.c')
-rw-r--r--src/segtree.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/src/segtree.c b/src/segtree.c
index 353a0053..a4e047e7 100644
--- a/src/segtree.c
+++ b/src/segtree.c
@@ -618,10 +618,27 @@ int set_to_intervals(struct list_head *errs, struct set *set,
struct expr *init, bool add, unsigned int debug_mask,
bool merge, struct output_ctx *octx)
{
+ struct expr *catchall = NULL, *i, *in, *key;
struct elementary_interval *ei, *next;
struct seg_tree tree;
LIST_HEAD(list);
+ list_for_each_entry_safe(i, in, &init->expressions, list) {
+ if (i->etype == EXPR_MAPPING)
+ key = i->left->key;
+ else if (i->etype == EXPR_SET_ELEM)
+ key = i->key;
+ else
+ continue;
+
+ if (key->etype == EXPR_SET_ELEM_CATCHALL) {
+ init->size--;
+ catchall = i;
+ list_del(&i->list);
+ break;
+ }
+ }
+
seg_tree_init(&tree, set, init, debug_mask);
if (set_to_segtree(errs, set, init, &tree, add, merge) < 0)
return -1;
@@ -643,6 +660,11 @@ int set_to_intervals(struct list_head *errs, struct set *set,
pr_gmp_debug("\n");
}
+ if (catchall) {
+ list_add_tail(&catchall->list, &init->expressions);
+ init->size++;
+ }
+
return 0;
}
@@ -682,6 +704,9 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init)
i->flags |= EXPR_F_INTERVAL_END;
compound_expr_add(new_init, expr_clone(i));
break;
+ case EXPR_SET_ELEM_CATCHALL:
+ compound_expr_add(new_init, expr_clone(i));
+ break;
default:
range_expr_value_low(low, i);
set_elem_add(set, new_init, low, 0, i->byteorder);
@@ -941,8 +966,8 @@ next:
void interval_map_decompose(struct expr *set)
{
+ struct expr *i, *next, *low = NULL, *end, *catchall = NULL, *key;
struct expr **elements, **ranges;
- struct expr *i, *next, *low = NULL, *end;
unsigned int n, m, size;
mpz_t range, p;
bool interval;
@@ -959,6 +984,17 @@ void interval_map_decompose(struct expr *set)
/* Sort elements */
n = 0;
list_for_each_entry_safe(i, next, &set->expressions, list) {
+ key = NULL;
+ if (i->etype == EXPR_SET_ELEM)
+ key = i->key;
+ else if (i->etype == EXPR_MAPPING)
+ key = i->left->key;
+
+ if (key && key->etype == EXPR_SET_ELEM_CATCHALL) {
+ list_del(&i->list);
+ catchall = i;
+ continue;
+ }
compound_expr_remove(set, i);
elements[n++] = i;
}
@@ -1094,6 +1130,9 @@ void interval_map_decompose(struct expr *set)
compound_expr_add(set, i);
out:
+ if (catchall)
+ compound_expr_add(set, catchall);
+
mpz_clear(range);
mpz_clear(p);