PageRenderTime 45ms CodeModel.GetById 14ms app.highlight 27ms RepoModel.GetById 1ms app.codeStats 1ms

/trunk/Source/Modules/xml.cxx

#
C++ | 324 lines | 260 code | 40 blank | 24 comment | 67 complexity | 6287297009fbb161cf94153bac1ea85b MD5 | raw file
  1/* -----------------------------------------------------------------------------
  2 * This file is part of SWIG, which is licensed as a whole under version 3 
  3 * (or any later version) of the GNU General Public License. Some additional
  4 * terms also apply to certain portions of SWIG. The full details of the SWIG
  5 * license and copyrights can be found in the LICENSE and COPYRIGHT files
  6 * included with the SWIG source code as distributed by the SWIG developers
  7 * and at http://www.swig.org/legal.html.
  8 *
  9 * xml.cxx
 10 *
 11 * An Xml parse tree generator.
 12 * ----------------------------------------------------------------------------- */
 13
 14char cvsroot_xml_cxx[] = "$Id: xml.cxx 11876 2010-02-27 23:53:33Z wsfulton $";
 15
 16#include "swigmod.h"
 17
 18static const char *usage = "\
 19XML Options (available with -xml)\n\
 20     -xmllang <lang> - Typedef language\n\
 21     -xmllite        - More lightweight version of XML\n\
 22     ------\n\
 23     deprecated (use -o): -xml <output.xml> - Use <output.xml> as output file (extension .xml mandatory)\n";
 24
 25static File *out = 0;
 26static int xmllite = 0;
 27
 28
 29class XML:public Language {
 30public:
 31
 32  int indent_level;
 33  long id;
 34
 35  XML() :indent_level(0) , id(0) {
 36  }
 37  
 38  virtual ~ XML() {
 39  }
 40
 41  virtual void main(int argc, char *argv[]) {
 42    SWIG_typemap_lang("xml");
 43    for (int iX = 0; iX < argc; iX++) {
 44      if (strcmp(argv[iX], "-xml") == 0) {
 45	char *extension = 0;
 46	if (iX + 1 >= argc)
 47	  continue;
 48	extension = argv[iX + 1] + strlen(argv[iX + 1]) - 4;
 49	if (strcmp(extension, ".xml"))
 50	  continue;
 51	iX++;
 52	Swig_mark_arg(iX);
 53	String *outfile = NewString(argv[iX]);
 54	out = NewFile(outfile, "w", SWIG_output_files());
 55	if (!out) {
 56	  FileErrorDisplay(outfile);
 57	  SWIG_exit(EXIT_FAILURE);
 58	}
 59	continue;
 60      }
 61      if (strcmp(argv[iX], "-xmllang") == 0) {
 62	Swig_mark_arg(iX);
 63	iX++;
 64	SWIG_typemap_lang(argv[iX]);
 65	Swig_mark_arg(iX);
 66	continue;
 67      }
 68      if (strcmp(argv[iX], "-help") == 0) {
 69	fputs(usage, stdout);
 70      }
 71      if (strcmp(argv[iX], "-xmllite") == 0) {
 72	Swig_mark_arg(iX);
 73	xmllite = 1;
 74      }
 75    }
 76
 77    // Add a symbol to the parser for conditional compilation
 78    Preprocessor_define("SWIGXML 1", 0);
 79  }
 80
 81  /* Top of the parse tree */
 82
 83  virtual int top(Node *n) {
 84    if (out == 0) {
 85      String *outfile = Getattr(n, "outfile");
 86      Replaceall(outfile, ".cxx", ".xml");
 87      Replaceall(outfile, ".cpp", ".xml");
 88      Replaceall(outfile, ".c", ".xml");
 89      out = NewFile(outfile, "w", SWIG_output_files());
 90      if (!out) {
 91	FileErrorDisplay(outfile);
 92	SWIG_exit(EXIT_FAILURE);
 93      }
 94    }
 95    Printf(out, "<?xml version=\"1.0\" ?> \n");
 96    Xml_print_tree(n);
 97    return SWIG_OK;
 98  }
 99
100  void print_indent(int l) {
101    int i;
102    for (i = 0; i < indent_level; i++) {
103      Printf(out, " ");
104    }
105    if (l) {
106      Printf(out, " ");
107    }
108  }
109
110  void Xml_print_tree(DOH *obj) {
111    while (obj) {
112      Xml_print_node(obj);
113      obj = nextSibling(obj);
114    }
115  }
116
117  void Xml_print_attributes(Node *obj) {
118    String *k;
119    indent_level += 4;
120    print_indent(0);
121    Printf(out, "<attributelist id=\"%ld\" addr=\"%x\" >\n", ++id, obj);
122    indent_level += 4;
123    Iterator ki;
124    ki = First(obj);
125    while (ki.key) {
126      k = ki.key;
127      if ((Cmp(k, "nodeType") == 0)
128	  || (Cmp(k, "firstChild") == 0)
129	  || (Cmp(k, "lastChild") == 0)
130	  || (Cmp(k, "parentNode") == 0)
131	  || (Cmp(k, "nextSibling") == 0)
132	  || (Cmp(k, "previousSibling") == 0)
133	  || (*(Char(k)) == '$')) {
134	/* Do nothing */
135      } else if (Cmp(k, "module") == 0) {
136	Xml_print_module(Getattr(obj, k));
137      } else if (Cmp(k, "baselist") == 0) {
138	Xml_print_baselist(Getattr(obj, k));
139      } else if (!xmllite && Cmp(k, "typescope") == 0) {
140	Xml_print_typescope(Getattr(obj, k));
141      } else if (!xmllite && Cmp(k, "typetab") == 0) {
142	Xml_print_typetab(Getattr(obj, k));
143      } else if (Cmp(k, "kwargs") == 0) {
144	Xml_print_kwargs(Getattr(obj, k));
145      } else if (Cmp(k, "parms") == 0 || Cmp(k, "pattern") == 0) {
146	Xml_print_parmlist(Getattr(obj, k));
147      } else {
148	DOH *o;
149	print_indent(0);
150	if (DohIsString(Getattr(obj, k))) {
151	  String *ck = NewString(k);
152	  o = Str(Getattr(obj, k));
153	  Replaceall(ck, ":", "_");
154	  Replaceall(ck, "<", "&lt;");
155	  /* Do first to avoid aliasing errors. */
156	  Replaceall(o, "&", "&amp;");
157	  Replaceall(o, "<", "&lt;");
158	  Replaceall(o, "\"", "&quot;");
159	  Replaceall(o, "\\", "\\\\");
160	  Replaceall(o, "\n", "&#10;");
161	  Printf(out, "<attribute name=\"%s\" value=\"%s\" id=\"%ld\" addr=\"%x\" />\n", ck, o, ++id, o);
162	  Delete(o);
163	  Delete(ck);
164	} else {
165	  o = Getattr(obj, k);
166	  String *ck = NewString(k);
167	  Replaceall(ck, ":", "_");
168	  Printf(out, "<attribute name=\"%s\" value=\"%x\" id=\"%ld\" addr=\"%x\" />\n", ck, o, ++id, o);
169	  Delete(ck);
170	}
171      }
172      ki = Next(ki);
173    }
174    indent_level -= 4;
175    print_indent(0);
176    Printf(out, "</attributelist >\n");
177    indent_level -= 4;
178  }
179
180  void Xml_print_node(Node *obj) {
181    Node *cobj;
182
183    print_indent(0);
184    Printf(out, "<%s id=\"%ld\" addr=\"%x\" >\n", nodeType(obj), ++id, obj);
185    Xml_print_attributes(obj);
186    cobj = firstChild(obj);
187    if (cobj) {
188      indent_level += 4;
189      Printf(out, "\n");
190      Xml_print_tree(cobj);
191      indent_level -= 4;
192    } else {
193      print_indent(1);
194      Printf(out, "\n");
195    }
196    print_indent(0);
197    Printf(out, "</%s >\n", nodeType(obj));
198  }
199
200
201  void Xml_print_parmlist(ParmList *p) {
202
203    print_indent(0);
204    Printf(out, "<parmlist id=\"%ld\" addr=\"%x\" >\n", ++id, p);
205    indent_level += 4;
206    while (p) {
207      print_indent(0);
208      Printf(out, "<parm id=\"%ld\">\n", ++id);
209      Xml_print_attributes(p);
210      print_indent(0);
211      Printf(out, "</parm >\n");
212      p = nextSibling(p);
213    }
214    indent_level -= 4;
215    print_indent(0);
216    Printf(out, "</parmlist >\n");
217  }
218
219  void Xml_print_baselist(List *p) {
220
221    print_indent(0);
222    Printf(out, "<baselist id=\"%ld\" addr=\"%x\" >\n", ++id, p);
223    indent_level += 4;
224    Iterator s;
225    for (s = First(p); s.item; s = Next(s)) {
226      print_indent(0);
227      String *item_name = Xml_escape_string(s.item);
228      Printf(out, "<base name=\"%s\" id=\"%ld\" addr=\"%x\" />\n", item_name, ++id, s.item);
229      Delete(item_name);
230    }
231    indent_level -= 4;
232    print_indent(0);
233    Printf(out, "</baselist >\n");
234  }
235
236  String *Xml_escape_string(String *str) {
237    String *escaped_str = 0;
238    if (str) {
239      escaped_str = NewString(str);
240      Replaceall(escaped_str, "&", "&amp;");
241      Replaceall(escaped_str, "<", "&lt;");
242      Replaceall(escaped_str, "\"", "&quot;");
243      Replaceall(escaped_str, "\\", "\\\\");
244      Replaceall(escaped_str, "\n", "&#10;");
245    }
246    return escaped_str;
247  }
248
249  void Xml_print_module(Node *p) {
250
251    print_indent(0);
252    Printf(out, "<attribute name=\"module\" value=\"%s\" id=\"%ld\" addr=\"%x\" />\n", Getattr(p, "name"), ++id, p);
253  }
254
255  void Xml_print_kwargs(Hash *p) {
256    Xml_print_hash(p, "kwargs");
257  }
258
259  void Xml_print_typescope(Hash *p) {
260
261    Xml_print_hash(p, "typescope");
262  }
263
264  void Xml_print_typetab(Hash *p) {
265
266    Xml_print_hash(p, "typetab");
267  }
268
269
270  void Xml_print_hash(Hash *p, const char *markup) {
271
272    print_indent(0);
273    Printf(out, "<%s id=\"%ld\" addr=\"%x\" >\n", markup, ++id, p);
274    Xml_print_attributes(p);
275    indent_level += 4;
276    Iterator n = First(p);
277    while (n.key) {
278      print_indent(0);
279      Printf(out, "<%ssitem id=\"%ld\" addr=\"%x\" >\n", markup, ++id, n.item);
280      Xml_print_attributes(n.item);
281      print_indent(0);
282      Printf(out, "</%ssitem >\n", markup);
283      n = Next(n);
284    }
285    indent_level -= 4;
286    print_indent(0);
287    Printf(out, "</%s >\n", markup);
288  }
289
290};
291
292/* -----------------------------------------------------------------------------
293 * Swig_print_xml
294 *
295 * Dump an XML version of the parse tree.  This is different from using the -xml
296 * language module normally as it allows the real language module to process the
297 * tree first, possibly stuffing in new attributes, so the XML that is output ends
298 * up being a post-processing version of the tree.
299 * ----------------------------------------------------------------------------- */
300
301void Swig_print_xml(DOH *obj, String *filename) {
302  XML xml;
303  xmllite = 1;
304
305  if (!filename) {
306    out = stdout;
307  } else {
308    out = NewFile(filename, "w", SWIG_output_files());
309    if (!out) {
310      FileErrorDisplay(filename);
311      SWIG_exit(EXIT_FAILURE);
312    }
313  }
314
315  Printf(out, "<?xml version=\"1.0\" ?> \n");
316  xml.Xml_print_tree(obj);
317}
318
319static Language *new_swig_xml() {
320  return new XML();
321}
322extern "C" Language *swig_xml(void) {
323  return new_swig_xml();
324}