diff tern.c @ 1522:63659fb92db4 nuklear_ui

Key binding menu is now functional
author Michael Pavone <pavone@retrodev.com>
date Tue, 06 Feb 2018 22:42:16 -0800
parents e890971f3757
children 193b804c9845
line wrap: on
line diff
--- a/tern.c	Mon Feb 05 23:39:14 2018 -0800
+++ b/tern.c	Tue Feb 06 22:42:16 2018 -0800
@@ -138,6 +138,39 @@
 	return NULL;
 }
 
+uint8_t tern_delete(tern_node **head, char const *key, tern_val *out)
+{
+	tern_node *cur = *head, **last = head;
+	while (cur)
+	{
+		if (cur->el == *key) {
+			if (*key) {
+				last = &cur->straight.next;
+				cur = cur->straight.next;
+				key++;
+			} else {
+				break;
+			}
+		} else if (*key < cur->el) {
+			last = &cur->left;
+			cur = cur->left;
+		} else {
+			last = &cur->right;
+			cur = cur->right;
+		}
+	}
+	if (!cur) {
+		return TVAL_NONE;
+	}
+	*last = cur->right;
+	uint8_t valtype = cur->valtype;
+	if (out) {
+		*out = cur->straight.value;
+	}
+	free(cur);
+	return valtype;
+}
+
 tern_val tern_find_path_default(tern_node *head, char const *key, tern_val def, uint8_t req_valtype)
 {
 	tern_val ret;
@@ -193,6 +226,25 @@
 	}
 }
 
+uint8_t tern_delete_path(tern_node **head, char const *key, tern_val *out)
+{
+	const char *next_key = key + strlen(key) + 1;
+	if (*next_key) {
+		tern_node *child = tern_find_node(*head, key);
+		if (!child) {
+			return TVAL_NONE;
+		}
+		tern_node *tmp = child;
+		uint8_t valtype = tern_delete_path(&tmp, next_key, out);
+		if (tmp != child) {
+			*head = tern_insert_node(*head, key, tmp);
+		}
+		return valtype;
+	} else {
+		return tern_delete(head, key, out);
+	}
+}
+
 uint32_t tern_count(tern_node *head)
 {
 	uint32_t count = 0;
@@ -220,7 +272,7 @@
 	if (head->left) {
 		tern_foreach_int(head->left, fun, data, keybuf, pos);
 	}
-	if (head->el) {
+	if (head->el && head->straight.next) {
 		if (pos == MAX_ITER_KEY) {
 			fatal_error("tern_foreach_int: exceeded maximum key size");
 		}