[PATCH 03/12] Introduce and use val_same() to decide if values are same or not
Sergey Popovich
popovich_sergei at mail.ru
Mon Sep 30 20:27:24 CEST 2013
val_same() compares passed @v1 and @v2 and returns 1 if they are
same, 0 if not and 999 in case their types not comparable.
Change pm_path_compare() to return 1 - if @m1 and @m2 are the same and
0 overwise. Rename pm_path_compare() to pm_path_same() according to its
return values. Use it in val_same() to compare path masks.
---
filter/filter.c | 102
+++++++++++++++++++++++++++++--------------------------
filter/filter.h | 1 +
2 files changed, 54 insertions(+), 49 deletions(-)
diff --git a/filter/filter.c b/filter/filter.c
index 6f59193..c089d94 100644
--- a/filter/filter.c
+++ b/filter/filter.c
@@ -58,20 +58,6 @@ adata_empty(struct linpool *pool, int l)
return res;
}
-static int
-pm_path_compare(struct f_path_mask *m1, struct f_path_mask *m2)
-{
- while (1) {
- if ((!m1) || (!m2))
- return !((!m1) && (!m2));
-
- /* FIXME: buggy, should return -1, 0, 1; but it doesn't matter */
- if ((m1->kind != m2->kind) || (m1->val != m2->val)) return 1;
- m1 = m1->next;
- m2 = m2->next;
- }
-}
-
u32 f_eval_asn(struct f_inst *expr);
static void
@@ -247,8 +233,6 @@ val_compare(struct f_val v1, struct f_val v2)
if (rc = ipa_compare(v1.val.px.ip, v2.val.px.ip))
return rc;
return int_cmp(v1.val.px.len, v2.val.px.len);
- case T_PATH_MASK:
- return pm_path_compare(v1.val.path_mask, v2.val.path_mask);
case T_STRING:
return strcmp(v1.val.s, v2.val.s);
case T_CLIST:
@@ -259,7 +243,50 @@ val_compare(struct f_val v1, struct f_val v2)
case T_VOID:
return 0;
default:
- debug( "Compare of unknown entities: %x\n", v1.type );
+ return CMP_ERROR;
+ }
+}
+
+static int
+pm_path_same(struct f_path_mask *m1, struct f_path_mask *m2)
+{
+ while (1) {
+ if ((!m1) || (!m2))
+ return (!m1) && (!m2);
+
+ if ((m1->kind != m2->kind) || (m1->val != m2->val))
+ return 0;
+
+ m1 = m1->next;
+ m2 = m2->next;
+ }
+}
+
+/**
+ * val_same - compare two values
+ * @v1: first value
+ * @v2: second value
+ *
+ * Compares two values and returns 1 if they are same, 0 if not
+ * and 999 on error.
+ */
+int
+val_same(struct f_val v1, struct f_val v2)
+{
+ int rc;
+
+ rc = val_compare(v1, v2);
+ if (rc != CMP_ERROR)
+ return !rc;
+
+ switch (v1.type) {
+ case T_PATH_MASK:
+ return pm_path_same(v1.val.path_mask, v2.val.path_mask);
+ case T_SET:
+ return same_tree(v1.val.t, v2.val.t);
+ case T_PREFIX_SET:
+ return trie_same(v1.val.ti, v2.val.ti);
+ default:
return CMP_ERROR;
}
}
@@ -776,19 +803,19 @@ interpret(struct f_inst *what)
/* Relational operators */
-#define COMPARE(x) \
+#define COMPARE(f,x) \
TWOARGS; \
- i = val_compare(v1, v2); \
- if (i==CMP_ERROR) \
+ i = f(v1, v2); \
+ if (i == CMP_ERROR) \
runtime( "Can't compare values of incompatible types" ); \
res.type = T_BOOL; \
res.val.i = (x); \
break;
- case P('!','='): COMPARE(i!=0);
- case P('=','='): COMPARE(i==0);
- case '<': COMPARE(i==-1);
- case P('<','='): COMPARE(i!=1);
+ case P('!','='): COMPARE(val_same, i == 0);
+ case P('=','='): COMPARE(val_same, i != 0);
+ case '<': COMPARE(val_compare, i < 0);
+ case P('<','='): COMPARE(val_compare, i <= 0);
case '!':
ONEARG;
@@ -1478,31 +1505,8 @@ i_same(struct f_inst *f1, struct f_inst *f2)
}
break;
case 'C': - {
- struct f_val *v1 = (struct f_val *) f1->a1.p;
- struct f_val *v2 = (struct f_val *) f2->a1.p;
-
- /* Handle some cases that are not handled by val_compare()
- also T_PATH, T_CLIST and T_ECLIST does not work,
- but you cannot easily create such constants */
-
- if ((v1->type == T_SET) && (v2->type == T_SET))
- {
- if (!same_tree(v1->val.t, v2->val.t))
- return 0;
- break;
- }
-
- if ((v1->type == T_PREFIX_SET) && (v2->type == T_PREFIX_SET))
- {
- if (!trie_same(v1->val.ti, v2->val.ti))
- return 0;
- break;
- }
-
- if (val_compare(*v1 , *v2))
- return 0;
- }
+ if (!val_same(* (struct f_val *) f1->a1.p, * (struct f_val *)
f2->a1.p))
+ return 0;
break;
case 'V': if (strcmp((char *) f1->a2.p, (char *) f2->a2.p))
diff --git a/filter/filter.h b/filter/filter.h
index dcac825..a3de530 100644
--- a/filter/filter.h
+++ b/filter/filter.h
@@ -116,6 +116,7 @@ int filter_same(struct filter *new, struct filter *old);
int i_same(struct f_inst *f1, struct f_inst *f2);
int val_compare(struct f_val v1, struct f_val v2);
+int val_same(struct f_val v1, struct f_val v2);
int tree_compare(const void *p1, const void *p2);
void val_print(struct f_val v);
--
1.7.10.4
More information about the Bird-users
mailing list