mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-09 12:48:43 +00:00
Conf: Symbol hashes for all scopes
This is a backport cherry-pick of commits165156beeb
cce974e8ea
from the v3.0 branch as we need symbol hashes directly inside their scopes for more general usage than before. The redefinable keywords must be specified in any .Y file as follows: toksym: THE_KEYWORD ;
This commit is contained in:
parent
a19a60bd6c
commit
df338396cd
@ -73,22 +73,22 @@ static uint cf_hash(const byte *c);
|
|||||||
#define KW_FN(k) cf_hash(k)
|
#define KW_FN(k) cf_hash(k)
|
||||||
#define KW_ORDER 8 /* Fixed */
|
#define KW_ORDER 8 /* Fixed */
|
||||||
|
|
||||||
#define SYM_KEY(n) n->name, n->scope
|
#define SYM_KEY(n) n->name
|
||||||
#define SYM_NEXT(n) n->next
|
#define SYM_NEXT(n) n->next
|
||||||
#define SYM_EQ(a,s1,b,s2) !strcmp(a,b) && s1 == s2
|
#define SYM_EQ(a,b) !strcmp(a,b)
|
||||||
#define SYM_FN(k,s) cf_hash(k) ^ ptr_hash(s)
|
#define SYM_FN(k) cf_hash(k)
|
||||||
#define SYM_ORDER 6 /* Initial */
|
#define SYM_ORDER 4 /* Initial */
|
||||||
|
|
||||||
#define SYM_REHASH sym_rehash
|
#define SYM_REHASH sym_rehash
|
||||||
#define SYM_PARAMS /8, *1, 2, 2, 6, 20
|
#define SYM_PARAMS /8, *1, 2, 2, 4, 20
|
||||||
|
|
||||||
|
|
||||||
HASH_DEFINE_REHASH_FN(SYM, struct symbol)
|
HASH_DEFINE_REHASH_FN(SYM, struct symbol)
|
||||||
|
|
||||||
HASH(struct keyword) kw_hash;
|
HASH(struct keyword) kw_hash;
|
||||||
|
|
||||||
|
|
||||||
struct sym_scope *conf_this_scope;
|
struct sym_scope *conf_this_scope;
|
||||||
|
struct sym_scope *global_root_scope;
|
||||||
|
|
||||||
linpool *cfg_mem;
|
linpool *cfg_mem;
|
||||||
|
|
||||||
@ -591,12 +591,13 @@ cf_new_symbol(const byte *c)
|
|||||||
*s = (struct symbol) { .scope = conf_this_scope, .class = SYM_VOID, };
|
*s = (struct symbol) { .scope = conf_this_scope, .class = SYM_VOID, };
|
||||||
strcpy(s->name, c);
|
strcpy(s->name, c);
|
||||||
|
|
||||||
if (!new_config->sym_hash.data)
|
if (!conf_this_scope->hash.data)
|
||||||
HASH_INIT(new_config->sym_hash, new_config->pool, SYM_ORDER);
|
HASH_INIT(conf_this_scope->hash, new_config->pool, SYM_ORDER);
|
||||||
|
|
||||||
HASH_INSERT2(new_config->sym_hash, SYM, new_config->pool, s);
|
HASH_INSERT2(conf_this_scope->hash, SYM, new_config->pool, s);
|
||||||
|
|
||||||
add_tail(&(new_config->symbols), &(s->n));
|
if (conf_this_scope == new_config->root_scope)
|
||||||
|
add_tail(&(new_config->symbols), &(s->n));
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -606,32 +607,27 @@ cf_symbol_from_keyword(const struct keyword *kw)
|
|||||||
{ return cf_new_symbol(kw->name); }
|
{ return cf_new_symbol(kw->name); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cf_find_local_symbol - find a symbol by name
|
* cf_find_symbol_scope - find a symbol by name
|
||||||
* @cfg: specificed config
|
* @scope: config scope
|
||||||
* @scope: specified symbol scope
|
|
||||||
* @c: symbol name
|
* @c: symbol name
|
||||||
*
|
*
|
||||||
* This functions searches the symbol table in the config @cfg for a symbol of
|
* This functions searches the symbol table in the scope @scope for a symbol of
|
||||||
* given name. First it examines the scope @scope, then the parent scope
|
* given name. First it examines the current scope, then the underlying one
|
||||||
* and so on until it either finds the symbol and returns a pointer to its
|
* and so on until it either finds the symbol and returns a pointer to its
|
||||||
* &symbol structure or reaches the end of the scope chain and returns %NULL to
|
* &symbol structure or reaches the end of the scope chain and returns %NULL to
|
||||||
* signify no match.
|
* signify no match.
|
||||||
*/
|
*/
|
||||||
struct symbol *
|
struct symbol *
|
||||||
cf_find_local_symbol(const struct config *cfg, const struct sym_scope *scope, const byte *c)
|
cf_find_symbol_scope(const struct sym_scope *scope, const byte *c)
|
||||||
{
|
{
|
||||||
struct symbol *s;
|
struct symbol *s;
|
||||||
|
|
||||||
if (cfg->sym_hash.data)
|
/* Find the symbol here or anywhere below */
|
||||||
for (; scope; scope = scope->next)
|
while (scope)
|
||||||
if (s = HASH_FIND(cfg->sym_hash, SYM, c, scope))
|
if (scope->hash.data && (s = HASH_FIND(scope->hash, SYM, c)))
|
||||||
return s;
|
return s;
|
||||||
|
else
|
||||||
/* In CLI command parsing, fallback points to the current config, otherwise it is NULL. */
|
scope = scope->next;
|
||||||
if (cfg->fallback &&
|
|
||||||
cfg->fallback->sym_hash.data &&
|
|
||||||
(s = HASH_FIND(cfg->fallback->sym_hash, SYM, c, cfg->fallback->root_scope)))
|
|
||||||
return s;
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -648,7 +644,7 @@ cf_find_local_symbol(const struct config *cfg, const struct sym_scope *scope, co
|
|||||||
struct symbol *
|
struct symbol *
|
||||||
cf_get_symbol(const byte *c)
|
cf_get_symbol(const byte *c)
|
||||||
{
|
{
|
||||||
return cf_find_local_symbol(new_config, conf_this_scope, c) ?: cf_new_symbol(c);
|
return cf_find_symbol_scope(conf_this_scope, c) ?: cf_new_symbol(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -667,7 +663,7 @@ cf_localize_symbol(struct symbol *sym)
|
|||||||
|
|
||||||
/* If the scope is the current, it is already defined in this scope. */
|
/* If the scope is the current, it is already defined in this scope. */
|
||||||
if (cf_symbol_is_local(sym))
|
if (cf_symbol_is_local(sym))
|
||||||
cf_error("Symbol '%s' already defined", sym->name);
|
cf_error("Symbol already defined");
|
||||||
|
|
||||||
/* Not allocated here yet, doing it now. */
|
/* Not allocated here yet, doing it now. */
|
||||||
return cf_new_symbol(sym->name);
|
return cf_new_symbol(sym->name);
|
||||||
@ -696,23 +692,15 @@ static enum yytokentype
|
|||||||
cf_lex_symbol(const char *data)
|
cf_lex_symbol(const char *data)
|
||||||
{
|
{
|
||||||
/* Have we defined such a symbol? */
|
/* Have we defined such a symbol? */
|
||||||
struct symbol *sym = cf_find_local_symbol(new_config, conf_this_scope, data);
|
struct symbol *sym = cf_get_symbol(data);
|
||||||
|
cf_lval.s = sym;
|
||||||
|
|
||||||
if (sym && (sym->class != SYM_VOID))
|
/* Is it a keyword? Prefer the keyword. */
|
||||||
{
|
|
||||||
cf_lval.s = sym;
|
|
||||||
return CF_SYM_KNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is it a keyword? */
|
|
||||||
struct keyword *k = HASH_FIND(kw_hash, KW, data);
|
struct keyword *k = HASH_FIND(kw_hash, KW, data);
|
||||||
if (k)
|
if (k)
|
||||||
{
|
{
|
||||||
if (k->value > 0)
|
if (k->value > 0)
|
||||||
{
|
|
||||||
cf_lval.kw = k;
|
|
||||||
return k->value;
|
return k->value;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cf_lval.i = -k->value;
|
cf_lval.i = -k->value;
|
||||||
@ -720,19 +708,23 @@ cf_lex_symbol(const char *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OK, undefined symbol */
|
/* OK, only a symbol. */
|
||||||
cf_lval.s = cf_new_symbol(data);
|
if (sym->class == SYM_VOID)
|
||||||
return CF_SYM_UNDEFINED;
|
return CF_SYM_UNDEFINED;
|
||||||
|
else
|
||||||
|
return CF_SYM_KNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cf_lex_init_kh(void)
|
cf_lex_init_kh(void)
|
||||||
{
|
{
|
||||||
HASH_INIT(kw_hash, config_pool, KW_ORDER);
|
HASH_INIT(kw_hash, &root_pool, KW_ORDER);
|
||||||
|
|
||||||
struct keyword *k;
|
struct keyword *k;
|
||||||
for (k=keyword_list; k->name; k++)
|
for (k=keyword_list; k->name; k++)
|
||||||
HASH_INSERT(kw_hash, KW, k);
|
HASH_INSERT(kw_hash, KW, k);
|
||||||
|
|
||||||
|
global_root_scope = mb_allocz(&root_pool, sizeof(*global_root_scope));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -768,6 +760,11 @@ cf_lex_init(int is_cli, struct config *c)
|
|||||||
c->root_scope = cfg_allocz(sizeof(struct sym_scope));
|
c->root_scope = cfg_allocz(sizeof(struct sym_scope));
|
||||||
conf_this_scope = c->root_scope;
|
conf_this_scope = c->root_scope;
|
||||||
conf_this_scope->active = 1;
|
conf_this_scope->active = 1;
|
||||||
|
|
||||||
|
if (is_cli)
|
||||||
|
conf_this_scope->next = config->root_scope;
|
||||||
|
else
|
||||||
|
conf_this_scope->next = global_root_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -170,7 +170,6 @@ int
|
|||||||
cli_parse(struct config *c)
|
cli_parse(struct config *c)
|
||||||
{
|
{
|
||||||
int done = 0;
|
int done = 0;
|
||||||
c->fallback = config;
|
|
||||||
new_config = c;
|
new_config = c;
|
||||||
cfg_mem = c->mem;
|
cfg_mem = c->mem;
|
||||||
if (setjmp(conf_jmpbuf))
|
if (setjmp(conf_jmpbuf))
|
||||||
@ -181,7 +180,6 @@ cli_parse(struct config *c)
|
|||||||
done = 1;
|
done = 1;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
c->fallback = NULL;
|
|
||||||
new_config = NULL;
|
new_config = NULL;
|
||||||
cfg_mem = NULL;
|
cfg_mem = NULL;
|
||||||
return done;
|
return done;
|
||||||
@ -551,7 +549,6 @@ order_shutdown(int gr)
|
|||||||
init_list(&c->tables);
|
init_list(&c->tables);
|
||||||
init_list(&c->symbols);
|
init_list(&c->symbols);
|
||||||
memset(c->def_tables, 0, sizeof(c->def_tables));
|
memset(c->def_tables, 0, sizeof(c->def_tables));
|
||||||
HASH_INIT(c->sym_hash, c->pool, 4);
|
|
||||||
c->shutdown = 1;
|
c->shutdown = 1;
|
||||||
c->gr_down = gr;
|
c->gr_down = gr;
|
||||||
|
|
||||||
|
21
conf/conf.h
21
conf/conf.h
@ -16,7 +16,6 @@
|
|||||||
#include "lib/timer.h"
|
#include "lib/timer.h"
|
||||||
|
|
||||||
/* Configuration structure */
|
/* Configuration structure */
|
||||||
|
|
||||||
struct config {
|
struct config {
|
||||||
pool *pool; /* Pool the configuration is stored in */
|
pool *pool; /* Pool the configuration is stored in */
|
||||||
linpool *mem; /* Linear pool containing configuration data */
|
linpool *mem; /* Linear pool containing configuration data */
|
||||||
@ -53,8 +52,7 @@ struct config {
|
|||||||
char *err_file_name; /* File name containing error */
|
char *err_file_name; /* File name containing error */
|
||||||
char *file_name; /* Name of main configuration file */
|
char *file_name; /* Name of main configuration file */
|
||||||
int file_fd; /* File descriptor of main configuration file */
|
int file_fd; /* File descriptor of main configuration file */
|
||||||
HASH(struct symbol) sym_hash; /* Lexer: symbol hash table */
|
|
||||||
struct config *fallback; /* Link to regular config for CLI parsing */
|
|
||||||
struct sym_scope *root_scope; /* Scope for root symbols */
|
struct sym_scope *root_scope; /* Scope for root symbols */
|
||||||
int obstacle_count; /* Number of items blocking freeing of this config */
|
int obstacle_count; /* Number of items blocking freeing of this config */
|
||||||
int shutdown; /* This is a pseudo-config for daemon shutdown */
|
int shutdown; /* This is a pseudo-config for daemon shutdown */
|
||||||
@ -133,12 +131,17 @@ struct symbol {
|
|||||||
struct sym_scope {
|
struct sym_scope {
|
||||||
struct sym_scope *next; /* Next on scope stack */
|
struct sym_scope *next; /* Next on scope stack */
|
||||||
struct symbol *name; /* Name of this scope */
|
struct symbol *name; /* Name of this scope */
|
||||||
|
|
||||||
|
HASH(struct symbol) hash; /* Local symbol hash */
|
||||||
|
|
||||||
uint slots; /* Variable slots */
|
uint slots; /* Variable slots */
|
||||||
byte active; /* Currently entered */
|
byte active; /* Currently entered */
|
||||||
byte block; /* No independent stack frame */
|
byte block; /* No independent stack frame */
|
||||||
byte soft_scopes; /* Number of soft scopes above */
|
byte soft_scopes; /* Number of soft scopes above */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct sym_scope *global_root_scope;
|
||||||
|
|
||||||
struct bytestring {
|
struct bytestring {
|
||||||
size_t length;
|
size_t length;
|
||||||
byte data[];
|
byte data[];
|
||||||
@ -187,12 +190,14 @@ int cf_lex(void);
|
|||||||
void cf_lex_init(int is_cli, struct config *c);
|
void cf_lex_init(int is_cli, struct config *c);
|
||||||
void cf_lex_unwind(void);
|
void cf_lex_unwind(void);
|
||||||
|
|
||||||
struct symbol *cf_find_local_symbol(const struct config *cfg, const struct sym_scope *scope, const byte *c);
|
struct symbol *cf_find_symbol_scope(const struct sym_scope *scope, const byte *c);
|
||||||
static inline struct symbol *cf_find_symbol(const struct config *cfg, const byte *c)
|
static inline struct symbol *cf_find_symbol_cfg(const struct config *cfg, const byte *c)
|
||||||
{ return cf_find_local_symbol(cfg, cfg->root_scope, c); }
|
{ return cf_find_symbol_scope(cfg->root_scope, c); }
|
||||||
|
|
||||||
struct keyword;
|
#define cf_find_symbol(where, what) _Generic(*(where), \
|
||||||
struct symbol *cf_symbol_from_keyword(const struct keyword *kw);
|
struct config: cf_find_symbol_cfg, \
|
||||||
|
struct sym_scope: cf_find_symbol_scope \
|
||||||
|
)((where), (what))
|
||||||
|
|
||||||
struct symbol *cf_get_symbol(const byte *c);
|
struct symbol *cf_get_symbol(const byte *c);
|
||||||
struct symbol *cf_default_name(char *template, int *counter);
|
struct symbol *cf_default_name(char *template, int *counter);
|
||||||
|
@ -117,8 +117,7 @@ CF_DECLS
|
|||||||
%type <mls> label_stack_start label_stack
|
%type <mls> label_stack_start label_stack
|
||||||
|
|
||||||
%type <t> text opttext
|
%type <t> text opttext
|
||||||
%type <s> symbol
|
%type <s> symbol symbol_known toksym
|
||||||
%type <kw> kw_sym
|
|
||||||
|
|
||||||
%nonassoc PREFIX_DUMMY
|
%nonassoc PREFIX_DUMMY
|
||||||
%left AND OR
|
%left AND OR
|
||||||
@ -163,7 +162,7 @@ definition:
|
|||||||
expr:
|
expr:
|
||||||
NUM
|
NUM
|
||||||
| '(' term ')' { $$ = f_eval_int(f_linearize($2, 1)); }
|
| '(' term ')' { $$ = f_eval_int(f_linearize($2, 1)); }
|
||||||
| CF_SYM_KNOWN {
|
| symbol_known {
|
||||||
if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number constant expected");
|
if ($1->class != (SYM_CONSTANT | T_INT)) cf_error("Number constant expected");
|
||||||
$$ = SYM_VAL($1).i; }
|
$$ = SYM_VAL($1).i; }
|
||||||
;
|
;
|
||||||
@ -174,7 +173,8 @@ expr_us:
|
|||||||
| expr US { $$ = $1 US_; }
|
| expr US { $$ = $1 US_; }
|
||||||
;
|
;
|
||||||
|
|
||||||
symbol: CF_SYM_UNDEFINED | CF_SYM_KNOWN | kw_sym { $$ = cf_symbol_from_keyword($1); } ;
|
symbol: CF_SYM_UNDEFINED | CF_SYM_KNOWN | toksym ;
|
||||||
|
symbol_known: CF_SYM_KNOWN | toksym ;
|
||||||
|
|
||||||
/* Switches */
|
/* Switches */
|
||||||
|
|
||||||
|
@ -26,8 +26,7 @@ m4_define(CF_DEFINES, `m4_divert(-1)')
|
|||||||
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, NULL },
|
||||||
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_$1]],,[[m4_define([[CF_tok_$1]],1)CF_handle_kw($1)]])')
|
||||||
m4_define(CF_KEYWORDS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token[[]]CF_toks
|
m4_define(CF_KEYWORDS, `CF_iterate([[CF_keywd]], [[$@]])DNL')
|
||||||
)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, [[ ]], [[,]]))
|
||||||
|
@ -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_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)')
|
m4_define(CF_iterate, `m4_define([[CF_iter]], m4_defn([[$1]]))CF_itera($2)')
|
||||||
|
|
||||||
# Keywords act as %token<kw>
|
# Keywords act as %token<s>
|
||||||
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<kw>[[]]CF_toks
|
m4_define(CF_KEYWORDS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
|
||||||
)DNL')
|
)DNL')
|
||||||
|
|
||||||
# CLI commands
|
# CLI commands
|
||||||
|
@ -316,8 +316,8 @@ CF_KEYWORDS(FUNCTION, PRINT, PRINTN, UNSET, RETURN,
|
|||||||
LEN, MAXLEN,
|
LEN, MAXLEN,
|
||||||
DATA, DATA1, DATA2,
|
DATA, DATA1, DATA2,
|
||||||
DEFINED,
|
DEFINED,
|
||||||
ADD, DELETE, CONTAINS, RESET,
|
ADD, DELETE, RESET,
|
||||||
PREPEND, FIRST, LAST, LAST_NONAGGREGATED, MATCH,
|
PREPEND, FIRST, LAST, LAST_NONAGGREGATED,
|
||||||
MIN, MAX,
|
MIN, MAX,
|
||||||
EMPTY,
|
EMPTY,
|
||||||
FILTER, WHERE, EVAL, ATTRIBUTE,
|
FILTER, WHERE, EVAL, ATTRIBUTE,
|
||||||
@ -371,7 +371,7 @@ custom_attr: ATTRIBUTE type symbol ';' {
|
|||||||
|
|
||||||
conf: bt_test_suite ;
|
conf: bt_test_suite ;
|
||||||
bt_test_suite:
|
bt_test_suite:
|
||||||
BT_TEST_SUITE '(' CF_SYM_KNOWN ',' text ')' {
|
BT_TEST_SUITE '(' symbol_known ',' text ')' {
|
||||||
cf_assert_symbol($3, SYM_FUNCTION);
|
cf_assert_symbol($3, SYM_FUNCTION);
|
||||||
struct f_bt_test_suite *t = cfg_allocz(sizeof(struct f_bt_test_suite));
|
struct f_bt_test_suite *t = cfg_allocz(sizeof(struct f_bt_test_suite));
|
||||||
t->fn = $3->function;
|
t->fn = $3->function;
|
||||||
@ -384,7 +384,7 @@ bt_test_suite:
|
|||||||
|
|
||||||
conf: bt_test_same ;
|
conf: bt_test_same ;
|
||||||
bt_test_same:
|
bt_test_same:
|
||||||
BT_TEST_SAME '(' CF_SYM_KNOWN ',' CF_SYM_KNOWN ',' NUM ')' {
|
BT_TEST_SAME '(' symbol_known ',' symbol_known ',' NUM ')' {
|
||||||
cf_assert_symbol($3, SYM_FUNCTION);
|
cf_assert_symbol($3, SYM_FUNCTION);
|
||||||
cf_assert_symbol($5, SYM_FUNCTION);
|
cf_assert_symbol($5, SYM_FUNCTION);
|
||||||
struct f_bt_test_suite *t = cfg_allocz(sizeof(struct f_bt_test_suite));
|
struct f_bt_test_suite *t = cfg_allocz(sizeof(struct f_bt_test_suite));
|
||||||
@ -465,7 +465,7 @@ function_vars:
|
|||||||
filter_body: function_body ;
|
filter_body: function_body ;
|
||||||
|
|
||||||
filter:
|
filter:
|
||||||
CF_SYM_KNOWN {
|
symbol_known {
|
||||||
cf_assert_symbol($1, SYM_FILTER);
|
cf_assert_symbol($1, SYM_FILTER);
|
||||||
$$ = $1->filter;
|
$$ = $1->filter;
|
||||||
}
|
}
|
||||||
@ -578,7 +578,7 @@ set_atom:
|
|||||||
if (f_eval(f_linearize($2, 1), cfg_mem, &($$)) > F_RETURN) cf_error("Runtime error");
|
if (f_eval(f_linearize($2, 1), cfg_mem, &($$)) > F_RETURN) cf_error("Runtime error");
|
||||||
if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
|
if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
|
||||||
}
|
}
|
||||||
| CF_SYM_KNOWN {
|
| symbol_known {
|
||||||
cf_assert_symbol($1, SYM_CONSTANT);
|
cf_assert_symbol($1, SYM_CONSTANT);
|
||||||
if (!f_valid_set_type(SYM_TYPE($1))) cf_error("%s: set-incompatible type", $1->name);
|
if (!f_valid_set_type(SYM_TYPE($1))) cf_error("%s: set-incompatible type", $1->name);
|
||||||
$$ = *$1->val;
|
$$ = *$1->val;
|
||||||
@ -749,7 +749,7 @@ var_list: /* EMPTY */ { $$ = NULL; }
|
|||||||
| var_list ',' term { $$ = $3; $$->next = $1; }
|
| var_list ',' term { $$ = $3; $$->next = $1; }
|
||||||
|
|
||||||
function_call:
|
function_call:
|
||||||
CF_SYM_KNOWN '(' var_list ')'
|
symbol_known '(' var_list ')'
|
||||||
{
|
{
|
||||||
if ($1->class != SYM_FUNCTION)
|
if ($1->class != SYM_FUNCTION)
|
||||||
cf_error("You can't call something which is not a function. Really.");
|
cf_error("You can't call something which is not a function. Really.");
|
||||||
@ -768,7 +768,7 @@ function_call:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
symbol_value: CF_SYM_KNOWN
|
symbol_value: symbol_known
|
||||||
{
|
{
|
||||||
switch ($1->class) {
|
switch ($1->class) {
|
||||||
case SYM_CONSTANT_RANGE:
|
case SYM_CONSTANT_RANGE:
|
||||||
@ -929,7 +929,7 @@ cmd:
|
|||||||
$$ = f_new_inst(FI_FOR_INIT, $6, $3);
|
$$ = f_new_inst(FI_FOR_INIT, $6, $3);
|
||||||
$$->next = f_new_inst(FI_FOR_NEXT, $3, $9);
|
$$->next = f_new_inst(FI_FOR_NEXT, $3, $9);
|
||||||
}
|
}
|
||||||
| CF_SYM_KNOWN '=' term ';' {
|
| symbol_known '=' term ';' {
|
||||||
switch ($1->class) {
|
switch ($1->class) {
|
||||||
case SYM_VARIABLE_RANGE:
|
case SYM_VARIABLE_RANGE:
|
||||||
$$ = f_new_inst(FI_VAR_SET, $3, $1);
|
$$ = f_new_inst(FI_VAR_SET, $3, $1);
|
||||||
|
19
nest/cmds.c
19
nest/cmds.c
@ -51,17 +51,18 @@ cmd_show_symbols(struct sym_show_data *sd)
|
|||||||
cli_msg(1010, "%-8s\t%s", sd->sym->name, cf_symbol_class_name(sd->sym));
|
cli_msg(1010, "%-8s\t%s", sd->sym->name, cf_symbol_class_name(sd->sym));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HASH_WALK(config->sym_hash, next, sym)
|
for (const struct sym_scope *scope = config->root_scope; scope; scope = scope->next)
|
||||||
{
|
HASH_WALK(scope->hash, next, sym)
|
||||||
if (!sym->scope->active)
|
{
|
||||||
continue;
|
if (!sym->scope->active)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (sd->type && (sym->class != sd->type))
|
if (sd->type && (sym->class != sd->type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
cli_msg(-1010, "%-8s\t%s", sym->name, cf_symbol_class_name(sym));
|
cli_msg(-1010, "%-8s\t%s", sym->name, cf_symbol_class_name(sym));
|
||||||
}
|
}
|
||||||
HASH_WALK_END;
|
HASH_WALK_END;
|
||||||
|
|
||||||
cli_msg(0, "");
|
cli_msg(0, "");
|
||||||
}
|
}
|
||||||
|
@ -118,11 +118,11 @@ CF_KEYWORDS(IPV4, IPV6, VPN4, VPN6, ROA4, ROA6, FLOW4, FLOW6, SADR, MPLS)
|
|||||||
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED, RPKI)
|
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED, RPKI)
|
||||||
CF_KEYWORDS(PASSWORD, KEY, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, CHANNELS, INTERFACES)
|
CF_KEYWORDS(PASSWORD, KEY, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, CHANNELS, INTERFACES)
|
||||||
CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512, BLAKE2S128, BLAKE2S256, BLAKE2B256, BLAKE2B512)
|
CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512, BLAKE2S128, BLAKE2S256, BLAKE2B256, BLAKE2B512)
|
||||||
CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, IN, COMMANDS, PREEXPORT, NOEXPORT, EXPORTED, GENERATE)
|
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, IN, COMMANDS, PREEXPORT, NOEXPORT, EXPORTED, GENERATE)
|
||||||
CF_KEYWORDS(BGP, PASSWORDS, DESCRIPTION)
|
CF_KEYWORDS(BGP, PASSWORDS, DESCRIPTION)
|
||||||
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
|
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
|
||||||
CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
|
CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
|
||||||
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
|
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, AS)
|
||||||
CF_KEYWORDS(MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE)
|
CF_KEYWORDS(MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE)
|
||||||
CF_KEYWORDS(CHECK, LINK)
|
CF_KEYWORDS(CHECK, LINK)
|
||||||
CF_KEYWORDS(SORTED, TRIE, MIN, MAX, SETTLE, TIME, GC, THRESHOLD, PERIOD)
|
CF_KEYWORDS(SORTED, TRIE, MIN, MAX, SETTLE, TIME, GC, THRESHOLD, PERIOD)
|
||||||
@ -154,7 +154,7 @@ CF_ENUM_PX(T_ENUM_AF, AF_, AFI_, IPV4, IPV6)
|
|||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
kw_sym: MIN MAX ;
|
toksym: MIN MAX ;
|
||||||
|
|
||||||
/* Setting of router ID */
|
/* Setting of router ID */
|
||||||
|
|
||||||
@ -642,7 +642,7 @@ r_args:
|
|||||||
$$ = cfg_allocz(sizeof(struct rt_show_data));
|
$$ = cfg_allocz(sizeof(struct rt_show_data));
|
||||||
init_list(&($$->tables));
|
init_list(&($$->tables));
|
||||||
$$->filter = FILTER_ACCEPT;
|
$$->filter = FILTER_ACCEPT;
|
||||||
$$->running_on_config = new_config->fallback;
|
$$->running_on_config = config;
|
||||||
}
|
}
|
||||||
| r_args net_any {
|
| r_args net_any {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -663,7 +663,7 @@ r_args:
|
|||||||
$$->addr = $3;
|
$$->addr = $3;
|
||||||
$$->addr_mode = RSD_ADDR_IN;
|
$$->addr_mode = RSD_ADDR_IN;
|
||||||
}
|
}
|
||||||
| r_args TABLE CF_SYM_KNOWN {
|
| r_args TABLE symbol_known {
|
||||||
cf_assert_symbol($3, SYM_TABLE);
|
cf_assert_symbol($3, SYM_TABLE);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
rt_show_add_table($$, $3->table->table);
|
rt_show_add_table($$, $3->table->table);
|
||||||
@ -708,7 +708,7 @@ r_args:
|
|||||||
$$ = $1;
|
$$ = $1;
|
||||||
$$->filtered = 1;
|
$$->filtered = 1;
|
||||||
}
|
}
|
||||||
| r_args export_mode CF_SYM_KNOWN {
|
| r_args export_mode symbol_known {
|
||||||
cf_assert_symbol($3, SYM_PROTO);
|
cf_assert_symbol($3, SYM_PROTO);
|
||||||
struct proto_config *c = (struct proto_config *) $3->proto;
|
struct proto_config *c = (struct proto_config *) $3->proto;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
@ -725,7 +725,7 @@ r_args:
|
|||||||
$$->export_channel = $3;
|
$$->export_channel = $3;
|
||||||
$$->tables_defined_by = RSD_TDB_INDIRECT;
|
$$->tables_defined_by = RSD_TDB_INDIRECT;
|
||||||
}
|
}
|
||||||
| r_args PROTOCOL CF_SYM_KNOWN {
|
| r_args PROTOCOL symbol_known {
|
||||||
cf_assert_symbol($3, SYM_PROTO);
|
cf_assert_symbol($3, SYM_PROTO);
|
||||||
struct proto_config *c = (struct proto_config *) $3->proto;
|
struct proto_config *c = (struct proto_config *) $3->proto;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
|
@ -45,8 +45,7 @@ CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER,
|
|||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
/* Workaround for collisions between keywords and symbols */
|
toksym: ROLE | PEER | PROVIDER | CUSTOMER | RS_SERVER | RS_CLIENT ;
|
||||||
kw_sym: ROLE | PEER | PROVIDER | CUSTOMER | RS_SERVER | RS_CLIENT ;
|
|
||||||
|
|
||||||
proto: bgp_proto '}' ;
|
proto: bgp_proto '}' ;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user