]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add fr_value_calc_list_cmp()
authorAlan T. DeKok <aland@freeradius.org>
Mon, 11 Jul 2022 20:43:45 +0000 (16:43 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 14 Jul 2022 14:04:00 +0000 (10:04 -0400)
which is O(N^2), and implements v3 functionality.

We arguably need a real list comparison, which checks each member
for equality

src/lib/util/calc.c
src/lib/util/calc.h

index bbe464874c6e6b2c5e1ed351f047ae7873edd5fb..57993f42d054e3fc8283f04870de9c83843041a1 100644 (file)
@@ -2177,3 +2177,54 @@ brute_force:
 
        return 0;
 }
+
+
+/*
+ *     Loop over input lists, calling fr_value_calc_binary_op()
+ *
+ *     This implementation is arguably wrong... it should be checking individual entries in list1 against individual entries in list2.
+ *     Instead, it checks if ANY entry in list1 matches ANY entry in list2.
+ */
+int fr_value_calc_list_cmp(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_list_t const *list1, fr_token_t op, fr_value_box_list_t const *list2)
+{
+       int rcode;
+       bool invert = false;
+
+       /*
+        *      v3 hack.  != really means !( ... == ... )
+        */
+       if (op == T_OP_NE) {
+               invert = true;
+               op = T_OP_CMP_EQ;
+       }
+
+       /*
+        *      Emulate v3.  :(
+        */
+       fr_dlist_foreach(list1, fr_value_box_t, a) {
+               fr_dlist_foreach(list2, fr_value_box_t, b) {
+                       rcode = fr_value_calc_binary_op(ctx, dst, FR_TYPE_BOOL, a, op, b);
+                       if (rcode < 0) return rcode;
+
+                       /*
+                        *      No match: keep looking for a match.
+                        */
+                       fr_assert(dst->type == FR_TYPE_BOOL);
+                       if (!dst->vb_bool) continue;
+
+                       /*
+                        *      Found a match, we're done.
+                        */
+                       dst->vb_bool = !invert;
+                       return 0;
+               }
+       }
+
+       /*
+        *      No match.
+        */
+       fr_value_box_clear(dst);
+       fr_value_box_init(dst, FR_TYPE_BOOL, NULL, false); // @todo - add enum!
+       dst->vb_bool = invert;
+       return 0;
+}
index f25ff809002945424ca033c6f6c95d6aa959a854..a28fb0c5e42fb13bf15c889bf43dd04133d84a7a 100644 (file)
@@ -40,6 +40,8 @@ int fr_value_calc_unary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op,
 
 int fr_value_calc_list_op(TALLOC_CTX *ctx, fr_value_box_t *box, fr_token_t op, fr_value_box_list_t const *list);
 
+int fr_value_calc_list_cmp(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_list_t const *list1, fr_token_t op, fr_value_box_list_t const *list2) CC_HINT(nonnull);
+
 #ifdef __cplusplus
 }
 #endif