summaryrefslogtreecommitdiff
path: root/src/user/highway/vars.c
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2020-09-13 22:06:40 -0400
committerBenji Dial <benji6283@gmail.com>2020-09-13 22:06:40 -0400
commit44d29a33df81ac07163d5146a9e43a0c4fb80af0 (patch)
tree94d4fb506a80d73cb53dc9ea66dfc952d7a9432a /src/user/highway/vars.c
parent143156f63e2448733f1a35a74e629fe0ae9bb567 (diff)
downloadportland-os-44d29a33df81ac07163d5146a9e43a0c4fb80af0.tar.gz
new shell
Diffstat (limited to 'src/user/highway/vars.c')
-rw-r--r--src/user/highway/vars.c98
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