From d2897fde0089a9f349f7a589c1e58a8e130a3d61 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Wed, 30 Jan 2002 16:37:32 +0000 Subject: [PATCH] commited early version of a python binding for private use only ATM Daniel * python/generator.py python/libxml.c python/libxml.py python/libxml_wrap.h: commited early version of a python binding for private use only ATM Daniel --- ChangeLog | 6 + doc/parsedecl.py | 2 - include/libxml/tree.h | 1 - python/generator.py | 284 +++++++++++++++++++ python/libxml.c | 619 ++++++++++++++++++++++++++++++++++++++++++ python/libxml.py | 115 ++++++++ python/libxml_wrap.h | 18 ++ 7 files changed, 1042 insertions(+), 3 deletions(-) create mode 100755 python/generator.py create mode 100644 python/libxml.c create mode 100644 python/libxml.py create mode 100644 python/libxml_wrap.h diff --git a/ChangeLog b/ChangeLog index c1fc6a57..426d8233 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Wed Jan 30 17:35:33 CET 2002 Daniel Veillard + + * python/generator.py python/libxml.c python/libxml.py + python/libxml_wrap.h: commited early version of a python binding + for private use only ATM + Sat Jan 26 22:41:13 CET 2002 Daniel Veillard * entities.c tree.c include/libxml/entities.h: applied patch diff --git a/doc/parsedecl.py b/doc/parsedecl.py index e93d6520..074a808e 100755 --- a/doc/parsedecl.py +++ b/doc/parsedecl.py @@ -3,8 +3,6 @@ # tries to parse the output of gtk-doc declaration files and make # an XML reusable description from them # -# TODO: try to extracts comments from the DocBook output of - import sys import string diff --git a/include/libxml/tree.h b/include/libxml/tree.h index 7692ff66..1952763c 100644 --- a/include/libxml/tree.h +++ b/include/libxml/tree.h @@ -512,7 +512,6 @@ struct _xmlDoc { /* * Variables. */ -LIBXML_DLL_IMPORT extern xmlNsPtr baseDTD; LIBXML_DLL_IMPORT extern int oldXMLWDcompatibility;/* maintain compatibility with old WD */ LIBXML_DLL_IMPORT extern int xmlIndentTreeOutput; /* try to indent the tree dumps */ LIBXML_DLL_IMPORT extern xmlBufferAllocationScheme xmlBufferAllocScheme; /* alloc scheme to use */ diff --git a/python/generator.py b/python/generator.py new file mode 100755 index 00000000..29428546 --- /dev/null +++ b/python/generator.py @@ -0,0 +1,284 @@ +#!/usr/bin/python -u +# +# generate python wrappers from the XML API description +# + +functions = {} + +import os +import xmllib +try: + import sgmlop +except ImportError: + sgmlop = None # accelerator not available + +debug = 0 + +if sgmlop: + class FastParser: + """sgmlop based XML parser. this is typically 15x faster + than SlowParser...""" + + def __init__(self, target): + + # setup callbacks + self.finish_starttag = target.start + self.finish_endtag = target.end + self.handle_data = target.data + + # activate parser + self.parser = sgmlop.XMLParser() + self.parser.register(self) + self.feed = self.parser.feed + self.entity = { + "amp": "&", "gt": ">", "lt": "<", + "apos": "'", "quot": '"' + } + + def close(self): + try: + self.parser.close() + finally: + self.parser = self.feed = None # nuke circular reference + + def handle_entityref(self, entity): + # entity + try: + self.handle_data(self.entity[entity]) + except KeyError: + self.handle_data("&%s;" % entity) + +else: + FastParser = None + + +class SlowParser(xmllib.XMLParser): + """slow but safe standard parser, based on the XML parser in + Python's standard library.""" + + def __init__(self, target): + self.unknown_starttag = target.start + self.handle_data = target.data + self.unknown_endtag = target.end + xmllib.XMLParser.__init__(self) + +def getparser(target = None): + # get the fastest available parser, and attach it to an + # unmarshalling object. return both objects. + if target == None: + target = docParser() + if FastParser: + return FastParser(target), target + return SlowParser(target), target + +class docParser: + def __init__(self): + self._methodname = None + self._data = [] + self.in_function = 0 + + def close(self): + if debug: + print "close" + + def getmethodname(self): + return self._methodname + + def data(self, text): + if debug: + print "data %s" % text + self._data.append(text) + + def start(self, tag, attrs): + if debug: + print "start %s, %s" % (tag, attrs) + if tag == 'function': + self._data = [] + self.in_function = 1 + self.function = None + self.function_args = [] + self.function_descr = None + self.function_return = None + self.function_file = None + if attrs.has_key('name'): + self.function = attrs['name'] + if attrs.has_key('file'): + self.function_file = attrs['file'] + elif tag == 'info': + self._data = [] + elif tag == 'arg': + if self.in_function == 1: + self.function_arg_name = None + self.function_arg_type = None + self.function_arg_info = None + if attrs.has_key('name'): + self.function_arg_name = attrs['name'] + if attrs.has_key('type'): + self.function_arg_type = attrs['type'] + if attrs.has_key('info'): + self.function_arg_info = attrs['info'] + elif tag == 'return': + if self.in_function == 1: + self.function_return_type = None + self.function_return_info = None + if attrs.has_key('type'): + self.function_return_type = attrs['type'] + if attrs.has_key('info'): + self.function_return_info = attrs['info'] + + + def end(self, tag): + if debug: + print "end %s" % tag + if tag == 'function': + if self.function != None: + function(self.function, self.function_descr, + self.function_return, self.function_args, + self.function_file) + self.in_function = 0 + elif tag == 'arg': + if self.in_function == 1: + self.function_args.append([self.function_arg_name, + self.function_arg_type, + self.function_arg_info]) + elif tag == 'return': + if self.in_function == 1: + self.function_return = [self.function_return_type, + self.function_return_info] + elif tag == 'info': + str = '' + for c in self._data: + str = str + c + if self.in_function == 1: + self.function_descr = str + + +def function(name, desc, ret, args, file): + global functions + + functions[name] = (desc, ret, args, file) + +skipped_modules = { + 'xmlmemory': None, +} +py_types = { + 'void': (None, None, None), + 'int': ('i', None, "int"), + 'xmlChar': ('c', None, "int"), + 'char *': ('s', None, "charPtr"), + 'const char *': ('s', None, "charPtr"), + 'xmlChar *': ('s', None, "xmlCharPtr"), + 'const xmlChar *': ('s', None, "xmlCharPtr"), +} + +unknown_types = {} + +def print_function_wrapper(name, output): + global py_types + global unknown_types + global functions + global skipped_modules + + try: + (desc, ret, args, file) = functions[name] + except: + print "failed to get function %s infos" + return + + if skipped_modules.has_key(file): + return 0 + + c_call = ""; + format="" + format_args="" + c_args="" + c_return="" + for arg in args: + c_args = c_args + " %s %s;\n" % (arg[1], arg[0]) + if py_types.has_key(arg[1]): + (f, t, n) = py_types[arg[1]] + if f != None: + format = format + f + if t != None: + format_args = format_args + ", &%s" % (t) + format_args = format_args + ", &%s" % (arg[0]) + if c_call != "": + c_call = c_call + ", "; + c_call = c_call + "%s" % (arg[0]) + else: + if unknown_types.has_key(arg[1]): + lst = unknown_types[arg[1]] + lst.append(name) + else: + unknown_types[arg[1]] = [name] + return -1 + if format != "": + format = format + ":%s" % (name) + + if ret[0] == 'void': + c_call = "\n %s(%s);\n" % (name, c_call); + ret_convert = " Py_INCREF(Py_None);\n return(Py_None);\n" + elif py_types.has_key(ret[0]): + (f, t, n) = py_types[ret[0]] + c_return = " %s c_retval;\n" % (ret[0]) + c_call = "\n c_retval = %s(%s);\n" % (name, c_call); + ret_convert = " py_retval = libxml_%sWrap(c_retval);\n return(py_retval);\n" % (n) + else: + if unknown_types.has_key(ret[0]): + lst = unknown_types[ret[0]] + lst.append(name) + else: + unknown_types[ret[0]] = [name] + return -1 + + output.write("PyObject *\n") + output.write("libxml_%s(PyObject *self, PyObject *args) {\n" % (name)) + if ret[0] != 'void': + output.write(" PyObject *py_retval;\n") + if c_return != "": + output.write(c_return) + if c_args != "": + output.write(c_args) + if format != "": + output.write("\n if (!PyArg_ParseTuple(args, \"%s\"%s))\n" % + (format, format_args)) + output.write(" return(NULL);\n") + + output.write(c_call) + output.write(ret_convert) + output.write("}\n\n") + return 1 + +try: + f = open("libxml2-api.xml") + data = f.read() + (parser, target) = getparser() + parser.feed(data) + parser.close() +except IOError, msg: + print file, ":", msg + +print "Found %d functions in libxml2-api.xml" % (len(functions.keys())) +nb_wrap = 0 +failed = 0 +skipped = 0 + +wrapper = open("libxml2-py.c", "w") +wrapper.write("/* Generated */\n\n") +wrapper.write("#include \n") +wrapper.write("#include \n") +wrapper.write("#include \"libxml_wrap.h\"\n") +wrapper.write("#include \"libxml2-py.h\"\n\n") +for function in functions.keys(): + ret = print_function_wrapper(function, wrapper) + if ret < 0: + failed = failed + 1 + if ret == 1: + nb_wrap = nb_wrap + 1 + if ret == 0: + skipped = skipped + 1 +wrapper.close() + +print "Generated %d wrapper functions, %d failed, %d skipped\n" % (nb_wrap, + failed, skipped); +print "Missing type converters: %s" % (unknown_types.keys()) diff --git a/python/libxml.c b/python/libxml.c new file mode 100644 index 00000000..13423f53 --- /dev/null +++ b/python/libxml.c @@ -0,0 +1,619 @@ +#include + +#include +#include +#include "libxml_wrap.h" + +/* #define DEBUG */ + +/************************************************************************ + * * + * Per type specific glue * + * * + ************************************************************************/ +PyObject * +libxml_intWrap(int val) { + PyObject *ret; + +#ifdef DEBUG + printf("libxml_intWrap: val = %d\n", val); +#endif + ret = PyInt_FromLong((long) val); + return(ret); +} + +PyObject * +libxml_charPtrWrap(const char *str) { + PyObject *ret; + +#ifdef DEBUG + printf("libxml_xmlcharPtrWrap: str = %s\n", str); +#endif + if (str == NULL) { + Py_INCREF(Py_None); + return(Py_None); + } + /* TODO: look at deallocation */ + ret = PyString_FromString(str); + return(ret); +} + +PyObject * +libxml_xmlCharPtrWrap(const xmlChar *str) { + PyObject *ret; + +#ifdef DEBUG + printf("libxml_xmlCharPtrWrap: str = %s\n", str); +#endif + if (str == NULL) { + Py_INCREF(Py_None); + return(Py_None); + } + /* TODO: look at deallocation */ + ret = PyString_FromString(str); + return(ret); +} + +PyObject * +libxml_xmlDocPtrWrap(xmlDocPtr doc) { + PyObject *ret; + +#ifdef DEBUG + printf("libxml_xmlDocPtrWrap: doc = %p\n", doc); +#endif + if (doc == NULL) { + Py_INCREF(Py_None); + return(Py_None); + } + /* TODO: look at deallocation */ + ret = PyCObject_FromVoidPtrAndDesc((void *) doc, "xmlDocPtr", NULL); + return(ret); +} + +PyObject * +libxml_xmlNodePtrWrap(xmlNodePtr node) { + PyObject *ret; + +#ifdef DEBUG + printf("libxml_xmlNodePtrWrap: node = %p\n", node); +#endif + if (node == NULL) { + Py_INCREF(Py_None); + return(Py_None); + } + ret = PyCObject_FromVoidPtrAndDesc((void *) node, "xmlNodePtr", NULL); + return(ret); +} + +PyObject * +libxml_xmlAttrPtrWrap(xmlAttrPtr attr) { + PyObject *ret; + +#ifdef DEBUG + printf("libxml_xmlNodePtrWrap: attr = %p\n", attr); +#endif + if (attr == NULL) { + Py_INCREF(Py_None); + return(Py_None); + } + ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttrPtr", NULL); + return(ret); +} + +#define PyxmlNode_Get(v) (((PyxmlNode_Object *)(v))->obj) + +typedef struct { + PyObject_HEAD + xmlNodePtr obj; +} PyxmlNode_Object; + +static void +PyxmlNode_dealloc(PyxmlNode_Object * self) +{ + printf("TODO PyxmlNode_dealloc\n"); + PyMem_DEL(self); +} + +static int +PyxmlNode_compare(PyxmlNode_Object * self, PyxmlNode_Object * v) +{ + if (self->obj == v->obj) + return 0; + if (self->obj > v->obj) + return -1; + return 1; +} + +static long +PyxmlNode_hash(PyxmlNode_Object * self) +{ + return (long) self->obj; +} + +static PyObject * +PyxmlNode_repr(PyxmlNode_Object * self) +{ + char buf[100]; + + sprintf(buf, "", + PyxmlNode_Get(self)->type, + (long) PyxmlNode_Get(self)); + return PyString_FromString(buf); +} + +static char PyxmlNode_Type__doc__[] = "This is the type of libxml Nodes"; + +static PyTypeObject PyxmlNode_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, /*ob_size */ + "xmlNode", /*tp_name */ + sizeof(PyxmlNode_Object), /*tp_basicsize */ + 0, /*tp_itemsize */ + (destructor) PyxmlNode_dealloc,/*tp_dealloc */ + (printfunc) 0, /*tp_print */ + (getattrfunc) 0, /*tp_getattr */ + (setattrfunc) 0, /*tp_setattr */ + (cmpfunc) PyxmlNode_compare,/*tp_compare */ + (reprfunc) PyxmlNode_repr, /*tp_repr */ + 0, /*tp_as_number */ + 0, /*tp_as_sequence */ + 0, /*tp_as_mapping */ + (hashfunc) PyxmlNode_hash, /*tp_hash */ + (ternaryfunc) 0, /*tp_call */ + (reprfunc) 0, /*tp_str */ + 0L, 0L, 0L, 0L, + PyxmlNode_Type__doc__ +}; + +/************************************************************************ + * * + * Global properties access * + * * + ************************************************************************/ +static PyObject * +libxml_name(PyObject *self, PyObject *args) +{ + PyObject *resultobj, *obj; + xmlNodePtr cur; + const xmlChar *res; + + if (!PyArg_ParseTuple(args, "O:name", &obj)) + return NULL; + cur = PyxmlNode_Get(obj); + +#ifdef DEBUG + printf("libxml_name: cur = %p type %d\n", cur, cur->type); +#endif + + switch(cur->type) { + case XML_DOCUMENT_NODE: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + case XML_HTML_DOCUMENT_NODE: { + xmlDocPtr doc = (xmlDocPtr) cur; + res = doc->URL; + break; + } + case XML_ATTRIBUTE_NODE: { + xmlAttrPtr attr = (xmlAttrPtr) cur; + res = attr->name; + break; + } + case XML_NAMESPACE_DECL: { + xmlNsPtr ns = (xmlNsPtr) cur; + res = ns->prefix; + break; + } + default: + res = cur->name; + break; + } + resultobj = libxml_xmlCharPtrWrap(res); + + return resultobj; +} + +static PyObject * +libxml_doc(PyObject *self, PyObject *args) +{ + PyObject *resultobj, *obj; + xmlNodePtr cur; + xmlDocPtr res; + + if (!PyArg_ParseTuple(args, "O:doc", &obj)) + return NULL; + cur = PyxmlNode_Get(obj); + +#ifdef DEBUG + printf("libxml_doc: cur = %p\n", cur); +#endif + + switch(cur->type) { + case XML_DOCUMENT_NODE: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + case XML_HTML_DOCUMENT_NODE: + res = NULL; + break; + case XML_ATTRIBUTE_NODE: { + xmlAttrPtr attr = (xmlAttrPtr) cur; + res = attr->doc; + break; + } + case XML_NAMESPACE_DECL: + res = NULL; + break; + default: + res = cur->doc; + break; + } + resultobj = libxml_xmlDocPtrWrap(res); + return resultobj; +} + +static PyObject * +libxml_properties(PyObject *self, PyObject *args) +{ + PyObject *resultobj, *obj; + xmlNodePtr cur = NULL; + xmlAttrPtr res; + + if (!PyArg_ParseTuple(args, "O:properties", &obj)) + return NULL; + cur = PyxmlNode_Get(obj); + if (cur->type == XML_ELEMENT_NODE) + res = cur->properties; + else + res = NULL; + resultobj = libxml_xmlAttrPtrWrap(res); + return resultobj; +} + +static PyObject * +libxml_next(PyObject *self, PyObject *args) +{ + PyObject *resultobj, *obj; + xmlNodePtr cur; + xmlNodePtr res; + + if (!PyArg_ParseTuple(args, "O:next", &obj)) + return NULL; + cur = PyxmlNode_Get(obj); + +#ifdef DEBUG + printf("libxml_next: cur = %p\n", cur); +#endif + + switch(cur->type) { + case XML_DOCUMENT_NODE: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + case XML_HTML_DOCUMENT_NODE: + res = NULL; + break; + case XML_ATTRIBUTE_NODE: { + xmlAttrPtr attr = (xmlAttrPtr) cur; + res = (xmlNodePtr) attr->next; + break; + } + case XML_NAMESPACE_DECL: { + xmlNsPtr ns = (xmlNsPtr) cur; + res = (xmlNodePtr) ns->next; + break; + } + default: + res = cur->next; + break; + + } + resultobj = libxml_xmlNodePtrWrap(res); + return resultobj; +} + +static PyObject * +libxml_prev(PyObject *self, PyObject *args) +{ + PyObject *resultobj, *obj; + xmlNodePtr cur; + xmlNodePtr res; + + if (!PyArg_ParseTuple(args, "O:prev", &obj)) + return NULL; + cur = PyxmlNode_Get(obj); + +#ifdef DEBUG + printf("libxml_prev: cur = %p\n", cur); +#endif + + switch(cur->type) { + case XML_DOCUMENT_NODE: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + case XML_HTML_DOCUMENT_NODE: + res = NULL; + break; + case XML_ATTRIBUTE_NODE: { + xmlAttrPtr attr = (xmlAttrPtr) cur; + res = (xmlNodePtr) attr->next; + } + case XML_NAMESPACE_DECL: + res = NULL; + break; + default: + res = cur->next; + break; + } + resultobj = libxml_xmlNodePtrWrap(res); + return resultobj; +} + +static PyObject * +libxml_children(PyObject *self, PyObject *args) +{ + PyObject *resultobj, *obj; + xmlNodePtr cur; + xmlNodePtr res; + + if (!PyArg_ParseTuple(args, "O:children", &obj)) + return NULL; + cur = PyxmlNode_Get(obj); + +#ifdef DEBUG + printf("libxml_children: cur = %p\n", cur); +#endif + + switch(cur->type) { + case XML_ELEMENT_NODE: + case XML_ENTITY_REF_NODE: + case XML_ENTITY_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + case XML_DOCUMENT_NODE: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + case XML_HTML_DOCUMENT_NODE: + case XML_DTD_NODE: + res = cur->children; + break; + case XML_ATTRIBUTE_NODE: { + xmlAttrPtr attr = (xmlAttrPtr) cur; + res = attr->children; + break; + } + default: + res = NULL; + break; + } + resultobj = libxml_xmlNodePtrWrap(res); + return resultobj; +} + +static PyObject * +libxml_last(PyObject *self, PyObject *args) +{ + PyObject *resultobj, *obj; + xmlNodePtr cur; + xmlNodePtr res; + + if (!PyArg_ParseTuple(args, "O:last", &obj)) + return NULL; + cur = PyxmlNode_Get(obj); + +#ifdef DEBUG + printf("libxml_last: cur = %p\n", cur); +#endif + + switch(cur->type) { + case XML_ELEMENT_NODE: + case XML_ENTITY_REF_NODE: + case XML_ENTITY_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: + case XML_DOCUMENT_NODE: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + case XML_HTML_DOCUMENT_NODE: + case XML_DTD_NODE: + res = cur->last; + break; + case XML_ATTRIBUTE_NODE: { + xmlAttrPtr attr = (xmlAttrPtr) cur; + res = attr->last; + } + default: + res = NULL; + break; + } + resultobj = libxml_xmlNodePtrWrap(res); + return resultobj; +} + +static PyObject * +libxml_parent(PyObject *self, PyObject *args) +{ + PyObject *resultobj, *obj; + xmlNodePtr cur; + xmlNodePtr res; + + if (!PyArg_ParseTuple(args, "O:parent", &obj)) + return NULL; + cur = PyxmlNode_Get(obj); + +#ifdef DEBUG + printf("libxml_parent: cur = %p\n", cur); +#endif + + switch(cur->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + res = NULL; + break; + case XML_ATTRIBUTE_NODE: { + xmlAttrPtr attr = (xmlAttrPtr) cur; + res = attr->parent; + } + case XML_ENTITY_DECL: + case XML_NAMESPACE_DECL: + case XML_XINCLUDE_START: + case XML_XINCLUDE_END: + res = NULL; + break; + default: + res = cur->parent; + break; + } + resultobj = libxml_xmlNodePtrWrap(res); + return resultobj; +} + +static PyObject * +libxml_type(PyObject *self, PyObject *args) +{ + PyObject *resultobj, *obj; + xmlNodePtr cur; + const xmlChar *res; + + if (!PyArg_ParseTuple(args, "O:last", &obj)) + return NULL; + cur = PyxmlNode_Get(obj); + +#ifdef DEBUG + printf("libxml_type: cur = %p\n", cur); +#endif + + switch(cur->type) { + case XML_ELEMENT_NODE: + res = (const xmlChar *) "element"; break; + case XML_ATTRIBUTE_NODE: + res = (const xmlChar *) "attribute"; break; + case XML_TEXT_NODE: + res = (const xmlChar *) "text"; break; + case XML_CDATA_SECTION_NODE: + res = (const xmlChar *) "cdata"; break; + case XML_ENTITY_REF_NODE: + res = (const xmlChar *) "entity_ref"; break; + case XML_ENTITY_NODE: + res = (const xmlChar *) "entity"; break; + case XML_PI_NODE: + res = (const xmlChar *) "pi"; break; + case XML_COMMENT_NODE: + res = (const xmlChar *) "comment"; break; + case XML_DOCUMENT_NODE: + res = (const xmlChar *) "document_xml"; break; + case XML_DOCUMENT_TYPE_NODE: + res = (const xmlChar *) "doctype"; break; + case XML_DOCUMENT_FRAG_NODE: + res = (const xmlChar *) "fragment"; break; + case XML_NOTATION_NODE: + res = (const xmlChar *) "notation"; break; + case XML_HTML_DOCUMENT_NODE: + res = (const xmlChar *) "document_html"; break; + case XML_DTD_NODE: + res = (const xmlChar *) "dtd"; break; + case XML_ELEMENT_DECL: + res = (const xmlChar *) "elem_decl"; break; + case XML_ATTRIBUTE_DECL: + res = (const xmlChar *) "attribute_decl"; break; + case XML_ENTITY_DECL: + res = (const xmlChar *) "entity_decl"; break; + case XML_NAMESPACE_DECL: + res = (const xmlChar *) "namespace"; break; + case XML_XINCLUDE_START: + res = (const xmlChar *) "xinclude_start"; break; + case XML_XINCLUDE_END: + res = (const xmlChar *) "xinclude_end"; break; +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: + res = (const xmlChar *) "document_docbook"; break; +#endif + } +#ifdef DEBUG + printf("libxml_type: cur = %p: %s\n", cur, res); +#endif + + resultobj = libxml_xmlCharPtrWrap(res); + return resultobj; +} + +/************************************************************************ + * * + * The interface raw code * + * * + ************************************************************************/ +static PyObject * +libxml_parseFile(PyObject *self, PyObject *args) +{ + PyObject *resultobj; + char *arg0; + xmlDocPtr result; + + if (!PyArg_ParseTuple(args, "s:parseFile", &arg0)) + return NULL; +#ifdef DEBUG + printf("libxml_parseFile: arg0 = %s\n", arg0); +#endif + result = (xmlDocPtr )xmlParseFile((char const *)arg0); + resultobj = libxml_xmlDocPtrWrap(result); +#ifdef DEBUG + printf("libxml_parseFile: resultobj = %p\n", resultobj); +#endif + return resultobj; +} + +static PyObject * +libxml_freeDoc(PyObject *self, PyObject *args) +{ + xmlDocPtr doc; + + if (!PyArg_ParseTuple(args, "O:freeDoc", &doc)) + return NULL; + switch(doc->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: +#ifdef LIBXML_DOCB_ENABLED + case XML_DOCB_DOCUMENT_NODE: +#endif + xmlFreeDoc(doc); + break; + default: + break; + } + Py_INCREF(Py_None); + return(Py_None); +} + +/************************************************************************ + * * + * The registration stuff * + * * + ************************************************************************/ +static PyMethodDef libxmlMethods[] = { + { "parseFile", libxml_parseFile, METH_VARARGS }, + { "freeDoc", libxml_freeDoc, METH_VARARGS }, + { "name", libxml_name, METH_VARARGS }, + { "children", libxml_children, METH_VARARGS }, + { "properties", libxml_properties, METH_VARARGS }, + { "last", libxml_last, METH_VARARGS }, + { "prev", libxml_prev, METH_VARARGS }, + { "next", libxml_next, METH_VARARGS }, + { "parent", libxml_parent, METH_VARARGS }, + { "type", libxml_type, METH_VARARGS }, + { "doc", libxml_doc, METH_VARARGS } +}; + +void init_libxml(void) { + PyObject *m, *d; + m = Py_InitModule("_libxml", libxmlMethods); + d = PyModule_GetDict(m); + PyDict_SetItemString(d, "xmlNodeType", (PyObject *)&PyxmlNode_Type); +} + diff --git a/python/libxml.py b/python/libxml.py new file mode 100644 index 00000000..af96383f --- /dev/null +++ b/python/libxml.py @@ -0,0 +1,115 @@ +import _libxml + +class xmlNode: + def __init__(self, _obj=None): + if _obj != None: + self._o = _obj; + return + self._o = None + +# def __getattr__(self, attr): +# attrs = { +# 'lower': _gtk.gtk_adjustment_get_lower, +# 'upper': _gtk.gtk_adjustment_get_upper, +# 'value': _gtk.gtk_adjustment_get_value, +# 'step_increment': _gtk.gtk_adjustment_get_step_increment, +# 'page_increment': _gtk.gtk_adjustment_get_page_increment, +# 'page_size': _gtk.gtk_adjustment_get_page_size +# } +# if attrs.has_key(attr): +# ret = attrs[attr](self._o) +# if ret == None: +# return None +# return attrs[attr](self._o) + def __getattr__(self, attr): + if attr == "parent": + ret = _libxml.parent(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + elif attr == "properties": + ret = _libxml.properties(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + elif attr == "children": + ret = _libxml.children(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + elif attr == "last": + ret = _libxml.last(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + elif attr == "next": + ret = _libxml.next(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + elif attr == "prev": + ret = _libxml.prev(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + elif attr == "content": + return self.content() + elif attr == "name": + return _libxml.name(self._o) + elif attr == "type": + return _libxml.type(self._o) + elif attr == "doc": + ret = _libxml.doc(self._o) + if ret == None: + return None + return xmlDoc(_doc=ret) + raise AttributeError,attr + + # + # Those are common attributes to nearly all type of nodes + # + def get_parent(self): + ret = _libxml.parent(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + def get_children(self): + ret = _libxml.children(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + def get_last(self): + ret = _libxml.last(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + def get_next(self): + ret = _libxml.next(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + def get_prev(self): + ret = _libxml.prev(self._o) + if ret == None: + return None + return xmlNode(_obj=ret) + def get_content(self): + return self.content() + def get_name(self): + return _libxml.name(self._o) + def get_type(self): + return _libxml.type(self._o) + def get_doc(self): + ret = _libxml.doc(self._o) + if ret == None: + return None + return xmlDoc(_doc=ret) + def free(self): + _libxml.freeDoc(self._o) + + +class xmlDoc(xmlNode): + def __init__(self, file = None, _doc=None): + if _doc == None and file != None: + _doc = _libxml.parseFile(file) + xmlNode.__init__(self, _obj=_doc) diff --git a/python/libxml_wrap.h b/python/libxml_wrap.h new file mode 100644 index 00000000..a3aca48b --- /dev/null +++ b/python/libxml_wrap.h @@ -0,0 +1,18 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PyObject * libxml_intWrap(int val); +PyObject * libxml_xmlCharPtrWrap(const xmlChar *str); +PyObject * libxml_charPtrWrap(const char *str); +PyObject * libxml_xmlDocPtrWrap(xmlDocPtr doc); +PyObject * libxml_xmlNodePtrWrap(xmlNodePtr node); +PyObject * libxml_xmlAttrPtrWrap(xmlAttrPtr attr);