]> git.ipfire.org Git - thirdparty/bird.git/blobdiff - filter/config.Y
Conf: Allow keywords to be redefined by user symbols
[thirdparty/bird.git] / filter / config.Y
index a1e5e9f17fd4bb31213b6ccdf3b063b009800d90..3bf3a2b6d67846406631be0642510ee6ce896171 100644 (file)
@@ -298,12 +298,13 @@ assert_assign(struct f_lval *lval, struct f_inst *expr, const char *start, const
 
 CF_DECLS
 
+CF_KEYWORDS_EXCLUSIVE(IN)
 CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
        ACCEPT, REJECT, ERROR,
        INT, BOOL, IP, TYPE, PREFIX, RD, PAIR, QUAD, EC, LC,
-       SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
+       SET, STRING, BYTESTRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
        IF, THEN, ELSE, CASE,
-       FOR, IN, DO,
+       FOR, DO,
        TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
        FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, ONLINK,
        PREFERENCE,
@@ -317,13 +318,14 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
        MIN, MAX,
        EMPTY,
        FILTER, WHERE, EVAL, ATTRIBUTE,
+       FROM_HEX,
        BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT)
 
 %nonassoc THEN
 %nonassoc ELSE
 
 %type <xp> cmds_int cmd_prep
-%type <x> term cmd cmd_var cmds cmds_scoped constant constructor print_list var var_init var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail
+%type <x> term term_bs cmd cmd_var cmds cmds_scoped constant constructor print_list var var_list function_call symbol_value bgp_path_expr bgp_path bgp_path_tail
 %type <fda> dynamic_attr
 %type <fsa> static_attr
 %type <f> filter where_filter
@@ -357,7 +359,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 ;
@@ -404,6 +406,7 @@ type:
  | EC { $$ = T_EC; }
  | LC { $$ = T_LC; }
  | STRING { $$ = T_STRING; }
+ | BYTESTRING { $$ = T_BYTESTRING; }
  | BGPMASK { $$ = T_PATH_MASK; }
  | BGPPATH { $$ = T_PATH; }
  | CLIST { $$ = T_CLIST; }
@@ -571,7 +574,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 {
@@ -583,13 +586,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); }
@@ -714,13 +717,14 @@ bgp_path_tail:
  ;
 
 constant:
-   NUM    { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = $1, }); }
- | TRUE   { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BOOL, .val.i = 1, }); }
- | FALSE  { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BOOL, .val.i = 0, }); }
- | TEXT   { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_STRING, .val.s = $1, }); }
- | fipa          { $$ = f_new_inst(FI_CONSTANT, $1); }
- | VPN_RD { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_RD, .val.ec = $1, }); }
- | net_   { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_NET, .val.net = $1, }); }
+   NUM      { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_INT, .val.i = $1, }); }
+ | TRUE     { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BOOL, .val.i = 1, }); }
+ | FALSE    { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BOOL, .val.i = 0, }); }
+ | TEXT     { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_STRING, .val.s = $1, }); }
+ | BYTETEXT { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_BYTESTRING, .val.bs = $1, }); }
+ | fipa     { $$ = f_new_inst(FI_CONSTANT, $1); }
+ | VPN_RD   { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_RD, .val.ec = $1, }); }
+ | net_     { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_NET, .val.net = $1, }); }
  | '[' ']' { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { .type = T_SET, .val.t = NULL, }); }
  | '[' set_items ']' {
      DBG( "We've got a set here..." );
@@ -868,9 +872,14 @@ term:
 
 /* | term '.' LEN { $$->code = P('P','l'); } */
 
+ | term_bs
  | function_call
  ;
 
+term_bs:
+   FROM_HEX '(' term ')' { $$ = f_new_inst(FI_FROM_HEX, $3); }
+ ;
+
 break_command:
    ACCEPT { $$ = F_ACCEPT; }
  | REJECT { $$ = F_REJECT; }
@@ -887,16 +896,16 @@ print_list: /* EMPTY */ { $$ = NULL; }
    }
  ;
 
-var_init:
-   /* empty */ { $$ = f_new_inst(FI_CONSTANT, (struct f_val) { }); }
- | '=' term { $$ = $2; }
- ;
-
 var:
-   type symbol var_init ';' {
+   type symbol '=' term ';' {
      struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope));
-     $$ = f_new_inst(FI_VAR_INIT, $3, sym);
+     $$ = f_new_inst(FI_VAR_INIT, $4, sym);
    }
+ | type symbol ';' {
+     struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope));
+     $$ = f_new_inst(FI_VAR_INIT0, sym);
+   }
+ ;
 
 for_var:
    type symbol { $$ = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); }