mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Filter/Conf: Method names have their own keyword hash
To allow for future dynamic method definition, parsing method names is done via a dedicated keyword hash/scope.
This commit is contained in:
parent
317c89cc8a
commit
3272dceb38
@ -54,6 +54,7 @@
|
|||||||
struct keyword {
|
struct keyword {
|
||||||
byte *name;
|
byte *name;
|
||||||
int value;
|
int value;
|
||||||
|
enum keyword_scope scope;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "conf/keywords.h"
|
#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");
|
global_root_scope_pool = rp_new(&root_pool, "Keywords pool");
|
||||||
linpool *kwlp = lp_new(global_root_scope_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++)
|
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->class = SYM_KEYWORD;
|
||||||
sym->keyword = k;
|
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);
|
ifs_head = ifs = push_ifs(NULL);
|
||||||
@ -751,7 +753,7 @@ cf_lex_init(int is_cli, struct config *c)
|
|||||||
if (is_cli)
|
if (is_cli)
|
||||||
c->current_scope->next = config->root_scope;
|
c->current_scope->next = config->root_scope;
|
||||||
else
|
else
|
||||||
c->current_scope->next = global_root_scope;
|
c->current_scope->next = &global_root_scope[CFK_KEYWORDS];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,6 +143,12 @@ struct sym_scope {
|
|||||||
byte readonly:1; /* Do not add new symbols */
|
byte readonly:1; /* Do not add new symbols */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum keyword_scope {
|
||||||
|
CFK_KEYWORDS,
|
||||||
|
CFK_METHODS,
|
||||||
|
CFK__MAX
|
||||||
|
};
|
||||||
|
|
||||||
extern struct sym_scope *global_root_scope;
|
extern struct sym_scope *global_root_scope;
|
||||||
|
|
||||||
struct bytestring {
|
struct bytestring {
|
||||||
|
@ -129,7 +129,7 @@ CF_DECLS
|
|||||||
|
|
||||||
%start config
|
%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
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
@ -23,10 +23,12 @@ m4_define(CF_DECLS, `m4_divert(-1)')
|
|||||||
m4_define(CF_DEFINES, `m4_divert(-1)')
|
m4_define(CF_DEFINES, `m4_divert(-1)')
|
||||||
|
|
||||||
# Keywords are translated to C initializers
|
# 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_divert(-1)')
|
||||||
m4_define(CF_keywd, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)CF_handle_kw($1)]])')
|
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, `CF_iterate([[CF_keywd]], [[$@]])DNL')
|
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
|
# CLI commands generate keywords as well
|
||||||
m4_define(CF_CLI, `CF_KEYWORDS(m4_translit($1, [[ ]], [[,]]))
|
m4_define(CF_CLI, `CF_KEYWORDS(m4_translit($1, [[ ]], [[,]]))
|
||||||
|
@ -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_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
|
m4_define(CF_KEYWORDS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
|
||||||
)DNL')
|
)DNL')
|
||||||
|
m4_define(CF_METHODS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
|
||||||
|
)DNL')
|
||||||
|
|
||||||
# CLI commands
|
# CLI commands
|
||||||
m4_define(CF_CLI, `m4_define([[CF_cmd]], cmd_[[]]m4_translit($1, [[ ]], _))DNL
|
m4_define(CF_CLI, `m4_define([[CF_cmd]], cmd_[[]]m4_translit($1, [[ ]], _))DNL
|
||||||
|
@ -21,6 +21,7 @@ static inline u32 pair_b(u32 p) { return p & 0xFFFF; }
|
|||||||
|
|
||||||
static struct f_method_scope {
|
static struct f_method_scope {
|
||||||
struct f_inst *object;
|
struct f_inst *object;
|
||||||
|
struct sym_scope scope;
|
||||||
} f_method_scope_stack[32];
|
} f_method_scope_stack[32];
|
||||||
static int f_method_scope_pos = -1;
|
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");
|
cf_error("Too many nested method calls");
|
||||||
FM = (struct f_method_scope) {
|
FM = (struct f_method_scope) {
|
||||||
.object = object,
|
.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)
|
static inline void f_pop_method_scope(void)
|
||||||
{
|
{
|
||||||
ASSERT_DIE(f_method_scope_pos >= 0);
|
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--;
|
f_method_scope_pos--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,25 +343,25 @@ CF_DECLS
|
|||||||
|
|
||||||
CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
||||||
ACCEPT, REJECT, ERROR,
|
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,
|
SET, STRING, BGPMASK, BGPPATH, CLIST, ECLIST, LCLIST,
|
||||||
IF, THEN, ELSE, CASE,
|
IF, THEN, ELSE, CASE,
|
||||||
FOR, IN, DO,
|
FOR, IN, DO,
|
||||||
TRUE, FALSE, RT, RO, UNKNOWN, GENERIC,
|
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,
|
PREFERENCE,
|
||||||
ROA_CHECK, ASN, SRC, DST,
|
ROA_CHECK,
|
||||||
IS_V4, IS_V6,
|
|
||||||
LEN, MAXLEN,
|
|
||||||
DATA, DATA1, DATA2,
|
|
||||||
DEFINED,
|
DEFINED,
|
||||||
ADD, DELETE, RESET,
|
ADD, DELETE, RESET,
|
||||||
PREPEND, FIRST, LAST, LAST_NONAGGREGATED,
|
PREPEND,
|
||||||
MIN, MAX,
|
|
||||||
EMPTY,
|
EMPTY,
|
||||||
FILTER, WHERE, EVAL, ATTRIBUTE,
|
FILTER, WHERE, EVAL, ATTRIBUTE,
|
||||||
BT_ASSERT, BT_TEST_SUITE, BT_CHECK_ASSIGN, BT_TEST_SAME, FORMAT)
|
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 THEN
|
||||||
%nonassoc ELSE
|
%nonassoc ELSE
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user