summaryrefslogtreecommitdiffstats
path: root/conf/cf-lex.l
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>1999-11-30 15:03:36 +0100
committerMartin Mares <mj@ucw.cz>1999-11-30 15:03:36 +0100
commitc9aae7f47fd7ad71b80cbc86c01a26c504ba08d0 (patch)
treee12cc810a25c7f829c86d69801202d87f6dce9e8 /conf/cf-lex.l
parentf0474f207061151183bb85d59f09422e7bb7e2ee (diff)
downloadbird-c9aae7f47fd7ad71b80cbc86c01a26c504ba08d0.tar
bird-c9aae7f47fd7ad71b80cbc86c01a26c504ba08d0.zip
Lexer supports fallback symbol tables and uses them to recognize
symbols from global config when parsing CLI commands. cf_lex_init_tables() is now called automatically inside the lexer.
Diffstat (limited to 'conf/cf-lex.l')
-rw-r--r--conf/cf-lex.l59
1 files changed, 35 insertions, 24 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 5959e70..dadc833 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -29,12 +29,12 @@ static struct keyword {
{ NULL, -1 } };
#define KW_HASH_SIZE 64
+static struct keyword *kw_hash[KW_HASH_SIZE];
+static int kw_hash_inited;
+
#define SYM_HASH_SIZE 128
#define SYM_MAX_LEN 32
-static struct keyword *kw_hash[KW_HASH_SIZE];
-static struct symbol **sym_hash;
-
struct sym_scope {
struct sym_scope *next; /* Next on scope stack */
struct symbol *name; /* Name of this scope */
@@ -192,21 +192,30 @@ static struct symbol *
cf_find_sym(byte *c, unsigned int h0)
{
unsigned int h = h0 & (SYM_HASH_SIZE-1);
- struct symbol *s;
+ struct symbol *s, **ht;
int l;
- if (!sym_hash)
- sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *));
- else
- for(s = sym_hash[h]; s; s=s->next)
+ if (ht = new_config->sym_hash)
+ {
+ for(s = ht[h]; s; s=s->next)
+ if (!strcmp(s->name, c) && s->scope->active)
+ return s;
+ }
+ if (new_config->sym_fallback)
+ {
+ /* We know only top-level scope is active */
+ for(s = new_config->sym_fallback[h]; s; s=s->next)
if (!strcmp(s->name, c) && s->scope->active)
return s;
+ }
+ if (!ht)
+ ht = new_config->sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *));
l = strlen(c);
if (l > SYM_MAX_LEN)
cf_error("Symbol too long");
s = cfg_alloc(sizeof(struct symbol) + l);
- s->next = sym_hash[h];
- sym_hash[h] = s;
+ s->next = ht[h];
+ ht[h] = s;
s->scope = conf_this_scope;
s->class = SYM_VOID;
s->def = NULL;
@@ -246,10 +255,25 @@ cf_define_symbol(struct symbol *sym, int type, void *def)
sym->def = def;
}
+static void
+cf_lex_init_kh(void)
+{
+ struct keyword *k;
+
+ for(k=keyword_list; k->name; k++)
+ {
+ unsigned h = cf_hash(k->name) & (KW_HASH_SIZE-1);
+ k->next = kw_hash[h];
+ kw_hash[h] = k;
+ }
+ kw_hash_inited = 1;
+}
+
void
cf_lex_init(int is_cli)
{
- sym_hash = NULL;
+ if (!kw_hash_inited)
+ cf_lex_init_kh();
conf_lino = 1;
yyrestart(NULL);
if (is_cli)
@@ -261,19 +285,6 @@ cf_lex_init(int is_cli)
}
void
-cf_lex_init_tables(void)
-{
- struct keyword *k;
-
- for(k=keyword_list; k->name; k++)
- {
- unsigned h = cf_hash(k->name) & (KW_HASH_SIZE-1);
- k->next = kw_hash[h];
- kw_hash[h] = k;
- }
-}
-
-void
cf_push_scope(struct symbol *sym)
{
struct sym_scope *s = cfg_alloc(sizeof(struct sym_scope));