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