Problemas com os relocs
[pspdecompiler.git] / nids.c
blob5770a2cae7a567dd0133b3a5ed855868fb47abfc
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 struct hashtable *libs;
13 char *buffer;
16 enum XMLSCOPE {
17 XMLS_LIBRARY,
18 XMLS_FUNCTION,
19 XMLS_VARIABLE
22 enum XMLELEMENT {
23 XMLE_DEFAULT,
24 XMLE_NID,
25 XMLE_NAME
28 struct xml_data {
29 enum XMLSCOPE scope;
30 enum XMLELEMENT last;
32 size_t buffer_pos;
33 struct nidstable *result;
34 struct hashtable *curlib;
35 const char *libname;
37 unsigned int nid;
38 const char *name;
39 int error;
42 static
43 void nids_free_callback (void *key, void *value, unsigned int hash, void *arg)
45 struct hashtable *lib = (struct hashtable *) value;
46 hashtable_free (lib, NULL, NULL);
49 void nids_free (struct nidstable *nids)
51 if (nids->libs) hashtable_free (nids->libs, &nids_free_callback, NULL);
52 nids->libs = NULL;
53 if (nids->buffer) free (nids->buffer);
54 nids->buffer = NULL;
55 free (nids);
59 static
60 void start_hndl (void *data, const char *el, const char **attr)
62 struct xml_data *d = (struct xml_data *) data;
64 d->last = XMLE_DEFAULT;
66 if (strcmp (el, "LIBRARY") == 0) {
67 d->scope = XMLS_LIBRARY;
68 } else if (strcmp (el, "NAME") == 0) {
69 d->last = XMLE_NAME;
70 } else if (strcmp (el, "FUNCTION") == 0) {
71 d->scope = XMLS_FUNCTION;
72 } else if (strcmp (el, "VARIABLE") == 0) {
73 d->scope = XMLS_VARIABLE;
74 } else if (strcmp (el, "NID") == 0) {
75 d->last = XMLE_NID;
79 static
80 void end_hndl (void *data, const char *el)
82 struct xml_data *d = (struct xml_data *) data;
84 d->last = XMLE_DEFAULT;
86 if (strcmp (el, "LIBRARY") == 0) {
87 d->curlib = NULL;
88 d->libname = NULL;
89 } else if (strcmp (el, "FUNCTION") == 0 || strcmp (el, "VARIABLE") == 0) {
90 d->scope = XMLS_LIBRARY;
91 if (d->name && d->nid && d->curlib) {
92 const char *name = hashtable_searchh (d->curlib, NULL, NULL, d->nid);
93 if (name) {
94 if (strcmp (name, d->name)) {
95 error (__FILE__ ": NID `0x%08X' repeated in library `%s'", d->nid, d->libname);
96 d->error = 1;
98 } else {
99 hashtable_inserth (d->curlib, NULL, (void *) d->name, d->nid);
101 } else {
102 error (__FILE__ ": missing function or variable definition");
103 d->error = 1;
105 d->name = NULL;
106 d->nid = 0;
110 static
111 const char *dup_string (struct xml_data *d, const char *txt, size_t len)
113 char *result;
115 result = &d->result->buffer[d->buffer_pos];
116 memcpy (result, txt, len);
117 result[len] = '\0';
118 d->buffer_pos += len + 1;
120 return (const char *) result;
123 static
124 void char_hndl (void *data, const char *txt, int txtlen)
126 struct xml_data *d = (struct xml_data *) data;
128 switch (d->scope) {
129 case XMLS_FUNCTION:
130 case XMLS_VARIABLE:
131 if (d->last == XMLE_NAME) {
132 if (d->name) {
133 error (__FILE__ ": repeated name in function/variable");
134 d->error = 1;
135 } else {
136 d->name = dup_string (d, txt, txtlen);
138 } else if (d->last == XMLE_NID) {
139 char buffer[256];
141 if (txtlen > sizeof (buffer) - 1)
142 txtlen = sizeof (buffer) - 1;
143 memcpy (buffer, txt, txtlen);
144 buffer[txtlen] = '\0';
146 if (d->nid) {
147 error (__FILE__ ": nid repeated in function/variable");
148 d->error = 1;
149 } else {
150 d->nid = 0;
151 sscanf (buffer, "0x%X", &d->nid);
154 break;
155 case XMLS_LIBRARY:
156 if (d->last == XMLE_NAME) {
157 d->libname = dup_string (d, txt, txtlen);
158 if (d->curlib) {
159 error (__FILE__ ": current lib is not null");
160 d->error = 1;
161 } else {
162 d->curlib = hashtable_search (d->result->libs, (void *) d->libname, NULL);
163 if (!d->curlib) {
164 d->curlib = hashtable_create (128, NULL, &hashtable_pointer_compare);
165 hashtable_insert (d->result->libs, (void *) d->libname, d->curlib);
169 break;
173 struct nidstable *nids_load (const char *xmlpath)
175 XML_Parser p;
176 struct xml_data data;
177 size_t size;
178 void *buf;
180 buf = read_file (xmlpath, &size);
181 if (!buf) {
182 return NULL;
185 p = XML_ParserCreate (NULL);
186 if (!p) {
187 error (__FILE__ ": can't create XML parser");
188 free (buf);
189 return 0;
192 data.error = 0;
193 data.curlib = NULL;
194 data.libname = NULL;
195 data.name = NULL;
196 data.nid = 0;
197 data.scope = XMLS_LIBRARY;
198 data.last = XMLE_DEFAULT;
200 data.result = (struct nidstable *) xmalloc (sizeof (struct nidstable));
201 data.result->libs = hashtable_create (32, &hashtable_hash_string, &hashtable_string_compare);
203 data.buffer_pos = 0;
204 data.result->buffer = xmalloc (size);
206 XML_SetUserData (p, (void *) &data);
207 XML_SetElementHandler (p, &start_hndl, &end_hndl);
208 XML_SetCharacterDataHandler (p, &char_hndl);
210 if (!XML_Parse (p, buf, size, 1)) {
211 error (__FILE__ ": parse error at line %d:\n %s\n", XML_GetCurrentLineNumber (p),
212 XML_ErrorString (XML_GetErrorCode (p)));
213 data.error = 1;
216 XML_ParserFree (p);
217 free (buf);
219 if (data.error) {
220 nids_free (data.result);
221 return NULL;
224 return data.result;
227 static
228 void print_level1 (void *key, void *value, unsigned int hash, void *arg)
230 report (" NID: 0x%08X - Name: %s\n", hash, (char *) value);
233 static
234 void print_level0 (void *key, void *value, unsigned int hash, void *arg)
236 struct hashtable *lib = (struct hashtable *) value;
237 report (" %s:\n", (char *) key);
238 hashtable_traverse (lib, &print_level1, NULL);
239 report ("\n");
242 void nids_print (struct nidstable *nids)
244 report ("Libraries:\n");
245 hashtable_traverse (nids->libs, &print_level0, NULL);
249 const char *nids_find (struct nidstable *nids, const char *library, unsigned int nid)
251 struct hashtable *lib;
253 lib = hashtable_search (nids->libs, (void *) library, NULL);
254 if (lib) return hashtable_searchh (lib, NULL, NULL, nid);
255 return NULL;
259 #ifdef TEST_NIDS
260 int main (int argc, char **argv)
262 struct nidstable *nids = NULL;
264 nids = nids_load (argv[1]);
265 if (nids) {
266 nids_print (nids);
267 nids_free (nids);
269 return 0;
272 #endif /* TEST_NIDS */