Mercurial > repos > blastem
annotate tern.c @ 1470:1e3e0205640f
Add support for writeable ROM and an entry for Game no Kanzume Otokuyou using that support as it expects the cart area to be writable
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 14 Oct 2017 05:03:38 -0700 |
parents | 071e761bcdcf |
children | e890971f3757 |
rev | line source |
---|---|
467
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
431
diff
changeset
|
1 /* |
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
431
diff
changeset
|
2 Copyright 2013 Michael Pavone |
498
51bf87f76d15
Pull shader file names from config file.
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
3 This file is part of BlastEm. |
467
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
431
diff
changeset
|
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. |
140af5509ce7
Added copyright notice to source files and added GPL license text in COPYING
Mike Pavone <pavone@retrodev.com>
parents:
431
diff
changeset
|
5 */ |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 #include "tern.h" |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
7 #include <stddef.h> |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
8 #include <stdlib.h> |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
9 #include <string.h> |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
10 #include <stdio.h> |
792
724bbec47f86
Use a new fatal_error function instead of calling fprintf and exit for fatal errors. This new function more gracefully handles the case in which BlastEm was not started from a terminal or disconnected from ther terminal (Windows).
Michael Pavone <pavone@retrodev.com>
parents:
768
diff
changeset
|
11 #include "util.h" |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
12 |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
13 tern_node * tern_insert(tern_node * head, char const * key, tern_val value, uint8_t valtype) |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
15 tern_node ** cur = &head; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
16 while(*key) |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
17 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 if (*cur) { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 while(*cur && (*cur)->el != *key) |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
21 if (*key < (*cur)->el) { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
22 cur = &(*cur)->left; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 } else { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 cur = &(*cur)->right; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
26 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 if (!*cur) { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 *cur = malloc(sizeof(tern_node)); |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 (*cur)->left = NULL; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 (*cur)->right = NULL; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 (*cur)->straight.next = NULL; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 (*cur)->el = *key; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
34 (*cur)->valtype = TVAL_NONE; |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
36 cur = &((*cur)->straight.next); |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
37 key++; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
38 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 while(*cur && (*cur)->el) |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
40 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 cur = &(*cur)->left; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 if (!*cur) { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
44 *cur = malloc(sizeof(tern_node)); |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 (*cur)->left = NULL; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 (*cur)->right = NULL; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 (*cur)->el = 0; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 (*cur)->straight.value = value; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
50 (*cur)->valtype = valtype; |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 return head; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
54 uint8_t tern_find(tern_node * head, char const * key, tern_val *ret) |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 tern_node * cur = head; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 while (cur) |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 if (cur->el == *key) { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 if (*key) { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 cur = cur->straight.next; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 key++; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 } else { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 *ret = cur->straight.value; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
65 return cur->valtype; |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 } else if (*key < cur->el) { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 cur = cur->left; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
69 } else { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 cur = cur->right; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 } |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
73 return TVAL_NONE; |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 |
1186
110251ea369e
Consting up some parameters to ternary tree functions
Michael Pavone <pavone@retrodev.com>
parents:
792
diff
changeset
|
76 tern_node * tern_find_prefix(tern_node * head, char const * key) |
431
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
77 { |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
78 tern_node * cur = head; |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
79 while (cur && *key) |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
80 { |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
81 if (cur->el == *key) { |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
82 cur = cur->straight.next; |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
83 key++; |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
84 } else if (*key < cur->el) { |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
85 cur = cur->left; |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
86 } else { |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
87 cur = cur->right; |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
88 } |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
89 } |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
90 return cur; |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
91 } |
440efd7d27a9
Read key bindings from config file
Mike Pavone <pavone@retrodev.com>
parents:
429
diff
changeset
|
92 |
1186
110251ea369e
Consting up some parameters to ternary tree functions
Michael Pavone <pavone@retrodev.com>
parents:
792
diff
changeset
|
93 intptr_t tern_find_int(tern_node * head, char const * key, intptr_t def) |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 tern_val ret; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
96 uint8_t valtype = tern_find(head, key, &ret); |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
97 if (valtype == TVAL_INT) { |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 return ret.intval; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 return def; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 |
1186
110251ea369e
Consting up some parameters to ternary tree functions
Michael Pavone <pavone@retrodev.com>
parents:
792
diff
changeset
|
103 tern_node * tern_insert_int(tern_node * head, char const * key, intptr_t value) |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 tern_val val; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 val.intval = value; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
107 return tern_insert(head, key, val, TVAL_INT); |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
109 |
1186
110251ea369e
Consting up some parameters to ternary tree functions
Michael Pavone <pavone@retrodev.com>
parents:
792
diff
changeset
|
110 void * tern_find_ptr_default(tern_node * head, char const * key, void * def) |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
111 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 tern_val ret; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
113 uint8_t valtype = tern_find(head, key, &ret); |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
114 if (valtype == TVAL_PTR) { |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
115 return ret.ptrval; |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
116 } |
498
51bf87f76d15
Pull shader file names from config file.
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
117 return def; |
51bf87f76d15
Pull shader file names from config file.
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
118 } |
51bf87f76d15
Pull shader file names from config file.
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
119 |
1186
110251ea369e
Consting up some parameters to ternary tree functions
Michael Pavone <pavone@retrodev.com>
parents:
792
diff
changeset
|
120 void * tern_find_ptr(tern_node * head, char const * key) |
498
51bf87f76d15
Pull shader file names from config file.
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
121 { |
51bf87f76d15
Pull shader file names from config file.
Mike Pavone <pavone@retrodev.com>
parents:
467
diff
changeset
|
122 return tern_find_ptr_default(head, key, NULL); |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
125 tern_node *tern_find_node(tern_node *head, char const *key) |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
126 { |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
127 tern_val ret; |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
128 uint8_t valtype = tern_find(head, key, &ret); |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
129 if (valtype == TVAL_NODE) { |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
130 return ret.ptrval; |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
131 } |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
132 return NULL; |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
133 } |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
134 |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
135 tern_val tern_find_path_default(tern_node *head, char const *key, tern_val def, uint8_t req_valtype) |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
136 { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
137 tern_val ret; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
138 while (*key) |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
139 { |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
140 uint8_t valtype = tern_find(head, key, &ret); |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
141 if (!valtype) { |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
142 return def; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
143 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
144 key = key + strlen(key) + 1; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
145 if (*key) { |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
146 if (valtype != TVAL_NODE) { |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
147 return def; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
148 } |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
149 head = ret.ptrval; |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
150 } else if (req_valtype && req_valtype != valtype) { |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
151 return def; |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
152 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
153 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
154 return ret; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
155 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
156 |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
157 tern_val tern_find_path(tern_node *head, char const *key, uint8_t valtype) |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
158 { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
159 tern_val def; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
160 def.ptrval = NULL; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
161 return tern_find_path_default(head, key, def, valtype); |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
162 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
163 |
1186
110251ea369e
Consting up some parameters to ternary tree functions
Michael Pavone <pavone@retrodev.com>
parents:
792
diff
changeset
|
164 tern_node * tern_insert_ptr(tern_node * head, char const * key, void * value) |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 { |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 tern_val val; |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
167 val.ptrval = value; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
168 return tern_insert(head, key, val, TVAL_PTR); |
429
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
169 } |
f6fdde540791
Added ternary tree implementation and a simple test program for it
Mike Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
170 |
1186
110251ea369e
Consting up some parameters to ternary tree functions
Michael Pavone <pavone@retrodev.com>
parents:
792
diff
changeset
|
171 tern_node * tern_insert_node(tern_node *head, char const *key, tern_node *value) |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
172 { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
173 tern_val val; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
174 val.ptrval = value; |
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
175 return tern_insert(head, key, val, TVAL_NODE); |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
176 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
177 |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
178 uint32_t tern_count(tern_node *head) |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
179 { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
180 uint32_t count = 0; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
181 if (head->left) { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
182 count += tern_count(head->left); |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
183 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
184 if (head->right) { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
185 count += tern_count(head->right); |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
186 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
187 if (!head->el) { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
188 count++; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
189 } else if (head->straight.next) { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
190 count += tern_count(head->straight.next); |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
191 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
192 return count; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
193 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
194 |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
195 #define MAX_ITER_KEY 127 |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
196 void tern_foreach_int(tern_node *head, iter_fun fun, void *data, char *keybuf, int pos) |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
197 { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
198 if (!head->el) { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
199 keybuf[pos] = 0; |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
200 fun(keybuf, head->straight.value, head->valtype, data); |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
201 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
202 if (head->left) { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
203 tern_foreach_int(head->left, fun, data, keybuf, pos); |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
204 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
205 if (head->el) { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
206 if (pos == MAX_ITER_KEY) { |
792
724bbec47f86
Use a new fatal_error function instead of calling fprintf and exit for fatal errors. This new function more gracefully handles the case in which BlastEm was not started from a terminal or disconnected from ther terminal (Windows).
Michael Pavone <pavone@retrodev.com>
parents:
768
diff
changeset
|
207 fatal_error("tern_foreach_int: exceeded maximum key size"); |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
208 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
209 keybuf[pos] = head->el; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
210 tern_foreach_int(head->straight.next, fun, data, keybuf, pos+1); |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
211 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
212 if (head->right) { |
768
2f48a3c187c6
Add support for reading cartridge memory map from ROM database, though without EEPROM support for now
Michael Pavone <pavone@retrodev.com>
parents:
766
diff
changeset
|
213 tern_foreach_int(head->right, fun, data, keybuf, pos); |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
214 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
215 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
216 |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
217 void tern_foreach(tern_node *head, iter_fun fun, void *data) |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
218 { |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
219 //lame, but good enough for my purposes |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
220 char key[MAX_ITER_KEY+1]; |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
221 tern_foreach_int(head, fun, data, key, 0); |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
222 } |
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
223 |
631
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
224 char * tern_int_key(uint32_t key, char * buf) |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
225 { |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
226 char * cur = buf; |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
227 while (key) |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
228 { |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
229 *(cur++) = (key & 0x7F) + 1; |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
230 key >>= 7; |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
231 } |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
232 *cur = 0; |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
233 return buf; |
de6f00204fa2
Add support for disassembling VOS program modules
Michael Pavone <pavone@retrodev.com>
parents:
498
diff
changeset
|
234 } |
766
1b2f8280ba81
WIP changes to support reading cart memory map from ROM DB
Michael Pavone <pavone@retrodev.com>
parents:
631
diff
changeset
|
235 |
1293
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
236 void tern_free(tern_node *head) |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
237 { |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
238 if (head->left) { |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
239 tern_free(head->left); |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
240 } |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
241 if (head->right) { |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
242 tern_free(head->right); |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
243 } |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
244 if (head->el) { |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
245 tern_free(head->straight.next); |
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
246 } |
1326
071e761bcdcf
Fix a deficiency in the way types were handled in my ternary tree. Fixes in which some paths that were constructed from a template with variables would sometimes get an extra garbage character thrown in
Michael Pavone <pavone@retrodev.com>
parents:
1293
diff
changeset
|
247 free(head); |
1293
72ea3885e7b5
Don't leak a ternary tree when building the menu's initial path
Michael Pavone <pavone@retrodev.com>
parents:
1186
diff
changeset
|
248 } |