]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Use more generic approach for intra-config expressions
authorAlexander Zubkov <green@qrator.net>
Thu, 24 Aug 2023 02:45:55 +0000 (04:45 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 24 Aug 2023 02:45:55 +0000 (04:45 +0200)
Replace f_eval_int() function with a type-generic variant: cf_eval().
Implement similar fuction: cf_eval_int() via inline call to cf_eval().

conf/confbase.Y
filter/config.Y
filter/filter.c
filter/filter.h
nest/config.Y

index da750d38164148c1911c106ae44ec57c5391c8d1..e109ddf5a802421e35576ae507e3b8dcf95fb438 100644 (file)
@@ -155,14 +155,14 @@ conf: definition ;
 definition:
    DEFINE symbol '=' term ';' {
      struct f_val *val = cfg_allocz(sizeof(struct f_val));
-     if (f_eval(f_linearize($4, 1), cfg_mem, val) > F_RETURN) cf_error("Runtime error");
+     *val = cf_eval($4, T_VOID);
      cf_define_symbol($2, SYM_CONSTANT | val->type, val, val);
    }
  ;
 
 expr:
    NUM
- | '(' term ')' { $$ = f_eval_int(f_linearize($2, 1)); }
+ | '(' term ')' { $$ = cf_eval_int($2); }
  | CF_SYM_KNOWN {
      if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number constant expected");
      $$ = SYM_VAL($1).i; }
index e2d133a9165b7816c813cce44a6231f292dae114..2a298843fd192a302f21267585c3b37d6b13a910 100644 (file)
@@ -358,7 +358,7 @@ filter_def:
 
 conf: filter_eval ;
 filter_eval:
-   EVAL term { f_eval_int(f_linearize($2, 1)); }
+   EVAL term { cf_eval_int($2); }
  ;
 
 conf: custom_attr ;
@@ -573,7 +573,7 @@ set_atom:
  | VPN_RD { $$.type = T_RD; $$.val.ec = $1; }
  | ENUM   { $$.type = pair_a($1); $$.val.i = pair_b($1); }
  | '(' term ')' {
-     if (f_eval(f_linearize($2, 1), cfg_mem, &($$)) > F_RETURN) cf_error("Runtime error");
+     $$ = cf_eval($2, T_VOID);
      if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
    }
  | CF_SYM_KNOWN {
@@ -585,13 +585,13 @@ set_atom:
 
 switch_atom:
    NUM   { $$.type = T_INT; $$.val.i = $1; }
- | '(' term ')' { $$.type = T_INT; $$.val.i = f_eval_int(f_linearize($2, 1)); }
+ | '(' term ')' { $$ = cf_eval($2, T_INT); }
  | fipa  { $$ = $1; }
  | ENUM  { $$.type = pair_a($1); $$.val.i = pair_b($1); }
  ;
 
 cnum:
-   term { $$ = f_eval_int(f_linearize($1, 1)); }
+   term { $$ = cf_eval_int($1); }
 
 pair_item:
    '(' cnum ',' cnum ')'               { $$ = f_new_pair_item($2, $2, $4, $4); }
index 20a380dc0a29f48ada71bdc8db4b989a364a43f4..d080cadcf747244e21a74e1ed986c191983b1310 100644 (file)
@@ -373,30 +373,22 @@ f_eval(const struct f_line *expr, struct linpool *tmp_pool, struct f_val *pres)
 }
 
 /*
- * f_eval_int - get an integer value of a term
+ * cf_eval - evaluate a value of a term and check its type
  * Called internally from the config parser, uses its internal memory pool
  * for allocations. Do not call in other cases.
  */
-uint
-f_eval_int(const struct f_line *expr)
+struct f_val
+cf_eval(const struct f_inst *inst, int type)
 {
-  /* Called independently in parse-time to eval expressions */
-  filter_state = (struct filter_state) {
-    .stack = &filter_stack,
-    .pool = cfg_mem,
-  };
-
   struct f_val val;
 
-  LOG_BUFFER_INIT(filter_state.buf);
-
-  if (interpret(&filter_state, expr, &val) > F_RETURN)
+  if (f_eval(f_linearize(inst, 1), cfg_mem, &val) > F_RETURN)
     cf_error("Runtime error while evaluating expression; see log for details");
 
-  if (val.type != T_INT)
-    cf_error("Integer expression expected");
+  if (type != T_VOID && val.type != type)
+    cf_error("Expression of type %s expected", f_type_name(type));
 
-  return val.val.i;
+  return val;
 }
 
 /*
index 26c1037b71f815491019220636cd4222e0096861..91de696cfd7be9a6a42e853f45e80be510a605d4 100644 (file)
@@ -15,6 +15,7 @@
 #include "lib/macro.h"
 #include "nest/route.h"
 #include "nest/attrs.h"
+#include "filter/data.h"
 
 /* Possible return values of filter execution */
 enum filter_return {
@@ -40,9 +41,8 @@ static inline const char *filter_return_str(const enum filter_return fret) {
   }
 }
 
-struct f_val;
-
 /* The filter encapsulating structure to be pointed-to from outside */
+struct f_inst;
 struct f_line;
 struct filter {
   struct symbol *sym;
@@ -53,9 +53,11 @@ struct rte;
 
 enum filter_return f_run(const struct filter *filter, struct rte **rte, struct linpool *tmp_pool, int flags);
 enum filter_return f_eval_rte(const struct f_line *expr, struct rte **rte, struct linpool *tmp_pool);
-uint f_eval_int(const struct f_line *expr);
 enum filter_return f_eval_buf(const struct f_line *expr, struct linpool *tmp_pool, buffer *buf);
 
+struct f_val cf_eval(const struct f_inst *inst, int type);
+static inline uint cf_eval_int(const struct f_inst *inst) { return cf_eval(inst, T_INT).val.i; };
+
 const char *filter_name(const struct filter *filter);
 int filter_same(const struct filter *new, const struct filter *old);
 int f_same(const struct f_line *f1, const struct f_line *f2);
index 9197f98535cd430b06697df74e83cb6029ed67c7..610b1c012f1fa2ec3fc8dd58494d07ae77258553 100644 (file)
@@ -167,7 +167,7 @@ rtrid:
 
 idval:
    NUM { $$ = $1; }
- | '(' term ')' { $$ = f_eval_int(f_linearize($2, 1)); }
+ | '(' term ')' { $$ = cf_eval_int($2); }
  | IP4 { $$ = ip4_to_u32($1); }
  | CF_SYM_KNOWN {
      if ($1->class == (SYM_CONSTANT | T_INT) || $1->class == (SYM_CONSTANT | T_QUAD))