diff --git a/doc/bird.sgml b/doc/bird.sgml index 3e7ae9dd..da887b1e 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1974,8 +1974,8 @@ and name is used). In both cases, it must have the same type as elements. <m/expr/ { else: | <m/num_or_prefix [ .. num_or_prefix]/: <m/statement/ ; [ ... ] }</cf>. The expression after <cf>case</cf> can be of any type which can be on the left side of the ˜ operator and anything that could be a member of -a set is allowed before <cf/:/. Multiple commands are allowed without <cf/{}/ -grouping. If <cf><m/expr/</cf> matches one of the <cf/:/ clauses, statements +a set is allowed before <cf/:/. Multiple commands must be grouped by <cf/{}/. +If <cf><m/expr/</cf> matches one of the <cf/:/ clauses, statements between it and next <cf/:/ statement are executed. If <cf><m/expr/</cf> matches neither of the <cf/:/ clauses, the statements after <cf/else:/ are executed. @@ -1993,7 +1993,7 @@ for int asn in bgp_path do { } case arg1 { - 2: print "two"; print "I can do more commands without {}"; + 2: { print "two"; print "Multiple commands must brace themselves."; } 3 .. 5: print "three to five"; else: print "something else"; } diff --git a/doc/migration-bird3.md b/doc/migration-bird3.md index fc7cc433..1a088d59 100644 --- a/doc/migration-bird3.md +++ b/doc/migration-bird3.md @@ -60,6 +60,11 @@ the given prefix. Experimental. Reload of filters is now done by `reload filters` command, contrary to just `reload` in BIRD 2. +## Filters + +We have removed the exception for `case` where multiple commands could be written +after the case label without braces. This caused unneeded complexity in the parser. + ## Route attributes All protocol attributes have been renamed in CLI to align with the filter language tokens. diff --git a/filter/config.Y b/filter/config.Y index 4d8b30c7..c21abd35 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -381,7 +381,7 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN, %nonassoc ELSE %type <xp> cmds_int cmd_prep -%type <x> term term_bs cmd cmd_var cmds cmds_scoped constant constructor var var_list var_list_r function_call bgp_path_expr bgp_path bgp_path_tail term_dot_method method_name_cont +%type <x> term term_bs cmd cmd_var cmds constant constructor var var_list var_list_r function_call bgp_path_expr bgp_path bgp_path_tail term_dot_method method_name_cont %type <fsa> static_attr %type <f> filter where_filter %type <fl> filter_body function_body @@ -625,8 +625,6 @@ cmds: /* EMPTY */ { $$ = NULL; } | cmds_int { $$ = $1.begin; } ; -cmds_scoped: { cf_push_soft_scope(new_config); } cmds { cf_pop_soft_scope(new_config); $$ = $2; } ; - cmd_var: var | cmd ; cmd_prep: cmd_var { @@ -781,14 +779,14 @@ fprefix_set: ; switch_body: /* EMPTY */ { $$ = NULL; } - | switch_body switch_items ':' cmds_scoped { + | switch_body switch_items ':' cmd { /* Fill data fields */ struct f_tree *t; for (t = $2; t; t = t->left) t->data = $4; $$ = f_merge_items($1, $2); } - | switch_body ELSECOL cmds_scoped { + | switch_body ELSECOL cmd { struct f_tree *t = f_new_tree(); t->from.type = t->to.type = T_VOID; t->right = t; @@ -990,9 +988,7 @@ for_var: ; cmd: - '{' cmds_scoped '}' { - $$ = $2; - } + '{' { cf_push_soft_scope(new_config); } cmds { cf_pop_soft_scope(new_config); } '}' { $$ = $3; } | IF term THEN cmd { $$ = f_new_inst(FI_CONDITION, $2, $4, NULL); } diff --git a/filter/test.conf b/filter/test.conf index f27ad0b7..24094e80 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -195,8 +195,11 @@ bt_test_suite(t_bool, "Testing boolean expressions"); function aux_t_int(int t; int u) { + int v; case t { 1: {} + 2: { int u; u = 1; v = 42; } + 3: if true then v = t + u + 53; else v = 35 + u + t; else: {} } }