diff tern.c @ 766:1b2f8280ba81

WIP changes to support reading cart memory map from ROM DB
author Michael Pavone <pavone@retrodev.com>
date Sun, 05 Jul 2015 14:21:34 -0700
parents de6f00204fa2
children 2f48a3c187c6
line wrap: on
line diff
--- a/tern.c	Thu Jul 02 20:43:01 2015 -0700
+++ b/tern.c	Sun Jul 05 14:21:34 2015 -0700
@@ -6,6 +6,8 @@
 #include "tern.h"
 #include <stddef.h>
 #include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
 
 tern_node * tern_insert(tern_node * head, char * key, tern_val value)
 {
@@ -115,6 +117,32 @@
 	return tern_find_ptr_default(head, key, NULL);
 }
 
+tern_val tern_find_path_default(tern_node *head, char *key, tern_val def)
+{
+	tern_val ret;
+	while (*key)
+	{
+		if (!tern_find(head, key, &ret)) {
+			return def;
+		}
+		key = key + strlen(key) + 1;
+		if (*key) {
+			head = tern_get_node(ret);
+			if (!head) {
+				return def;
+			}
+		}
+	}
+	return ret;
+}
+
+tern_val tern_find_path(tern_node *head, char *key)
+{
+	tern_val def;
+	def.ptrval = NULL;
+	return tern_find_path_default(head, key, def);
+}
+
 tern_node * tern_insert_ptr(tern_node * head, char * key, void * value)
 {
 	tern_val val;
@@ -122,6 +150,60 @@
 	return tern_insert(head, key, val);
 }
 
+tern_node * tern_insert_node(tern_node *head, char *key, tern_node *value)
+{
+	tern_val val;
+	val.intval = ((intptr_t)value) | 1;
+	return tern_insert(head, key, val);
+}
+
+uint32_t tern_count(tern_node *head)
+{
+	uint32_t count = 0;
+	if (head->left) {
+		count += tern_count(head->left);
+	}
+	if (head->right) {
+		count += tern_count(head->right);
+	}
+	if (!head->el) {
+		count++;
+	} else if (head->straight.next) {
+		count += tern_count(head->straight.next);
+	}
+	return count;
+}
+
+#define MAX_ITER_KEY 127
+void tern_foreach_int(tern_node *head, iter_fun fun, void *data, char *keybuf, int pos)
+{
+	if (!head->el) {
+		keybuf[pos] = 0;
+		fun(keybuf, head->straight.value, data);
+	}
+	if (head->left) {
+		tern_foreach_int(head->left, fun, data, keybuf, pos);
+	}
+	if (head->el) {
+		if (pos == MAX_ITER_KEY) {
+			fputs("exceeded maximum key size", stderr);
+			exit(1);
+		}
+		keybuf[pos] = head->el;
+		tern_foreach_int(head->straight.next, fun, data, keybuf, pos+1);
+	}
+	if (head->right) {
+		tern_foreach_int(head->left, fun, data, keybuf, pos);
+	}
+}
+
+void tern_foreach(tern_node *head, iter_fun fun, void *data)
+{
+	//lame, but good enough for my purposes
+	char key[MAX_ITER_KEY+1];
+	tern_foreach_int(head, fun, data, key, 0);
+}
+
 char * tern_int_key(uint32_t key, char * buf)
 {
 	char * cur = buf;
@@ -133,3 +215,8 @@
 	*cur = 0;
 	return buf;
 }
+
+tern_node * tern_get_node(tern_val value)
+{
+	return value.intval & 1 ? (tern_node *)(value.intval & ~1) : NULL;
+}