mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Conf: Keywords have their default symbols
This avoids unnecessary collapsed soft scopes caused by keyword symbol multiallocation.
This commit is contained in:
parent
8e177cf35b
commit
58efa94460
@ -54,7 +54,6 @@
|
||||
struct keyword {
|
||||
byte *name;
|
||||
int value;
|
||||
struct keyword *next;
|
||||
};
|
||||
|
||||
#include "conf/keywords.h"
|
||||
@ -67,12 +66,6 @@ struct keyword {
|
||||
|
||||
static uint cf_hash(const byte *c);
|
||||
|
||||
#define KW_KEY(n) n->name
|
||||
#define KW_NEXT(n) n->next
|
||||
#define KW_EQ(a,b) !strcmp(a,b)
|
||||
#define KW_FN(k) cf_hash(k)
|
||||
#define KW_ORDER 8 /* Fixed */
|
||||
|
||||
#define SYM_KEY(n) n->name
|
||||
#define SYM_NEXT(n) n->next
|
||||
#define SYM_EQ(a,b) !strcmp(a,b)
|
||||
@ -85,10 +78,9 @@ static uint cf_hash(const byte *c);
|
||||
|
||||
HASH_DEFINE_REHASH_FN(SYM, struct symbol)
|
||||
|
||||
HASH(struct keyword) kw_hash;
|
||||
|
||||
struct sym_scope *conf_this_scope;
|
||||
struct sym_scope *global_root_scope;
|
||||
static pool *global_root_scope_pool;
|
||||
|
||||
linpool *cfg_mem;
|
||||
|
||||
@ -576,14 +568,19 @@ cf_new_symbol(const byte *c)
|
||||
|
||||
cf_swap_soft_scope();
|
||||
|
||||
s = cfg_allocz(sizeof(struct symbol) + l + 1);
|
||||
pool *p = new_config->pool;
|
||||
|
||||
if (conf_this_scope == global_root_scope)
|
||||
s = mb_allocz(p = global_root_scope_pool, sizeof(struct symbol) + l + 1);
|
||||
else
|
||||
s = cfg_allocz(sizeof(struct symbol) + l + 1);
|
||||
*s = (struct symbol) { .scope = conf_this_scope, .class = SYM_VOID, };
|
||||
strcpy(s->name, c);
|
||||
|
||||
if (!conf_this_scope->hash.data)
|
||||
HASH_INIT(conf_this_scope->hash, new_config->pool, SYM_ORDER);
|
||||
HASH_INIT(conf_this_scope->hash, p, SYM_ORDER);
|
||||
|
||||
HASH_INSERT2(conf_this_scope->hash, SYM, new_config->pool, s);
|
||||
HASH_INSERT2(conf_this_scope->hash, SYM, p, s);
|
||||
|
||||
if (conf_this_scope == new_config->root_scope)
|
||||
add_tail(&(new_config->symbols), &(s->n));
|
||||
@ -684,36 +681,20 @@ cf_lex_symbol(const char *data)
|
||||
struct symbol *sym = cf_get_symbol(data);
|
||||
cf_lval.s = sym;
|
||||
|
||||
/* Is it a keyword? Prefer the keyword. */
|
||||
struct keyword *k = HASH_FIND(kw_hash, KW, data);
|
||||
if (k)
|
||||
switch (sym->class)
|
||||
{
|
||||
if (k->value > 0)
|
||||
return k->value;
|
||||
else
|
||||
case SYM_KEYWORD:
|
||||
{
|
||||
cf_lval.i = -k->value;
|
||||
int val = sym->keyword->value;
|
||||
if (val > 0) return val;
|
||||
cf_lval.i = -val;
|
||||
return ENUM;
|
||||
}
|
||||
case SYM_VOID:
|
||||
return CF_SYM_UNDEFINED;
|
||||
default:
|
||||
return CF_SYM_KNOWN;
|
||||
}
|
||||
|
||||
/* OK, only a symbol. */
|
||||
if (sym->class == SYM_VOID)
|
||||
return CF_SYM_UNDEFINED;
|
||||
else
|
||||
return CF_SYM_KNOWN;
|
||||
}
|
||||
|
||||
static void
|
||||
cf_lex_init_kh(void)
|
||||
{
|
||||
HASH_INIT(kw_hash, &root_pool, KW_ORDER);
|
||||
|
||||
struct keyword *k;
|
||||
for (k=keyword_list; k->name; k++)
|
||||
HASH_INSERT(kw_hash, KW, k);
|
||||
|
||||
global_root_scope = mb_allocz(&root_pool, sizeof(*global_root_scope));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -727,8 +708,14 @@ cf_lex_init_kh(void)
|
||||
void
|
||||
cf_lex_init(int is_cli, struct config *c)
|
||||
{
|
||||
if (!kw_hash.data)
|
||||
cf_lex_init_kh();
|
||||
if (!global_root_scope_pool)
|
||||
{
|
||||
global_root_scope_pool = rp_new(&root_pool, "Keywords pool");
|
||||
conf_this_scope = global_root_scope = mb_allocz(global_root_scope_pool, sizeof(*global_root_scope));
|
||||
|
||||
for (const struct keyword *k = keyword_list; k->name; k++)
|
||||
cf_define_symbol(cf_get_symbol(k->name), SYM_KEYWORD, keyword, k);
|
||||
}
|
||||
|
||||
ifs_head = ifs = push_ifs(NULL);
|
||||
if (!is_cli)
|
||||
|
@ -123,6 +123,7 @@ struct symbol {
|
||||
struct f_dynamic_attr *attribute; /* For SYM_ATTRIBUTE */
|
||||
struct f_val *val; /* For SYM_CONSTANT */
|
||||
uint offset; /* For SYM_VARIABLE */
|
||||
const struct keyword *keyword; /* For SYM_KEYWORD */
|
||||
};
|
||||
|
||||
char name[0];
|
||||
@ -157,6 +158,7 @@ struct bytestring {
|
||||
#define SYM_FILTER 4
|
||||
#define SYM_TABLE 5
|
||||
#define SYM_ATTRIBUTE 6
|
||||
#define SYM_KEYWORD 7
|
||||
|
||||
#define SYM_VARIABLE 0x100 /* 0x100-0x1ff are variable types */
|
||||
#define SYM_VARIABLE_RANGE SYM_VARIABLE ... (SYM_VARIABLE | 0xff)
|
||||
|
@ -23,7 +23,7 @@ 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, NULL },
|
||||
m4_define(CF_handle_kw, `m4_divert(1){ "m4_translit($1,[[A-Z]],[[a-z]])", $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_KEYWORDS, `CF_iterate([[CF_keywd]], [[$@]])DNL')
|
||||
@ -35,7 +35,7 @@ m4_define(CF_CLI, `CF_KEYWORDS(m4_translit($1, [[ ]], [[,]]))
|
||||
|
||||
# Enums are translated to C initializers: use CF_ENUM(typename, prefix, values)
|
||||
# For different prefix: CF_ENUM_PX(typename, external prefix, C prefix, values)
|
||||
m4_define(CF_enum, `m4_divert(1){ "CF_enum_prefix_ext[[]]$1", -((CF_enum_type<<16) | CF_enum_prefix_int[[]]$1), NULL },
|
||||
m4_define(CF_enum, `m4_divert(1){ "CF_enum_prefix_ext[[]]$1", -((CF_enum_type<<16) | CF_enum_prefix_int[[]]$1) },
|
||||
m4_divert(-1)')
|
||||
m4_define(CF_ENUM, `m4_define([[CF_enum_type]],$1)m4_define([[CF_enum_prefix_ext]],$2)m4_define([[CF_enum_prefix_int]],$2)CF_iterate([[CF_enum]], [[m4_shift(m4_shift($@))]])DNL')
|
||||
m4_define(CF_ENUM_PX, `m4_define([[CF_enum_type]],$1)m4_define([[CF_enum_prefix_ext]],$2)m4_define([[CF_enum_prefix_int]],$3)CF_iterate([[CF_enum]], [[m4_shift(m4_shift(m4_shift($@)))]])DNL')
|
||||
@ -43,8 +43,8 @@ m4_define(CF_ENUM_PX, `m4_define([[CF_enum_type]],$1)m4_define([[CF_enum_prefix_
|
||||
# After all configuration templates end, we generate the
|
||||
m4_m4wrap(`
|
||||
m4_divert(0)
|
||||
static struct keyword keyword_list[] = {
|
||||
m4_undivert(1){ NULL, -1, NULL } };
|
||||
static const struct keyword keyword_list[] = {
|
||||
m4_undivert(1){ NULL, -1 } };
|
||||
')
|
||||
|
||||
# As we are processing C source, we must access all M4 primitives via
|
||||
|
Loading…
Reference in New Issue
Block a user