read.c 41 KB
Newer Older
1
2
3
/* -*- c -*- */

/*
Florian Liekweg's avatar
Florian Liekweg committed
4
5
6
7
 * Project:     libFIRM
 * File name:   ir/external/read.c
 * Purpose:     Read descriptions of external effects
 * Author:      Florian
Boris Boesler's avatar
Boris Boesler committed
8
 * Modified by: Boris Boesler
Florian Liekweg's avatar
Florian Liekweg committed
9
 * Created:     11.10.2004
Boris Boesler's avatar
Boris Boesler committed
10
 * CVS-ID:      $Id$
Florian Liekweg's avatar
Florian Liekweg committed
11
12
13
 * Copyright:   (c) 1999-2004 Universitt Karlsruhe
 * Licence:     This file is protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */
14

15
16
17
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
Boris Boesler's avatar
Boris Boesler committed
18

19
20
21
22
23
24
25
/* get prototype for alloca somehow */
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
Michael Beck's avatar
Michael Beck committed
26
#ifdef HAVE_STRING_H
Florian Liekweg's avatar
Florian Liekweg committed
27
# include <string.h>
Michael Beck's avatar
Michael Beck committed
28
#endif
Florian Liekweg's avatar
Florian Liekweg committed
29

Michael Beck's avatar
Michael Beck committed
30
31
32
33
34
35
#include <assert.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/encoding.h>

36
37
#include "read_t.h"
#include "read.h"
Boris Boesler's avatar
Boris Boesler committed
38
39
#include "irprog.h"
#include "irgraph.h"
Götz Lindenmaier's avatar
Götz Lindenmaier committed
40
#include "pseudo_irg.h"
Boris Boesler's avatar
Boris Boesler committed
41
42
43
44
45
46
#include "ircons.h"
#include "irmode.h"
#include "irdump.h"
#include "irvrfy.h"
#include "type.h"
#include "tv.h"
Michael Beck's avatar
Michael Beck committed
47
48
49
50
51
52
53
54
55
56
57
#include "xmalloc.h"

# define MY_ENCODING "ISO-8859-1"

# define CHECK(ptr,msg)     assert (ptr && msg)

# define NODE_NAME(n, m) (0 == xmlStrcmp (n->name, (const xmlChar*) #m))
# define CHECK_NAME(n, m) assert (0 == xmlStrcmp (n->name, (const xmlChar*) #m))

# define NEW(T)     (T*)xmalloc(sizeof (T))

Boris Boesler's avatar
Boris Boesler committed
58

59
#define VERBOSE_PRINTING 0
60
61

#if VERBOSE_PRINTING
Boris Boesler's avatar
Boris Boesler committed
62
63
64
65
66
67
# define VERBOSE_PRINT(s) fprintf s
#else
# define VERBOSE_PRINT(s)
#endif

#define NO_ID NULL
68
69
70

static type_t *types = NULL;
static entity_t *entities = NULL;
Boris Boesler's avatar
Boris Boesler committed
71
72
73
74
75
76
static proc_t *procs = NULL;
static module_t *modules = NULL;

/* @@@ HACK */
static module_t *current_module = NULL;

Florian Liekweg's avatar
Florian Liekweg committed
77
78
#if VERBOSE_PRINTING
/* this is only used inside a VERBOSE_PRINT() call */
Michael Beck's avatar
Michael Beck committed
79
static const char *effect_string[] = {
Boris Boesler's avatar
Boris Boesler committed
80
81
82
83
84
85
86
87
88
89
90
91
  "arg",
  "valref",
  "select",
  "load",
  "store",
  "alloc",
  "call",
  "unknown",
  "join",
  "raise",
  "ret"
};
Florian Liekweg's avatar
Florian Liekweg committed
92
#endif /* defined VERBOSE_PRINTING */
93

94
95
static const ident*
getNodeModuleIdent (xmlNodePtr node)
96
{
Rubino Geiß's avatar
Rubino Geiß committed
97
  const char *mod_str = (const char*) xmlGetProp (node, BAD_CAST "module");
98
99
100
101

  if (NULL == mod_str) {
    return (NULL);
  } else {
102
    const ident *res = new_id_from_str (mod_str);
103
104
105
106
    return (res);
  }
}

Boris Boesler's avatar
Boris Boesler committed
107
static const char*
108
109
getNodeProcName (xmlNodePtr node)
{
Boris Boesler's avatar
Boris Boesler committed
110
  const char *proc_str = (const char*) xmlGetProp (node, BAD_CAST "procname");
111
  assert (proc_str);
112
  return (proc_str);
Boris Boesler's avatar
Boris Boesler committed
113
}
114

115
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
116
117
118
119
120
static char*
getNodeClassName (xmlNodePtr node)
{
  char *proc_str = (char*) xmlGetProp (node, BAD_CAST "class");
  assert (proc_str);
121
  return ( (proc_str));
122
}
123
# endif /* defined NEEDED */
124

Boris Boesler's avatar
Boris Boesler committed
125
static const char*
126
127
getNodeId (xmlNodePtr node)
{
Boris Boesler's avatar
Boris Boesler committed
128
  const char *id_str = (const char*) xmlGetProp (node, BAD_CAST "id");
129
  assert (id_str);
130
  return (id_str);
131
132
}

133
static const char *
134
135
getNodeRefId (xmlNodePtr node)
{
136
  const char *refid_str = (char*) xmlGetProp (node, BAD_CAST "refid");
137
  assert (refid_str);
138
  return ((refid_str));
139
140
}

141
static const char*
142
143
getNodeTypeId (xmlNodePtr node)
{
144
  const char *type_str = (char*) xmlGetProp (node, BAD_CAST "type");
145
  assert (type_str);
146
  return ((type_str));
147
148
149
150
151
152
153
154
155
156
}

static const char
*getNodeTypeStr (xmlNodePtr node)
{
  const char *type_str = (char*) xmlGetProp (node, BAD_CAST "type");
  assert (type_str);
  return (type_str);
}

Boris Boesler's avatar
Boris Boesler committed
157
158
159
160
161
162
163
164
static const char*
getNodeOwnerStr (xmlNodePtr node)
{
  const char *owner_str = (char*) xmlGetProp (node, BAD_CAST "owner");
  assert (owner_str);
  return (owner_str);
}

165
166
167
168
169
170
171
172
173
static const char
*getNodeEntityStr (xmlNodePtr node)
{
  const char *ent_str = (char*) xmlGetProp (node, BAD_CAST "entity");
  assert (ent_str);

  return (ent_str);
}

Boris Boesler's avatar
Boris Boesler committed
174
175
176
177

/*
  was Public Interface
*/
178
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
179
static
180
type_t *getTypeByIdent (const ident *id)
Boris Boesler's avatar
Boris Boesler committed
181
{
182
  type_t *curr = types; // @@@ TODO module -> types
Boris Boesler's avatar
Boris Boesler committed
183
184

  while (NULL != curr) {
185
    if (id == curr -> type_ident) {
Boris Boesler's avatar
Boris Boesler committed
186
187
188
189
190
191
192
      return (curr);
    }
    curr = curr->prev;
  }

  return (NULL);
}
193
# endif /* defined NEEDED */
Boris Boesler's avatar
Boris Boesler committed
194

195
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
196
static
197
type_t *getTypeById (const ident *id)
Boris Boesler's avatar
Boris Boesler committed
198
{
199
  type_t *curr = types; // which ones?
Boris Boesler's avatar
Boris Boesler committed
200
201

  while (NULL != curr) {
202
    if (id == curr -> id) {
Boris Boesler's avatar
Boris Boesler committed
203
204
205
206
207
208
209
      return (curr);
    }
    curr = curr->prev;
  }

  return (NULL);
}
210
# endif /* defined NEEDED */
Boris Boesler's avatar
Boris Boesler committed
211

212
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
213
static
214
entity_t *getEntityByIdents (const ident *name, const ident *tp_ident)
Boris Boesler's avatar
Boris Boesler committed
215
{
216
  entity_t *curr = entities; // TODO module -> entities
Boris Boesler's avatar
Boris Boesler committed
217
218

  while (NULL != curr) {
219
    if ((name == curr -> ent_ident)
Florian Liekweg's avatar
Florian Liekweg committed
220
    && (tp_ident == curr -> tp_ident)) {
Boris Boesler's avatar
Boris Boesler committed
221
222
223
224
225
226
227
      return (curr);
    }
    curr = curr->prev;
  }

  return (NULL);
}
228
# endif /* defined NEEDED */
Boris Boesler's avatar
Boris Boesler committed
229
230

static
231
entity_t *getEntityById (const ident *id)
Boris Boesler's avatar
Boris Boesler committed
232
233
234
235
{
  entity_t *curr = entities;

  while (NULL != curr) {
236
    if (id == curr -> id) {
Boris Boesler's avatar
Boris Boesler committed
237
238
239
240
241
242
243
244
      return (curr);
    }
    curr = curr->prev;
  }

  return (NULL);
}

245
# ifdef NEEDED
Boris Boesler's avatar
Boris Boesler committed
246
static
247
proc_t *getEffectByName (const ident *proc_ident)
Boris Boesler's avatar
Boris Boesler committed
248
249
250
251
{
  proc_t *curr_effs = procs;

  while (NULL != curr_effs) {
252
    if (proc_ident == curr_effs -> proc_ident) {
Boris Boesler's avatar
Boris Boesler committed
253
254
255
256
257
258
259
      return (curr_effs);
    }
    curr_effs = curr_effs->next;
  }

  return (NULL);
}
260
# endif /* defined NEEDED */
Boris Boesler's avatar
Boris Boesler committed
261

262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
static
xmlNodePtr get_any_valid_child(xmlNodePtr elem)
{
  xmlNodePtr child;

  assert(elem && "no element");
  child = elem -> xmlChildrenNode;
  while(child && (NODE_NAME (child, comment))) {
    child = child -> next;
  }
  return(child);
}

static
xmlNodePtr get_valid_child(xmlNodePtr elem)
{
  xmlNodePtr child;

  child = get_any_valid_child(elem);
  assert(child && "lost child in deep black forest");
  return(child);
}
Boris Boesler's avatar
Boris Boesler committed
284
285
286
287
288

/*
 * parse XML structure and construct an additional structure
 */
static eff_t *
289
290
parseArg (xmlDocPtr doc, xmlNodePtr argelm)
{
Boris Boesler's avatar
Boris Boesler committed
291
292
  const char *id;
  const char *typeid;
293
294
  int num;
  char *num_str;
Boris Boesler's avatar
Boris Boesler committed
295
  eff_t *arg;
296
297

  CHECK_NAME (argelm, arg);
Boris Boesler's avatar
Boris Boesler committed
298
  VERBOSE_PRINT ((stdout, "arg node \t0x%08x\n", (int) argelm));
299
300

  id = getNodeId (argelm);
Boris Boesler's avatar
Boris Boesler committed
301
  VERBOSE_PRINT ((stdout, "arg->id = \"%s\"\n", id));
302
303
  num_str = (char*) xmlGetProp (argelm, BAD_CAST "number");
  num = atoi (num_str);
Boris Boesler's avatar
Boris Boesler committed
304
  VERBOSE_PRINT ((stdout, "arg->no = \"%d\"\n", num));
305

Boris Boesler's avatar
Boris Boesler committed
306
307
308
309
  typeid = getNodeTypeStr (argelm);

  arg = NEW (eff_t);
  arg -> kind = eff_arg;
310
  arg -> id = new_id_from_str(id);
Boris Boesler's avatar
Boris Boesler committed
311
  arg -> effect.arg.num = num;
312
  arg -> effect.arg.type_ident = new_id_from_str(typeid);
313
314
315
316

  return (arg);
}

Florian Liekweg's avatar
Florian Liekweg committed
317
318
static eff_t*
parseValref (xmlDocPtr doc, xmlNodePtr valelm)
319
{
320
  const char *ref_id;
Boris Boesler's avatar
Boris Boesler committed
321
322
  eff_t *valref;

323
  CHECK_NAME (valelm, valref);
Boris Boesler's avatar
Boris Boesler committed
324
  VERBOSE_PRINT ((stdout, "valref node \t0x%08x\n", (int) valelm));
325
326

  ref_id = getNodeRefId (valelm);
Boris Boesler's avatar
Boris Boesler committed
327
  VERBOSE_PRINT ((stdout, "val->refid = \"%s\"\n", ref_id));
328

Boris Boesler's avatar
Boris Boesler committed
329
  valref = NEW (eff_t);
330
  valref->kind = eff_valref;
331
  valref-> id = new_id_from_str(ref_id);
332
333
334
335

  return (valref);
}

Florian Liekweg's avatar
Florian Liekweg committed
336
337
static eff_t*
parseSelect (xmlDocPtr doc, xmlNodePtr selelm)
338
{
339
  const ident *entity_id = new_id_from_str(getNodeEntityStr (selelm));
340
341
  entity_t *ent;
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
342
343
  eff_t *valref = NULL;
  eff_t *sel = NEW (eff_t);
344
345
346
  sel->kind = eff_select;

  CHECK_NAME (selelm, select);
Boris Boesler's avatar
Boris Boesler committed
347
  VERBOSE_PRINT ((stdout, "select node \t0x%08x\n", (int) selelm));
348
349

  ent = getEntityById (entity_id);
Boris Boesler's avatar
Boris Boesler committed
350
  assert(ent && "entity not found");
351
  VERBOSE_PRINT ((stdout, "select entity %s\n", get_id_str(ent -> ent_ident)));
352
353
354
355
356
357
358

  child = selelm->xmlChildrenNode;

  if (child) {
    valref = parseValref (doc, child);
  }

Boris Boesler's avatar
Boris Boesler committed
359
360
  sel-> id = valref ? valref-> id : NO_ID;
  sel-> effect.select.ent = ent;
361
362
363
364
365
366
367
368

  if (valref) {
    free (valref);
  }

  return (sel);
}

Florian Liekweg's avatar
Florian Liekweg committed
369
370
static eff_t*
parseLoad (xmlDocPtr doc, xmlNodePtr loadelm)
371
{
372
  const ident *id;
373
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
374
375
  eff_t *sel;
  eff_t *load = NEW (eff_t);
376
377
378
  load->kind = eff_load;

  CHECK_NAME (loadelm, load);
Boris Boesler's avatar
Boris Boesler committed
379
  VERBOSE_PRINT ((stdout, "load node \t0x%08x\n", (int) loadelm));
380
  id = new_id_from_str(getNodeId (loadelm));
381

382
383
384
385
386
  child = get_valid_child(loadelm);
  if(NODE_NAME (child, select)) {
    sel = parseSelect (doc, child);
    load-> effect.load.ent = sel-> effect.select.ent;
    VERBOSE_PRINT ((stdout, "load entity \t%s\n",
Florian Liekweg's avatar
Florian Liekweg committed
387
            get_id_str(load -> effect.load.ent -> ent_ident)));
388
389
390
391
392
  }
  else {
    sel = parseValref (doc, child);
    load-> effect.load.ent = NULL;
  }
393

Boris Boesler's avatar
Boris Boesler committed
394
395
  load-> id = id;
  load-> effect.load.ptrrefid = sel-> id;
396
397
398
399
400
401

  free (sel);

  return (load);
}

Florian Liekweg's avatar
Florian Liekweg committed
402
403
static eff_t*
parseStore (xmlDocPtr doc, xmlNodePtr storeelm)
404
405
{
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
406
407
408
  eff_t *sel;
  eff_t *valref;
  eff_t *store = NEW (eff_t);
409
410
411
  store->kind = eff_store;

  CHECK_NAME (storeelm, store);
Boris Boesler's avatar
Boris Boesler committed
412
  VERBOSE_PRINT ((stdout, "store node \t0x%08x\n", (int) storeelm));
413

414
415
416
417
418
419
420
421
422
423
  child = get_valid_child(storeelm);
  if(NODE_NAME (child, select)) {
    sel = parseSelect (doc, child);
    store-> effect.store.ent = sel-> effect.select.ent;
  }
  else {
    sel = parseValref (doc, child);
    store-> effect.store.ent = NULL;
  }

424
425
426
  child = child->next;
  valref = parseValref (doc, child);

Boris Boesler's avatar
Boris Boesler committed
427
428
  store-> effect.store.ptrrefid = sel-> id;
  store-> effect.store.valrefid = valref-> id;
429
430
431
432
433
434
435

  free (sel);
  free (valref);

  return (store);
}

Florian Liekweg's avatar
Florian Liekweg committed
436
437
static eff_t*
parseAlloc (xmlDocPtr doc, xmlNodePtr allocelm)
438
{
439
440
  const ident *id;
  const ident *type_id;
Boris Boesler's avatar
Boris Boesler committed
441
  eff_t *alloc = NEW (eff_t); /* ...! */
442
443
444
  alloc->kind = eff_alloc;

  CHECK_NAME (allocelm, alloc);
Boris Boesler's avatar
Boris Boesler committed
445
  VERBOSE_PRINT ((stdout, "alloc node \t0x%08x\n", (int) allocelm));
446
447
448
449
  id = new_id_from_str(getNodeId (allocelm));
  VERBOSE_PRINT ((stdout, "alloc->id = \"%s\"\n", get_id_str(id)));
  type_id = new_id_from_str(getNodeTypeId (allocelm));
  VERBOSE_PRINT ((stdout, "alloc->type_id = \"%s\"\n", get_id_str(type_id)));
450

Boris Boesler's avatar
Boris Boesler committed
451
452
  alloc-> id = id;
  alloc-> effect.alloc.tp_id = type_id;
453
454
455
456

  return (alloc);
}

Florian Liekweg's avatar
Florian Liekweg committed
457
458
static eff_t*
parseCall (xmlDocPtr doc, xmlNodePtr callelm)
459
{
460
  const ident *id;
461
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
462
  eff_t *sel;
463
464
  xmlNodePtr arg;
  int n_args;
Boris Boesler's avatar
Boris Boesler committed
465
  eff_t *call = NEW (eff_t);
466
467
468
  call->kind = eff_call;

  CHECK_NAME (callelm, call);
Boris Boesler's avatar
Boris Boesler committed
469
  VERBOSE_PRINT ((stdout, "call node \t0x%08x\n", (int) callelm));
470
471
  id = new_id_from_str(getNodeId (callelm));
  VERBOSE_PRINT ((stdout, "call->id = \"%s\"\n", get_id_str(id)));
472

473
474
475
476
477
478
479
480
481
482
  child = get_valid_child(callelm);
  if(NODE_NAME (child, select)) {
    sel = parseSelect (doc, child);
    call-> effect.call.ent = sel-> effect.select.ent;
  }
  else {
    sel = parseValref (doc, child);
    call-> effect.call.ent = NULL;
  }

483
484
485
486
487
488
489
490
  arg = child = child->next;
  n_args = 0;

  while (NULL != child) {
    n_args ++;
    child = child->next;
  }

Boris Boesler's avatar
Boris Boesler committed
491
492
493
494
  call-> id = id;
  call-> effect.call.valrefid = sel-> id;
  call-> effect.call.n_args = n_args;
  call-> effect.call.args = NULL;
495
496
497
498

  free (sel);

  if (0 != n_args) {
Michael Beck's avatar
Michael Beck committed
499
    const ident **args = (const ident**) xmalloc(n_args * sizeof(const ident*));
500
501
502
    int i = 0;

    while (NULL != arg) {
Boris Boesler's avatar
Boris Boesler committed
503
504
      eff_t *valref = parseValref (doc, arg);
      args [i ++] = valref-> id;
505
506
507
508
      free (valref);
      arg = arg->next;
    }

Boris Boesler's avatar
Boris Boesler committed
509
    call-> effect.call.args = args;
510
511
512
513
514
  }

  return (call);
}

Florian Liekweg's avatar
Florian Liekweg committed
515
516
static eff_t*
parseJoin (xmlDocPtr doc, xmlNodePtr joinelm)
517
{
518
  const ident *id;
519
  int n_ins;
520
  const ident **ins;
521
522
  int i;
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
523
  eff_t *join = NEW (eff_t);
524
525
526
  join->kind = eff_join;

  CHECK_NAME (joinelm, join);
Boris Boesler's avatar
Boris Boesler committed
527
  VERBOSE_PRINT ((stdout, "join node \t0x%08x\n", (int) joinelm));
528
529
  id = new_id_from_str(getNodeId (joinelm));
  VERBOSE_PRINT ((stdout, "join->id = \"%s\"\n", get_id_str(id)));
530

531
  child = get_valid_child(joinelm);
532
533
534
535
536
537
538
  n_ins = 0;

  while (NULL != child) {
    n_ins ++;
    child = child->next;
  }

Michael Beck's avatar
Michael Beck committed
539
  ins = (const ident **) xmalloc (n_ins * sizeof (const ident *) );
540
  i = 0;
541
  child = get_valid_child(joinelm);
542
543

  while (NULL != child) {
Boris Boesler's avatar
Boris Boesler committed
544
545
546
    eff_t *valref = parseValref (doc, child);
    ins [i ++] = valref-> id;
    free(valref);
547
548
549
    child = child->next;
  }

Boris Boesler's avatar
Boris Boesler committed
550
551
552
  join-> id = id;
  join-> effect.join.n_ins = n_ins;
  join-> effect.join.ins = ins;
553
554
555
556

  return (join);
}

Florian Liekweg's avatar
Florian Liekweg committed
557
558
static eff_t*
parseUnknown (xmlDocPtr doc, xmlNodePtr unknownelm)
559
{
560
  const ident *id;
Boris Boesler's avatar
Boris Boesler committed
561
  eff_t *unknown = NEW (eff_t);
562
563
564
  unknown->kind = eff_unknown;

  CHECK_NAME (unknownelm, unknown);
Boris Boesler's avatar
Boris Boesler committed
565
  VERBOSE_PRINT ((stdout, "unknown node \t0x%08x\n", (int) unknownelm));
566
  id = new_id_from_str(getNodeId (unknownelm));
Boris Boesler's avatar
Boris Boesler committed
567
  unknown-> id = id;
568
569
570
571

  return (unknown);
}

Florian Liekweg's avatar
Florian Liekweg committed
572
573
static eff_t*
parseReturn (xmlDocPtr doc, xmlNodePtr retelm)
574
575
{
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
576
  eff_t *ret = NEW (eff_t);
577
578
579
  ret->kind = eff_ret;

  CHECK_NAME (retelm, ret);
Boris Boesler's avatar
Boris Boesler committed
580
  VERBOSE_PRINT ((stdout, "ret node \t0x%08x\n", (int) retelm));
581

582
  child = get_any_valid_child(retelm);
583
584

  if (child) {
Boris Boesler's avatar
Boris Boesler committed
585
586
    eff_t *valref = parseValref (doc, child);
    ret-> effect.ret.ret_id = valref-> id;
587
588
    free (valref);
  } else {
Boris Boesler's avatar
Boris Boesler committed
589
    ret-> effect.ret.ret_id = NO_ID;
590
591
592
593
594
  }

  return (ret);
}

Florian Liekweg's avatar
Florian Liekweg committed
595
596
static eff_t*
parseRaise (xmlDocPtr doc, xmlNodePtr raiseelm)
597
{
598
  const char *tp_id;
Boris Boesler's avatar
Boris Boesler committed
599
  eff_t *valref;
600
  xmlNodePtr child;
Boris Boesler's avatar
Boris Boesler committed
601
  eff_t *raise = NEW (eff_t);
602
603
604
  raise->kind = eff_raise;

  CHECK_NAME (raiseelm, raise);
Boris Boesler's avatar
Boris Boesler committed
605
  VERBOSE_PRINT ((stdout, "raise node \t0x%08x\n", (int) raiseelm));
606
  tp_id = getNodeTypeId (raiseelm);
Boris Boesler's avatar
Boris Boesler committed
607
  VERBOSE_PRINT ((stdout, "raise->type = \"%s\"\n", tp_id));
608
  child = get_valid_child(raiseelm);
609
610
611
612

  assert (NULL != child);

  valref = parseValref (doc, child);
Boris Boesler's avatar
Boris Boesler committed
613
  raise-> effect.raise.valref = valref-> id;
614
  raise-> effect.raise.tp_id = new_id_from_str(tp_id);
615
616
617
618
619
  free (valref);

  return (raise);
}

Boris Boesler's avatar
Boris Boesler committed
620

621
622
623
624
625
626
627
628
629
/*
  Types and Entities
*/

/** parse a type node and insert it into the list */
static void
parseType (xmlDocPtr doc, xmlNodePtr typeelm)
{
  type_t *type;
630
  const char *tp_id = getNodeId (typeelm);
Boris Boesler's avatar
Boris Boesler committed
631
632
  VERBOSE_PRINT ((stdout, "type node \t0x%08x (%s)\n", (int) typeelm, tp_id));
  VERBOSE_PRINT ((stdout, "type = \"%s\"\n", getNodeTypeStr (typeelm)));
633

Michael Beck's avatar
Michael Beck committed
634
  type = (type_t*) xmalloc (sizeof (type_t));
635
636
  type -> type_ident = new_id_from_str(getNodeTypeStr (typeelm));
  type -> id         = new_id_from_str(tp_id);
637
638
639
640
641
642
643
644
645
646
647
648

  type->prev = types;
  types = type;
}

/** parse an entity node and insert it into the list */
static void
parseEntity (xmlDocPtr doc, xmlNodePtr entelm)
{
  entity_t *ent = NEW (entity_t);

  /* parse it */
649
  const char *ent_id = getNodeId (entelm);
650
  /* fprintf (stdout, "entity node \t0x%08x (%d)\n", (int) entelm, ent_id); */
Boris Boesler's avatar
Boris Boesler committed
651
  VERBOSE_PRINT ((stdout, "ent  = \"%s.%s\"\n",
Florian Liekweg's avatar
Florian Liekweg committed
652
653
          getNodeTypeStr (entelm),
          getNodeEntityStr (entelm)));
654
655


656
657
658
659
  ent -> ent_ident = new_id_from_str (getNodeEntityStr (entelm));
  ent -> tp_ident  = new_id_from_str (getNodeTypeStr   (entelm));
  ent -> owner     = new_id_from_str (getNodeOwnerStr  (entelm));
  ent -> id = new_id_from_str(ent_id);
660
661
662
663
664
665
666
667
668

  ent->prev = entities;
  entities = ent;
}

/** parse any effect, and turn it into an eff_t (TODO) */
static void
parseEffect (xmlDocPtr doc, xmlNodePtr effelm)
{
Boris Boesler's avatar
Boris Boesler committed
669
670
  xmlNodePtr cur;
  const char *procname = getNodeProcName (effelm);
671
  const char *ownerid = getNodeOwnerStr (effelm);
Boris Boesler's avatar
Boris Boesler committed
672
  proc_t *curr_effs = NULL;
673
674
675
  int i = 0;
  int n_effs = 0;

Boris Boesler's avatar
Boris Boesler committed
676
  VERBOSE_PRINT ((stdout, "effect for method \"%s\"\n", procname));
677

Boris Boesler's avatar
Boris Boesler committed
678
  cur = effelm -> xmlChildrenNode;
679
680
681
682
  while (NULL != cur) {
    n_effs ++;
    cur = cur->next;
  }
Boris Boesler's avatar
Boris Boesler committed
683
  VERBOSE_PRINT ((stdout, "has %d effects\n", n_effs));
684

Boris Boesler's avatar
Boris Boesler committed
685
  curr_effs = NEW (proc_t);
686
  curr_effs -> proc_ident = new_id_from_str(procname);
687
  curr_effs -> ownerid = new_id_from_str(ownerid);
Michael Beck's avatar
Michael Beck committed
688
  curr_effs->effs = (eff_t**) xmalloc (n_effs * sizeof (eff_t*));
689

Boris Boesler's avatar
Boris Boesler committed
690
  cur = effelm -> xmlChildrenNode;
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
  while (NULL != cur) {
    eff_t *eff = NULL;

    if (NODE_NAME (cur, arg)) {
      eff = (eff_t*) parseArg (doc, cur);
    } else if (NODE_NAME (cur, load)) {
      eff = (eff_t*) parseLoad (doc, cur);
    } else if (NODE_NAME (cur, store)) {
      eff = (eff_t*) parseStore (doc, cur);
    } else if (NODE_NAME (cur, alloc)) {
      eff = (eff_t*) parseAlloc (doc, cur);
    } else if (NODE_NAME (cur, call)) {
      eff = (eff_t*) parseCall (doc, cur);
    } else if (NODE_NAME (cur, join)) {
      eff = (eff_t*) parseJoin (doc, cur);
    } else if (NODE_NAME (cur, unknown)) {
      eff = (eff_t*) parseUnknown (doc, cur);
    } else if (NODE_NAME (cur, ret)) {
      eff = (eff_t*) parseReturn (doc, cur);
    } else if (NODE_NAME (cur, raise)) {
      eff = (eff_t*) parseRaise (doc, cur);
    } else if (NODE_NAME (cur, comment)) {
      /* comment */
Boris Boesler's avatar
Boris Boesler committed
714
      --n_effs;
715
716
717
718
    } else {
      fprintf (stderr, "wrong element \"%s\"\n", BAD_CAST cur->name);
      exit (EXIT_FAILURE);
    }
Boris Boesler's avatar
Boris Boesler committed
719
720
721
722
723
724
725
726
727
728
729
    if(eff) {
      VERBOSE_PRINT ((stdout, "effect %p@%d\n", (void*)eff, i));
      curr_effs -> effs[i++] = eff;
    }
    cur = cur -> next;
  }
  assert((i == n_effs) && "incorrect number of effects");
  curr_effs -> n_effs = n_effs;
  curr_effs -> next = procs;
  procs = curr_effs;
}
730
731


Boris Boesler's avatar
Boris Boesler committed
732
733
734
735
736
737
static
void read_extern (const char *filename)
{
  /* xmlNsPtr ns = NULL; */           /* no namespace for us */
  xmlDocPtr doc;                /* whole document */
  xmlNodePtr cur;               /* current node */
738
  ident *mod_id;
Boris Boesler's avatar
Boris Boesler committed
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
  module_t *module;

  /* i've got no idea what the VERSION cast is all about. voodoo
     programming at its finest. */
  LIBXML_TEST_VERSION xmlKeepBlanksDefault (0);
  VERBOSE_PRINT((stdout, "read file %s\n", filename));
  doc = xmlParseFile (filename);
  CHECK (doc, "xmlParseFile");

  cur = xmlDocGetRootElement (doc);
  CHECK (cur, "xmlDocGetRootElement");

  if (! NODE_NAME (cur, effects)) {
    fprintf (stderr,"root node \"%s\" != \"effects\"\n", BAD_CAST cur->name);
    xmlFreeDoc (doc);
    exit (EXIT_FAILURE);
  }

757
758
759
  mod_id = getNodeModuleIdent (cur);
  if (NULL != mod_id) {
    VERBOSE_PRINT ((stdout, "effects for \"%s\"\n",
Florian Liekweg's avatar
Florian Liekweg committed
760
            get_id_str(mod_id)));
Boris Boesler's avatar
Boris Boesler committed
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
  }
  else {
    VERBOSE_PRINT ((stdout, "effects \t0x%08x\n", (int) cur));
  }

  /* parse entities */
  cur = cur->xmlChildrenNode;
  while (cur != NULL) {
    if (NODE_NAME (cur, type)) {
      parseType (doc, cur);
    } else if (NODE_NAME (cur, entity)) {
      parseEntity (doc, cur);
    } else if (NODE_NAME (cur, effect)) {
      parseEffect (doc, cur);
    } else if ((NODE_NAME (cur, comment))) {
      /* comment */
    } else {
      fprintf (stderr, "wrong element \"%s\"\n", BAD_CAST cur->name);
      exit (EXIT_FAILURE);
    }
    cur = cur->next;
782
783
  }

Boris Boesler's avatar
Boris Boesler committed
784
  module = NEW(module_t);
785
  module -> id = mod_id;
Boris Boesler's avatar
Boris Boesler committed
786
787
788
789
790
791
792
793
794
795
  module -> types = types;
  module -> entities = entities;
  module -> procs = procs;

  types = NULL;
  entities = NULL;
  procs = NULL;

  module -> next = modules;
  modules = module;
796
797
}

Boris Boesler's avatar
Boris Boesler committed
798
799
/********************************************************************/

800
/*
Boris Boesler's avatar
Boris Boesler committed
801
802
803
804
 * free additional structure
 */
static
void freeArg (eff_t *arg)
805
{
Boris Boesler's avatar
Boris Boesler committed
806
807
808
809
  VERBOSE_PRINT ((stdout, "free arg node \t0x%08x\n", (int) arg));
  free(arg);
  return;
}
810

Boris Boesler's avatar
Boris Boesler committed
811
812
813
814
815
816
817
static
void freeValref (eff_t *valref)
{
  VERBOSE_PRINT ((stdout, "free valref node \t0x%08x\n", (int) valref));
  free(valref);
  return;
}
818

Boris Boesler's avatar
Boris Boesler committed
819
820
821
822
823
824
825
static
void freeSelect (eff_t *sel)
{
  VERBOSE_PRINT ((stdout, "free select node \t0x%08x\n", (int) sel));
  free(sel);
  return;
}
826

Boris Boesler's avatar
Boris Boesler committed
827
828
829
830
831
832
static
void freeLoad (eff_t *load)
{
  VERBOSE_PRINT ((stdout, "free load node \t0x%08x\n", (int) load));
  free (load);
  return;
833
834
}

Boris Boesler's avatar
Boris Boesler committed
835
836
static
void freeStore (eff_t *store)
837
{
Boris Boesler's avatar
Boris Boesler committed
838
839
840
841
  VERBOSE_PRINT ((stdout, "free store node \t0x%08x\n", (int) store));
  free (store);
  return;
}
842

Boris Boesler's avatar
Boris Boesler committed
843
844
845
846
847
848
849
static
void freeAlloc (eff_t *alloc)
{
  VERBOSE_PRINT ((stdout, "free alloc node \t0x%08x\n", (int) alloc));
  free(alloc);
  return;
}
850

Boris Boesler's avatar
Boris Boesler committed
851
852
853
854
855
856
857
858
static
void freeCall (eff_t *call)
{
  VERBOSE_PRINT ((stdout, "free call node \t0x%08x\n", (int) call));
  free(call -> effect.call.args);
  free(call);
  return;
}
859

Boris Boesler's avatar
Boris Boesler committed
860
861
862
863
864
865
866
static
void freeJoin (eff_t *join)
{
  VERBOSE_PRINT ((stdout, "free join node \t0x%08x\n", (int) join));
  free(join -> effect.join.ins);
  free(join);
  return;
867
868
}

Boris Boesler's avatar
Boris Boesler committed
869
870
static
void freeUnknown (eff_t *unknown)
871
{
Boris Boesler's avatar
Boris Boesler committed
872
873
874
875
  VERBOSE_PRINT ((stdout, "free unknown node \t0x%08x\n", (int) unknown));
  free(unknown);
  return;
}
876

Boris Boesler's avatar
Boris Boesler committed
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
static
void freeReturn (eff_t *ret)
{
  VERBOSE_PRINT ((stdout, "free ret node \t0x%08x\n", (int) ret));
  free(ret);
  return;
}

static
void freeRaise (eff_t *raise)
{
  VERBOSE_PRINT ((stdout, "free raise node \t0x%08x\n", (int) raise));
  free (raise);
  return;
}


static
void freeProcEffs(proc_t *proc)
{
  int i;
  int num;

900
  VERBOSE_PRINT ((stdout, "free effect for method \"%s\"\n",
Florian Liekweg's avatar
Florian Liekweg committed
901
          get_id_str(proc -> proc_ident)));
902

Boris Boesler's avatar
Boris Boesler committed
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
  num = proc -> n_effs;
  for(i = 0; i < num; i++) {
    switch(proc -> effs[i] -> kind) {
    case eff_arg:
      freeArg(proc -> effs[i]);
      break;
    case eff_valref:
      freeValref(proc -> effs[i]);
      break;
    case eff_select:
      freeSelect(proc -> effs[i]);
      break;
    case eff_load:
      freeLoad(proc -> effs[i]);
      break;
    case eff_store:
      freeStore(proc -> effs[i]);
      break;
    case eff_alloc:
      freeAlloc(proc -> effs[i]);
      break;
    case eff_call:
      freeCall(proc -> effs[i]);
      break;
    case eff_unknown:
      freeUnknown(proc -> effs[i]);
      break;
    case eff_join:
      freeJoin(proc -> effs[i]);
      break;
    case eff_raise:
      freeRaise(proc -> effs[i]);
      break;
    case eff_ret:
      freeReturn(proc -> effs[i]);
      break;
    default:
      assert(0 && "try to free an unknown effect");
      break;
942
    }
Boris Boesler's avatar
Boris Boesler committed
943
944
945
946
  }
  free(proc -> effs);
  proc -> effs = NULL;
}
947

Boris Boesler's avatar
Boris Boesler committed
948
949
950
951
952
static
void freeModuleProcs(module_t *module)
{
  proc_t *next_proc, *proc;

953
  VERBOSE_PRINT ((stdout, "free procs for module \"%s\"\n",
Florian Liekweg's avatar
Florian Liekweg committed
954
          get_id_str(module -> id)));
955

Boris Boesler's avatar
Boris Boesler committed
956
957
958
959
960
961
  proc = module -> procs;
  while(proc) {
    next_proc = proc -> next;
    freeProcEffs(proc);
    free(proc);
    proc = next_proc;
962
  }
Boris Boesler's avatar
Boris Boesler committed
963
}
964

Boris Boesler's avatar
Boris Boesler committed
965
966
967
968
969
970
971
972
973
974
975
976
static
void free_data(void)
{
  module_t *module, *next_module;

  module = modules;
  while(module) {
    freeModuleProcs(module);
    next_module = module -> next;
    free(module);
    module = next_module;
  }
977
978
}

Boris Boesler's avatar
Boris Boesler committed
979
980
981
/********************************************************************/

static
982
type_t *find_type_in_module(module_t *module, const ident *typeid)
983
{
Boris Boesler's avatar
Boris Boesler committed
984
  type_t *type;
985

Boris Boesler's avatar
Boris Boesler committed
986
  for(type = module -> types; type; type = type -> prev) {
987
988
989
    VERBOSE_PRINT((stdout, "test typeid %s\n", get_id_str(type -> id)));
    if(type -> id == typeid) {
      VERBOSE_PRINT((stdout, "found\n"));
Boris Boesler's avatar
Boris Boesler committed
990
      return(type);
991
992
    }
  }
993
  VERBOSE_PRINT((stdout, "did not find type id %s\n", get_id_str(typeid)));
Boris Boesler's avatar
Boris Boesler committed
994
995
  return(NULL);
}
996

Boris Boesler's avatar
Boris Boesler committed
997
998
999
1000
/********************************************************************/

static void add_value_to_proc(proc_t *proc, eff_t *eff)
{
For faster browsing, not all history is shown. View entire blame