]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Fix scope handling in for loops
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 5 Oct 2023 12:26:22 +0000 (14:26 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 5 Oct 2023 12:26:22 +0000 (14:26 +0200)
Changes in scope implementation broke scope handling in for loops.
The term in for loops is supposed to be parsed in the parent scope.

filter/config.Y
filter/test.conf

index 3cd8e3e40eda77726b799506d9ea78ecda3ae8e6..f3ed2dc5acd1dc193ecea7115538ff436402a581 100644 (file)
@@ -20,6 +20,7 @@ static inline u32 pair_a(u32 p) { return p >> 16; }
 static inline u32 pair_b(u32 p) { return p & 0xFFFF; }
 
 static struct symbol *this_function;
+static struct sym_scope *this_for_scope;
 
 static struct f_method_scope {
   struct f_inst *object;
@@ -993,7 +994,9 @@ cmd:
      new_config->current_scope->slots += 2;
    } for_var IN
    /* Parse term in the parent scope */
-   { new_config->current_scope->active = 0; } term { new_config->current_scope->active = 1; }
+   { this_for_scope = new_config->current_scope; new_config->current_scope = this_for_scope->next; }
+   term
+   { new_config->current_scope = this_for_scope; this_for_scope = NULL; }
    DO cmd {
      cf_pop_block_scope(new_config);
      $$ = f_for_cycle($3, $6, $9);
index 22b4984a11235b617fe498116fca229b39694d3d..f9289189ef848f4a50e3de454df119badd7d5a89 100644 (file)
@@ -1938,6 +1938,63 @@ bt_test_suite(t_if_else, "Testing if-else statement");
 
 
 
+/*
+ *     Test for-in statement
+ *     ---------------------
+ */
+
+function t_for_in()
+{
+       bgppath p = +empty+.prepend(5).prepend(4).prepend(3).prepend(2).prepend(1);
+       bgppath q = +empty+.prepend(30).prepend(20).prepend(10);
+       int a;
+
+       # basic for loop
+       a = 0;
+       for int i in p do {
+               a = 2 * a + i;
+       }
+       bt_assert(a = 57);
+
+       # basic for loop, no braces
+       a = 0;
+       for int i in p do a = 2 * a + i;
+       bt_assert(a = 57);
+
+       # for loop with empty body
+       a = 0;
+       for int i in p do { }
+       bt_assert(a = 0);
+
+       # for loop over empty path
+       a = 0;
+       for int i in +empty+ do a = 1;
+       bt_assert(a = 0);
+
+       # for loop with var name shadowing
+       a = 0;
+       for int p in p do {
+               a = 2 * a + p;
+       }
+       bt_assert(a = 57);
+
+       # nested for loops
+       a = 0;
+       int n = 1;
+       for int i in p do {
+               for int j in q do {
+                       a = a + i * j * n;
+                       n = n + 1;
+               }
+       }
+       bt_assert(a = 9300);
+}
+
+bt_test_suite(t_for_in, "Testing for-in statement");
+
+
+
+
 /*
  *     Unused functions -- testing only parsing
  *     ----------------------------------------