]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Lexer supports fallback symbol tables and uses them to recognize
authorMartin Mares <mj@ucw.cz>
Tue, 30 Nov 1999 14:03:36 +0000 (14:03 +0000)
committerMartin Mares <mj@ucw.cz>
Tue, 30 Nov 1999 14:03:36 +0000 (14:03 +0000)
symbols from global config when parsing CLI commands.

cf_lex_init_tables() is now called automatically inside the lexer.

conf/cf-lex.l
conf/conf.c
conf/conf.h

index 5959e70190a6d0210bdcea3b788f2a254b501d17..dadc833ab8aaf873b624093dd1c025564e19a3c8 100644 (file)
@@ -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)
@@ -260,19 +284,6 @@ cf_lex_init(int is_cli)
   conf_this_scope->active = 1;
 }
 
-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)
 {
index 47d4db4e87301e421ec11d248e80e04d7e4cd29a..4e2f920d14365e88044672328ee41c5ac311d07d 100644 (file)
@@ -45,7 +45,6 @@ config_parse(struct config *c)
   if (setjmp(conf_jmpbuf))
     return 0;
   cf_lex_init(0);
-  cf_lex_init_tables();
   protos_preconfig(c);
   rt_preconfig(c);
   cf_parse();
@@ -62,6 +61,7 @@ int
 cli_parse(struct config *c)
 {
   new_config = c;
+  c->sym_fallback = config->sym_hash;
   cfg_mem = c->mem;
   if (setjmp(conf_jmpbuf))
     return 0;
index ec8be407f5c14a685664542f5f92fe3117a2812a..957ce443490a964dd86574fc41703d4e733a5038 100644 (file)
@@ -23,6 +23,8 @@ struct config {
   char *err_msg;                       /* Parser error message */
   int err_lino;                                /* Line containing error */
   char *file_name;                     /* Name of configuration file */
+  struct symbol **sym_hash;            /* Lexer: symbol hash table */
+  struct symbol **sym_fallback;                /* Lexer: fallback symbol hash table */
 };
 
 extern struct config *config, *new_config;
@@ -69,7 +71,6 @@ struct symbol {
 
 extern int conf_lino;
 
-void cf_lex_init_tables(void);
 int cf_lex(void);
 void cf_lex_init(int is_cli);
 struct symbol *cf_find_symbol(byte *c);