0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-09 12:48:43 +00:00

Conf: Improve handling of keywords

For whatever reason, parser allocated a symbol for every parsed keyword
in each scope. That wasted time and memory. The effect is worsened with
recent changes allowing local scopes, so keywords often promote soft
scopes (with no symbols) to real scopes.

Do not allocate a symbol for a keyword. Take care of keywords that could
be promoted to symbols (kw_sym) and do it explicitly.
This commit is contained in:
Ondrej Zajicek 2023-04-27 18:20:49 +02:00 committed by Igor Putovny
parent 3aef1bc7fc
commit d44409f0c0
6 changed files with 24 additions and 8 deletions

View File

@ -601,6 +601,10 @@ cf_new_symbol(const byte *c)
return s;
}
struct symbol *
cf_symbol_from_keyword(const struct keyword *kw)
{ return cf_new_symbol(kw->name); }
/**
* cf_find_local_symbol - find a symbol by name
* @cfg: specificed config
@ -692,18 +696,23 @@ static enum yytokentype
cf_lex_symbol(const char *data)
{
/* Have we defined such a symbol? */
struct symbol *sym = cf_get_symbol(data);
cf_lval.s = sym;
struct symbol *sym = cf_find_local_symbol(new_config, conf_this_scope, data);
if (sym->class != SYM_VOID)
if (sym && (sym->class != SYM_VOID))
{
cf_lval.s = sym;
return CF_SYM_KNOWN;
}
/* Is it a keyword? */
struct keyword *k = HASH_FIND(kw_hash, KW, data);
if (k)
{
if (k->value > 0)
{
cf_lval.kw = k;
return k->value;
}
else
{
cf_lval.i = -k->value;
@ -712,7 +721,7 @@ cf_lex_symbol(const char *data)
}
/* OK, undefined symbol */
cf_lval.s = sym;
cf_lval.s = cf_new_symbol(data);
return CF_SYM_UNDEFINED;
}

View File

@ -191,6 +191,9 @@ struct symbol *cf_find_local_symbol(const struct config *cfg, const struct sym_s
static inline struct symbol *cf_find_symbol(const struct config *cfg, const byte *c)
{ return cf_find_local_symbol(cfg, cfg->root_scope, c); }
struct keyword;
struct symbol *cf_symbol_from_keyword(const struct keyword *kw);
struct symbol *cf_get_symbol(const byte *c);
struct symbol *cf_default_name(char *template, int *counter);
struct symbol *cf_localize_symbol(struct symbol *sym);

View File

@ -62,6 +62,7 @@ CF_DECLS
net_addr net;
net_addr *net_ptr;
struct symbol *s;
struct keyword *kw;
const char *t;
struct rtable_config *r;
struct channel_config *cc;
@ -120,6 +121,7 @@ CF_DECLS
%type <t> text opttext
%type <s> symbol
%type <kw> kw_sym
%nonassoc PREFIX_DUMMY
%left AND OR
@ -175,7 +177,7 @@ expr_us:
| expr US { $$ = $1 US_; }
;
symbol: CF_SYM_UNDEFINED | CF_SYM_KNOWN ;
symbol: CF_SYM_UNDEFINED | CF_SYM_KNOWN | kw_sym { $$ = cf_symbol_from_keyword($1); } ;
/* Switches */

View File

@ -29,9 +29,9 @@ m4_define(CF_END, `m4_divert(-1)')
m4_define(CF_itera, `m4_ifelse($#, 1, [[CF_iter($1)]], [[CF_iter($1)[[]]CF_itera(m4_shift($@))]])')
m4_define(CF_iterate, `m4_define([[CF_iter]], m4_defn([[$1]]))CF_itera($2)')
# Keywords act as untyped %token
# Keywords act as %token<kw>
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<kw>[[]]CF_toks
)DNL')
# CLI commands

View File

@ -154,6 +154,8 @@ CF_ENUM_PX(T_ENUM_AF, AF_, AFI_, IPV4, IPV6)
CF_GRAMMAR
kw_sym: MIN MAX ;
/* Setting of router ID */
conf: rtrid ;

View File

@ -46,7 +46,7 @@ CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER,
CF_GRAMMAR
/* Workaround for collisions between keywords and symbols */
symbol: ROLE | PEER | PROVIDER | CUSTOMER | RS_SERVER | RS_CLIENT ;
kw_sym: ROLE | PEER | PROVIDER | CUSTOMER | RS_SERVER | RS_CLIENT ;
proto: bgp_proto '}' ;