Arquivo de build
[pspdecompiler.git] / nids.c
blobe7b093956f1ffe3fbde1014f3660587537810dfc
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <expat.h>
7 #include "nids.h"
8 #include "hash.h"
9 #include "utils.h"
11 struct nidstable {
12 hashpool pool;
13 hashtable libs;
14 char *buffer;
17 enum XMLSCOPE {
18 XMLS_LIBRARY,
19 XMLS_FUNCTION,
20 XMLS_VARIABLE
23 enum XMLELEMENT {
24 XMLE_DEFAULT,
25 XMLE_NID,
26 XMLE_NAME
29 struct xml_data {
30 enum XMLSCOPE scope;
31 enum XMLELEMENT last;
33 size_t buffer_pos;
34 struct nidstable *result;
35 hashtable curlib;
36 const char *libname;
38 unsigned int nid;
39 const char *name;
40 int error;
43 void nids_free (struct nidstable *nids)
45 nids->libs = NULL;
46 if (nids->buffer) free (nids->buffer);
47 nids->buffer = NULL;
48 if (nids->pool) hashpool_destroy (nids->pool);
49 nids->pool = NULL;
50 free (nids);
54 static
55 void start_hndl (void *data, const char *el, const char **attr)
57 struct xml_data *d = (struct xml_data *) data;
59 d->last = XMLE_DEFAULT;
61 if (strcmp (el, "LIBRARY") == 0) {
62 d->scope = XMLS_LIBRARY;
63 } else if (strcmp (el, "NAME") == 0) {
64 d->last = XMLE_NAME;
65 } else if (strcmp (el, "FUNCTION") == 0) {
66 d->scope = XMLS_FUNCTION;
67 } else if (strcmp (el, "VARIABLE") == 0) {
68 d->scope = XMLS_VARIABLE;
69 } else if (strcmp (el, "NID") == 0) {
70 d->last = XMLE_NID;
74 static
75 void end_hndl (void *data, const char *el)
77 struct xml_data *d = (struct xml_data *) data;
79 d->last = XMLE_DEFAULT;
81 if (strcmp (el, "LIBRARY") == 0) {
82 d->curlib = NULL;
83 d->libname = NULL;
84 } else if (strcmp (el, "FUNCTION") == 0 || strcmp (el, "VARIABLE") == 0) {
85 d->scope = XMLS_LIBRARY;
86 if (d->name && d->nid && d->curlib) {
87 const char *name = hashtable_searchhash (d->curlib, NULL, NULL, d->nid);
88 if (name) {
89 if (strcmp (name, d->name)) {
90 error (__FILE__ ": NID `0x%08X' repeated in library `%s'", d->nid, d->libname);
91 d->error = 1;
93 } else {
94 hashtable_inserthash (d->curlib, NULL, (void *) d->name, d->nid);
96 } else {
97 error (__FILE__ ": missing function or variable definition");
98 d->error = 1;
100 d->name = NULL;
101 d->nid = 0;
105 static
106 const char *dup_string (struct xml_data *d, const char *txt, size_t len)
108 char *result;
110 result = &d->result->buffer[d->buffer_pos];
111 memcpy (result, txt, len);
112 result[len] = '\0';
113 d->buffer_pos += len + 1;
115 return (const char *) result;
118 static
119 void char_hndl (void *data, const char *txt, int txtlen)
121 struct xml_data *d = (struct xml_data *) data;
123 switch (d->scope) {
124 case XMLS_FUNCTION:
125 case XMLS_VARIABLE:
126 if (d->last == XMLE_NAME) {
127 if (d->name) {
128 error (__FILE__ ": repeated name in function/variable");
129 d->error = 1;
130 } else {
131 d->name = dup_string (d, txt, txtlen);
133 } else if (d->last == XMLE_NID) {
134 char buffer[256];
136 if (txtlen > sizeof (buffer) - 1)
137 txtlen = sizeof (buffer) - 1;
138 memcpy (buffer, txt, txtlen);
139 buffer[txtlen] = '\0';
141 if (d->nid) {
142 error (__FILE__ ": nid repeated in function/variable");
143 d->error = 1;
144 } else {
145 d->nid = 0;
146 sscanf (buffer, "0x%X", &d->nid);
149 break;
150 case XMLS_LIBRARY:
151 if (d->last == XMLE_NAME) {
152 d->libname = dup_string (d, txt, txtlen);
153 if (d->curlib) {
154 error (__FILE__ ": current lib is not null");
155 d->error = 1;
156 } else {
157 d->curlib = hashtable_search (d->result->libs, (void *) d->libname, NULL);
158 if (!d->curlib) {
159 d->curlib = hashtable_alloc (d->result->pool, 128, NULL, &hashtable_pointer_compare);
160 hashtable_insert (d->result->libs, (void *) d->libname, d->curlib);
164 break;
168 struct nidstable *nids_load (const char *xmlpath)
170 XML_Parser p;
171 struct xml_data data;
172 size_t size;
173 void *buf;
175 buf = read_file (xmlpath, &size);
176 if (!buf) {
177 return NULL;
180 p = XML_ParserCreate (NULL);
181 if (!p) {
182 error (__FILE__ ": can't create XML parser");
183 free (buf);
184 return 0;
187 data.error = 0;
188 data.curlib = NULL;
189 data.libname = NULL;
190 data.name = NULL;
191 data.nid = 0;
192 data.scope = XMLS_LIBRARY;
193 data.last = XMLE_DEFAULT;
195 data.result = (struct nidstable *) xmalloc (sizeof (struct nidstable));
196 data.result->pool = hashpool_create (256, 8192);
197 data.result->libs = hashtable_alloc (data.result->pool, 32, &hashtable_hash_string, &hashtable_string_compare);
199 data.buffer_pos = 0;
200 data.result->buffer = buf;
201 buf = xmalloc (size);
203 memcpy (buf, data.result->buffer, size);
205 XML_SetUserData (p, (void *) &data);
206 XML_SetElementHandler (p, &start_hndl, &end_hndl);
207 XML_SetCharacterDataHandler (p, &char_hndl);
209 if (!XML_Parse (p, buf, size, 1)) {
210 error (__FILE__ ": parse error at line %d:\n %s\n", XML_GetCurrentLineNumber (p),
211 XML_ErrorString (XML_GetErrorCode (p)));
212 data.error = 1;
215 XML_ParserFree (p);
216 free (buf);
218 if (data.error) {
219 nids_free (data.result);
220 return NULL;
223 return data.result;
226 static
227 void print_level1 (void *key, void *value, unsigned int hash, void *arg)
229 report (" NID: 0x%08X - Name: %s\n", hash, (char *) value);
232 static
233 void print_level0 (void *key, void *value, unsigned int hash, void *arg)
235 hashtable lib = (hashtable) value;
236 report (" %s:\n", (char *) key);
237 hashtable_traverse (lib, &print_level1, NULL);
238 report ("\n");
241 void nids_print (struct nidstable *nids)
243 report ("Libraries:\n");
244 hashtable_traverse (nids->libs, &print_level0, NULL);
248 const char *nids_find (struct nidstable *nids, const char *library, unsigned int nid)
250 hashtable lib;
252 lib = hashtable_search (nids->libs, (void *) library, NULL);
253 if (lib) return hashtable_searchhash (lib, NULL, NULL, nid);
254 return NULL;
258 #ifdef TEST_NIDS
259 int main (int argc, char **argv)
261 struct nidstable *nids = NULL;
263 nids = nids_load (argv[1]);
264 if (nids) {
265 nids_print (nids);
266 nids_free (nids);
268 return 0;
271 #endif /* TEST_NIDS */