]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter/Conf: Method names have their own keyword hash
authorMaria Matejka <mq@ucw.cz>
Tue, 13 Jun 2023 07:39:29 +0000 (09:39 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 12 Sep 2023 13:47:24 +0000 (15:47 +0200)
To allow for future dynamic method definition, parsing method names is
done via a dedicated keyword hash/scope.

conf/cf-lex.l
conf/conf.h
conf/confbase.Y
conf/gen_keywords.m4
conf/gen_parser.m4
filter/config.Y

index 8dc0ac89ac3e88624efc97ca82a48685e21e2318..9e52417ac4eaed450c61716ec39a02bdca29b4d1 100644 (file)
@@ -54,6 +54,7 @@
 struct keyword {
   byte *name;
   int value;
+  enum keyword_scope scope;
 };
 
 #include "conf/keywords.h"
@@ -707,16 +708,17 @@ cf_lex_init(int is_cli, struct config *c)
   {
     global_root_scope_pool = rp_new(&root_pool, "Keywords pool");
     linpool *kwlp = lp_new(global_root_scope_pool);
-    global_root_scope = lp_allocz(kwlp, sizeof(*global_root_scope));
+    global_root_scope = lp_allocz(kwlp, sizeof(*global_root_scope) * CFK__MAX);
 
     for (const struct keyword *k = keyword_list; k->name; k++)
     {
-      struct symbol *sym = cf_new_symbol(global_root_scope, global_root_scope_pool, kwlp, k->name);
+      struct symbol *sym = cf_new_symbol(&global_root_scope[k->scope], global_root_scope_pool, kwlp, k->name);
       sym->class = SYM_KEYWORD;
       sym->keyword = k;
     }
 
-    global_root_scope->readonly = 1;
+    for (int s = 0; s < CFK__MAX; s++)
+      global_root_scope[s].readonly = 1;
   }
 
   ifs_head = ifs = push_ifs(NULL);
@@ -740,7 +742,7 @@ cf_lex_init(int is_cli, struct config *c)
   if (is_cli)
     c->current_scope->next = config->root_scope;
   else
-    c->current_scope->next = global_root_scope;
+    c->current_scope->next = &global_root_scope[CFK_KEYWORDS];
 }
 
 /**
index 8558fcbaedef1b987ac4180dfc49f847ceeb44ef..f91d7039a422fbe22afc8998e6054b92c7f59623 100644 (file)
@@ -143,6 +143,12 @@ struct sym_scope {
   byte readonly:1;                     /* Do not add new symbols */
 };
 
+enum keyword_scope {
+  CFK_KEYWORDS,
+  CFK_METHODS,
+  CFK__MAX
+};
+
 extern struct sym_scope *global_root_scope;
 
 struct bytestring {
index df1e038b82978bec6a3901b07d40a6f312c484dd..e10666f8ba1cfdeae9b6824ea4d6e0e984a4aef1 100644 (file)
@@ -133,7 +133,7 @@ CF_DECLS
 
 %start config
 
-CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN, MPLS, FROM)
+CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT, VPN, MPLS, FROM, MAX, AS)
 
 CF_GRAMMAR
 
index 4e8651f6d426d3914594e66ef445c21e146cc488..06a38ffd101f6186eb97ff3f7636955604c7cbe2 100644 (file)
@@ -23,10 +23,11 @@ m4_define(CF_DECLS, `m4_divert(-1)')
 m4_define(CF_DEFINES, `m4_divert(-1)')
 
 # Keywords are translated to C initializers
-m4_define(CF_handle_kw, `m4_divert(1){ "m4_translit($1,[[A-Z]],[[a-z]])", $1 },
+m4_define(CF_handle_kw, `m4_divert(1){ "m4_translit($1,[[A-Z]],[[a-z]])", $1, CF_keywd_target },
 m4_divert(-1)')
-m4_define(CF_keywd, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)CF_handle_kw($1)]])')
-m4_define(CF_KEYWORDS, `CF_iterate([[CF_keywd]], [[$@]])DNL')
+m4_define(CF_keywd, `m4_ifdef([[CF_tok_]]CF_keywd_target[[_$1]],,[[m4_define([[CF_tok_]]CF_keywd_target[[_$1]],1)CF_handle_kw($1)]])')
+m4_define(CF_KEYWORDS, `m4_define([[CF_keywd_target]],CFK_KEYWORDS)CF_iterate([[CF_keywd]], [[$@]])DNL')
+m4_define(CF_METHODS, `m4_define([[CF_keywd_target]],CFK_METHODS)CF_iterate([[CF_keywd]], [[$@]])DNL')
 m4_define(CF_KEYWORDS_EXCLUSIVE, `CF_KEYWORDS($@)')
 
 # CLI commands generate keywords as well
index caf22307064bb5dea08ef40f18802e43c9b15f80..80071aefa19bce7287288dcf04c2e73a0b403a2f 100644 (file)
@@ -35,6 +35,8 @@ m4_define(CF_append, `m4_define([[$1]], m4_ifdef([[$1]], m4_defn([[$1]])[[$3]])[
 m4_define(CF_keywd, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)CF_append([[CF_kw_rule]],$1,[[ | ]])m4_define([[CF_toks]],CF_toks $1)]])')
 m4_define(CF_KEYWORDS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
 )DNL')
+m4_define(CF_METHODS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
+)DNL')
 
 m4_define(CF_keywd2, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)m4_define([[CF_toks]],CF_toks $1)]])')
 m4_define(CF_KEYWORDS_EXCLUSIVE, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd2]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
index e1eca9a5ee00c34f79dd1c0c96bf4b93c9d0e0ea..b72e5ea709a5206336d07796a6303c1b3cc2dd5d 100644 (file)
@@ -21,6 +21,7 @@ static inline u32 pair_b(u32 p) { return p & 0xFFFF; }
 
 static struct f_method_scope {
   struct f_inst *object;
+  struct sym_scope scope;
 } f_method_scope_stack[32];
 static int f_method_scope_pos = -1;
 
@@ -32,12 +33,24 @@ static inline void f_push_method_scope(struct f_inst *object)
     cf_error("Too many nested method calls");
   FM = (struct f_method_scope) {
     .object = object,
+    .scope = {
+      .next = new_config->current_scope,
+      .hash = global_root_scope[CFK_METHODS].hash,
+      .active = 1,
+      .block = 1,
+      .readonly = 1,
+    },
   };
+  new_config->current_scope = &FM.scope;
 }
 
 static inline void f_pop_method_scope(void)
 {
   ASSERT_DIE(f_method_scope_pos >= 0);
+
+  ASSERT_DIE(&FM.scope == new_config->current_scope);
+  new_config->current_scope = FM.scope.next;
+
   f_method_scope_pos--;
 }
 
@@ -331,26 +344,26 @@ 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,
+       INT, BOOL, IP, PREFIX, RD, PAIR, QUAD, EC, LC,
        SET, STRING, BYTESTRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
        IF, THEN, ELSE, CASE,
        FOR, DO,
        TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
-       FROM, GW, NET, MASK, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, ONLINK,
+       FROM, GW, NET, PROTO, SOURCE, SCOPE, DEST, IFNAME, IFINDEX, WEIGHT, GW_MPLS, ONLINK,
        PREFERENCE,
-       ROA_CHECK, ASN, SRC, DST,
-       IS_V4, IS_V6,
-       LEN, MAXLEN,
-       DATA, DATA1, DATA2,
+       ROA_CHECK,
        DEFINED,
        ADD, DELETE, RESET,
-       PREPEND, FIRST, LAST, LAST_NONAGGREGATED,
-       MIN, MAX,
+       PREPEND,
        EMPTY,
        FILTER, WHERE, EVAL, ATTRIBUTE,
        FROM_HEX,
        BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT)
 
+CF_METHODS(IS_V4, TYPE, IP, RD, LEN, MAXLEN, ASN, SRC, DST, MASK,
+       FIRST, LAST, LAST_NONAGGREGATED, DATA, DATA1, DATA2, MIN, MAX,
+       EMPTY, PREPEND, ADD, DELETE, FILTER)
+
 %nonassoc THEN
 %nonassoc ELSE