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