adding error redirections and preformat to a python handler cleanup made
* python/Makefile.am python/libxml.c python/libxml2-python-api.xml
python/libxml2class.txt: adding error redirections and preformat
to a python handler
* python/tests/Makefile.am python/tests/*.py: cleanup made all
tests self checking
Daniel
diff --git a/ChangeLog b/ChangeLog
index 61cb2b6..43d7aa3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sat Feb 2 22:47:10 CET 2002 Daniel Veillard <daniel@veillard.com>
+
+ * python/Makefile.am python/libxml.c python/libxml2-python-api.xml
+ python/libxml2class.txt: adding error redirections and preformat
+ to a python handler
+ * python/tests/Makefile.am python/tests/*.py: cleanup made all
+ tests self checking
+
Sat Feb 2 13:18:54 CET 2002 Daniel Veillard <daniel@veillard.com>
* python/libxml.c python/libxml.py: fixed a stupid bug when renaming
diff --git a/python/Makefile.am b/python/Makefile.am
index a7eca5b..0da7d79 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -2,7 +2,7 @@
LIBS=-L../.libs -L.. $(XML_LIBS)
INCLUDES=-I/usr/include/python$(PYTHON_VERSION) -I$(PYTHON_INCLUDES) -I$(top_srcdir)/include
-SHCFLAGS=$(INCLUDES) -Wall -fPIC
+SHCFLAGS=$(INCLUDES) -Wall -fPIC -g
LINK_FLAGS= -shared
DOCS_DIR = $(prefix)/share/doc/libxml2-python-$(LIBXML_VERSION)
diff --git a/python/TODO b/python/TODO
index 0fc997b..d8e39b1 100644
--- a/python/TODO
+++ b/python/TODO
@@ -7,7 +7,6 @@
- handling of node.content
- SAX interfaces
-- error redirections and preformat
- memory debug interfaces
- enums -> libxml.py
- access to XPath variables
@@ -41,5 +40,6 @@
- spec file: automatically generate for pythonX.Y if found
Done, a bit ugly by running new makes in %install for each level
found.
+- error redirections and preformat
Daniel Veillard
diff --git a/python/libxml.c b/python/libxml.c
index efd2a7a..cca2b04 100644
--- a/python/libxml.c
+++ b/python/libxml.c
@@ -4,12 +4,14 @@
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
+#include <libxml/xmlerror.h>
#include <libxml/xpathInternals.h>
#include "libxml_wrap.h"
#include "libxml2-py.h"
/* #define DEBUG */
/* #define DEBUG_XPATH */
+/* #define DEBUG_ERROR */
/************************************************************************
* *
@@ -285,6 +287,110 @@
Py_DECREF(obj);
return(ret);
}
+
+/************************************************************************
+ * *
+ * Error message callback *
+ * *
+ ************************************************************************/
+
+static PyObject *libxml_xmlPythonErrorFuncHandler = NULL;
+static PyObject *libxml_xmlPythonErrorFuncCtxt = NULL;
+
+static void
+libxml_xmlErrorFuncHandler(void *ctx, const char *msg, ...) {
+ int size;
+ int chars;
+ char *larger;
+ va_list ap;
+ char *str;
+ PyObject *list;
+ PyObject *message;
+ PyObject *result;
+
+#ifdef DEBUG_ERROR
+ printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
+#endif
+
+
+ if (libxml_xmlPythonErrorFuncHandler == NULL) {
+ va_start(ap, msg);
+ vfprintf(stdout, msg, ap);
+ va_end(ap);
+ } else {
+ str = (char *) xmlMalloc(150);
+ if (str == NULL)
+ return;
+
+ size = 150;
+
+ while (1) {
+ va_start(ap, msg);
+ chars = vsnprintf(str, size, msg, ap);
+ va_end(ap);
+ if ((chars > -1) && (chars < size))
+ break;
+ if (chars > -1)
+ size += chars + 1;
+ else
+ size += 100;
+ if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
+ xmlFree(str);
+ return;
+ }
+ str = larger;
+ }
+
+ list = PyTuple_New(2);
+ PyTuple_SetItem(list, 0, libxml_xmlPythonErrorFuncCtxt);
+ Py_XINCREF(libxml_xmlPythonErrorFuncCtxt);
+ message = libxml_charPtrWrap(str);
+ PyTuple_SetItem(list, 1, message);
+ result = PyEval_CallObject(libxml_xmlPythonErrorFuncHandler, list);
+ Py_XDECREF(list);
+ Py_XDECREF(result);
+ }
+}
+
+static void
+libxml_xmlErrorInitialize(void) {
+#ifdef DEBUG_ERROR
+ printf("libxml_xmlErrorInitialize() called\n");
+#endif
+ xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
+}
+
+PyObject *
+libxml_xmlRegisterErrorHandler(PyObject *self, PyObject *args) {
+ PyObject *py_retval;
+ PyObject *pyobj_f;
+ PyObject *pyobj_ctx;
+
+ if (!PyArg_ParseTuple(args, "OO:xmlRegisterErrorHandler", &pyobj_f,
+ &pyobj_ctx))
+ return(NULL);
+
+#ifdef DEBUG_ERROR
+ printf("libxml_registerXPathFunction(%p, %p) called\n", pyobj_ctx, pyobj_f);
+#endif
+
+ if (libxml_xmlPythonErrorFuncHandler != NULL) {
+ Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
+ }
+ if (libxml_xmlPythonErrorFuncCtxt != NULL) {
+ Py_XDECREF(libxml_xmlPythonErrorFuncCtxt);
+ }
+
+ Py_XINCREF(pyobj_ctx);
+ Py_XINCREF(pyobj_f);
+
+ /* TODO: check f is a function ! */
+ libxml_xmlPythonErrorFuncHandler = pyobj_f;
+ libxml_xmlPythonErrorFuncCtxt = pyobj_ctx;
+
+ py_retval = libxml_intWrap(1);
+ return(py_retval);
+}
/************************************************************************
* *
* XPath extensions *
@@ -954,5 +1060,6 @@
d = PyModule_GetDict(m);
PyDict_SetItemString(d, "xmlNodeType", (PyObject *)&PyxmlNode_Type);
PyDict_SetItemString(d, "xmlXPathContextType", (PyObject *)&PyxmlXPathContext_Type);
+ libxml_xmlErrorInitialize();
}
diff --git a/python/libxml2-python-api.xml b/python/libxml2-python-api.xml
index 29dca23..5cdc992 100644
--- a/python/libxml2-python-api.xml
+++ b/python/libxml2-python-api.xml
@@ -14,5 +14,11 @@
<arg name='ns_uri' type='xmlChar *' info='the namespace or NULL'/>
<arg name='f' type='pythonObject' info='the python function'/>
</function>
+ <function name='xmlRegisterErrorHandler' file='python'>
+ <info>Register a Python written function to for error reporting. The function is called back as f(ctx, error).</info>
+ <return type='int' info="1 in case of success, 0 or -1 in case of error"/>
+ <arg name='f' type='pythonObject' info='the python function'/>
+ <arg name='ctx' type='pythonObject' info='a context for the callback'/>
+ </function>
</symbols>
</api>
diff --git a/python/libxml2class.txt b/python/libxml2class.txt
index a5c45d3..0411124 100644
--- a/python/libxml2class.txt
+++ b/python/libxml2class.txt
@@ -99,6 +99,9 @@
isLetter()
isPubidChar()
+# functions from module python
+registerErrorHandler()
+
# functions from module tree
compressMode()
newComment()
diff --git a/python/tests/Makefile.am b/python/tests/Makefile.am
index 366ad06..79d5456 100644
--- a/python/tests/Makefile.am
+++ b/python/tests/Makefile.am
@@ -4,6 +4,7 @@
tst.py \
tstxpath.py \
xpathext.py \
+ error.py \
xpath.py
XMLS= \
@@ -13,7 +14,7 @@
if WITH_PYTHON
tests: $(TESTS)
- -@(CLASSPATH=".." ; export CLASSPATH; \
+ -@(PYTHONPATH=".." ; export PYTHONPATH; \
for test in $(TESTS) ; do echo "-- $$test" ; $(PYTHON) $$test ; done)
else
tests:
diff --git a/python/tests/tst.py b/python/tests/tst.py
index 86ac64b..dc6e4d4 100755
--- a/python/tests/tst.py
+++ b/python/tests/tst.py
@@ -1,10 +1,18 @@
#!/usr/bin/python -u
+import sys
import libxml2
doc = libxml2.parseFile("tst.xml")
-print doc.name
+if doc.name != "tst.xml":
+ print "doc.name failed"
+ sys.exit(1)
root = doc.children
-print root.name
+if root.name != "doc":
+ print "root.name failed"
+ sys.exit(1)
child = root.children
-print child.name
+if child.name != "foo":
+ print "child.name failed"
+ sys.exit(1)
doc.freeDoc()
+print "OK"
diff --git a/python/tests/tstxpath.py b/python/tests/tstxpath.py
index f6c675a..97d392c 100755
--- a/python/tests/tstxpath.py
+++ b/python/tests/tstxpath.py
@@ -1,29 +1,38 @@
#!/usr/bin/python -u
+import sys
import libxml2
def foo(x):
- # print "foo called %s" % (x)
return x + 1
def bar(x):
- # print "foo called %s" % (x)
- return "%s" % (x + 1)
+ return "%d" % (x + 2)
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
-print res
+if len(res) != 2:
+ print "xpath query: wrong node set size"
+ sys.exit(1)
+if res[0].name != "doc" or res[1].name != "foo":
+ print "xpath query: wrong node set value"
+ sys.exit(1)
libxml2.registerXPathFunction(ctxt._o, "foo", None, foo)
libxml2.registerXPathFunction(ctxt._o, "bar", None, bar)
i = 10000
while i > 0:
res = ctxt.xpathEval("foo(1)")
+ if res != 2:
+ print "xpath extension failure"
+ sys.exit(1)
i = i - 1
-print res
i = 10000
while i > 0:
res = ctxt.xpathEval("bar(1)")
+ if res != "3":
+ print "xpath extension failure got %s expecting '3'"
+ sys.exit(1)
i = i - 1
-print res
doc.freeDoc()
+print "OK"
diff --git a/python/tests/xpath.py b/python/tests/xpath.py
index fdbd839..49a697f 100755
--- a/python/tests/xpath.py
+++ b/python/tests/xpath.py
@@ -3,10 +3,23 @@
# this test exercise the XPath basic engine, parser, etc, and
# allows to detect memory leaks
#
+import sys
import libxml2
doc = libxml2.parseFile("tst.xml")
-print doc
+if doc.name != "tst.xml":
+ print "doc.name error"
+ sys.exit(1);
+
+ctxt = doc.xpathNewContext()
+res = ctxt.xpathEval("//*")
+if len(res) != 2:
+ print "xpath query: wrong node set size"
+ sys.exit(1)
+if res[0].name != "doc" or res[1].name != "foo":
+ print "xpath query: wrong node set value"
+ sys.exit(1)
+doc.freeDoc()
i = 1000
while i > 0:
doc = libxml2.parseFile("tst.xml")
@@ -14,8 +27,4 @@
res = ctxt.xpathEval("//*")
doc.freeDoc()
i = i -1
-doc = libxml2.parseFile("tst.xml")
-ctxt = doc.xpathNewContext()
-res = ctxt.xpathEval("//*")
-print res
-doc.freeDoc()
+print "OK"
diff --git a/python/tests/xpathext.py b/python/tests/xpathext.py
index d6f0455..97d392c 100755
--- a/python/tests/xpathext.py
+++ b/python/tests/xpathext.py
@@ -1,33 +1,38 @@
#!/usr/bin/python -u
-#
-# This test exercise the extension of the XPath engine with
-# functions defined in Python.
-#
+import sys
import libxml2
def foo(x):
- # print "foo called %s" % (x)
return x + 1
def bar(x):
- # print "foo called %s" % (x)
- return "%s" % (x + 1)
+ return "%d" % (x + 2)
doc = libxml2.parseFile("tst.xml")
ctxt = doc.xpathNewContext()
res = ctxt.xpathEval("//*")
-print res
+if len(res) != 2:
+ print "xpath query: wrong node set size"
+ sys.exit(1)
+if res[0].name != "doc" or res[1].name != "foo":
+ print "xpath query: wrong node set value"
+ sys.exit(1)
libxml2.registerXPathFunction(ctxt._o, "foo", None, foo)
libxml2.registerXPathFunction(ctxt._o, "bar", None, bar)
i = 10000
while i > 0:
res = ctxt.xpathEval("foo(1)")
+ if res != 2:
+ print "xpath extension failure"
+ sys.exit(1)
i = i - 1
-print res
i = 10000
while i > 0:
res = ctxt.xpathEval("bar(1)")
+ if res != "3":
+ print "xpath extension failure got %s expecting '3'"
+ sys.exit(1)
i = i - 1
-print res
doc.freeDoc()
+print "OK"