diff options
Diffstat (limited to 'src/user/highway/vars.c')
-rw-r--r-- | src/user/highway/vars.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/user/highway/vars.c b/src/user/highway/vars.c new file mode 100644 index 0000000..6090b76 --- /dev/null +++ b/src/user/highway/vars.c @@ -0,0 +1,98 @@ +#include <knob/block.h> +#include <knob/heap.h> +#include <knob/user.h> + +struct no_null_sn { + char *data; + uint32_t length; +}; + +struct var_dict_node { + struct var_dict_node *next; + struct var_dict_node *prev; + struct no_null_sn name; + struct no_null_sn value; +}; + +static struct var_dict_node *var_dict_start = 0; + +__attribute__ ((pure)) +static struct var_dict_node *get_node(struct no_null_sn name) { + for (struct var_dict_node *i = var_dict_start; i; i = i->next) + if ((i->name.length == name.length) && + blockequ(i->name.data, name.data, name.length)) + return i; + return 0; +} + +static struct var_dict_node *new_node() { + struct var_dict_node *node = get_block(sizeof(struct var_dict_node)); + node->prev = 0; + node->next = var_dict_start; + if (var_dict_start) + var_dict_start->prev = node; + var_dict_start = node; + return node; +} + +void set_var(struct no_null_sn name, struct no_null_sn value) { + struct var_dict_node *node = get_node(name); + if (node) + free_block(node->value.data); + else { + node = new_node(); + node->name.length = name.length; + node->name.data = get_block(name.length); + blockcpy(node->name.data, name.data, name.length); + } + node->value.length = value.length; + node->value.data = get_block(value.length); + blockcpy(node->value.data, value.data, value.length); +} + +__attribute__ ((pure)) +const struct no_null_sn *get_var(struct no_null_sn name) { + struct var_dict_node *node = get_node(name); + return node ? &node->value : 0; +} + +void del_var(struct no_null_sn name) { + struct var_dict_node *node = get_node(name); + if (!node) + return; + free_block(node->name.data); + free_block(node->value.data); + if (node->prev) + node->prev->next = node->next; + if (node->next) + node->next->prev = node->prev; + if (node == var_dict_start) + var_dict_start = node->next; + free_block(node); +} + +void dump_vars() { + for (struct var_dict_node *node = var_dict_start; node; node = node->next) { + tell_user_sz("$"); + + char *buf = get_block(node->name.length + 1); + blockcpy(buf, node->name.data, node->name.length); + buf[node->name.length] = '\0'; + + tell_user_sz(buf); + + free_block(buf); + + tell_user_sz("$ = "); + + buf = get_block(node->value.length + 1); + blockcpy(buf, node->value.data, node->value.length); + buf[node->value.length] = '\0'; + + tell_user_sz(buf); + + free_block(buf); + + tell_user_sz("\n"); + } +}
\ No newline at end of file |