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