~ubuntu-branches/ubuntu/warty/swig1.3/warty

« back to all changes in this revision

Viewing changes to Source/Swig/tree.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Landschoff
  • Date: 2002-03-29 01:56:07 UTC
  • Revision ID: james.westby@ubuntu.com-20020329015607-c0wt03xu8oy9ioj7
Tags: upstream-1.3.11
ImportĀ upstreamĀ versionĀ 1.3.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ----------------------------------------------------------------------------- 
 
2
 * tree.c
 
3
 *
 
4
 *     This file provides some general purpose functions for manipulating 
 
5
 *     parse trees.
 
6
 * 
 
7
 * Author(s) : David Beazley (beazley@cs.uchicago.edu)
 
8
 *
 
9
 * Copyright (C) 1999-2000.  The University of Chicago
 
10
 * See the file LICENSE for information on usage and redistribution.    
 
11
 * ----------------------------------------------------------------------------- */
 
12
 
 
13
#include "swig.h"
 
14
#include <stdarg.h>
 
15
#include <assert.h>
 
16
 
 
17
static char cvsroot[] = "$Header: /cvs/projects/SWIG/Source/Swig/tree.c,v 1.6.4.8 2001/12/10 21:14:27 beazley Exp $";
 
18
 
 
19
/* -----------------------------------------------------------------------------
 
20
 * Swig_dump_tags()
 
21
 *
 
22
 * Dump the tag structure of a parse tree to standard output
 
23
 * ----------------------------------------------------------------------------- */
 
24
 
 
25
void 
 
26
Swig_dump_tags(DOH *obj, DOH *root) {
 
27
  DOH *croot, *newroot;
 
28
  DOH *cobj;
 
29
 
 
30
  if (!root) croot = NewString("");
 
31
  else croot = root;
 
32
 
 
33
  while (obj) {
 
34
    Printf(stdout,"%s . %s (%s:%d)\n", croot, nodeType(obj), Getfile(obj), Getline(obj));
 
35
    cobj = firstChild(obj);
 
36
    if (cobj) {
 
37
      newroot = NewStringf("%s . %s",croot,nodeType(obj));
 
38
      Swig_dump_tags(cobj,newroot);
 
39
      Delete(newroot);
 
40
    }
 
41
    obj = nextSibling(obj);
 
42
  }
 
43
  if (!root)
 
44
    Delete(croot);
 
45
}
 
46
 
 
47
 
 
48
/* -----------------------------------------------------------------------------
 
49
 * Swig_dump_tree()
 
50
 *
 
51
 * Dump the tree structure of a parse tree to standard output
 
52
 * ----------------------------------------------------------------------------- */
 
53
 
 
54
static int indent_level = 0;
 
55
 
 
56
static void print_indent(int l) {
 
57
  int i;
 
58
  for (i = 0; i < indent_level; i++) {
 
59
    fputc(' ', stdout);
 
60
  }
 
61
  if (l) {
 
62
    fputc('|', stdout);
 
63
    fputc(' ', stdout);
 
64
  }
 
65
}
 
66
 
 
67
void 
 
68
Swig_dump_tree(DOH *obj) {
 
69
  DOH *k;
 
70
  DOH *cobj;
 
71
 
 
72
  while (obj) {
 
73
    print_indent(0);
 
74
    Printf(stdout,"+++ %s ----------------------------------------\n", nodeType(obj));
 
75
      
 
76
    k = Firstkey(obj);
 
77
    while (k) {
 
78
      if ((Cmp(k,"nodeType") == 0) || (Cmp(k,"firstChild") == 0) || (Cmp(k,"lastChild") == 0) ||
 
79
          (Cmp(k,"parentNode") == 0) || (Cmp(k,"nextSibling") == 0) ||
 
80
          (Cmp(k,"previousSibling") == 0) || (*(Char(k)) == '$')) {
 
81
        /* Do nothing */
 
82
      } else if (Cmp(k,"parms") == 0) {
 
83
        print_indent(2);
 
84
        Printf(stdout,"%-12s - %s\n", k, ParmList_protostr(Getattr(obj,k)));
 
85
      } else {
 
86
        DOH *o;
 
87
        char *trunc = "";
 
88
        print_indent(2);
 
89
        if (DohIsString(Getattr(obj,k))) {
 
90
          o = Str(Getattr(obj,k));
 
91
          if (Len(o) > 40) {
 
92
            trunc = "...";
 
93
          }
 
94
          Printf(stdout,"%-12s - \"%(escape)-0.40s%s\"\n", k, o, trunc);
 
95
          Delete(o);
 
96
        } else {
 
97
          Printf(stdout,"%-12s - 0x%x\n", k, Getattr(obj,k));
 
98
        }
 
99
      }
 
100
      k = Nextkey(obj);
 
101
    }
 
102
    cobj = firstChild(obj);
 
103
    if (cobj) {
 
104
      indent_level += 6;
 
105
      Printf(stdout,"\n");
 
106
      Swig_dump_tree(cobj);
 
107
      indent_level -= 6;
 
108
    } else {
 
109
      print_indent(1);
 
110
      Printf(stdout,"\n");
 
111
    }
 
112
    obj = nextSibling(obj);
 
113
  }
 
114
}
 
115
 
 
116
/* -----------------------------------------------------------------------------
 
117
 * appendChild()
 
118
 *
 
119
 * Appends a new child to a node
 
120
 * ----------------------------------------------------------------------------- */
 
121
 
 
122
void
 
123
appendChild(Node *node, Node *chd) {
 
124
  Node *lc;
 
125
 
 
126
  if (!chd) return;
 
127
 
 
128
  lc = lastChild(node);
 
129
  if (!lc) {
 
130
    set_firstChild(node,chd);
 
131
  } else {
 
132
    set_nextSibling(lc,chd);
 
133
    set_previousSibling(chd,lc);
 
134
  }
 
135
  while (chd) {
 
136
    lc = chd;
 
137
    set_parentNode(chd,node);
 
138
    chd = nextSibling(chd);
 
139
  }
 
140
  set_lastChild(node,lc);
 
141
}
 
142
 
 
143
 
 
144
/* -----------------------------------------------------------------------------
 
145
 * Swig_require()
 
146
 * ----------------------------------------------------------------------------- */
 
147
 
 
148
#define MAX_SWIG_STACK 256
 
149
static Hash    *attr_stack[MAX_SWIG_STACK];
 
150
static Node   **nodeptr_stack[MAX_SWIG_STACK];
 
151
static Node    *node_stack[MAX_SWIG_STACK];
 
152
static int      stackp = 0;
 
153
static int      stack_direction = 0;
 
154
 
 
155
static void set_direction(int n, int *x) {
 
156
  if (n == 1) {
 
157
    set_direction(0,&n);
 
158
  } else {
 
159
    if (&n < x) {
 
160
      stack_direction = -1;   /* Stack grows down */
 
161
    } else {
 
162
      stack_direction = 1;    /* Stack grows up */
 
163
    }
 
164
  }
 
165
}
 
166
 
 
167
int 
 
168
Swig_require(Node **nptr, ...) {
 
169
  va_list ap;
 
170
  char *name;
 
171
  DOH *obj;
 
172
  DOH *frame = 0;
 
173
  Node *n = *nptr;
 
174
  va_start(ap, nptr);
 
175
  name = va_arg(ap, char *);
 
176
  while (name) {
 
177
    int newref = 0;
 
178
    int opt = 0;
 
179
    if (*name == '*') {
 
180
      newref = 1;
 
181
      name++;
 
182
    } else if (*name == '?') {
 
183
      newref = 1;
 
184
      opt = 1;
 
185
      name++;
 
186
    }
 
187
    obj = Getattr(n,name);
 
188
    if (!opt && !obj) {
 
189
      Printf(stderr,"%s:%d. Fatal error (Swig_require).  Missing attribute '%s' in node '%s'.\n", 
 
190
             Getfile(n), Getline(n), name, nodeType(n));
 
191
      assert(obj);
 
192
    }
 
193
    if (!obj) obj = DohNone;
 
194
    if (newref) {
 
195
      if (!attr_stack[stackp]) {
 
196
        attr_stack[stackp]= NewHash();
 
197
      }
 
198
      frame = attr_stack[stackp];
 
199
      if (Setattr(frame,name,obj)) {
 
200
        Printf(stderr,"Swig_require('%s'): Warning, attribute '%s' was already saved.\n", nodeType(n), name);
 
201
      }
 
202
    } 
 
203
    name = va_arg(ap, char *);
 
204
  }
 
205
  va_end(ap);
 
206
  if (frame) {
 
207
    /* This is a sanity check to make sure no one is saving data, but not restoring it */
 
208
    if (stackp > 0) {
 
209
      int e = 0;
 
210
      if (!stack_direction) set_direction(1,0);
 
211
      
 
212
      if (stack_direction < 0) {
 
213
        if ((((char *) nptr) >= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
 
214
      } else {
 
215
        if ((((char *) nptr) <= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
 
216
      }
 
217
      if (e) {
 
218
        Printf(stderr,
 
219
"Swig_require('%s'): Fatal memory management error.  If you are seeing this\n\
 
220
message. It means that the target language module is not managing its memory\n\
 
221
correctly.  A handler for '%s' probably forgot to call Swig_restore().\n\
 
222
Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1]));
 
223
        assert(0);
 
224
      }
 
225
    }
 
226
    nodeptr_stack[stackp] = nptr;
 
227
    node_stack[stackp] = n;
 
228
    stackp++;
 
229
  }
 
230
  return 1;
 
231
}
 
232
 
 
233
 
 
234
int 
 
235
Swig_save(Node **nptr, ...) {
 
236
  va_list ap;
 
237
  char *name;
 
238
  DOH *obj;
 
239
  DOH *frame;
 
240
  Node *n = *nptr;
 
241
 
 
242
  if ((stackp > 0) && (nodeptr_stack[stackp-1] == nptr)) {
 
243
      frame = attr_stack[stackp-1];
 
244
  } else {
 
245
    if (stackp > 0) {
 
246
      int e = 0;
 
247
      if (!stack_direction) set_direction(1,0);
 
248
      if (stack_direction < 0) {
 
249
        if ((((char *) nptr) >= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
 
250
      } else {
 
251
        if ((((char *) nptr) <= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
 
252
      }
 
253
      if (e) {
 
254
        Printf(stderr,
 
255
"Swig_save('%s'): Fatal memory management error.  If you are seeing this\n\
 
256
message. It means that the target language module is not managing its memory\n\
 
257
correctly.  A handler for '%s' probably forgot to call Swig_restore().\n\
 
258
Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1]));
 
259
        assert(0);
 
260
      }
 
261
    }
 
262
    attr_stack[stackp] = NewHash();
 
263
    nodeptr_stack[stackp] = nptr;
 
264
    node_stack[stackp] = n;
 
265
    frame = attr_stack[stackp];
 
266
    stackp++;
 
267
  }
 
268
  va_start(ap, nptr);
 
269
  name = va_arg(ap, char *);
 
270
  while (name) {
 
271
    if (*name == '*') {
 
272
      name++;
 
273
    } else if (*name == '?') {
 
274
      name++;
 
275
    }
 
276
    obj = Getattr(n,name);
 
277
    if (!obj) {
 
278
      obj = DohNone;
 
279
    }
 
280
    if (Setattr(frame,name,obj)) {
 
281
      Printf(stderr,"Swig_save('%s'): Warning, attribute '%s' was already saved.\n", nodeType(n), name);
 
282
    }
 
283
    name = va_arg(ap, char *);
 
284
  }
 
285
  va_end(ap);
 
286
  return 1;
 
287
}
 
288
 
 
289
void 
 
290
Swig_restore(Node **nptr) {
 
291
  String *key;
 
292
  Hash   *frame;
 
293
  Node   *n = *nptr;
 
294
  assert(stackp > 0);
 
295
  if (!(nptr==nodeptr_stack[stackp-1])) {
 
296
        Printf(stderr,
 
297
"Swig_restore('%s'): Fatal memory management error.  If you are seeing this\n\
 
298
message. It means that the target language module is not managing its memory\n\
 
299
correctly.  A handler for '%s' probably forgot to call Swig_restore().\n\
 
300
Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1]));
 
301
    assert(0);
 
302
  }
 
303
  stackp--;
 
304
  frame = attr_stack[stackp];
 
305
  nodeptr_stack[stackp] = 0;
 
306
  node_stack[stackp] = 0;
 
307
  for (key = Firstkey(frame); key; key = Nextkey(frame)) {
 
308
    DOH *obj = Getattr(frame,key);
 
309
    if (obj != DohNone) {
 
310
      Setattr(n,key,obj);
 
311
    } else {
 
312
      Delattr(n,key);
 
313
    }
 
314
    Delattr(frame,key);
 
315
  }
 
316
}