summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/cf-lex.l22
-rw-r--r--conf/conf.h4
-rw-r--r--lib/hash.h2
3 files changed, 16 insertions, 12 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index ceedee8a..0a02dd73 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -73,10 +73,10 @@ static uint cf_hash(const byte *c);
#define KW_FN(k) cf_hash(k)
#define KW_ORDER 8 /* Fixed */
-#define SYM_KEY(n) n->name, n->scope->active
+#define SYM_KEY(n) n->name, n->scope
#define SYM_NEXT(n) n->next
#define SYM_EQ(a,s1,b,s2) !strcmp(a,b) && s1 == s2
-#define SYM_FN(k,s) cf_hash(k)
+#define SYM_FN(k,s) cf_hash(k) ^ ptr_hash(s)
#define SYM_ORDER 6 /* Initial */
#define SYM_REHASH sym_rehash
@@ -602,29 +602,31 @@ cf_new_symbol(const byte *c)
}
/**
- * cf_find_symbol - find a symbol by name
+ * cf_find_local_symbol - find a symbol by name
* @cfg: specificed config
+ * @scope: specified symbol scope
* @c: symbol name
*
* This functions searches the symbol table in the config @cfg for a symbol of
- * given name. First it examines the current scope, then the second recent one
+ * given name. First it examines the scope @scope, then the parent scope
* 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
* signify no match.
*/
struct symbol *
-cf_find_symbol(const struct config *cfg, const byte *c)
+cf_find_local_symbol(const struct config *cfg, const struct sym_scope *scope, const byte *c)
{
struct symbol *s;
- if (cfg->sym_hash.data &&
- (s = HASH_FIND(cfg->sym_hash, SYM, c, 1)))
- return s;
+ if (cfg->sym_hash.data)
+ for (; scope; scope = scope->next)
+ if (s = HASH_FIND(cfg->sym_hash, SYM, c, scope))
+ return s;
/* In CLI command parsing, fallback points to the current config, otherwise it is NULL. */
if (cfg->fallback &&
cfg->fallback->sym_hash.data &&
- (s = HASH_FIND(cfg->fallback->sym_hash, SYM, c, 1)))
+ (s = HASH_FIND(cfg->fallback->sym_hash, SYM, c, cfg->fallback->root_scope)))
return s;
return NULL;
@@ -642,7 +644,7 @@ cf_find_symbol(const struct config *cfg, const byte *c)
struct symbol *
cf_get_symbol(const byte *c)
{
- return cf_find_symbol(new_config, c) ?: cf_new_symbol(c);
+ return cf_find_local_symbol(new_config, conf_this_scope, c) ?: cf_new_symbol(c);
}
/**
diff --git a/conf/conf.h b/conf/conf.h
index b409750e..cb47e7d0 100644
--- a/conf/conf.h
+++ b/conf/conf.h
@@ -187,7 +187,9 @@ int cf_lex(void);
void cf_lex_init(int is_cli, struct config *c);
void cf_lex_unwind(void);
-struct symbol *cf_find_symbol(const struct config *cfg, const byte *c);
+struct symbol *cf_find_local_symbol(const struct config *cfg, const struct sym_scope *scope, const byte *c);
+static inline struct symbol *cf_find_symbol(const struct config *cfg, const byte *c)
+{ return cf_find_local_symbol(cfg, cfg->root_scope, c); }
struct symbol *cf_get_symbol(const byte *c);
struct symbol *cf_default_name(char *template, int *counter);
diff --git a/lib/hash.h b/lib/hash.h
index 8febb33f..b30f7830 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -237,7 +237,7 @@ mem_hash(const void *p, uint s)
}
static inline uint
-ptr_hash(void *ptr)
+ptr_hash(const void *ptr)
{
uintptr_t p = (uintptr_t) ptr;
return p ^ (p << 8) ^ (p >> 16);