Mercurial > repos > blastem
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; +}