Cleanup, comments ...
[libfirm] / ir / external / read.c
1 /* -*- c -*- */
2
3 /*
4  * Project:     libFIRM
5  * File name:   ir/external/read.c
6  * Purpose:     Read descriptions of external effects
7  * Author:      Florian
8  * Modified by:
9  * Created:     11.10.2004
10  * CVS-ID:      $$
11  * Copyright:   (c) 1999-2004 Universität Karlsruhe
12  * Licence:     This file is protected by GPL -  GNU GENERAL PUBLIC LICENSE.
13  */
14
15 # include "read.h"
16
17 static type_t *types = NULL;
18 static entity_t *entities = NULL;
19 static effs_t *effs = NULL;
20
21 static int _ent_id = 0;
22 /* static int _node_id = 0; */
23
24 static const char*
25 getNodeModule (xmlNodePtr node)
26 {
27   char *mod_str = (char*) xmlGetProp (node, BAD_CAST "module");
28
29   if (NULL == mod_str) {
30     return (NULL);
31   } else {
32     const char *res = strdup (mod_str);
33
34     return (res);
35   }
36 }
37
38 static char*
39 getNodeProcName (xmlNodePtr node)
40 {
41   char *proc_str = (char*) xmlGetProp (node, BAD_CAST "procname");
42
43   assert (proc_str);
44
45   return (strdup (proc_str));
46 }
47
48 static const int
49 getNodeId (xmlNodePtr node)
50 {
51   char *id_str = (char*) xmlGetProp (node, BAD_CAST "id");
52   int id;
53   assert (id_str);
54   id = atoi (id_str+1);
55
56   return (id);
57 }
58
59 static const int
60 getNodeRefId (xmlNodePtr node)
61 {
62   char *refid_str = (char*) xmlGetProp (node, BAD_CAST "refid");
63   int refid;
64   assert (refid_str);
65   refid = atoi (refid_str+1);
66
67   return (refid);
68 }
69
70 static const int
71 getNodeTypeId (xmlNodePtr node)
72 {
73   char *type_str = (char*) xmlGetProp (node, BAD_CAST "type");
74   int type_id;
75   assert (type_str);
76   type_id = atoi (type_str+1);
77
78   return (type_id);
79 }
80
81 static const char
82 *getNodeTypeStr (xmlNodePtr node)
83 {
84   const char *type_str = (char*) xmlGetProp (node, BAD_CAST "type");
85   assert (type_str);
86
87   return (type_str);
88 }
89
90 static const char
91 *getNodeEntityStr (xmlNodePtr node)
92 {
93   const char *ent_str = (char*) xmlGetProp (node, BAD_CAST "entity");
94   assert (ent_str);
95
96   return (ent_str);
97 }
98
99 static arg_t *
100 parseArg (xmlDocPtr doc, xmlNodePtr argelm)
101 {
102   int id;
103   int num;
104   char *num_str;
105   arg_t *arg;
106
107   CHECK_NAME (argelm, arg);
108   /* fprintf (stdout, "arg node \t0x%08x\n", (int) argelm); */
109
110   id = getNodeId (argelm);
111   /* fprintf (stdout, "arg->id = \"%d\"\n", id); */
112   num_str = (char*) xmlGetProp (argelm, BAD_CAST "number");
113   num = atoi (num_str);
114   /* fprintf (stdout, "arg->no = \"%d\"\n", no); */
115
116   arg = NEW (arg_t);
117   arg->kind = eff_arg;
118   arg->id = id;
119   arg->num = num;
120
121   return (arg);
122 }
123
124 static valref_t
125 *parseValref (xmlDocPtr doc, xmlNodePtr valelm)
126 {
127   int ref_id;
128   valref_t *valref;
129   CHECK_NAME (valelm, valref);
130   /* fprintf (stdout, "valref node \t0x%08x\n", (int) valelm); */
131
132   ref_id = getNodeRefId (valelm);
133   /* fprintf (stdout, "val->refid = \"%d\"\n", ref_id); */
134
135   valref = NEW (valref_t);
136   valref->kind = eff_valref;
137   valref->refid = ref_id;
138
139   return (valref);
140 }
141
142 static select_t
143 *parseSelect (xmlDocPtr doc, xmlNodePtr selelm)
144 {
145   char *entity_str = (char*) xmlGetProp (selelm, BAD_CAST "entity");
146   const int entity_id = atoi (entity_str+1);
147   entity_t *ent;
148   xmlNodePtr child;
149   valref_t *valref = NULL;
150   select_t *sel = NEW (select_t);
151   sel->kind = eff_select;
152
153   CHECK_NAME (selelm, select);
154   /* fprintf (stdout, "select node \t0x%08x\n", (int) selelm); */
155
156   ent = getEntityById (entity_id);
157
158   child = selelm->xmlChildrenNode;
159
160   if (child) {
161     valref = parseValref (doc, child);
162   }
163
164   sel->valrefid = valref ? valref->refid : -1;
165   sel->ent = ent;
166
167   if (valref) {
168     free (valref);
169   }
170
171   return (sel);
172 }
173
174 static load_t
175 *parseLoad (xmlDocPtr doc, xmlNodePtr loadelm)
176 {
177   int id;
178   xmlNodePtr child;
179   select_t *sel;
180   load_t *load = NEW (load_t);
181   load->kind = eff_load;
182
183   CHECK_NAME (loadelm, load);
184   /* fprintf (stdout, "load node \t0x%08x\n", (int) loadelm); */
185   id = getNodeId (loadelm);
186
187   child = loadelm->xmlChildrenNode;
188
189   sel = parseSelect (doc, child);
190
191   load->id = id;
192   load->ptrrefid = sel->valrefid;
193   load->ent = sel->ent;
194
195   free (sel);
196
197   return (load);
198 }
199
200 static store_t
201 *parseStore (xmlDocPtr doc, xmlNodePtr storeelm)
202 {
203   xmlNodePtr child;
204   select_t *sel;
205   valref_t *valref;
206   store_t *store = NEW (store_t);
207   store->kind = eff_store;
208
209   CHECK_NAME (storeelm, store);
210   /* fprintf (stdout, "store node \t0x%08x\n", (int) storeelm); */
211
212   child = storeelm->xmlChildrenNode;
213
214   sel = parseSelect (doc, child);
215
216   child = child->next;
217
218   valref = parseValref (doc, child);
219
220   store->ent = sel->ent;
221   store->ptrrefid = sel->valrefid;
222   store->valrefid = valref->refid;
223
224   free (sel);
225   free (valref);
226
227   return (store);
228 }
229
230 static alloc_t
231 *parseAlloc (xmlDocPtr doc, xmlNodePtr allocelm)
232 {
233   int id;
234   int type_id;
235   alloc_t *alloc = NEW (alloc_t); /* ...! */
236   alloc->kind = eff_alloc;
237
238   CHECK_NAME (allocelm, alloc);
239   /* fprintf (stdout, "alloc node \t0x%08x\n", (int) allocelm); */
240   id = getNodeId (allocelm);
241   /* fprintf (stdout, "alloc->id = \"%d\"\n", id); */
242   type_id = getNodeTypeId (allocelm);
243   /* fprintf (stdout, "alloc->type_id = \"%d\"\n", type_id); */
244
245   alloc->id = id;
246   alloc->tp_id = type_id;
247
248   return (alloc);
249 }
250
251 static call_t
252 *parseCall (xmlDocPtr doc, xmlNodePtr callelm)
253 {
254   int id;
255   xmlNodePtr child;
256   select_t *sel;
257   xmlNodePtr arg;
258   int n_args;
259   call_t *call = NEW (call_t);
260   call->kind = eff_call;
261
262   CHECK_NAME (callelm, call);
263   /* fprintf (stdout, "call node \t0x%08x\n", (int) callelm); */
264   id = getNodeId (callelm);
265   /* fprintf (stdout, "call->id = \"%d\"\n", id); */
266
267   child = callelm->xmlChildrenNode;
268
269   sel = parseSelect (doc, child);
270
271   arg = child = child->next;
272
273   n_args = 0;
274
275   while (NULL != child) {
276     n_args ++;
277
278     child = child->next;
279   }
280
281   call->id = id;
282   call->valrefid = sel->valrefid;
283   call->ent = sel->ent;
284   call->n_args = n_args;
285   call->args = NULL;
286
287   free (sel);
288
289   if (0 != n_args) {
290     int *args = (int*) malloc (n_args * sizeof (int) );
291     int i = 0;
292
293     while (NULL != arg) {
294       valref_t *valref = parseValref (doc, arg);
295       args [i ++] = valref->refid;
296       free (valref);
297
298       arg = arg->next;
299     }
300
301     call->args = args;
302   }
303
304   return (call);
305 }
306
307 static join_t
308 *parseJoin (xmlDocPtr doc, xmlNodePtr joinelm)
309 {
310   int id;
311   int n_ins;
312   int *ins;
313   int i;
314   xmlNodePtr child;
315   join_t *join = NEW (join_t);
316   join->kind = eff_join;
317
318   CHECK_NAME (joinelm, join);
319   /* fprintf (stdout, "join node \t0x%08x\n", (int) joinelm); */
320   id = getNodeId (joinelm);
321   /* fprintf (stdout, "join->id = \"%d\"\n", id); */
322
323   child = joinelm->xmlChildrenNode;
324
325   n_ins = 0;
326
327   while (NULL != child) {
328     n_ins ++;
329     child = child->next;
330   }
331
332   ins = (int*) malloc (n_ins * sizeof (int) );
333   i = 0;
334
335   child = joinelm->xmlChildrenNode;
336
337   while (NULL != child) {
338     valref_t *valref = parseValref (doc, child);
339     ins [i ++] = valref->refid;
340
341     child = child->next;
342   }
343
344   join->id = id;
345   join->n_ins = n_ins;
346   join->ins = ins;
347
348   return (join);
349 }
350
351 static unknown_t
352 *parseUnknown (xmlDocPtr doc, xmlNodePtr unknownelm)
353 {
354   int id;
355   unknown_t *unknown = NEW (unknown_t);
356   unknown->kind = eff_unknown;
357
358   CHECK_NAME (unknownelm, unknown);
359   /* fprintf (stdout, "unknown node \t0x%08x\n", (int) unknownelm); */
360   id = getNodeId (unknownelm);
361
362   unknown->id = id;
363
364   return (unknown);
365 }
366
367 static ret_t
368 *parseReturn (xmlDocPtr doc, xmlNodePtr retelm)
369 {
370   xmlNodePtr child;
371   ret_t *ret = NEW (ret_t);
372   ret->kind = eff_ret;
373
374   CHECK_NAME (retelm, ret);
375   /* fprintf (stdout, "ret node \t0x%08x\n", (int) retelm); */
376
377   child = retelm->xmlChildrenNode;
378
379   if (child) {
380     valref_t *valref = parseValref (doc, child);
381     ret->ret_id = valref->refid;
382     free (valref);
383   } else {
384     ret->ret_id = -1;
385   }
386
387   return (ret);
388 }
389
390 static raise_t
391 *parseRaise (xmlDocPtr doc, xmlNodePtr raiseelm)
392 {
393   int tp_id;
394   valref_t *valref;
395   xmlNodePtr child;
396   raise_t *raise = NEW (raise_t);
397   raise->kind = eff_raise;
398
399   CHECK_NAME (raiseelm, raise);
400   /* fprintf (stdout, "raise node \t0x%08x\n", (int) raiseelm); */
401
402   tp_id = getNodeTypeId (raiseelm);
403   /* fprintf (stdout, "raise->type = \"%d\"\n", tp_id); */
404
405   child = raiseelm->xmlChildrenNode;
406
407   assert (NULL != child);
408
409   valref = parseValref (doc, child);
410
411   raise->valref = valref->refid;
412   raise->tp_id = tp_id;
413
414   free (valref);
415
416   return (raise);
417 }
418
419 /*
420   Types and Entities
421 */
422
423 /** parse a type node and insert it into the list */
424 static void
425 parseType (xmlDocPtr doc, xmlNodePtr typeelm)
426 {
427   type_t *type;
428   const int tp_id = getNodeId (typeelm);
429   /* fprintf (stdout, "type node \t0x%08x (%d)\n", (int) typeelm, tp_id); */
430   fprintf (stdout, "type = \"%s\"\n", getNodeTypeStr (typeelm));
431
432   type = (type_t*) malloc (sizeof (type_t));
433
434   type->name = (char*) strdup (getNodeTypeStr (typeelm));
435   type->id = tp_id;
436
437   type->prev = types;
438   types = type;
439
440   if (_ent_id <= tp_id) {
441     _ent_id = tp_id+1;
442   }
443 }
444
445 /** parse an entity node and insert it into the list */
446 static void
447 parseEntity (xmlDocPtr doc, xmlNodePtr entelm)
448 {
449   entity_t *ent = NEW (entity_t);
450
451   /* parse it */
452   const int ent_id = getNodeId (entelm);
453   /* fprintf (stdout, "entity node \t0x%08x (%d)\n", (int) entelm, ent_id); */
454   fprintf (stdout, "ent  = \"%s.%s\"\n",
455            getNodeTypeStr (entelm),
456            getNodeEntityStr (entelm));
457
458
459   ent->name    = (char*) strdup (getNodeEntityStr (entelm));
460   ent->tp_name = (char*) strdup (getNodeTypeStr   (entelm));
461   ent->id = ent_id;
462
463   ent->prev = entities;
464   entities = ent;
465
466   if (_ent_id <= ent_id) {
467     _ent_id = ent_id+1;
468   }
469 }
470
471 /** parse any effect, and turn it into an eff_t (TODO) */
472 static void
473 parseEffect (xmlDocPtr doc, xmlNodePtr effelm)
474 {
475   xmlNodePtr cur = effelm->xmlChildrenNode;
476   char *procname = getNodeProcName (effelm);
477   effs_t *curr_effs = NULL;
478   int i = 0;
479   int n_effs = 0;
480
481   fprintf (stdout, "effect for \"%s\"\n", procname);
482
483   while (NULL != cur) {
484     n_effs ++;
485     cur = cur->next;
486   }
487
488   curr_effs = NEW (effs_t);
489   curr_effs->procname = procname;
490   curr_effs->n_effs = n_effs;
491   curr_effs->effs = (eff_t**) malloc (n_effs * sizeof (eff_t*));
492
493   while (NULL != cur) {
494     eff_t *eff = NULL;
495
496     if (NODE_NAME (cur, arg)) {
497       eff = (eff_t*) parseArg (doc, cur);
498     } else if (NODE_NAME (cur, load)) {
499       eff = (eff_t*) parseLoad (doc, cur);
500     } else if (NODE_NAME (cur, store)) {
501       eff = (eff_t*) parseStore (doc, cur);
502     } else if (NODE_NAME (cur, alloc)) {
503       eff = (eff_t*) parseAlloc (doc, cur);
504     } else if (NODE_NAME (cur, call)) {
505       eff = (eff_t*) parseCall (doc, cur);
506     } else if (NODE_NAME (cur, join)) {
507       eff = (eff_t*) parseJoin (doc, cur);
508     } else if (NODE_NAME (cur, unknown)) {
509       eff = (eff_t*) parseUnknown (doc, cur);
510     } else if (NODE_NAME (cur, ret)) {
511       eff = (eff_t*) parseReturn (doc, cur);
512     } else if (NODE_NAME (cur, raise)) {
513       eff = (eff_t*) parseRaise (doc, cur);
514     } else if (NODE_NAME (cur, comment)) {
515       /* comment */
516     } else {
517       fprintf (stderr, "wrong element \"%s\"\n", BAD_CAST cur->name);
518       exit (EXIT_FAILURE);
519     }
520
521     cur = cur->next;
522
523     curr_effs->effs [i ++] = eff;
524   }
525
526   curr_effs->next = effs;
527   effs = curr_effs;
528 }
529
530 /*
531   Public Interface
532 */
533 type_t *getTypeByName (const char *name)
534 {
535   type_t *curr = types;
536
537   while (NULL != curr) {
538     if (0 == strcmp (name, curr->name)) {
539       return (curr);
540     }
541
542     curr = curr->prev;
543   }
544
545   return (NULL);
546 }
547
548 type_t *getTypeById (const int id)
549 {
550   type_t *curr = types;
551
552   while (NULL != curr) {
553     if (id == curr->id) {
554       return (curr);
555     }
556
557     curr = curr->prev;
558   }
559
560   return (NULL);
561 }
562
563 entity_t *getEntityByNames (const char *name, const char *tp_name)
564 {
565   entity_t *curr = entities;
566
567   while (NULL != curr) {
568     if ((0 == strcmp (name, curr->name)) && (0 == strcmp (tp_name, curr->tp_name))) {
569       return (curr);
570     }
571
572     curr = curr->prev;
573   }
574
575   return (NULL);
576 }
577
578 entity_t *getEntityById (const int id)
579 {
580   entity_t *curr = entities;
581
582   while (NULL != curr) {
583     if (id == curr->id) {
584       return (curr);
585     }
586
587     curr = curr->prev;
588   }
589
590   return (NULL);
591 }
592
593 effs_t *getEffectByName (const char *procname)
594 {
595   effs_t *curr_effs = effs;
596
597   while (NULL != curr_effs) {
598     if (0 == strcmp (procname, curr_effs->procname)) {
599       return (curr_effs);
600     }
601
602     curr_effs = curr_effs->next;
603   }
604
605   return (NULL);
606 }
607
608 void extern_init ()
609 {
610   /* nothing to do */
611 }
612
613 void extern_read (const char *filename)
614 {
615   /* xmlNsPtr ns = NULL; */           /* no namespace for us */
616   xmlDocPtr doc;                /* whole document */
617   xmlNodePtr cur;               /* current node */
618
619   /* i've got no idea what the VERSION cast is all about. voodoo
620      programming at its finest. */
621   LIBXML_TEST_VERSION xmlKeepBlanksDefault (0);
622   doc = xmlParseFile (filename);
623   CHECK (doc, "xmlParseFile");
624
625   cur = xmlDocGetRootElement (doc);
626   CHECK (cur, "xmlDocGetRootElement");
627
628   if (! NODE_NAME (cur, effects)) {
629     fprintf (stderr,"root node \"%s\" != \"effects\"\n", BAD_CAST cur->name);
630     xmlFreeDoc (doc);
631
632     exit (EXIT_FAILURE);
633   }
634
635   if (EXTERN_VERBOSE) {
636     const char *mod_str = getNodeModule (cur);
637
638     if (NULL != mod_str) {
639       fprintf (stdout, "effects for \"%s\"\n", mod_str);
640     } else {
641       fprintf (stdout, "effects \t0x%08x\n", (int) cur);
642     }
643   }
644
645   /* parse entities */
646   cur = cur->xmlChildrenNode;
647   while (cur != NULL) {
648     if (NODE_NAME (cur, type)) {
649       parseType (doc, cur);
650     } else if (NODE_NAME (cur, entity)) {
651       parseEntity (doc, cur);
652     } else if (NODE_NAME (cur, effect)) {
653       parseEffect (doc, cur);
654     } else if ((NODE_NAME (cur, comment))) {
655       /* comment */
656     } else {
657       fprintf (stderr, "wrong element \"%s\"\n", BAD_CAST cur->name);
658       exit (EXIT_FAILURE);
659     }
660
661     cur = cur->next;
662   }
663 }
664
665 /** clean up our mess */
666 void extern_cleanup ()
667 {
668   /* the types */
669   {
670     type_t *tp = types;
671
672     while (NULL != tp) {
673       type_t *curr = tp;
674       tp = tp->prev;
675
676       free ((char*) curr->name);
677       memset (curr, 0x00, sizeof (type_t));
678       free (curr);
679     }
680
681     types = NULL;
682   }
683
684   /* the ennities */
685   {
686     entity_t *ent = entities;
687
688     while (NULL != ent) {
689       entity_t *curr = ent;
690       ent = ent->prev;
691
692       free ((char*) curr->name);
693       free ((char*) curr->tp_name);
694       memset (curr, 0x00, sizeof (entity_t));
695       free (curr);
696     }
697
698     entities = NULL;
699   }
700
701   /* the effs */
702   {
703     effs_t *eff = effs;
704
705     while (NULL != eff) {
706       int i;
707       effs_t *curr = eff;
708       eff = eff->next;
709
710       for (i = 0; i < curr->n_effs; i ++) {
711         free (curr->effs [i]);
712       }
713
714       free (curr);
715     }
716   }
717
718   effs = NULL;
719 }
720
721
722 void test_getEffectByName ()
723 {
724   /* test getEffectByName */
725   char *names [] = {
726     "store_unknown_proc",
727     "rise_something",
728     "other_fake_proc",
729     "ret_alloc",
730     "mash_args",
731     "ret_arg",
732     "empty_external",
733     "no_this_doesn't_really_exist",
734     "my_fake_proc",
735     NULL
736   };
737
738   int i = 0;
739
740   while (NULL != names [i]) {
741     effs_t *the_eff = getEffectByName (names [i]);
742
743     if (the_eff) {
744       fprintf (stdout, "Effect for \"%s\" is at 0x%08x\n",
745                names [i], (int) the_eff);
746     } else {
747       fprintf (stdout, "Effect for \"%s\" not found\n",
748                names [i]);
749     }
750     i ++;
751   }
752 }
753
754
755
756 \f
757 /*
758  * $Log$
759  * Revision 1.2  2004/10/11 15:56:09  liekweg
760  * Cleanup, comments ...
761  * Added init func --flo
762  *
763  * Revision 1.1  2004/10/11 09:31:06  liekweg
764  * First Import of XML reading procs --flo
765  *
766  */