cleanup added class for parser context, added first cut for push mode
* python/Makefile.am python/types.c: cleanup
* python/libxml.c python/libxml.py python/libxml_wrap.h
python/generator.py python/libxml2-python-api.xml
python/libxml2class.txt: added class for parser context, added
first cut for push mode support. Added a framework to generate
accessors functions.
* python/tests/Makefile.am python/tests/push.py: added a push
test
Daniel
diff --git a/ChangeLog b/ChangeLog
index a3c8b1d..800e435 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Sun Feb 3 16:03:55 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+ * python/Makefile.am python/types.c: cleanup
+ * python/libxml.c python/libxml.py python/libxml_wrap.h
+ python/generator.py python/libxml2-python-api.xml
+ python/libxml2class.txt: added class for parser context, added
+ first cut for push mode support. Added a framework to generate
+ accessors functions.
+ * python/tests/Makefile.am python/tests/push.py: added a push
+ test
+
Sun Feb 3 00:17:26 CET 2002 Daniel Veillard <daniel@veillard.com>
* python/Makefile.am python/TODO python/libxml.py: fixed a small
diff --git a/python/Makefile.am b/python/Makefile.am
index a76492a..7d02f53 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -10,6 +10,7 @@
EXTRA_DIST = \
libxml.c \
+ types.c \
generator.py \
libxml_wrap.h \
libxml.py \
@@ -22,8 +23,8 @@
libxml2.py: $(srcdir)/libxml.py libxml2class.py
cat $(srcdir)/libxml.py libxml2class.py > libxml2.py
-_libxml.so: libxml.o libxml2-py.o
- $(CC) $(LINK_FLAGS) libxml2-py.o libxml.o $(LIBS) -o _libxml.so
+_libxml.so: libxml.o libxml2-py.o types.o
+ $(CC) $(LINK_FLAGS) libxml.o libxml2-py.o types.o $(LIBS) -o _libxml.so
else
all:
endif
@@ -31,6 +32,9 @@
libxml.o: libxml.c libxml2-export.c libxml_wrap.h
$(CC) $(SHCFLAGS) -c -o libxml.o $(srcdir)/libxml.c
+types.o: types.c libxml_wrap.h
+ $(CC) $(SHCFLAGS) -c -o types.o $(srcdir)/types.c
+
libxml2-py.o: libxml2-py.c libxml2-py.h libxml_wrap.h
$(CC) $(SHCFLAGS) -c -o libxml2-py.o $(srcdir)/libxml2-py.c
@@ -44,9 +48,7 @@
$(GENERATED): $(srcdir)/$(GENERATE) $(API_DESC)
cd $(srcdir) && $(PYTHON) $(GENERATE)
-dummy:
-
-tests: dummy
+tests: all
cd tests && $(MAKE) tests
clean:
diff --git a/python/generator.py b/python/generator.py
index 80dca7b..587528a 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -129,10 +129,13 @@
if self.in_function == 1:
self.function_return_type = None
self.function_return_info = None
+ self.function_return_field = None
if attrs.has_key('type'):
self.function_return_type = attrs['type']
if attrs.has_key('info'):
self.function_return_info = attrs['info']
+ if attrs.has_key('field'):
+ self.function_return_field = attrs['field']
def end(self, tag):
@@ -152,7 +155,8 @@
elif tag == 'return':
if self.in_function == 1:
self.function_return = [self.function_return_type,
- self.function_return_info]
+ self.function_return_info,
+ self.function_return_field]
elif tag == 'info':
str = ''
for c in self._data:
@@ -186,8 +190,6 @@
'int *': "usually a return type",
'xmlSAXHandlerPtr': "not the proper interface for SAX",
'htmlSAXHandlerPtr': "not the proper interface for SAX",
- 'xmlParserCtxtPtr': "not the proper interface for the parser",
- 'htmlParserCtxtPtr': "not the proper interface for the parser",
'xmlRMutexPtr': "thread specific, skipped",
'xmlMutexPtr': "thread specific, skipped",
'xmlGlobalStatePtr': "thread specific, skipped",
@@ -257,6 +259,10 @@
'const htmlNode *': ('O', "xmlNode", "xmlNodePtr", "xmlNodePtr"),
'xmlXPathContextPtr': ('O', "xmlXPathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
'xmlXPathContext *': ('O', "xpathContext", "xmlXPathContextPtr", "xmlXPathContextPtr"),
+ 'xmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
+ 'xmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
+ 'htmlParserCtxtPtr': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
+ 'htmlParserCtxt *': ('O', "parserCtxt", "xmlParserCtxtPtr", "xmlParserCtxtPtr"),
}
py_return_types = {
@@ -340,7 +346,10 @@
elif py_types.has_key(ret[0]):
(f, t, n, c) = py_types[ret[0]]
c_return = " %s c_retval;\n" % (ret[0])
- c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
+ if file == "python_accessor":
+ c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2])
+ else:
+ c_call = "\n c_retval = %s(%s);\n" % (name, c_call);
ret_convert = " py_retval = libxml_%sWrap((%s) c_retval);\n" % (n,c)
ret_convert = ret_convert + " return(py_retval);\n"
elif py_return_types.has_key(ret[0]):
@@ -476,6 +485,8 @@
"xmlAttributePtr": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
"xmlAttribute *": ("._o", "xmlAttribute(_obj=%s)", "xmlAttribute"),
"xmlXPathContextPtr": ("._o", "xpathContext(_obj=%s)", "xpathContext"),
+ "xmlParserCtxtPtr": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
+ "xmlParserCtxt *": ("._o", "parserCtxt(_obj=%s)", "parserCtxt"),
}
converter_type = {
@@ -496,6 +507,7 @@
}
classes_destructors = {
"xpathContext": "xmlXPathFreeContext",
+ "parserCtxt": "xmlFreeParserCtxt",
}
function_classes = {}
@@ -530,13 +542,16 @@
ctypes.append(type)
ctypes_processed[type] = ()
-def nameFixup(function, classe, type):
+def nameFixup(function, classe, type, file):
listname = classe + "List"
ll = len(listname)
l = len(classe)
if name[0:l] == listname:
func = name[l:]
func = string.lower(func[0:1]) + func[1:]
+ elif name[0:12] == "xmlParserGet" and file == "python_accessor":
+ func = name[12:]
+ func = string.lower(func[0:1]) + func[1:]
elif name[0:l] == classe:
func = name[l:]
func = string.lower(func[0:1]) + func[1:]
@@ -573,22 +588,22 @@
if name[0:3] == "xml" and len(args) >= 1 and args[0][1] == type:
found = 1
- func = nameFixup(name, classe, type)
+ func = nameFixup(name, classe, type, file)
info = (0, func, name, ret, args, file)
function_classes[classe].append(info)
elif name[0:3] == "xml" and len(args) >= 2 and args[1][1] == type:
found = 1
- func = nameFixup(name, classe, type)
+ func = nameFixup(name, classe, type, file)
info = (1, func, name, ret, args, file)
function_classes[classe].append(info)
elif name[0:4] == "html" and len(args) >= 1 and args[0][1] == type:
found = 1
- func = nameFixup(name, classe, type)
+ func = nameFixup(name, classe, type, file)
info = (0, func, name, ret, args, file)
function_classes[classe].append(info)
elif name[0:4] == "html" and len(args) >= 2 and args[1][1] == type:
found = 1
- func = nameFixup(name, classe, type)
+ func = nameFixup(name, classe, type, file)
info = (1, func, name, ret, args, file)
function_classes[classe].append(info)
if found == 1:
@@ -601,7 +616,7 @@
continue
if name[0:10] == "xmlCharStr":
continue
- func = nameFixup(name, "None", file)
+ func = nameFixup(name, "None", file, file)
info = (0, func, name, ret, args, file)
function_classes['None'].append(info)
@@ -612,6 +627,10 @@
def functionCompare(info1, info2):
(index1, func1, name1, ret1, args1, file1) = info1
(index2, func2, name2, ret2, args2, file2) = info2
+ if file1 == "python_accessor":
+ return -1
+ if file2 == "python_accessor":
+ return 1
if file1 < file2:
return -1
if file1 > file2:
@@ -701,6 +720,12 @@
classes.write(" self._o = None\n")
classes.write(" %s.__init__(self, _obj=_obj)\n\n" % (
classes_ancestor[classname]))
+ if classes_ancestor[classname] == "xmlCore" or \
+ classes_ancestor[classname] == "xmlNode":
+ classes.write(" def __repr__(self):\n")
+ format = "%s:%%s" % (classname)
+ classes.write(" return \"%s\" %% (self.name)\n\n" % (
+ format))
else:
txt.write("Class %s()\n" % (classname))
classes.write("class %s:\n" % (classname))
@@ -713,21 +738,21 @@
classes.write(" _libxml.%s(self._o)\n" %
classes_destructors[classname]);
classes.write(" self._o = None\n\n");
- classes.write(" def __repr__(self):\n")
- format = "%s:%%s" % (classname)
- classes.write(" return \"%s\" %% (self.name)\n\n" % (
- format))
flist = function_classes[classname]
flist.sort(functionCompare)
oldfile = ""
for info in flist:
(index, func, name, ret, args, file) = info
if file != oldfile:
- classes.write(" #\n")
- classes.write(" # %s functions from module %s\n" % (
- classname, file))
- txt.write("\n # functions from module %s\n" % file)
- classes.write(" #\n\n")
+ if file == "python_accessor":
+ classes.write(" # accessors for %s\n" % (classname))
+ txt.write(" # accessors\n")
+ else:
+ classes.write(" #\n")
+ classes.write(" # %s functions from module %s\n" % (
+ classname, file))
+ txt.write("\n # functions from module %s\n" % file)
+ classes.write(" #\n\n")
oldfile = file
classes.write(" def %s(self" % func)
txt.write(" %s()\n" % func);
diff --git a/python/libxml.c b/python/libxml.c
index cca2b04..57e370f 100644
--- a/python/libxml.c
+++ b/python/libxml.c
@@ -1,5 +1,14 @@
+/*
+ * libxml.c: this modules implements the main part of the glue of the
+ * libxml2 library and the Python interpreter. It provides the
+ * entry points where an automatically generated stub is either
+ * unpractical or would not match cleanly the Python model.
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
#include <Python.h>
-
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
@@ -15,277 +24,48 @@
/************************************************************************
* *
- * Per type specific glue *
+ * Handling SAX/xmllib/sgmlop callback interfaces *
* *
************************************************************************/
-PyObject *
-libxml_intWrap(int val) {
- PyObject *ret;
-#ifdef DEBUG
- printf("libxml_intWrap: val = %d\n", val);
-#endif
- ret = PyInt_FromLong((long) val);
- return(ret);
-}
+typedef struct pySAXhandler {
+ PyObject *startDocument;
+ /* TODO !!! */
+} pySAXhandler, *pySAXhandlerPtr;
+
+/************************************************************************
+ * *
+ * Handling of specific parser context *
+ * *
+ ************************************************************************/
PyObject *
-libxml_doubleWrap(double val) {
- PyObject *ret;
+libxml_xmlCreatePushParser(PyObject *self, PyObject *args) {
+ xmlChar *chunk;
+ int size;
+ xmlChar *URI;
+ PyObject *pyobj_SAX;
+ xmlSAXHandlerPtr SAX = NULL;
+ pySAXhandlerPtr SAXdata = NULL;
+ xmlParserCtxtPtr ret;
+ PyObject *pyret;
-#ifdef DEBUG
- printf("libxml_doubleWrap: val = %f\n", val);
+ if (!PyArg_ParseTuple(args, "Oziz:xmlCreatePushParser", &pyobj_SAX,
+ &chunk, &size, &URI))
+ return(NULL);
+
+#ifdef DEBUG_ERROR
+ printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
+ pyobj_SAX, chunk, size, URI);
#endif
- ret = PyFloat_FromDouble((double) val);
- return(ret);
-}
-
-PyObject *
-libxml_charPtrWrap(char *str) {
- PyObject *ret;
-
-#ifdef DEBUG
- printf("libxml_xmlcharPtrWrap: str = %s\n", str);
-#endif
- if (str == NULL) {
+ if (pyobj_SAX != Py_None) {
+ printf("xmlCreatePushParser: event interface not supported yet !\n");
Py_INCREF(Py_None);
return(Py_None);
}
- /* TODO: look at deallocation */
- ret = PyString_FromString(str);
- xmlFree(str);
- return(ret);
-}
-
-PyObject *
-libxml_xmlCharPtrWrap(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);
- xmlFree(str);
- return(ret);
-}
-
-PyObject *
-libxml_constcharPtrWrap(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_constxmlCharPtrWrap(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_xmlNsPtrWrap(xmlNsPtr ns) {
- PyObject *ret;
-
-#ifdef DEBUG
- printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
-#endif
- if (ns == NULL) {
- Py_INCREF(Py_None);
- return(Py_None);
- }
- ret = PyCObject_FromVoidPtrAndDesc((void *) ns, "xmlNsPtr", NULL);
- return(ret);
-}
-
-PyObject *
-libxml_xmlAttrPtrWrap(xmlAttrPtr attr) {
- PyObject *ret;
-
-#ifdef DEBUG
- printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
-#endif
- if (attr == NULL) {
- Py_INCREF(Py_None);
- return(Py_None);
- }
- ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttrPtr", NULL);
- return(ret);
-}
-
-PyObject *
-libxml_xmlAttributePtrWrap(xmlAttributePtr attr) {
- PyObject *ret;
-
-#ifdef DEBUG
- printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
-#endif
- if (attr == NULL) {
- Py_INCREF(Py_None);
- return(Py_None);
- }
- ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttributePtr", NULL);
- return(ret);
-}
-
-PyObject *
-libxml_xmlElementPtrWrap(xmlElementPtr elem) {
- PyObject *ret;
-
-#ifdef DEBUG
- printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
-#endif
- if (elem == NULL) {
- Py_INCREF(Py_None);
- return(Py_None);
- }
- ret = PyCObject_FromVoidPtrAndDesc((void *) elem, "xmlElementPtr", NULL);
- return(ret);
-}
-
-PyObject *
-libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt) {
- PyObject *ret;
-
-#ifdef DEBUG
- printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
-#endif
- if (ctxt == NULL) {
- Py_INCREF(Py_None);
- return(Py_None);
- }
- ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, "xmlXPathContextPtr",
- NULL);
- return(ret);
-}
-
-PyObject *
-libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) {
- PyObject *ret;
-
-#ifdef DEBUG
- printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
-#endif
- if (obj == NULL) {
- Py_INCREF(Py_None);
- return(Py_None);
- }
- switch(obj->type) {
- case XPATH_XSLT_TREE:
- /* TODO !!!! Allocation problems */
- case XPATH_NODESET:
- if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0))
- ret = PyList_New(0);
- else {
- int i;
- xmlNodePtr node;
-
- ret = PyList_New(obj->nodesetval->nodeNr);
- for (i = 0;i < obj->nodesetval->nodeNr;i++) {
- node = obj->nodesetval->nodeTab[i];
- /* TODO: try to cast directly to the proper node type */
- PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
- }
- }
- break;
- case XPATH_BOOLEAN:
- ret = PyInt_FromLong((long) obj->boolval);
- break;
- case XPATH_NUMBER:
- ret = PyFloat_FromDouble(obj->floatval);
- break;
- case XPATH_STRING:
- ret = PyString_FromString(obj->stringval);
- break;
- case XPATH_POINT:
- case XPATH_RANGE:
- case XPATH_LOCATIONSET:
- default:
- printf("Unable to convert XPath object type %d\n", obj->type);
- Py_INCREF(Py_None);
- ret = Py_None;
- }
- xmlXPathFreeObject(obj);
- return(ret);
-}
-
-xmlXPathObjectPtr
-libxml_xmlXPathObjectPtrConvert(PyObject * obj) {
- xmlXPathObjectPtr ret;
-
-#ifdef DEBUG
- printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
-#endif
- if (obj == NULL) {
- return(NULL);
- }
- if PyFloat_Check(obj) {
- ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
- } else if PyString_Check(obj) {
- xmlChar *str;
-
- str = xmlStrndup((const xmlChar *)PyString_AS_STRING(obj),
- PyString_GET_SIZE(obj));
- ret = xmlXPathWrapString(str);
- } else {
- printf("Unable to convert Python Object to XPath");
- }
- Py_DECREF(obj);
- return(ret);
+ ret = xmlCreatePushParserCtxt(SAX, SAXdata, chunk, size, URI);
+ pyret = libxml_xmlParserCtxtPtrWrap(ret);
+ return(pyret);
}
/************************************************************************
@@ -534,131 +314,6 @@
/************************************************************************
* *
- * The PyxmlNode type *
- * *
- ************************************************************************/
-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, "<xmlNode of type %d at %lx>",
- 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__
-};
-
-/************************************************************************
- * *
- * The PyxmlXPathContext type *
- * *
- ************************************************************************/
-static void
-PyxmlXPathContext_dealloc(PyxmlXPathContext_Object * self)
-{
- printf("TODO PyxmlXPathContext_dealloc\n");
- PyMem_DEL(self);
-}
-
-static int
-PyxmlXPathContext_compare(PyxmlXPathContext_Object * self, PyxmlXPathContext_Object * v)
-{
- if (self->obj == v->obj)
- return 0;
- if (self->obj > v->obj)
- return -1;
- return 1;
-}
-
-static long
-PyxmlXPathContext_hash(PyxmlXPathContext_Object * self)
-{
- return (long) self->obj;
-}
-
-static PyObject *
-PyxmlXPathContext_repr(PyxmlXPathContext_Object * self)
-{
- char buf[100];
-
- sprintf(buf, "<xmlXPathContext at %lx>",
- (long) PyxmlXPathContext_Get(self));
- return PyString_FromString(buf);
-}
-
-static char PyxmlXPathContext_Type__doc__[] = "This is the type of XPath evaluation contexts";
-
-PyTypeObject PyxmlXPathContext_Type = {
- PyObject_HEAD_INIT(&PyType_Type)
- 0, /*ob_size */
- "xmlXPathContext", /*tp_name */
- sizeof(PyxmlXPathContext_Object), /*tp_basicsize */
- 0, /*tp_itemsize */
- (destructor) PyxmlXPathContext_dealloc,/*tp_dealloc */
- (printfunc) 0, /*tp_print */
- (getattrfunc) 0, /*tp_getattr */
- (setattrfunc) 0, /*tp_setattr */
- (cmpfunc) PyxmlXPathContext_compare,/*tp_compare */
- (reprfunc) PyxmlXPathContext_repr, /*tp_repr */
- 0, /*tp_as_number */
- 0, /*tp_as_sequence */
- 0, /*tp_as_mapping */
- (hashfunc) PyxmlXPathContext_hash, /*tp_hash */
- (ternaryfunc) 0, /*tp_call */
- (reprfunc) 0, /*tp_str */
- 0L, 0L, 0L, 0L,
- PyxmlXPathContext_Type__doc__
-};
-
-/************************************************************************
- * *
* Global properties access *
* *
************************************************************************/
@@ -1055,11 +710,8 @@
};
void init_libxml(void) {
- PyObject *m, *d;
+ PyObject *m;
m = Py_InitModule("_libxml", libxmlMethods);
- d = PyModule_GetDict(m);
- PyDict_SetItemString(d, "xmlNodeType", (PyObject *)&PyxmlNode_Type);
- PyDict_SetItemString(d, "xmlXPathContextType", (PyObject *)&PyxmlXPathContext_Type);
libxml_xmlErrorInitialize();
}
diff --git a/python/libxml.py b/python/libxml.py
index 6f5197b..22749f8 100644
--- a/python/libxml.py
+++ b/python/libxml.py
@@ -148,14 +148,6 @@
ret = _libxml.xmlRegisterXPathFunction(ctxt, name, ns_uri, f)
#
-# A parser context
-#
-class parserCtxt:
- def __init__(self, _obj=None):
- self._o = _obj
-
-
-#
# Everything below this point is automatically generated
#
diff --git a/python/libxml2-python-api.xml b/python/libxml2-python-api.xml
index 5cdc992..ec76f6e 100644
--- a/python/libxml2-python-api.xml
+++ b/python/libxml2-python-api.xml
@@ -20,5 +20,18 @@
<arg name='f' type='pythonObject' info='the python function'/>
<arg name='ctx' type='pythonObject' info='a context for the callback'/>
</function>
+ <function name='xmlCreatePushParser' file='python'>
+ <info>Create a progressive parser context to build either an event flow if the SAX object is not None, or a DOM tree otherwise.</info>
+ <return type='xmlParserCtxtPtr' info="the parser context or None in case of error"/>
+ <arg name='SAX' type='pythonObject' info='the SAX callback object or None'/>
+ <arg name='chunk' type='xmlChar *' info='the initial data'/>
+ <arg name='size' type='int' info='the size of the initial data'/>
+ <arg name='URI' type='xmlChar *' info='The URI used for base computations'/>
+ </function>
+ <function name='xmlParserGetDoc' file='python_accessor'>
+ <info>Get the document tree from a parser context.</info>
+ <return type='xmlDocPtr' info="the document tree" field="myDoc"/>
+ <arg name='ctxt' type='xmlParserCtxtPtr' info='the SAX callback object or None'/>
+ </function>
</symbols>
</api>
diff --git a/python/libxml2class.txt b/python/libxml2class.txt
index 0411124..d952c2c 100644
--- a/python/libxml2class.txt
+++ b/python/libxml2class.txt
@@ -6,9 +6,13 @@
# functions from module HTMLparser
+htmlFreeParserCtxt()
htmlHandleOmittedElem()
htmlIsScriptAttribute()
+htmlParseCharRef()
+htmlParseChunk()
htmlParseDoc()
+htmlParseElement()
htmlParseFile()
# functions from module HTMLtree
@@ -68,6 +72,7 @@
# functions from module parser
cleanupParser()
+createDocParserCtxt()
defaultSAXHandlerInit()
htmlDefaultSAXHandlerInit()
initParser()
@@ -88,6 +93,10 @@
checkLanguageID()
copyChar()
copyCharMultiByte()
+createEntityParserCtxt()
+createFileParserCtxt()
+createMemoryParserCtxt()
+htmlCreateFileParserCtxt()
htmlInitAutoClose()
isBaseChar()
isBlank()
@@ -98,8 +107,14 @@
isIdeographic()
isLetter()
isPubidChar()
+namePop()
+namePush()
+newParserCtxt()
+nodePop()
+nodePush()
# functions from module python
+createPushParser()
registerErrorHandler()
# functions from module tree
@@ -315,6 +330,66 @@
Class xmlElement(xmlNode)
+Class parserCtxt()
+ # accessors
+ doc()
+
+ # functions from module parser
+ clearParserCtxt()
+ initParserCtxt()
+ parseChunk()
+ parseDocument()
+ parseExtParsedEnt()
+ stopParser()
+
+ # functions from module parserInternals
+ decodeEntities()
+ freeParserCtxt()
+ handleEntity()
+ namespaceParseNCName()
+ namespaceParseNSDef()
+ nextChar()
+ parseAttValue()
+ parseAttributeListDecl()
+ parseCDSect()
+ parseCharData()
+ parseCharRef()
+ parseComment()
+ parseContent()
+ parseDocTypeDecl()
+ parseElement()
+ parseElementDecl()
+ parseEncName()
+ parseEncodingDecl()
+ parseEndTag()
+ parseEntityDecl()
+ parseEntityRef()
+ parseExternalSubset()
+ parseMarkupDecl()
+ parseMisc()
+ parseName()
+ parseNamespace()
+ parseNmtoken()
+ parseNotationDecl()
+ parsePEReference()
+ parsePI()
+ parsePITarget()
+ parsePubidLiteral()
+ parseQuotedString()
+ parseReference()
+ parseSDDecl()
+ parseStartTag()
+ parseSystemLiteral()
+ parseTextDecl()
+ parseVersionInfo()
+ parseVersionNum()
+ parseXMLDecl()
+ parserHandlePEReference()
+ parserHandleReference()
+ popInput()
+ scanName()
+ skipBlankChars()
+ stringDecodeEntities()
Class xpathContext()
# functions from module python
diff --git a/python/libxml_wrap.h b/python/libxml_wrap.h
index 972e871..d6d89aa 100644
--- a/python/libxml_wrap.h
+++ b/python/libxml_wrap.h
@@ -1,3 +1,4 @@
+#include <Python.h>
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/parserInternals.h>
@@ -27,6 +28,12 @@
xmlXPathContextPtr obj;
} PyxmlXPathContext_Object;
+#define PyparserCtxt_Get(v) (((PyparserCtxt_Object *)(v))->obj)
+typedef struct {
+ PyObject_HEAD
+ xmlParserCtxtPtr obj;
+} PyparserCtxt_Object;
+
PyObject * libxml_intWrap(int val);
PyObject * libxml_xmlCharPtrWrap(xmlChar *str);
PyObject * libxml_constxmlCharPtrWrap(const xmlChar *str);
@@ -40,5 +47,7 @@
PyObject * libxml_xmlElementPtrWrap(xmlElementPtr ns);
PyObject * libxml_doubleWrap(double val);
PyObject * libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt);
+PyObject * libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt);
PyObject * libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj);
+xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am
index 79d5456..b8e9cec 100644
--- a/python/tests/Makefile.am
+++ b/python/tests/Makefile.am
@@ -4,6 +4,7 @@
tst.py \
tstxpath.py \
xpathext.py \
+ push.py \
error.py \
xpath.py
@@ -20,6 +21,9 @@
tests:
endif
+clean:
+ rm -f *.pyc core
+
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(EXAMPLE_DIR)
-(for test in $(TESTS) $(XMLS); \
diff --git a/python/tests/push.py b/python/tests/push.py
new file mode 100755
index 0000000..738d3e9
--- /dev/null
+++ b/python/tests/push.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python -u
+import sys
+import libxml2
+
+ctxt = libxml2.createPushParser(None, "<foo", 4, "test.xml")
+ctxt.parseChunk("/>", 2, 1)
+doc = ctxt.doc()
+ctxt=None
+if doc.name != "test.xml":
+ print "document name error"
+ sys.exit(1)
+root = doc.children
+if root.name != "foo":
+ print "root element name error"
+ sys.exit(1)
+doc.freeDoc()
+i = 10000
+while i > 0:
+ ctxt = libxml2.createPushParser(None, "<foo", 4, "test.xml")
+ ctxt.parseChunk("/>", 2, 1)
+ doc = ctxt.doc()
+ doc.freeDoc()
+ i = i -1
+ctxt=None
+print "OK"
diff --git a/python/types.c b/python/types.c
new file mode 100644
index 0000000..07a178e
--- /dev/null
+++ b/python/types.c
@@ -0,0 +1,297 @@
+/*
+ * types.c: converter functions between the internal representation
+ * and the Python objects
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+#include "libxml_wrap.h"
+
+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_doubleWrap(double val) {
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_doubleWrap: val = %f\n", val);
+#endif
+ ret = PyFloat_FromDouble((double) val);
+ return(ret);
+}
+
+PyObject *
+libxml_charPtrWrap(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);
+ xmlFree(str);
+ return(ret);
+}
+
+PyObject *
+libxml_xmlCharPtrWrap(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);
+ xmlFree(str);
+ return(ret);
+}
+
+PyObject *
+libxml_constcharPtrWrap(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_constxmlCharPtrWrap(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_xmlNsPtrWrap(xmlNsPtr ns) {
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
+#endif
+ if (ns == NULL) {
+ Py_INCREF(Py_None);
+ return(Py_None);
+ }
+ ret = PyCObject_FromVoidPtrAndDesc((void *) ns, "xmlNsPtr", NULL);
+ return(ret);
+}
+
+PyObject *
+libxml_xmlAttrPtrWrap(xmlAttrPtr attr) {
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
+#endif
+ if (attr == NULL) {
+ Py_INCREF(Py_None);
+ return(Py_None);
+ }
+ ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttrPtr", NULL);
+ return(ret);
+}
+
+PyObject *
+libxml_xmlAttributePtrWrap(xmlAttributePtr attr) {
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
+#endif
+ if (attr == NULL) {
+ Py_INCREF(Py_None);
+ return(Py_None);
+ }
+ ret = PyCObject_FromVoidPtrAndDesc((void *) attr, "xmlAttributePtr", NULL);
+ return(ret);
+}
+
+PyObject *
+libxml_xmlElementPtrWrap(xmlElementPtr elem) {
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
+#endif
+ if (elem == NULL) {
+ Py_INCREF(Py_None);
+ return(Py_None);
+ }
+ ret = PyCObject_FromVoidPtrAndDesc((void *) elem, "xmlElementPtr", NULL);
+ return(ret);
+}
+
+PyObject *
+libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt) {
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
+#endif
+ if (ctxt == NULL) {
+ Py_INCREF(Py_None);
+ return(Py_None);
+ }
+ ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, "xmlXPathContextPtr",
+ NULL);
+ return(ret);
+}
+
+PyObject *
+libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt) {
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlParserCtxtPtrWrap: ctxt = %p\n", ctxt);
+#endif
+ if (ctxt == NULL) {
+ Py_INCREF(Py_None);
+ return(Py_None);
+ }
+ ret = PyCObject_FromVoidPtrAndDesc((void *) ctxt, "xmlParserCtxtPtr",
+ NULL);
+ return(ret);
+}
+
+PyObject *
+libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj) {
+ PyObject *ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
+#endif
+ if (obj == NULL) {
+ Py_INCREF(Py_None);
+ return(Py_None);
+ }
+ switch(obj->type) {
+ case XPATH_XSLT_TREE:
+ /* TODO !!!! Allocation problems */
+ case XPATH_NODESET:
+ if ((obj->nodesetval == NULL) || (obj->nodesetval->nodeNr == 0))
+ ret = PyList_New(0);
+ else {
+ int i;
+ xmlNodePtr node;
+
+ ret = PyList_New(obj->nodesetval->nodeNr);
+ for (i = 0;i < obj->nodesetval->nodeNr;i++) {
+ node = obj->nodesetval->nodeTab[i];
+ /* TODO: try to cast directly to the proper node type */
+ PyList_SetItem(ret, i, libxml_xmlNodePtrWrap(node));
+ }
+ }
+ break;
+ case XPATH_BOOLEAN:
+ ret = PyInt_FromLong((long) obj->boolval);
+ break;
+ case XPATH_NUMBER:
+ ret = PyFloat_FromDouble(obj->floatval);
+ break;
+ case XPATH_STRING:
+ ret = PyString_FromString(obj->stringval);
+ break;
+ case XPATH_POINT:
+ case XPATH_RANGE:
+ case XPATH_LOCATIONSET:
+ default:
+ printf("Unable to convert XPath object type %d\n", obj->type);
+ Py_INCREF(Py_None);
+ ret = Py_None;
+ }
+ xmlXPathFreeObject(obj);
+ return(ret);
+}
+
+xmlXPathObjectPtr
+libxml_xmlXPathObjectPtrConvert(PyObject * obj) {
+ xmlXPathObjectPtr ret;
+
+#ifdef DEBUG
+ printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
+#endif
+ if (obj == NULL) {
+ return(NULL);
+ }
+ if PyFloat_Check(obj) {
+ ret = xmlXPathNewFloat((double) PyFloat_AS_DOUBLE(obj));
+ } else if PyString_Check(obj) {
+ xmlChar *str;
+
+ str = xmlStrndup((const xmlChar *)PyString_AS_STRING(obj),
+ PyString_GET_SIZE(obj));
+ ret = xmlXPathWrapString(str);
+ } else {
+ printf("Unable to convert Python Object to XPath");
+ }
+ Py_DECREF(obj);
+ return(ret);
+}
+
+