comparison 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
comparison
equal deleted inserted replaced
765:dc54387ee1cd 766:1b2f8280ba81
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. 4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
5 */ 5 */
6 #include "tern.h" 6 #include "tern.h"
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdio.h>
9 11
10 tern_node * tern_insert(tern_node * head, char * key, tern_val value) 12 tern_node * tern_insert(tern_node * head, char * key, tern_val value)
11 { 13 {
12 tern_node ** cur = &head; 14 tern_node ** cur = &head;
13 while(*key) 15 while(*key)
113 void * tern_find_ptr(tern_node * head, char * key) 115 void * tern_find_ptr(tern_node * head, char * key)
114 { 116 {
115 return tern_find_ptr_default(head, key, NULL); 117 return tern_find_ptr_default(head, key, NULL);
116 } 118 }
117 119
120 tern_val tern_find_path_default(tern_node *head, char *key, tern_val def)
121 {
122 tern_val ret;
123 while (*key)
124 {
125 if (!tern_find(head, key, &ret)) {
126 return def;
127 }
128 key = key + strlen(key) + 1;
129 if (*key) {
130 head = tern_get_node(ret);
131 if (!head) {
132 return def;
133 }
134 }
135 }
136 return ret;
137 }
138
139 tern_val tern_find_path(tern_node *head, char *key)
140 {
141 tern_val def;
142 def.ptrval = NULL;
143 return tern_find_path_default(head, key, def);
144 }
145
118 tern_node * tern_insert_ptr(tern_node * head, char * key, void * value) 146 tern_node * tern_insert_ptr(tern_node * head, char * key, void * value)
119 { 147 {
120 tern_val val; 148 tern_val val;
121 val.ptrval = value; 149 val.ptrval = value;
122 return tern_insert(head, key, val); 150 return tern_insert(head, key, val);
123 } 151 }
124 152
153 tern_node * tern_insert_node(tern_node *head, char *key, tern_node *value)
154 {
155 tern_val val;
156 val.intval = ((intptr_t)value) | 1;
157 return tern_insert(head, key, val);
158 }
159
160 uint32_t tern_count(tern_node *head)
161 {
162 uint32_t count = 0;
163 if (head->left) {
164 count += tern_count(head->left);
165 }
166 if (head->right) {
167 count += tern_count(head->right);
168 }
169 if (!head->el) {
170 count++;
171 } else if (head->straight.next) {
172 count += tern_count(head->straight.next);
173 }
174 return count;
175 }
176
177 #define MAX_ITER_KEY 127
178 void tern_foreach_int(tern_node *head, iter_fun fun, void *data, char *keybuf, int pos)
179 {
180 if (!head->el) {
181 keybuf[pos] = 0;
182 fun(keybuf, head->straight.value, data);
183 }
184 if (head->left) {
185 tern_foreach_int(head->left, fun, data, keybuf, pos);
186 }
187 if (head->el) {
188 if (pos == MAX_ITER_KEY) {
189 fputs("exceeded maximum key size", stderr);
190 exit(1);
191 }
192 keybuf[pos] = head->el;
193 tern_foreach_int(head->straight.next, fun, data, keybuf, pos+1);
194 }
195 if (head->right) {
196 tern_foreach_int(head->left, fun, data, keybuf, pos);
197 }
198 }
199
200 void tern_foreach(tern_node *head, iter_fun fun, void *data)
201 {
202 //lame, but good enough for my purposes
203 char key[MAX_ITER_KEY+1];
204 tern_foreach_int(head, fun, data, key, 0);
205 }
206
125 char * tern_int_key(uint32_t key, char * buf) 207 char * tern_int_key(uint32_t key, char * buf)
126 { 208 {
127 char * cur = buf; 209 char * cur = buf;
128 while (key) 210 while (key)
129 { 211 {
131 key >>= 7; 213 key >>= 7;
132 } 214 }
133 *cur = 0; 215 *cur = 0;
134 return buf; 216 return buf;
135 } 217 }
218
219 tern_node * tern_get_node(tern_val value)
220 {
221 return value.intval & 1 ? (tern_node *)(value.intval & ~1) : NULL;
222 }