diff options
author | Martin Mares <mj@ucw.cz> | 1999-11-30 14:03:36 +0000 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 1999-11-30 14:03:36 +0000 |
commit | c9aae7f47fd7ad71b80cbc86c01a26c504ba08d0 (patch) | |
tree | e12cc810a25c7f829c86d69801202d87f6dce9e8 /conf/cf-lex.l | |
parent | f0474f207061151183bb85d59f09422e7bb7e2ee (diff) |
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.l | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 5959e701..dadc833a 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)); |