From 3bf56226d69538dce4b2dca0d5ca5fbc21e0a650 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 25 May 2012 16:47:14 +0300 Subject: [PATCH] constraints: replace get_common_relationship() with get_shared_relations() The get_common_relationship() was a crap API. It was used to join to lists so it should have taken lists as arguments. Signed-off-by: Dan Carpenter --- smatch_constraints.c | 62 +++++++++++++++++++++++++++++++++++++++++----------- smatch_extra.c | 9 ++------ smatch_extra.h | 4 ++-- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/smatch_constraints.c b/smatch_constraints.c index 34e12085..badecaad 100644 --- a/smatch_constraints.c +++ b/smatch_constraints.c @@ -105,21 +105,57 @@ struct related_list *clone_related_list(struct related_list *related) return to_list; } -struct relation *get_common_relationship(struct smatch_state *state, int op, - const char *name, struct symbol *sym) +static int cmp_relation(struct relation *a, struct relation *b) { - struct relation *tmp; + int ret; - // FIXME... - // Find the common x < y and x <= y - FOR_EACH_PTR(estate_related(state), tmp) { - if (tmp->op < op || tmp->sym < sym || strcmp(tmp->name, name) < 0) - continue; - if (tmp->op == op && tmp->sym == sym && !strcmp(tmp->name, name)) - return tmp; - return NULL; - } END_FOR_EACH_PTR(tmp); - return NULL; + if (a == b) + return 0; + + if (a->op > b->op) + return -1; + if (a->op < b->op) + return 1; + + if (a->sym > b->sym) + return -1; + if (a->sym < b->sym) + return 1; + + ret = strcmp(a->name, b->name); + if (ret) + return ret; + + return 0; + +} + +struct related_list *get_shared_relations(struct related_list *one, + struct related_list *two) +{ + struct related_list *ret = NULL; + struct relation *one_rel; + struct relation *two_rel; + + PREPARE_PTR_LIST(one, one_rel); + PREPARE_PTR_LIST(two, two_rel); + for (;;) { + if (!one_rel || !two_rel) + break; + if (cmp_relation(one_rel, two_rel) < 0) { + NEXT_PTR_LIST(one_rel); + } else if (cmp_relation(one_rel, two_rel) == 0) { + add_ptr_list(&ret, one_rel); + NEXT_PTR_LIST(one_rel); + NEXT_PTR_LIST(two_rel); + } else { + NEXT_PTR_LIST(two_rel); + } + } + FINISH_PTR_LIST(two_rel); + FINISH_PTR_LIST(one_rel); + + return ret; } static void debug_addition(struct smatch_state *state, int op, const char *name) diff --git a/smatch_extra.c b/smatch_extra.c index c3ce6f4d..cc45ead3 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -150,16 +150,11 @@ static struct smatch_state *merge_func(const char *name, struct symbol *sym, { struct smatch_state *tmp; struct range_list *value_ranges; - struct relation *rel; - struct relation *new; value_ranges = range_list_union(estate_ranges(s1), estate_ranges(s2)); tmp = alloc_estate_range_list(value_ranges); - FOR_EACH_PTR(estate_related(s1), rel) { - new = get_common_relationship(s2, rel->op, rel->name, rel->sym); - if (new) - add_related(tmp, new->op, new->name, new->sym); - } END_FOR_EACH_PTR(rel); + get_dinfo(tmp)->related = get_shared_relations(estate_related(s1), + estate_related(s2)); return tmp; } diff --git a/smatch_extra.h b/smatch_extra.h index f85d5852..aeda2ddd 100644 --- a/smatch_extra.h +++ b/smatch_extra.h @@ -110,8 +110,8 @@ struct expression *value_expr(long long val); /* implemented in smatch_constraints */ void set_equiv(struct expression *left, struct expression *right); -struct relation *get_common_relationship(struct smatch_state *estate, int op, - const char *name, struct symbol *sym); +struct related_list *get_shared_relations(struct related_list *one, + struct related_list *two); struct related_list *clone_related_list(struct related_list *related); void add_related(struct smatch_state *state, int op, const char *name, struct symbol *sym); void add_equiv(struct smatch_state *state, const char *name, struct symbol *sym); -- 2.11.4.GIT