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 10char cvsroot_xml_cxx[] = "$Id: xml.cxx 10898 2008-11-03 12:51:45Z wsfulton $"; 11 12#include "swigmod.h" 13 14static const char *usage = "\ 15XML 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 21static File *out = 0; 22static int xmllite = 0; 23 24 25class XML:public Language { 26public: 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, "<", "<"); 151 /* Do first to avoid aliasing errors. */ 152 Replaceall(o, "&", "&"); 153 Replaceall(o, "<", "<"); 154 Replaceall(o, "\"", """); 155 Replaceall(o, "\\", "\\\\"); 156 Replaceall(o, "\n", " "); 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, "&", "&"); 237 Replaceall(escaped_str, "<", "<"); 238 Replaceall(escaped_str, "\"", """); 239 Replaceall(escaped_str, "\\", "\\\\"); 240 Replaceall(escaped_str, "\n", " "); 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 297void 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 315static Language *new_swig_xml() { 316 return new XML(); 317} 318extern "C" Language *swig_xml(void) { 319 return new_swig_xml(); 320} 321