]> 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)
committerMaria Matejka <mq@ucw.cz>
Tue, 13 Jun 2023 10:26:50 +0000 (12:26 +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 04a6c99459f0f9f91119ef9eabf20e0848e73935..9d5890ed150bde6d163615d9a3483bd340fbb2ec 100644 (file)
@@ -54,6 +54,7 @@
 struct keyword {
   byte *name;
   int value;
+  enum keyword_scope scope;
 };
 
 #include "conf/keywords.h"
@@ -718,16 +719,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);
@@ -751,7 +753,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 fbc6df62f355eb005a51a3414e5c7f93d0c3b9ef..a6f038fea03b68812fc0713d8b92bc6a5d1a4718 100644 (file)
@@ -129,7 +129,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 a1be584711e5510462e62831d3c7bf78429eca12..0d7c5d4dbdba24d3947f6d0aadf9bf58e0097542 100644 (file)
@@ -23,10 +23,12 @@ 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')
+
 
 # CLI commands generate keywords as well
 m4_define(CF_CLI, `CF_KEYWORDS(m4_translit($1, [[ ]], [[,]]))
index c4791218a0c54fa063887fc4a5cf565f866c5154..993320c40be94062b4db95887b1c0487f7489c40 100644 (file)
@@ -33,6 +33,8 @@ m4_define(CF_iterate, `m4_define([[CF_iter]], m4_defn([[$1]]))CF_itera($2)')
 m4_define(CF_keywd, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],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')
 
 # CLI commands
 m4_define(CF_CLI, `m4_define([[CF_cmd]], cmd_[[]]m4_translit($1, [[ ]], _))DNL
index bf2aa469d99075c624358273a21f4e518652694f..a4acd729729c1c3bddd611a060e78ba98d3b76a6 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--;
 }
 
@@ -330,25 +343,25 @@ CF_DECLS
 
 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, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
        IF, THEN, ELSE, CASE,
        FOR, IN, 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,
        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