diff options
Diffstat (limited to 'Source/Modules/xml.cxx')
-rw-r--r-- | Source/Modules/xml.cxx | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/Source/Modules/xml.cxx b/Source/Modules/xml.cxx new file mode 100644 index 0000000..a3d393a --- /dev/null +++ b/Source/Modules/xml.cxx @@ -0,0 +1,320 @@ +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * xml.cxx + * + * An Xml parse tree generator. + * ----------------------------------------------------------------------------- */ + +char cvsroot_xml_cxx[] = "$Id: xml.cxx 10898 2008-11-03 12:51:45Z wsfulton $"; + +#include "swigmod.h" + +static const char *usage = "\ +XML Options (available with -xml)\n\ + -xmllang <lang> - Typedef language\n\ + -xmllite - More lightweight version of XML\n\ + ------\n\ + deprecated (use -o): -xml <output.xml> - Use <output.xml> as output file (extension .xml mandatory)\n"; + +static File *out = 0; +static int xmllite = 0; + + +class XML:public Language { +public: + + int indent_level; + long id; + + XML() :indent_level(0) , id(0) { + } + + virtual ~ XML() { + } + + virtual void main(int argc, char *argv[]) { + SWIG_typemap_lang("xml"); + for (int iX = 0; iX < argc; iX++) { + if (strcmp(argv[iX], "-xml") == 0) { + char *extension = 0; + if (iX + 1 >= argc) + continue; + extension = argv[iX + 1] + strlen(argv[iX + 1]) - 4; + if (strcmp(extension, ".xml")) + continue; + iX++; + Swig_mark_arg(iX); + String *outfile = NewString(argv[iX]); + out = NewFile(outfile, "w", SWIG_output_files()); + if (!out) { + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); + } + continue; + } + if (strcmp(argv[iX], "-xmllang") == 0) { + Swig_mark_arg(iX); + iX++; + SWIG_typemap_lang(argv[iX]); + Swig_mark_arg(iX); + continue; + } + if (strcmp(argv[iX], "-help") == 0) { + fputs(usage, stdout); + } + if (strcmp(argv[iX], "-xmllite") == 0) { + Swig_mark_arg(iX); + xmllite = 1; + } + } + + // Add a symbol to the parser for conditional compilation + Preprocessor_define("SWIGXML 1", 0); + } + + /* Top of the parse tree */ + + virtual int top(Node *n) { + if (out == 0) { + String *outfile = Getattr(n, "outfile"); + Replaceall(outfile, ".cxx", ".xml"); + Replaceall(outfile, ".cpp", ".xml"); + Replaceall(outfile, ".c", ".xml"); + out = NewFile(outfile, "w", SWIG_output_files()); + if (!out) { + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); + } + } + Printf(out, "<?xml version=\"1.0\" ?> \n"); + Xml_print_tree(n); + return SWIG_OK; + } + + void print_indent(int l) { + int i; + for (i = 0; i < indent_level; i++) { + Printf(out, " "); + } + if (l) { + Printf(out, " "); + } + } + + void Xml_print_tree(DOH *obj) { + while (obj) { + Xml_print_node(obj); + obj = nextSibling(obj); + } + } + + void Xml_print_attributes(Node *obj) { + String *k; + indent_level += 4; + print_indent(0); + Printf(out, "<attributelist id=\"%ld\" addr=\"%x\" >\n", ++id, obj); + indent_level += 4; + Iterator ki; + ki = First(obj); + while (ki.key) { + k = ki.key; + if ((Cmp(k, "nodeType") == 0) + || (Cmp(k, "firstChild") == 0) + || (Cmp(k, "lastChild") == 0) + || (Cmp(k, "parentNode") == 0) + || (Cmp(k, "nextSibling") == 0) + || (Cmp(k, "previousSibling") == 0) + || (*(Char(k)) == '$')) { + /* Do nothing */ + } else if (Cmp(k, "module") == 0) { + Xml_print_module(Getattr(obj, k)); + } else if (Cmp(k, "baselist") == 0) { + Xml_print_baselist(Getattr(obj, k)); + } else if (!xmllite && Cmp(k, "typescope") == 0) { + Xml_print_typescope(Getattr(obj, k)); + } else if (!xmllite && Cmp(k, "typetab") == 0) { + Xml_print_typetab(Getattr(obj, k)); + } else if (Cmp(k, "kwargs") == 0) { + Xml_print_kwargs(Getattr(obj, k)); + } else if (Cmp(k, "parms") == 0 || Cmp(k, "pattern") == 0) { + Xml_print_parmlist(Getattr(obj, k)); + } else { + DOH *o; + print_indent(0); + if (DohIsString(Getattr(obj, k))) { + String *ck = NewString(k); + o = Str(Getattr(obj, k)); + Replaceall(ck, ":", "_"); + Replaceall(ck, "<", "<"); + /* Do first to avoid aliasing errors. */ + Replaceall(o, "&", "&"); + Replaceall(o, "<", "<"); + Replaceall(o, "\"", """); + Replaceall(o, "\\", "\\\\"); + Replaceall(o, "\n", " "); + Printf(out, "<attribute name=\"%s\" value=\"%s\" id=\"%ld\" addr=\"%x\" />\n", ck, o, ++id, o); + Delete(o); + Delete(ck); + } else { + o = Getattr(obj, k); + String *ck = NewString(k); + Replaceall(ck, ":", "_"); + Printf(out, "<attribute name=\"%s\" value=\"%x\" id=\"%ld\" addr=\"%x\" />\n", ck, o, ++id, o); + Delete(ck); + } + } + ki = Next(ki); + } + indent_level -= 4; + print_indent(0); + Printf(out, "</attributelist >\n"); + indent_level -= 4; + } + + void Xml_print_node(Node *obj) { + Node *cobj; + + print_indent(0); + Printf(out, "<%s id=\"%ld\" addr=\"%x\" >\n", nodeType(obj), ++id, obj); + Xml_print_attributes(obj); + cobj = firstChild(obj); + if (cobj) { + indent_level += 4; + Printf(out, "\n"); + Xml_print_tree(cobj); + indent_level -= 4; + } else { + print_indent(1); + Printf(out, "\n"); + } + print_indent(0); + Printf(out, "</%s >\n", nodeType(obj)); + } + + + void Xml_print_parmlist(ParmList *p) { + + print_indent(0); + Printf(out, "<parmlist id=\"%ld\" addr=\"%x\" >\n", ++id, p); + indent_level += 4; + while (p) { + print_indent(0); + Printf(out, "<parm id=\"%ld\">\n", ++id); + Xml_print_attributes(p); + print_indent(0); + Printf(out, "</parm >\n"); + p = nextSibling(p); + } + indent_level -= 4; + print_indent(0); + Printf(out, "</parmlist >\n"); + } + + void Xml_print_baselist(List *p) { + + print_indent(0); + Printf(out, "<baselist id=\"%ld\" addr=\"%x\" >\n", ++id, p); + indent_level += 4; + Iterator s; + for (s = First(p); s.item; s = Next(s)) { + print_indent(0); + String *item_name = Xml_escape_string(s.item); + Printf(out, "<base name=\"%s\" id=\"%ld\" addr=\"%x\" />\n", item_name, ++id, s.item); + Delete(item_name); + } + indent_level -= 4; + print_indent(0); + Printf(out, "</baselist >\n"); + } + + String *Xml_escape_string(String *str) { + String *escaped_str = 0; + if (str) { + escaped_str = NewString(str); + Replaceall(escaped_str, "&", "&"); + Replaceall(escaped_str, "<", "<"); + Replaceall(escaped_str, "\"", """); + Replaceall(escaped_str, "\\", "\\\\"); + Replaceall(escaped_str, "\n", " "); + } + return escaped_str; + } + + void Xml_print_module(Node *p) { + + print_indent(0); + Printf(out, "<attribute name=\"module\" value=\"%s\" id=\"%ld\" addr=\"%x\" />\n", Getattr(p, "name"), ++id, p); + } + + void Xml_print_kwargs(Hash *p) { + Xml_print_hash(p, "kwargs"); + } + + void Xml_print_typescope(Hash *p) { + + Xml_print_hash(p, "typescope"); + } + + void Xml_print_typetab(Hash *p) { + + Xml_print_hash(p, "typetab"); + } + + + void Xml_print_hash(Hash *p, const char *markup) { + + print_indent(0); + Printf(out, "<%s id=\"%ld\" addr=\"%x\" >\n", markup, ++id, p); + Xml_print_attributes(p); + indent_level += 4; + Iterator n = First(p); + while (n.key) { + print_indent(0); + Printf(out, "<%ssitem id=\"%ld\" addr=\"%x\" >\n", markup, ++id, n.item); + Xml_print_attributes(n.item); + print_indent(0); + Printf(out, "</%ssitem >\n", markup); + n = Next(n); + } + indent_level -= 4; + print_indent(0); + Printf(out, "</%s >\n", markup); + } + +}; + +/* ----------------------------------------------------------------------------- + * Swig_print_xml + * + * Dump an XML version of the parse tree. This is different from using the -xml + * language module normally as it allows the real language module to process the + * tree first, possibly stuffing in new attributes, so the XML that is output ends + * up being a post-processing version of the tree. + * ----------------------------------------------------------------------------- */ + +void Swig_print_xml(DOH *obj, String *filename) { + XML xml; + xmllite = 1; + + if (!filename) { + out = stdout; + } else { + out = NewFile(filename, "w", SWIG_output_files()); + if (!out) { + FileErrorDisplay(filename); + SWIG_exit(EXIT_FAILURE); + } + } + + Printf(out, "<?xml version=\"1.0\" ?> \n"); + xml.Xml_print_tree(obj); +} + +static Language *new_swig_xml() { + return new XML(); +} +extern "C" Language *swig_xml(void) { + return new_swig_xml(); +} |