]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Use common initializer for undefined variables and eattrs. mq-func-types
authorOndrej Zajicek <santiago@crfreenet.org>
Wed, 13 Sep 2023 04:21:26 +0000 (06:21 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Wed, 13 Sep 2023 04:21:26 +0000 (06:21 +0200)
Undefined paths and clists should use typed f_val with empty adata
instead of just void f_val. Use common initializer to handle both
variables and eattrs.

filter/config.Y
filter/data.h
filter/f-inst.c

index dc4d75eded9fe9868870a119e331a8e816eabb4a..a87fb0e5ff93dfb02cf478102380071872ee6f43 100644 (file)
@@ -244,23 +244,6 @@ f_new_lc_item(u32 f1, u32 t1, u32 f2, u32 t2, u32 f3, u32 t3)
   return t;
 }
 
-static inline struct f_inst *
-f_const_empty(enum f_type t)
-{
-  switch (t) {
-    case T_PATH:
-    case T_CLIST:
-    case T_ECLIST:
-    case T_LCLIST:
-      return f_new_inst(FI_CONSTANT, (struct f_val) {
-       .type = t,
-       .val.ad = &null_adata,
-      });
-    default:
-      return f_new_inst(FI_CONSTANT, (struct f_val) {});
-  }
-}
-
 /*
  * Remove all new lines and doubled whitespaces
  * and convert all tabulators to spaces
@@ -914,11 +897,12 @@ term:
 
  | term_dot_method
 
- | '+' EMPTY '+' { $$ = f_const_empty(T_PATH); }
- | '-' EMPTY '-' { $$ = f_const_empty(T_CLIST); }
- | '-' '-' EMPTY '-' '-' { $$ = f_const_empty(T_ECLIST); }
- | '-' '-' '-' EMPTY '-' '-' '-' { $$ = f_const_empty(T_LCLIST); }
- | PREPEND '(' term ',' term ')' { $$ = f_dispatch_method_x("prepend", $3->type, $3, $5); }
+ | '+' EMPTY '+' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_PATH)); }
+ | '-' EMPTY '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_CLIST)); }
+ | '-' '-' EMPTY '-' '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_ECLIST)); }
+ | '-' '-' '-' EMPTY '-' '-' '-' { $$ = f_new_inst(FI_CONSTANT, val_empty(T_LCLIST)); }
+
+| PREPEND '(' term ',' term ')' { $$ = f_dispatch_method_x("prepend", $3->type, $3, $5); }
  | ADD '(' term ',' term ')' { $$ = f_dispatch_method_x("add", $3->type, $3, $5); }
  | DELETE '(' term ',' term ')' { $$ = f_dispatch_method_x("delete", $3->type, $3, $5); }
  | FILTER '(' term ',' term ')' { $$ = f_dispatch_method_x("filter", $3->type, $3, $5); }
index 6420d37337d6091409afa21cac937a3b1b90bd0e..574b4a1bafa34f89f58a0f54e9415f40c372b97a 100644 (file)
@@ -318,14 +318,32 @@ const struct adata *lclist_filter(struct linpool *pool, const struct adata *list
 
 
 /* Special undef value for paths and clists */
+
 static inline int
-undef_value(struct f_val v)
+val_is_undefined(struct f_val v)
 {
   return ((v.type == T_PATH) || (v.type == T_CLIST) ||
          (v.type == T_ECLIST) || (v.type == T_LCLIST)) &&
     (v.val.ad == &null_adata);
 }
 
+static inline struct f_val
+val_empty(enum f_type t)
+{
+  switch (t)
+  {
+  case T_PATH:
+  case T_CLIST:
+  case T_ECLIST:
+  case T_LCLIST:
+    return (struct f_val) { .type = t, .val.ad = &null_adata };
+
+  default:
+    return (struct f_val) { };
+  }
+}
+
+
 extern const struct f_val f_const_empty_prefix_set;
 
 enum filter_return f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres);
index f24e6219f325d6b4edb74e775de62d58b18fac26..104a05f1a1ae85025d9cba0f289e8d88d7c53058 100644 (file)
 
   INST(FI_DEFINED, 1, 1) {
     ARG_ANY(1);
-    RESULT(T_BOOL, i, (v1.type != T_VOID) && !undef_value(v1));
+    RESULT(T_BOOL, i, (v1.type != T_VOID) && !val_is_undefined(v1));
   }
 
   METHOD_R(T_NET, type, T_ENUM_NETTYPE, i, v1.val.net->type);
 
     /* New variable is always the last on stack */
     uint pos = curline.vbase + sym->offset;
-    fstk->vstk[pos] = (struct f_val) { };
+    fstk->vstk[pos] = val_empty(sym->class & 0xff);
     fstk->vcnt = pos + 1;
   }
 
       eattr *e = ea_find(*fs->eattrs, da.ea_code);
 
       if (!e) {
-       /* A special case: undefined as_path looks like empty as_path */
-       if (da.type == EAF_TYPE_AS_PATH) {
-         RESULT_(T_PATH, ad, &null_adata);
-         break;
-       }
-
-       /* The same special case for int_set */
-       if (da.type == EAF_TYPE_INT_SET) {
-         RESULT_(T_CLIST, ad, &null_adata);
-         break;
-       }
-
-       /* The same special case for ec_set */
-       if (da.type == EAF_TYPE_EC_SET) {
-         RESULT_(T_ECLIST, ad, &null_adata);
-         break;
-       }
-
-       /* The same special case for lc_set */
-       if (da.type == EAF_TYPE_LC_SET) {
-         RESULT_(T_LCLIST, ad, &null_adata);
-         break;
-       }
-
-       /* Undefined value */
-       RESULT_VOID;
+       RESULT_VAL(val_empty(da.f_type));
        break;
       }