1 /* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
7 * This file provides some general purpose functions for manipulating
9 * ----------------------------------------------------------------------------- */
11 char cvsroot_tree_c[] = "$Id: tree.c 11080 2009-01-24 13:15:51Z bhy $";
17 /* -----------------------------------------------------------------------------
20 * Dump the tag structure of a parse tree to standard output
21 * ----------------------------------------------------------------------------- */
23 void Swig_print_tags(DOH *obj, DOH *root) {
28 croot = NewStringEmpty();
33 Printf(stdout, "%s . %s (%s:%d)\n", croot, nodeType(obj), Getfile(obj), Getline(obj));
34 cobj = firstChild(obj);
36 newroot = NewStringf("%s . %s", croot, nodeType(obj));
37 Swig_print_tags(cobj, newroot);
40 obj = nextSibling(obj);
46 static int indent_level = 0;
48 static void print_indent(int l) {
50 for (i = 0; i < indent_level; i++) {
60 /* -----------------------------------------------------------------------------
61 * Swig_print_node(Node *n)
62 * ----------------------------------------------------------------------------- */
64 void Swig_print_node(Node *obj) {
69 Printf(stdout, "+++ %s ----------------------------------------\n", nodeType(obj));
73 if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) ||
74 (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) {
76 } else if (Cmp(k, "parms") == 0) {
78 Printf(stdout, "%-12s - %s\n", k, ParmList_protostr(Getattr(obj, k)));
83 if (DohIsString(Getattr(obj, k))) {
84 o = Str(Getattr(obj, k));
88 Printf(stdout, "%-12s - \"%(escape)-0.80s%s\"\n", k, o, trunc);
91 Printf(stdout, "%-12s - 0x%x\n", k, Getattr(obj, k));
96 cobj = firstChild(obj);
100 Swig_print_tree(cobj);
104 Printf(stdout, "\n");
108 /* -----------------------------------------------------------------------------
111 * Dump the tree structure of a parse tree to standard output
112 * ----------------------------------------------------------------------------- */
114 void Swig_print_tree(DOH *obj) {
116 Swig_print_node(obj);
117 obj = nextSibling(obj);
121 /* -----------------------------------------------------------------------------
124 * Appends a new child to a node
125 * ----------------------------------------------------------------------------- */
127 void appendChild(Node *node, Node *chd) {
133 lc = lastChild(node);
135 set_firstChild(node, chd);
137 set_nextSibling(lc, chd);
138 set_previousSibling(chd, lc);
142 set_parentNode(chd, node);
143 chd = nextSibling(chd);
145 set_lastChild(node, lc);
148 /* -----------------------------------------------------------------------------
151 * Prepends a new child to a node
152 * ----------------------------------------------------------------------------- */
154 void prependChild(Node *node, Node *chd) {
160 fc = firstChild(node);
162 set_nextSibling(chd, fc);
163 set_previousSibling(fc, chd);
165 set_firstChild(node, chd);
167 set_parentNode(chd, node);
168 chd = nextSibling(chd);
172 /* -----------------------------------------------------------------------------
175 * Removes a node from the parse tree. Detaches it from its parent's child list.
176 * ----------------------------------------------------------------------------- */
178 void removeNode(Node *n) {
183 parent = parentNode(n);
186 prev = previousSibling(n);
187 next = nextSibling(n);
189 set_nextSibling(prev, next);
192 set_firstChild(parent, next);
196 set_previousSibling(next, prev);
199 set_lastChild(parent, prev);
203 /* Delete attributes */
204 Delattr(n,"parentNode");
205 Delattr(n,"nextSibling");
206 Delattr(n,"prevSibling");
209 /* -----------------------------------------------------------------------------
212 * Copies a node, but only copies simple attributes (no lists, hashes).
213 * ----------------------------------------------------------------------------- */
215 Node *copyNode(Node *n) {
218 for (ki = First(n); ki.key; ki = Next(ki)) {
219 if (DohIsString(ki.item)) {
220 Setattr(c, ki.key, Copy(ki.item));
223 Setfile(c, Getfile(n));
224 Setline(c, Getline(n));
228 /* -----------------------------------------------------------------------------
230 * ----------------------------------------------------------------------------- */
232 int checkAttribute(Node *n, const_String_or_char_ptr name, const_String_or_char_ptr value) {
233 String *v = Getattr(n, name);
234 return v ? Equal(v, value) : 0;
237 /* -----------------------------------------------------------------------------
239 * ns - namespace for the view name for saving any attributes under
241 * ... - list of attribute names of type char*
242 * This method checks that the attribute names exist in the node n and asserts if
243 * not. Assert will only occur unless the attribute is optional. An attribute is
244 * optional if it is prefixed by ?, eg "?value". If the attribute name is prefixed
245 * by * or ?, eg "*value" then a copy of the attribute is saved. The saved
246 * attributes will be restored on a subsequent call to Swig_restore(). All the
247 * saved attributes are saved in the view namespace (prefixed by ns).
248 * This function can be called more than once with different namespaces.
249 * ----------------------------------------------------------------------------- */
251 void Swig_require(const char *ns, Node *n, ...) {
257 name = va_arg(ap, char *);
264 } else if (*name == '?') {
269 obj = Getattr(n, name);
271 Printf(stderr, "%s:%d. Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", Getfile(n), Getline(n), name, nodeType(n));
277 /* Save a copy of the attribute */
278 Setattr(n, NewStringf("%s:%s", ns, name), obj);
280 name = va_arg(ap, char *);
286 String *view = Getattr(n, "view");
288 if (Strcmp(view, ns) != 0) {
289 Setattr(n, NewStringf("%s:view", ns), view);
290 Setattr(n, "view", ns);
293 Setattr(n, "view", ns);
299 /* -----------------------------------------------------------------------------
301 * Same as Swig_require(), but all attribute names are optional and all attributes
302 * are saved, ie behaves as if all the attribute names were prefixed by ?.
303 * ----------------------------------------------------------------------------- */
305 void Swig_save(const char *ns, Node *n, ...) {
311 name = va_arg(ap, char *);
315 } else if (*name == '?') {
318 obj = Getattr(n, name);
322 /* Save a copy of the attribute */
323 if (Setattr(n, NewStringf("%s:%s", ns, name), obj)) {
324 Printf(stderr, "Swig_save('%s','%s'): Warning, attribute '%s' was already saved.\n", ns, nodeType(n), name);
326 name = va_arg(ap, char *);
332 String *view = Getattr(n, "view");
334 if (Strcmp(view, ns) != 0) {
335 Setattr(n, NewStringf("%s:view", ns), view);
336 Setattr(n, "view", ns);
339 Setattr(n, "view", ns);
344 /* -----------------------------------------------------------------------------
346 * Restores attributes saved by a previous call to Swig_require() or Swig_save().
347 * ----------------------------------------------------------------------------- */
349 void Swig_restore(Node *n) {
356 ns = Getattr(n, "view");
361 temp = NewStringf("%s:", ns);
364 for (ki = First(n); ki.key; ki = Next(ki)) {
365 if (Strncmp(temp, ki.key, len) == 0) {
369 for (ki = First(l); ki.item; ki = Next(ki)) {
370 DOH *obj = Getattr(n, ki.item);
371 Setattr(n, Char(ki.item) + len, obj);