summaryrefslogtreecommitdiff
path: root/conf/cf-lex.l
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-03-19 16:23:42 +0100
committerMaria Matejka <mq@ucw.cz>2022-05-04 15:39:19 +0200
commit17f91f9e6e70f7e3f29502e854823c0d48571eaa (patch)
treefab70e2115ce8d4e070382368df3eff4f3f44b97 /conf/cf-lex.l
parent165156beeb2926472bbceca3c103aacc3f81a8cc (diff)
Explicit definition structures of route attributes
Changes in internal API: * Every route attribute must be defined as struct ea_class somewhere. * Registration of route attributes known at startup must be done by ea_register_init() from protocol build functions. * Every attribute has now its symbol registered in a global symbol table defined as SYM_ATTRIBUTE * All attribute ID's are dynamically allocated. * Attribute value custom formatting hook is defined in the ea_class. * Attribute names are the same for display and filters, always prefixed by protocol name. Also added some unit testing code for filters with route attributes.
Diffstat (limited to 'conf/cf-lex.l')
-rw-r--r--conf/cf-lex.l54
1 files changed, 51 insertions, 3 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index bd424c69..e84e1d9d 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -86,9 +86,12 @@ static uint cf_hash(const byte *c);
HASH_DEFINE_REHASH_FN(SYM, struct symbol)
HASH(struct keyword) kw_hash;
+HASH(struct ea_class) ea_name_hash;
struct sym_scope *conf_this_scope;
-struct sym_scope *global_root_scope;
+
+static struct sym_scope global_root_scope__init = { .active = 1, };
+struct sym_scope *global_root_scope = &global_root_scope__init;
linpool *cfg_mem;
@@ -598,6 +601,25 @@ cf_new_symbol(const byte *c)
return s;
}
+static struct symbol *
+cf_root_symbol(const byte *c)
+{
+ uint l = strlen(c);
+ if (l > SYM_MAX_LEN)
+ bug("Root symbol %s too long", c);
+
+ struct symbol *s = mb_alloc(&root_pool, sizeof(struct symbol) + l + 1);
+ *s = (struct symbol) { .scope = global_root_scope, .class = SYM_VOID, };
+ memcpy(s->name, c, l+1);
+
+ if (!global_root_scope->hash.data)
+ HASH_INIT(global_root_scope->hash, &root_pool, SYM_ORDER);
+
+ HASH_INSERT2(global_root_scope->hash, SYM, &root_pool, s);
+ return s;
+}
+
+
/**
* cf_find_symbol_scope - find a symbol by name
* @scope: config scope
@@ -652,7 +674,7 @@ cf_localize_symbol(struct symbol *sym)
/* If the symbol type is void, it has been recently allocated just in this scope. */
if (!sym->class)
return sym;
-
+
/* If the scope is the current, it is already defined in this scope. */
if (sym->scope == conf_this_scope)
cf_error("Symbol already defined");
@@ -716,8 +738,34 @@ cf_lex_init_kh(void)
struct keyword *k;
for (k=keyword_list; k->name; k++)
HASH_INSERT(kw_hash, KW, k);
+}
+
+void
+ea_lex_register(struct ea_class *def)
+{
+ struct symbol *sym = cf_root_symbol(def->name);
+ sym->class = SYM_ATTRIBUTE;
+ sym->attribute = def;
+ def->sym = sym;
+}
- global_root_scope = mb_allocz(&root_pool, sizeof(*global_root_scope));
+void
+ea_lex_unregister(struct ea_class *def)
+{
+ struct symbol *sym = def->sym;
+ HASH_REMOVE2(global_root_scope->hash, SYM, &root_pool, sym);
+ mb_free(sym);
+ def->sym = NULL;
+}
+
+struct ea_class *
+ea_class_find_by_name(const char *name)
+{
+ struct symbol *sym = cf_find_symbol(global_root_scope, name);
+ if (!sym || (sym->class != SYM_ATTRIBUTE))
+ return NULL;
+ else
+ return sym->attribute;
}
/**