summaryrefslogtreecommitdiff
path: root/conf/cf-lex.l
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-05-02 20:29:03 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2023-09-12 15:20:50 +0200
commit8e177cf35b582ec973c1abce4709c80847adb711 (patch)
treefcf14a0c11d2ae7d5ae67229c658d579e61c32fc /conf/cf-lex.l
parenta5a6de581b79641b21b26277580cb4cc118da7ea (diff)
Conf: Symbol hashes for all scopes
This is a backport cherry-pick of commits 165156beeb2926472bbceca3c103aacc3f81a8cc cce974e8ea992d0e6d2f649eca7880b436d91d71 from the v3.0 branch as we need symbol hashes directly inside their scopes for more general usage than before.
Diffstat (limited to 'conf/cf-lex.l')
-rw-r--r--conf/cf-lex.l81
1 files changed, 39 insertions, 42 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index e789e864..8637de40 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -73,22 +73,22 @@ 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
+#define SYM_KEY(n) n->name
#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) ^ ptr_hash(s)
-#define SYM_ORDER 6 /* Initial */
+#define SYM_EQ(a,b) !strcmp(a,b)
+#define SYM_FN(k) cf_hash(k)
+#define SYM_ORDER 4 /* Initial */
#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(struct keyword) kw_hash;
-
struct sym_scope *conf_this_scope;
+struct sym_scope *global_root_scope;
linpool *cfg_mem;
@@ -580,12 +580,13 @@ cf_new_symbol(const byte *c)
*s = (struct symbol) { .scope = conf_this_scope, .class = SYM_VOID, };
strcpy(s->name, c);
- if (!new_config->sym_hash.data)
- HASH_INIT(new_config->sym_hash, new_config->pool, SYM_ORDER);
+ if (!conf_this_scope->hash.data)
+ 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;
}
@@ -595,32 +596,27 @@ cf_symbol_from_keyword(const struct keyword *kw)
{ return cf_new_symbol(kw->name); }
/**
- * cf_find_local_symbol - find a symbol by name
- * @cfg: specificed config
- * @scope: specified symbol scope
+ * cf_find_symbol_scope - find a symbol by name
+ * @scope: config scope
* @c: symbol name
*
- * This functions searches the symbol table in the config @cfg for a symbol of
- * given name. First it examines the scope @scope, then the parent scope
+ * This functions searches the symbol table in the scope @scope for a symbol of
+ * 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
* &symbol structure or reaches the end of the scope chain and returns %NULL to
* signify no match.
*/
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;
- 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, cfg->fallback->root_scope)))
- return s;
+ /* Find the symbol here or anywhere below */
+ while (scope)
+ if (scope->hash.data && (s = HASH_FIND(scope->hash, SYM, c)))
+ return s;
+ else
+ scope = scope->next;
return NULL;
}
@@ -637,7 +633,7 @@ cf_find_local_symbol(const struct config *cfg, const struct sym_scope *scope, co
struct symbol *
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);
}
/**
@@ -685,23 +681,15 @@ static enum yytokentype
cf_lex_symbol(const char *data)
{
/* Have we defined such a symbol? */
- struct symbol *sym = cf_find_local_symbol(new_config, conf_this_scope, data);
-
- if (sym && (sym->class != SYM_VOID))
- {
- cf_lval.s = sym;
- return CF_SYM_KNOWN;
- }
+ struct symbol *sym = cf_get_symbol(data);
+ cf_lval.s = sym;
- /* Is it a keyword? */
+ /* Is it a keyword? Prefer the keyword. */
struct keyword *k = HASH_FIND(kw_hash, KW, data);
if (k)
{
if (k->value > 0)
- {
- cf_lval.kw = k;
return k->value;
- }
else
{
cf_lval.i = -k->value;
@@ -709,19 +697,23 @@ cf_lex_symbol(const char *data)
}
}
- /* OK, undefined symbol */
- cf_lval.s = cf_new_symbol(data);
- return CF_SYM_UNDEFINED;
+ /* OK, only a symbol. */
+ if (sym->class == SYM_VOID)
+ return CF_SYM_UNDEFINED;
+ else
+ return CF_SYM_KNOWN;
}
static 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;
for (k=keyword_list; k->name; k++)
HASH_INSERT(kw_hash, KW, k);
+
+ global_root_scope = mb_allocz(&root_pool, sizeof(*global_root_scope));
}
/**
@@ -757,6 +749,11 @@ cf_lex_init(int is_cli, struct config *c)
c->root_scope = cfg_allocz(sizeof(struct sym_scope));
conf_this_scope = c->root_scope;
conf_this_scope->active = 1;
+
+ if (is_cli)
+ conf_this_scope->next = config->root_scope;
+ else
+ conf_this_scope->next = global_root_scope;
}
/**