mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-30 22:43:14 +03:00
patch from Stphane Bidoul for better per context error message APIs
* xmlreader.c python/drv_libxml2.py python/generator.py python/libxml.c python/libxml.py python/libxml_wrap.h python/types.c: patch from Stphane Bidoul for better per context error message APIs * python/tests/ctxterror.py python/tests/readererr.py: update of the tests Daniel
This commit is contained in:
@ -1,3 +1,12 @@
|
|||||||
|
Mon Jan 20 23:25:00 CET 2003 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
|
* xmlreader.c python/drv_libxml2.py python/generator.py
|
||||||
|
python/libxml.c python/libxml.py python/libxml_wrap.h
|
||||||
|
python/types.c: patch from St<53>phane Bidoul for better per
|
||||||
|
context error message APIs
|
||||||
|
* python/tests/ctxterror.py python/tests/readererr.py:
|
||||||
|
update of the tests
|
||||||
|
|
||||||
Sun Jan 19 17:09:28 MST 2003 John Fleck <jfleck@inkstain.net>
|
Sun Jan 19 17:09:28 MST 2003 John Fleck <jfleck@inkstain.net>
|
||||||
|
|
||||||
* doc/guidelines.html
|
* doc/guidelines.html
|
||||||
|
@ -24,11 +24,11 @@ typedef enum {
|
|||||||
} xmlParserProperties;
|
} xmlParserProperties;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
XMLREADER_SEVERITY_VALIDITY_WARNING = 1,
|
XML_PARSER_SEVERITY_VALIDITY_WARNING = 1,
|
||||||
XMLREADER_SEVERITY_VALIDITY_ERROR = 2,
|
XML_PARSER_SEVERITY_VALIDITY_ERROR = 2,
|
||||||
XMLREADER_SEVERITY_WARNING = 3,
|
XML_PARSER_SEVERITY_WARNING = 3,
|
||||||
XMLREADER_SEVERITY_ERROR = 4
|
XML_PARSER_SEVERITY_ERROR = 4
|
||||||
} xmlReaderSeverities;
|
} xmlParserSeverities;
|
||||||
|
|
||||||
typedef struct _xmlTextReader xmlTextReader;
|
typedef struct _xmlTextReader xmlTextReader;
|
||||||
typedef xmlTextReader *xmlTextReaderPtr;
|
typedef xmlTextReader *xmlTextReaderPtr;
|
||||||
@ -110,12 +110,14 @@ xmlDocPtr xmlTextReaderCurrentDoc (xmlTextReaderPtr reader);
|
|||||||
/*
|
/*
|
||||||
* Error handling extensions
|
* Error handling extensions
|
||||||
*/
|
*/
|
||||||
typedef void (*xmlTextReaderErrorFunc) (void *arg,
|
typedef void * xmlTextReaderLocatorPtr;
|
||||||
|
typedef void (*xmlTextReaderErrorFunc) (void *arg,
|
||||||
const char *msg,
|
const char *msg,
|
||||||
int line,
|
xmlParserSeverities severity,
|
||||||
int col,
|
xmlTextReaderLocatorPtr locator);
|
||||||
const char *URI,
|
int xmlTextReaderLocatorLineNumber (xmlTextReaderLocatorPtr locator);
|
||||||
xmlReaderSeverities severity);
|
/*int xmlTextReaderLocatorLinePosition(xmlTextReaderLocatorPtr locator);*/
|
||||||
|
xmlChar * xmlTextReaderLocatorBaseURI (xmlTextReaderLocatorPtr locator);
|
||||||
void xmlTextReaderSetErrorHandler (xmlTextReaderPtr reader,
|
void xmlTextReaderSetErrorHandler (xmlTextReaderPtr reader,
|
||||||
xmlTextReaderErrorFunc f,
|
xmlTextReaderErrorFunc f,
|
||||||
void *arg);
|
void *arg);
|
||||||
|
@ -9,10 +9,10 @@ USAGE
|
|||||||
CAVEATS
|
CAVEATS
|
||||||
- Lexical handlers are supported, except for start/endEntity
|
- Lexical handlers are supported, except for start/endEntity
|
||||||
(waiting for XmlReader.ResolveEntity) and start/endDTD
|
(waiting for XmlReader.ResolveEntity) and start/endDTD
|
||||||
- as understand it, libxml2 error handlers are globals (per thread);
|
- Error callbacks are not exactly synchronous, they tend
|
||||||
each call to parse() registers a new error handler,
|
to be invoked before the corresponding content callback,
|
||||||
overwriting any previously registered handler
|
because the underlying reader interface parses
|
||||||
--> you can't have 2 LibXml2Reader active at the same time
|
data by chunks of 512 bytes
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
- search for TODO
|
- search for TODO
|
||||||
@ -34,7 +34,7 @@ TODO
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = u"St<EFBFBD>phane Bidoul <sbi@skynet.be>"
|
__author__ = u"St<EFBFBD>phane Bidoul <sbi@skynet.be>"
|
||||||
__version__ = "0.2"
|
__version__ = "0.3"
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
import sys
|
import sys
|
||||||
@ -69,15 +69,27 @@ except ImportError, e:
|
|||||||
raise SAXReaderNotAvailable("libxml2 not available: " \
|
raise SAXReaderNotAvailable("libxml2 not available: " \
|
||||||
"import error was: %s" % e)
|
"import error was: %s" % e)
|
||||||
|
|
||||||
def _registerErrorHandler(handler):
|
class Locator(xmlreader.Locator):
|
||||||
if not sys.modules.has_key('libxslt'):
|
"""SAX Locator adapter for libxml2.xmlTextReaderLocator"""
|
||||||
# normal behaviour when libxslt is not imported
|
|
||||||
libxml2.registerErrorHandler(handler,"drv_libxml2")
|
def __init__(self,locator):
|
||||||
else:
|
self.__locator = locator
|
||||||
# when libxslt is imported, one must
|
|
||||||
# use libxst's error handler instead (see libxml2 bug 102181)
|
def getColumnNumber(self):
|
||||||
import libxslt
|
"Return the column number where the current event ends."
|
||||||
libxslt.registerErrorHandler(handler,"drv_libxml2")
|
return -1
|
||||||
|
|
||||||
|
def getLineNumber(self):
|
||||||
|
"Return the line number where the current event ends."
|
||||||
|
return self.__locator.LineNumber()
|
||||||
|
|
||||||
|
def getPublicId(self):
|
||||||
|
"Return the public identifier for the current event."
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getSystemId(self):
|
||||||
|
"Return the system identifier for the current event."
|
||||||
|
return self.__locator.BaseURI()
|
||||||
|
|
||||||
class LibXml2Reader(xmlreader.XMLReader):
|
class LibXml2Reader(xmlreader.XMLReader):
|
||||||
|
|
||||||
@ -95,21 +107,30 @@ class LibXml2Reader(xmlreader.XMLReader):
|
|||||||
# error messages accumulator
|
# error messages accumulator
|
||||||
self.__errors = None
|
self.__errors = None
|
||||||
|
|
||||||
def _errorHandler(self,ctx,str):
|
def _errorHandler(self,arg,msg,severity,locator):
|
||||||
if self.__errors is None:
|
if self.__errors is None:
|
||||||
self.__errors = []
|
self.__errors = []
|
||||||
self.__errors.append(str)
|
self.__errors.append((severity,
|
||||||
|
SAXParseException(msg,None,
|
||||||
|
Locator(locator))))
|
||||||
|
|
||||||
def _reportError(self,callback):
|
def _reportErrors(self,fatal):
|
||||||
# TODO: use SAXParseException, but we need a Locator for that
|
for severity,exception in self.__errors:
|
||||||
# TODO: distinguish warnings from errors
|
if severity in (libxml2.PARSER_SEVERITY_VALIDITY_WARNING,
|
||||||
msg = "".join(self.__errors)
|
libxml2.PARSER_SEVERITY_WARNING):
|
||||||
|
self._err_handler.warning(exception)
|
||||||
|
else:
|
||||||
|
# when fatal is set, the parse will stop;
|
||||||
|
# we consider that the last error reported
|
||||||
|
# is the fatal one.
|
||||||
|
if fatal and exception is self.__errors[-1][1]:
|
||||||
|
self._err_handler.fatalError(exception)
|
||||||
|
else:
|
||||||
|
self._err_handler.error(exception)
|
||||||
self.__errors = None
|
self.__errors = None
|
||||||
callback(SAXException(msg))
|
|
||||||
|
|
||||||
def parse(self, source):
|
def parse(self, source):
|
||||||
self.__parsing = 1
|
self.__parsing = 1
|
||||||
_registerErrorHandler(self._errorHandler)
|
|
||||||
try:
|
try:
|
||||||
# prepare source and create reader
|
# prepare source and create reader
|
||||||
if type(source) in StringTypes:
|
if type(source) in StringTypes:
|
||||||
@ -118,6 +139,7 @@ class LibXml2Reader(xmlreader.XMLReader):
|
|||||||
source = saxutils.prepare_input_source(source)
|
source = saxutils.prepare_input_source(source)
|
||||||
input = libxml2.inputBuffer(source.getByteStream())
|
input = libxml2.inputBuffer(source.getByteStream())
|
||||||
reader = input.newTextReader(source.getSystemId())
|
reader = input.newTextReader(source.getSystemId())
|
||||||
|
reader.SetErrorHandler(self._errorHandler,None)
|
||||||
# configure reader
|
# configure reader
|
||||||
reader.SetParserProp(libxml2.PARSER_LOADDTD,1)
|
reader.SetParserProp(libxml2.PARSER_LOADDTD,1)
|
||||||
reader.SetParserProp(libxml2.PARSER_DEFAULTATTRS,1)
|
reader.SetParserProp(libxml2.PARSER_DEFAULTATTRS,1)
|
||||||
@ -137,21 +159,18 @@ class LibXml2Reader(xmlreader.XMLReader):
|
|||||||
# check for errors
|
# check for errors
|
||||||
if r == 1:
|
if r == 1:
|
||||||
if not self.__errors is None:
|
if not self.__errors is None:
|
||||||
# non-fatal error
|
self._reportErrors(0)
|
||||||
self._reportError(self._err_handler.error)
|
|
||||||
elif r == 0:
|
elif r == 0:
|
||||||
if not self.__errors is None:
|
if not self.__errors is None:
|
||||||
# non-fatal error
|
self._reportErrors(0)
|
||||||
self._reportError(self._err_handler.error)
|
break # end of parse
|
||||||
break
|
|
||||||
else:
|
else:
|
||||||
# fatal error
|
|
||||||
if not self.__errors is None:
|
if not self.__errors is None:
|
||||||
self._reportError(self._err_handler.fatalError)
|
self._reportErrors(1)
|
||||||
else:
|
else:
|
||||||
self._err_handler.fatalError(\
|
self._err_handler.fatalError(\
|
||||||
SAXException("Read failed (no details available)"))
|
SAXException("Read failed (no details available)"))
|
||||||
break
|
break # fatal parse error
|
||||||
# get node type
|
# get node type
|
||||||
nodeType = reader.NodeType()
|
nodeType = reader.NodeType()
|
||||||
# Element
|
# Element
|
||||||
@ -180,6 +199,7 @@ class LibXml2Reader(xmlreader.XMLReader):
|
|||||||
_d(reader.LocalName()))
|
_d(reader.LocalName()))
|
||||||
qnames[attName] = qname
|
qnames[attName] = qname
|
||||||
attrs[attName] = value
|
attrs[attName] = value
|
||||||
|
reader.MoveToElement()
|
||||||
self._cont_handler.startElementNS( \
|
self._cont_handler.startElementNS( \
|
||||||
eltName,eltQName,attributesNSImpl)
|
eltName,eltQName,attributesNSImpl)
|
||||||
if reader.IsEmptyElement():
|
if reader.IsEmptyElement():
|
||||||
@ -194,6 +214,7 @@ class LibXml2Reader(xmlreader.XMLReader):
|
|||||||
while reader.MoveToNextAttribute():
|
while reader.MoveToNextAttribute():
|
||||||
attName = _d(reader.Name())
|
attName = _d(reader.Name())
|
||||||
attrs[attName] = _d(reader.Value())
|
attrs[attName] = _d(reader.Value())
|
||||||
|
reader.MoveToElement()
|
||||||
self._cont_handler.startElement( \
|
self._cont_handler.startElement( \
|
||||||
eltName,attributesImpl)
|
eltName,attributesImpl)
|
||||||
if reader.IsEmptyElement():
|
if reader.IsEmptyElement():
|
||||||
@ -275,7 +296,6 @@ class LibXml2Reader(xmlreader.XMLReader):
|
|||||||
reader.Close()
|
reader.Close()
|
||||||
finally:
|
finally:
|
||||||
self.__parsing = 0
|
self.__parsing = 0
|
||||||
# TODO: unregister error handler?
|
|
||||||
|
|
||||||
def setDTDHandler(self, handler):
|
def setDTDHandler(self, handler):
|
||||||
# TODO (when supported, the inherited method works just fine)
|
# TODO (when supported, the inherited method works just fine)
|
||||||
|
@ -271,6 +271,7 @@ py_types = {
|
|||||||
'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
|
'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
|
||||||
'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
|
'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
|
||||||
'xmlRegexpPtr': ('O', "xmlReg", "xmlRegexpPtr", "xmlRegexpPtr"),
|
'xmlRegexpPtr': ('O', "xmlReg", "xmlRegexpPtr", "xmlRegexpPtr"),
|
||||||
|
'xmlTextReaderLocatorPtr': ('O', "xmlTextReaderLocator", "xmlTextReaderLocatorPtr", "xmlTextReaderLocatorPtr"),
|
||||||
'xmlTextReaderPtr': ('O', "xmlTextReader", "xmlTextReaderPtr", "xmlTextReaderPtr"),
|
'xmlTextReaderPtr': ('O', "xmlTextReader", "xmlTextReaderPtr", "xmlTextReaderPtr"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,6 +603,7 @@ classes_type = {
|
|||||||
"xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
|
"xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
|
||||||
"xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
|
"xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
|
||||||
"xmlRegexpPtr": ("._o", "xmlReg(_obj=%s)", "xmlReg"),
|
"xmlRegexpPtr": ("._o", "xmlReg(_obj=%s)", "xmlReg"),
|
||||||
|
"xmlTextReaderLocatorPtr": ("._o", "xmlTextReaderLocator(_obj=%s)", "xmlTextReaderLocator"),
|
||||||
"xmlTextReaderPtr": ("._o", "xmlTextReader(_obj=%s)", "xmlTextReader"),
|
"xmlTextReaderPtr": ("._o", "xmlTextReader(_obj=%s)", "xmlTextReader"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,6 +692,8 @@ def nameFixup(name, classe, type, file):
|
|||||||
func = "regexp" + name[9:]
|
func = "regexp" + name[9:]
|
||||||
elif name[0:6] == "xmlReg" and file == "xmlregexp":
|
elif name[0:6] == "xmlReg" and file == "xmlregexp":
|
||||||
func = "regexp" + name[6:]
|
func = "regexp" + name[6:]
|
||||||
|
elif name[0:20] == "xmlTextReaderLocator" and file == "xmlreader":
|
||||||
|
func = name[20:]
|
||||||
elif name[0:13] == "xmlTextReader" and file == "xmlreader":
|
elif name[0:13] == "xmlTextReader" and file == "xmlreader":
|
||||||
func = name[13:]
|
func = name[13:]
|
||||||
elif name[0:11] == "xmlACatalog":
|
elif name[0:11] == "xmlACatalog":
|
||||||
|
266
python/libxml.c
266
python/libxml.c
@ -1177,32 +1177,6 @@ libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
|
|||||||
return (Py_None);
|
return (Py_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
|
||||||
libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
|
|
||||||
xmlParserCtxtPtr ctxt;
|
|
||||||
PyObject *pyobj_ctxt;
|
|
||||||
xmlParserCtxtPyCtxtPtr pyCtxt;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
|
|
||||||
return(NULL);
|
|
||||||
ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
|
|
||||||
|
|
||||||
if (ctxt != NULL) {
|
|
||||||
pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
|
|
||||||
if (pyCtxt) {
|
|
||||||
Py_XDECREF(pyCtxt->errorFunc);
|
|
||||||
Py_XDECREF(pyCtxt->errorFuncArg);
|
|
||||||
Py_XDECREF(pyCtxt->warningFunc);
|
|
||||||
Py_XDECREF(pyCtxt->warningFuncArg);
|
|
||||||
xmlFree(pyCtxt);
|
|
||||||
}
|
|
||||||
xmlFreeParserCtxt(ctxt);
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
|
||||||
return(Py_None);
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
* Error message callback *
|
* Error message callback *
|
||||||
@ -1332,44 +1306,87 @@ libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
|
|||||||
* *
|
* *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
static void
|
typedef struct
|
||||||
libxml_xmlParserCtxtErrorFuncHandler(void *ctxt, const char *msg, ...)
|
{
|
||||||
|
PyObject *f;
|
||||||
|
PyObject *arg;
|
||||||
|
} xmlParserCtxtPyCtxt;
|
||||||
|
typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
|
||||||
|
|
||||||
|
static void
|
||||||
|
libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
|
||||||
{
|
{
|
||||||
char *str;
|
|
||||||
va_list ap;
|
|
||||||
PyObject *list;
|
PyObject *list;
|
||||||
PyObject *message;
|
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
xmlParserCtxtPtr ctxt;
|
||||||
xmlParserCtxtPyCtxtPtr pyCtxt;
|
xmlParserCtxtPyCtxtPtr pyCtxt;
|
||||||
|
|
||||||
#ifdef DEBUG_ERROR
|
#ifdef DEBUG_ERROR
|
||||||
printf("libxml_xmlParserCtxtErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
|
printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
|
ctxt = (xmlParserCtxtPtr)ctx;
|
||||||
|
pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
|
||||||
|
|
||||||
if (pyCtxt->errorFunc == NULL) {
|
list = PyTuple_New(4);
|
||||||
va_start(ap, msg);
|
PyTuple_SetItem(list, 0, pyCtxt->arg);
|
||||||
vfprintf(stdout, msg, ap);
|
Py_XINCREF(pyCtxt->arg);
|
||||||
va_end(ap);
|
PyTuple_SetItem(list, 1, libxml_charPtrWrap(str));
|
||||||
} else {
|
PyTuple_SetItem(list, 2, libxml_intWrap(severity));
|
||||||
va_start(ap, msg);
|
PyTuple_SetItem(list, 3, Py_None);
|
||||||
str = libxml_buildMessage(msg,ap);
|
Py_INCREF(Py_None);
|
||||||
va_end(ap);
|
result = PyEval_CallObject(pyCtxt->f, list);
|
||||||
|
if (result == NULL)
|
||||||
list = PyTuple_New(2);
|
{
|
||||||
PyTuple_SetItem(list, 0, pyCtxt->errorFuncArg);
|
/* TODO: manage for the exception to be propagated... */
|
||||||
Py_XINCREF(pyCtxt->errorFuncArg);
|
PyErr_Print();
|
||||||
message = libxml_charPtrWrap(str);
|
|
||||||
PyTuple_SetItem(list, 1, message);
|
|
||||||
result = PyEval_CallObject(pyCtxt->errorFunc, list);
|
|
||||||
Py_XDECREF(list);
|
|
||||||
Py_XDECREF(result);
|
|
||||||
}
|
}
|
||||||
|
Py_XDECREF(list);
|
||||||
|
Py_XDECREF(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
libxml_xmlParserCtxtErrorFuncHandler(void *ctx, const char *msg, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, msg);
|
||||||
|
libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_ERROR,libxml_buildMessage(msg,ap));
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
libxml_xmlParserCtxtWarningFuncHandler(void *ctx, const char *msg, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, msg);
|
||||||
|
libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_WARNING,libxml_buildMessage(msg,ap));
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
libxml_xmlParserCtxtValidityErrorFuncHandler(void *ctx, const char *msg, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, msg);
|
||||||
|
libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_ERROR,libxml_buildMessage(msg,ap));
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
libxml_xmlParserCtxtValidityWarningFuncHandler(void *ctx, const char *msg, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, msg);
|
||||||
|
libxml_xmlParserCtxtGenericErrorFuncHandler(ctx,XML_PARSER_SEVERITY_VALIDITY_WARNING,libxml_buildMessage(msg,ap));
|
||||||
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
libxml_xmlSetParserCtxtErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
|
libxml_xmlParserCtxtSetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *py_retval;
|
PyObject *py_retval;
|
||||||
xmlParserCtxtPtr ctxt;
|
xmlParserCtxtPtr ctxt;
|
||||||
@ -1378,7 +1395,7 @@ libxml_xmlSetParserCtxtErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *a
|
|||||||
PyObject *pyobj_f;
|
PyObject *pyobj_f;
|
||||||
PyObject *pyobj_arg;
|
PyObject *pyobj_arg;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, (char *)"OOO:xmlSetParserCtxtErrorHandler",
|
if (!PyArg_ParseTuple(args, (char *)"OOO:xmlParserCtxtSetErrorHandler",
|
||||||
&pyobj_ctxt, &pyobj_f, &pyobj_arg))
|
&pyobj_ctxt, &pyobj_f, &pyobj_arg))
|
||||||
return(NULL);
|
return(NULL);
|
||||||
ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
|
ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
|
||||||
@ -1392,99 +1409,88 @@ libxml_xmlSetParserCtxtErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *a
|
|||||||
ctxt->_private = pyCtxt;
|
ctxt->_private = pyCtxt;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pyCtxt = ctxt->_private;
|
pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
|
||||||
}
|
}
|
||||||
/* TODO: check f is a function ! */
|
/* TODO: check f is a function ! */
|
||||||
Py_XDECREF(pyCtxt->errorFunc);
|
Py_XDECREF(pyCtxt->f);
|
||||||
Py_XINCREF(pyobj_f);
|
Py_XINCREF(pyobj_f);
|
||||||
pyCtxt->errorFunc = pyobj_f;
|
pyCtxt->f = pyobj_f;
|
||||||
Py_XDECREF(pyCtxt->errorFuncArg);
|
Py_XDECREF(pyCtxt->arg);
|
||||||
Py_XINCREF(pyobj_arg);
|
Py_XINCREF(pyobj_arg);
|
||||||
pyCtxt->errorFuncArg = pyobj_arg;
|
pyCtxt->arg = pyobj_arg;
|
||||||
|
|
||||||
ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
|
if (pyobj_f != Py_None) {
|
||||||
ctxt->vctxt.error = libxml_xmlParserCtxtErrorFuncHandler;
|
ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
|
||||||
|
ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
|
||||||
|
ctxt->vctxt.error = libxml_xmlParserCtxtValidityErrorFuncHandler;
|
||||||
|
ctxt->vctxt.warning = libxml_xmlParserCtxtValidityWarningFuncHandler;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctxt->sax->error = xmlParserError;
|
||||||
|
ctxt->vctxt.error = xmlParserValidityError;
|
||||||
|
ctxt->sax->warning = xmlParserWarning;
|
||||||
|
ctxt->vctxt.warning = xmlParserValidityWarning;
|
||||||
|
}
|
||||||
|
|
||||||
py_retval = libxml_intWrap(1);
|
py_retval = libxml_intWrap(1);
|
||||||
return(py_retval);
|
return(py_retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
libxml_xmlParserCtxtWarningFuncHandler(void *ctxt, const char *msg, ...)
|
|
||||||
{
|
|
||||||
char *str;
|
|
||||||
va_list ap;
|
|
||||||
PyObject *list;
|
|
||||||
PyObject *message;
|
|
||||||
PyObject *result;
|
|
||||||
xmlParserCtxtPyCtxtPtr pyCtxt;
|
|
||||||
|
|
||||||
#ifdef DEBUG_ERROR
|
|
||||||
printf("libxml_xmlParserCtxtWarningFuncHandler(%p, %s, ...) called\n", ctx, msg);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
|
|
||||||
|
|
||||||
if (pyCtxt->warningFunc == NULL) {
|
|
||||||
va_start(ap, msg);
|
|
||||||
vfprintf(stdout, msg, ap);
|
|
||||||
va_end(ap);
|
|
||||||
} else {
|
|
||||||
va_start(ap, msg);
|
|
||||||
str = libxml_buildMessage(msg,ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
list = PyTuple_New(2);
|
|
||||||
PyTuple_SetItem(list, 0, pyCtxt->warningFuncArg);
|
|
||||||
Py_XINCREF(pyCtxt->warningFuncArg);
|
|
||||||
message = libxml_charPtrWrap(str);
|
|
||||||
PyTuple_SetItem(list, 1, message);
|
|
||||||
result = PyEval_CallObject(pyCtxt->warningFunc, list);
|
|
||||||
Py_XDECREF(list);
|
|
||||||
Py_XDECREF(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
libxml_xmlSetParserCtxtWarningHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
|
libxml_xmlParserCtxtGetErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *py_retval;
|
PyObject *py_retval;
|
||||||
xmlParserCtxtPtr ctxt;
|
xmlParserCtxtPtr ctxt;
|
||||||
xmlParserCtxtPyCtxtPtr pyCtxt;
|
xmlParserCtxtPyCtxtPtr pyCtxt;
|
||||||
PyObject *pyobj_ctxt;
|
PyObject *pyobj_ctxt;
|
||||||
PyObject *pyobj_f;
|
|
||||||
PyObject *pyobj_arg;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, (char *)"OOO:xmlSetParserCtxtWarningHandler", &pyobj_ctxt, &pyobj_f, &pyobj_arg))
|
if (!PyArg_ParseTuple(args, (char *)"O:xmlParserCtxtGetErrorHandler",
|
||||||
|
&pyobj_ctxt))
|
||||||
return(NULL);
|
return(NULL);
|
||||||
ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
|
ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
|
||||||
if (ctxt->_private == NULL) {
|
py_retval = PyTuple_New(2);
|
||||||
pyCtxt = xmlMalloc(sizeof(xmlParserCtxtPyCtxt));
|
if (ctxt->_private != NULL) {
|
||||||
if (pyCtxt == NULL) {
|
pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
|
||||||
py_retval = libxml_intWrap(-1);
|
|
||||||
return(py_retval);
|
PyTuple_SetItem(py_retval, 0, pyCtxt->f);
|
||||||
}
|
Py_XINCREF(pyCtxt->f);
|
||||||
memset(pyCtxt,0,sizeof(xmlParserCtxtPyCtxt));
|
PyTuple_SetItem(py_retval, 1, pyCtxt->arg);
|
||||||
ctxt->_private = pyCtxt;
|
Py_XINCREF(pyCtxt->arg);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pyCtxt = ctxt->_private;
|
/* no python error handler registered */
|
||||||
|
PyTuple_SetItem(py_retval, 0, Py_None);
|
||||||
|
Py_XINCREF(Py_None);
|
||||||
|
PyTuple_SetItem(py_retval, 1, Py_None);
|
||||||
|
Py_XINCREF(Py_None);
|
||||||
}
|
}
|
||||||
/* TODO: check f is a function ! */
|
|
||||||
Py_XDECREF(pyCtxt->warningFunc);
|
|
||||||
Py_XINCREF(pyobj_f);
|
|
||||||
pyCtxt->warningFunc = pyobj_f;
|
|
||||||
Py_XDECREF(pyCtxt->warningFuncArg);
|
|
||||||
Py_XINCREF(pyobj_arg);
|
|
||||||
pyCtxt->warningFuncArg = pyobj_arg;
|
|
||||||
|
|
||||||
ctxt->sax->warning = libxml_xmlParserCtxtWarningFuncHandler;
|
|
||||||
ctxt->vctxt.warning = libxml_xmlParserCtxtWarningFuncHandler;
|
|
||||||
|
|
||||||
py_retval = libxml_intWrap(1);
|
|
||||||
return(py_retval);
|
return(py_retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
libxml_xmlFreeParserCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
|
||||||
|
xmlParserCtxtPtr ctxt;
|
||||||
|
PyObject *pyobj_ctxt;
|
||||||
|
xmlParserCtxtPyCtxtPtr pyCtxt;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, (char *)"O:xmlFreeParserCtxt", &pyobj_ctxt))
|
||||||
|
return(NULL);
|
||||||
|
ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
|
||||||
|
|
||||||
|
if (ctxt != NULL) {
|
||||||
|
pyCtxt = (xmlParserCtxtPyCtxtPtr)((xmlParserCtxtPtr)ctxt)->_private;
|
||||||
|
if (pyCtxt) {
|
||||||
|
Py_XDECREF(pyCtxt->f);
|
||||||
|
Py_XDECREF(pyCtxt->arg);
|
||||||
|
xmlFree(pyCtxt);
|
||||||
|
}
|
||||||
|
xmlFreeParserCtxt(ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return(Py_None);
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* *
|
* *
|
||||||
* Per xmlTextReader error handler *
|
* Per xmlTextReader error handler *
|
||||||
@ -1501,27 +1507,23 @@ typedef xmlTextReaderPyCtxt *xmlTextReaderPyCtxtPtr;
|
|||||||
static void
|
static void
|
||||||
libxml_xmlTextReaderErrorCallback(void *arg,
|
libxml_xmlTextReaderErrorCallback(void *arg,
|
||||||
const char *msg,
|
const char *msg,
|
||||||
int line,
|
int severity,
|
||||||
int col,
|
xmlTextReaderLocatorPtr locator)
|
||||||
const char *URI,
|
|
||||||
int severity)
|
|
||||||
{
|
{
|
||||||
xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
|
xmlTextReaderPyCtxt *pyCtxt = (xmlTextReaderPyCtxt *)arg;
|
||||||
PyObject *list;
|
PyObject *list;
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
|
||||||
list = PyTuple_New(6);
|
list = PyTuple_New(4);
|
||||||
PyTuple_SetItem(list, 0, pyCtxt->arg);
|
PyTuple_SetItem(list, 0, pyCtxt->arg);
|
||||||
Py_XINCREF(pyCtxt->arg);
|
Py_XINCREF(pyCtxt->arg);
|
||||||
PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
|
PyTuple_SetItem(list, 1, libxml_charPtrConstWrap(msg));
|
||||||
PyTuple_SetItem(list, 2, libxml_intWrap(line));
|
PyTuple_SetItem(list, 2, libxml_intWrap(severity));
|
||||||
PyTuple_SetItem(list, 3, libxml_intWrap(col));
|
PyTuple_SetItem(list, 3, libxml_xmlTextReaderLocatorPtrWrap(locator));
|
||||||
PyTuple_SetItem(list, 4, libxml_charPtrConstWrap(URI));
|
|
||||||
PyTuple_SetItem(list, 5, libxml_intWrap(severity));
|
|
||||||
result = PyEval_CallObject(pyCtxt->f, list);
|
result = PyEval_CallObject(pyCtxt->f, list);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
{
|
{
|
||||||
/* TODO: manage for the exception to be go up... */
|
/* TODO: manage for the exception to be propagated... */
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
}
|
}
|
||||||
Py_XDECREF(list);
|
Py_XDECREF(list);
|
||||||
@ -2558,8 +2560,8 @@ static PyMethodDef libxmlMethods[] = {
|
|||||||
{(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
|
{(char *) "inputBufferCreate", libxml_xmlCreateInputBuffer, METH_VARARGS, NULL},
|
||||||
{(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
|
{(char *) "setEntityLoader", libxml_xmlSetEntityLoader, METH_VARARGS, NULL},
|
||||||
{(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
|
{(char *)"xmlRegisterErrorHandler", libxml_xmlRegisterErrorHandler, METH_VARARGS, NULL },
|
||||||
{(char *)"xmlSetParserCtxtErrorHandler", libxml_xmlSetParserCtxtErrorHandler, METH_VARARGS, NULL },
|
{(char *)"xmlParserCtxtSetErrorHandler", libxml_xmlParserCtxtSetErrorHandler, METH_VARARGS, NULL },
|
||||||
{(char *)"xmlSetParserCtxtWarningHandler", libxml_xmlSetParserCtxtWarningHandler, METH_VARARGS, NULL },
|
{(char *)"xmlParserCtxtGetErrorHandler", libxml_xmlParserCtxtGetErrorHandler, METH_VARARGS, NULL },
|
||||||
{(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
|
{(char *)"xmlFreeParserCtxt", libxml_xmlFreeParserCtxt, METH_VARARGS, NULL },
|
||||||
{(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
|
{(char *)"xmlTextReaderSetErrorHandler", libxml_xmlTextReaderSetErrorHandler, METH_VARARGS, NULL },
|
||||||
{(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
|
{(char *)"xmlTextReaderGetErrorHandler", libxml_xmlTextReaderGetErrorHandler, METH_VARARGS, NULL },
|
||||||
|
@ -462,12 +462,12 @@ PARSER_VALIDATE=3
|
|||||||
PARSER_SUBST_ENTITIES=4
|
PARSER_SUBST_ENTITIES=4
|
||||||
|
|
||||||
#
|
#
|
||||||
# For the xmlTextReader error severities
|
# For the error callback severities
|
||||||
#
|
#
|
||||||
XMLREADER_SEVERITY_VALIDITY_WARNING=1
|
PARSER_SEVERITY_VALIDITY_WARNING=1
|
||||||
XMLREADER_SEVERITY_VALIDITY_ERROR=2
|
PARSER_SEVERITY_VALIDITY_ERROR=2
|
||||||
XMLREADER_SEVERITY_WARNING=3
|
PARSER_SEVERITY_WARNING=3
|
||||||
XMLREADER_SEVERITY_ERROR=4
|
PARSER_SEVERITY_ERROR=4
|
||||||
|
|
||||||
#
|
#
|
||||||
# register the libxml2 error handler
|
# register the libxml2 error handler
|
||||||
@ -499,11 +499,21 @@ class parserCtxtCore:
|
|||||||
libxml2mod.xmlFreeParserCtxt(self._o)
|
libxml2mod.xmlFreeParserCtxt(self._o)
|
||||||
self._o = None
|
self._o = None
|
||||||
|
|
||||||
def registerErrorHandler(self,f,arg):
|
def setErrorHandler(self,f,arg):
|
||||||
libxml2mod.xmlSetParserCtxtErrorHandler(self._o,f,arg)
|
"""Register an error handler that will be called back as
|
||||||
|
f(arg,msg,severity,reserved).
|
||||||
|
|
||||||
|
@reserved is currently always None."""
|
||||||
|
libxml2mod.xmlParserCtxtSetErrorHandler(self._o,f,arg)
|
||||||
|
|
||||||
def registerWarningHandler(self,f,arg):
|
def getErrorHandler(self):
|
||||||
libxml2mod.xmlSetParserCtxtWarningHandler(self._o,f,arg)
|
"""Return (f,arg) as previously registered with setErrorHandler
|
||||||
|
or (None,None)."""
|
||||||
|
return libxml2mod.xmlParserCtxtGetErrorHandler(self._o)
|
||||||
|
|
||||||
|
def _xmlTextReaderErrorFunc((f,arg),msg,severity,locator):
|
||||||
|
"""Intermediate callback to wrap the locator"""
|
||||||
|
return f(arg,msg,severity,xmlTextReaderLocator(locator))
|
||||||
|
|
||||||
class xmlTextReaderCore:
|
class xmlTextReaderCore:
|
||||||
|
|
||||||
@ -517,15 +527,25 @@ class xmlTextReaderCore:
|
|||||||
libxml2mod.xmlFreeTextReader(self._o)
|
libxml2mod.xmlFreeTextReader(self._o)
|
||||||
self._o = None
|
self._o = None
|
||||||
|
|
||||||
def setErrorHandler(self,f,arg):
|
def SetErrorHandler(self,f,arg):
|
||||||
"""Register an error handler that will be called back as
|
"""Register an error handler that will be called back as
|
||||||
f(arg,msg,line,col,URI,severity)."""
|
f(arg,msg,severity,locator)."""
|
||||||
libxml2mod.xmlTextReaderSetErrorHandler(self._o,f,arg)
|
if f is None:
|
||||||
|
libxml2mod.xmlTextReaderSetErrorHandler(\
|
||||||
|
self._o,None,None)
|
||||||
|
else:
|
||||||
|
libxml2mod.xmlTextReaderSetErrorHandler(\
|
||||||
|
self._o,_xmlTextReaderErrorFunc,(f,arg))
|
||||||
|
|
||||||
def getErrorHandler(self):
|
def GetErrorHandler(self):
|
||||||
"""Return (f,arg) as previously registered with setErrorHandler
|
"""Return (f,arg) as previously registered with setErrorHandler
|
||||||
or (None,None)."""
|
or (None,None)."""
|
||||||
return libxml2mod.xmlTextReaderGetErrorHandler(self._o)
|
f,arg = libxml2mod.xmlTextReaderGetErrorHandler(self._o)
|
||||||
|
if f is None:
|
||||||
|
return None,None
|
||||||
|
else:
|
||||||
|
# assert f is _xmlTextReaderErrorFunc
|
||||||
|
return arg
|
||||||
|
|
||||||
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||||
#
|
#
|
||||||
|
@ -93,6 +93,14 @@ typedef struct {
|
|||||||
xmlTextReaderPtr obj;
|
xmlTextReaderPtr obj;
|
||||||
} PyxmlTextReader_Object;
|
} PyxmlTextReader_Object;
|
||||||
|
|
||||||
|
#define PyxmlTextReaderLocator_Get(v) (((v) == Py_None) ? NULL : \
|
||||||
|
(((PyxmlTextReaderLocator_Object *)(v))->obj))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
xmlTextReaderLocatorPtr obj;
|
||||||
|
} PyxmlTextReaderLocator_Object;
|
||||||
|
|
||||||
#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
|
#define PyURI_Get(v) (((v) == Py_None) ? NULL : \
|
||||||
(((PyURI_Object *)(v))->obj))
|
(((PyURI_Object *)(v))->obj))
|
||||||
|
|
||||||
@ -147,19 +155,6 @@ PyObject * libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer);
|
|||||||
PyObject * libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer);
|
PyObject * libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer);
|
||||||
PyObject * libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp);
|
PyObject * libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp);
|
||||||
PyObject * libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader);
|
PyObject * libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader);
|
||||||
|
PyObject * libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator);
|
||||||
|
|
||||||
xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
|
xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
|
||||||
|
|
||||||
/*
|
|
||||||
* Data structure that makes the link from the parser context
|
|
||||||
* to the python wrapper.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
PyObject *errorFunc;
|
|
||||||
PyObject *errorFuncArg;
|
|
||||||
PyObject *warningFunc;
|
|
||||||
PyObject *warningFuncArg;
|
|
||||||
} xmlParserCtxtPyCtxt;
|
|
||||||
typedef xmlParserCtxtPyCtxt *xmlParserCtxtPyCtxtPtr;
|
|
||||||
|
|
||||||
|
@ -9,20 +9,22 @@ import libxml2
|
|||||||
# Memory debug specific
|
# Memory debug specific
|
||||||
libxml2.debugMemory(1)
|
libxml2.debugMemory(1)
|
||||||
|
|
||||||
expect="""--> Opening and ending tag mismatch: x and y
|
expect="""--> (3) xmlns: URI foo is not absolute
|
||||||
|
--> (4) Opening and ending tag mismatch: x and y
|
||||||
"""
|
"""
|
||||||
|
|
||||||
err=""
|
err=""
|
||||||
def callback(ctx, str):
|
def callback(arg,msg,severity,reserved):
|
||||||
global err
|
global err
|
||||||
|
err = err + "%s (%d) %s" % (arg,severity,msg)
|
||||||
|
|
||||||
err = err + "%s %s" % (ctx, str)
|
s = """<x xmlns="foo"></y>"""
|
||||||
|
|
||||||
s = """<x></y>"""
|
|
||||||
|
|
||||||
parserCtxt = libxml2.createPushParser(None,"",0,"test.xml")
|
parserCtxt = libxml2.createPushParser(None,"",0,"test.xml")
|
||||||
parserCtxt.registerErrorHandler(callback, "-->")
|
parserCtxt.setErrorHandler(callback, "-->")
|
||||||
parserCtxt.registerWarningHandler(callback, "-->")
|
if parserCtxt.getErrorHandler() != (callback,"-->"):
|
||||||
|
print "getErrorHandler failed"
|
||||||
|
sys.exit(1)
|
||||||
parserCtxt.parseChunk(s,len(s),1)
|
parserCtxt.parseChunk(s,len(s),1)
|
||||||
doc = parserCtxt.doc()
|
doc = parserCtxt.doc()
|
||||||
doc.freeDoc()
|
doc.freeDoc()
|
||||||
@ -37,8 +39,7 @@ if err != expect:
|
|||||||
i = 10000
|
i = 10000
|
||||||
while i > 0:
|
while i > 0:
|
||||||
parserCtxt = libxml2.createPushParser(None,"",0,"test.xml")
|
parserCtxt = libxml2.createPushParser(None,"",0,"test.xml")
|
||||||
parserCtxt.registerErrorHandler(callback, "-->")
|
parserCtxt.setErrorHandler(callback, "-->")
|
||||||
parserCtxt.registerWarningHandler(callback, "-->")
|
|
||||||
parserCtxt.parseChunk(s,len(s),1)
|
parserCtxt.parseChunk(s,len(s),1)
|
||||||
doc = parserCtxt.doc()
|
doc = parserCtxt.doc()
|
||||||
doc.freeDoc()
|
doc.freeDoc()
|
||||||
|
@ -13,14 +13,14 @@ expect="""--> (3) test1:1:xmlns: URI foo is not absolute
|
|||||||
--> (4) test1:1:Opening and ending tag mismatch: c and a
|
--> (4) test1:1:Opening and ending tag mismatch: c and a
|
||||||
"""
|
"""
|
||||||
err=""
|
err=""
|
||||||
def myErrorHandler(arg,msg,line,col,URI,severity):
|
def myErrorHandler(arg,msg,severity,locator):
|
||||||
global err
|
global err
|
||||||
err = err + "%s (%d) %s:%d:%s" % (arg,severity,URI,line,msg)
|
err = err + "%s (%d) %s:%d:%s" % (arg,severity,locator.BaseURI(),locator.LineNumber(),msg)
|
||||||
|
|
||||||
f = StringIO.StringIO("""<a xmlns="foo"><b b1="b1"/><c>content of c</a>""")
|
f = StringIO.StringIO("""<a xmlns="foo"><b b1="b1"/><c>content of c</a>""")
|
||||||
input = libxml2.inputBuffer(f)
|
input = libxml2.inputBuffer(f)
|
||||||
reader = input.newTextReader("test1")
|
reader = input.newTextReader("test1")
|
||||||
reader.setErrorHandler(myErrorHandler,"-->")
|
reader.SetErrorHandler(myErrorHandler,"-->")
|
||||||
while reader.Read() == 1:
|
while reader.Read() == 1:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -30,9 +30,9 @@ if err != expect:
|
|||||||
print "expected %s" %(expect)
|
print "expected %s" %(expect)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
reader.setErrorHandler(None,None)
|
reader.SetErrorHandler(None,None)
|
||||||
if reader.getErrorHandler() != (None,None):
|
if reader.GetErrorHandler() != (None,None):
|
||||||
print "getErrorHandler failed"
|
print "GetErrorHandler failed"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -566,3 +566,22 @@ libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
|
|||||||
(char *) "xmlTextReaderPtr", NULL);
|
(char *) "xmlTextReaderPtr", NULL);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)
|
||||||
|
{
|
||||||
|
PyObject *ret;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("libxml_xmlTextReaderLocatorPtrWrap: locator = %p\n", locator);
|
||||||
|
#endif
|
||||||
|
if (locator == NULL) {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return (Py_None);
|
||||||
|
}
|
||||||
|
ret =
|
||||||
|
PyCObject_FromVoidPtrAndDesc((void *) locator,
|
||||||
|
(char *) "xmlTextReaderLocatorPtr", NULL);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1219,6 +1219,9 @@ xmlCleanupPredefinedEntities
|
|||||||
/* Error handling extensions */
|
/* Error handling extensions */
|
||||||
xmlTextReaderSetErrorHandler
|
xmlTextReaderSetErrorHandler
|
||||||
xmlTextReaderGetErrorHandler
|
xmlTextReaderGetErrorHandler
|
||||||
|
xmlTextReaderLocatorLineNumber
|
||||||
|
/*xmlTextReaderLocatorLinePosition*/
|
||||||
|
xmlTextReaderLocatorBaseURI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
129
xmlreader.c
129
xmlreader.c
@ -2281,6 +2281,74 @@ xmlTextReaderBuildMessage(const char *msg, va_list ap) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlTextReaderLocatorLineNumber
|
||||||
|
* @locator: the xmlTextReaderLocatorPtr used
|
||||||
|
*
|
||||||
|
* Obtain the line number for the given locator.
|
||||||
|
*
|
||||||
|
* Returns the line number or -1 in case of error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator) {
|
||||||
|
/* we know that locator is a xmlParserCtxtPtr */
|
||||||
|
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (ctx->node != NULL) {
|
||||||
|
ret = xmlGetLineNo(ctx->node);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* inspired from error.c */
|
||||||
|
xmlParserInputPtr input;
|
||||||
|
input = ctx->input;
|
||||||
|
if ((input->filename == NULL) && (ctx->inputNr > 1))
|
||||||
|
input = ctx->inputTab[ctx->inputNr - 2];
|
||||||
|
if (input != NULL) {
|
||||||
|
ret = input->line;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlTextReaderLocatorBaseURI
|
||||||
|
* @locator: the xmlTextReaderLocatorPtr used
|
||||||
|
*
|
||||||
|
* Obtain the base URI for the given locator.
|
||||||
|
*
|
||||||
|
* Returns the base URI or NULL in case of error.
|
||||||
|
*/
|
||||||
|
xmlChar *
|
||||||
|
xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator) {
|
||||||
|
/* we know that locator is a xmlParserCtxtPtr */
|
||||||
|
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)locator;
|
||||||
|
xmlChar *ret = NULL;
|
||||||
|
|
||||||
|
if (ctx->node != NULL) {
|
||||||
|
ret = xmlNodeGetBase(NULL,ctx->node);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* inspired from error.c */
|
||||||
|
xmlParserInputPtr input;
|
||||||
|
input = ctx->input;
|
||||||
|
if ((input->filename == NULL) && (ctx->inputNr > 1))
|
||||||
|
input = ctx->inputTab[ctx->inputNr - 2];
|
||||||
|
if (input != NULL) {
|
||||||
|
ret = xmlStrdup(input->filename);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xmlTextReaderGenericError(void *ctxt, int severity, char *str) {
|
xmlTextReaderGenericError(void *ctxt, int severity, char *str) {
|
||||||
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)ctxt;
|
xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)ctxt;
|
||||||
@ -2289,10 +2357,8 @@ xmlTextReaderGenericError(void *ctxt, int severity, char *str) {
|
|||||||
if (str != NULL) {
|
if (str != NULL) {
|
||||||
reader->errorFunc(reader->errorFuncArg,
|
reader->errorFunc(reader->errorFuncArg,
|
||||||
str,
|
str,
|
||||||
ctx->input->line,
|
severity,
|
||||||
ctx->input->col,
|
(xmlTextReaderLocatorPtr)ctx);
|
||||||
ctx->input->filename,
|
|
||||||
severity);
|
|
||||||
xmlFree(str);
|
xmlFree(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2303,7 +2369,7 @@ xmlTextReaderError(void *ctxt, const char *msg, ...) {
|
|||||||
|
|
||||||
va_start(ap,msg);
|
va_start(ap,msg);
|
||||||
xmlTextReaderGenericError(ctxt,
|
xmlTextReaderGenericError(ctxt,
|
||||||
XMLREADER_SEVERITY_ERROR,
|
XML_PARSER_SEVERITY_ERROR,
|
||||||
xmlTextReaderBuildMessage(msg,ap));
|
xmlTextReaderBuildMessage(msg,ap));
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
@ -2315,7 +2381,7 @@ xmlTextReaderWarning(void *ctxt, const char *msg, ...) {
|
|||||||
|
|
||||||
va_start(ap,msg);
|
va_start(ap,msg);
|
||||||
xmlTextReaderGenericError(ctxt,
|
xmlTextReaderGenericError(ctxt,
|
||||||
XMLREADER_SEVERITY_WARNING,
|
XML_PARSER_SEVERITY_WARNING,
|
||||||
xmlTextReaderBuildMessage(msg,ap));
|
xmlTextReaderBuildMessage(msg,ap));
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
@ -2323,24 +2389,37 @@ xmlTextReaderWarning(void *ctxt, const char *msg, ...) {
|
|||||||
static void
|
static void
|
||||||
xmlTextReaderValidityError(void *ctxt, const char *msg, ...) {
|
xmlTextReaderValidityError(void *ctxt, const char *msg, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
int len = xmlStrlen((const xmlChar *) msg);
|
||||||
|
|
||||||
va_start(ap,msg);
|
if ((len > 1) && (msg[len - 2] != ':')) {
|
||||||
xmlTextReaderGenericError(ctxt,
|
/*
|
||||||
XMLREADER_SEVERITY_VALIDITY_ERROR,
|
* some callbacks only report locator information:
|
||||||
xmlTextReaderBuildMessage(msg,ap));
|
* skip them (mimicking behaviour in error.c)
|
||||||
va_end(ap);
|
*/
|
||||||
|
va_start(ap,msg);
|
||||||
|
xmlTextReaderGenericError(ctxt,
|
||||||
|
XML_PARSER_SEVERITY_VALIDITY_ERROR,
|
||||||
|
xmlTextReaderBuildMessage(msg,ap));
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) {
|
xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
int len = xmlStrlen((const xmlChar *) msg);
|
||||||
|
|
||||||
va_start(ap,msg);
|
if ((len != 0) && (msg[len - 1] != ':')) {
|
||||||
xmlTextReaderGenericError(ctxt,
|
/*
|
||||||
XMLREADER_SEVERITY_VALIDITY_WARNING,
|
* some callbacks only report locator information:
|
||||||
xmlTextReaderBuildMessage(msg,ap));
|
* skip them (mimicking behaviour in error.c)
|
||||||
va_end(ap);
|
*/
|
||||||
|
va_start(ap,msg);
|
||||||
|
xmlTextReaderGenericError(ctxt,
|
||||||
|
XML_PARSER_SEVERITY_VALIDITY_WARNING,
|
||||||
|
xmlTextReaderBuildMessage(msg,ap));
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2349,13 +2428,14 @@ xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) {
|
|||||||
* @f: the callback function to call on error and warnings
|
* @f: the callback function to call on error and warnings
|
||||||
* @arg: a user argument to pass to the callback function
|
* @arg: a user argument to pass to the callback function
|
||||||
*
|
*
|
||||||
|
* Register a callback function that will be called on error and warnings.
|
||||||
|
*
|
||||||
* If @f is NULL, the default error and warning handlers are restored.
|
* If @f is NULL, the default error and warning handlers are restored.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
|
xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
|
||||||
xmlTextReaderErrorFunc f,
|
xmlTextReaderErrorFunc f,
|
||||||
void *arg)
|
void *arg) {
|
||||||
{
|
|
||||||
if (f != NULL) {
|
if (f != NULL) {
|
||||||
reader->ctxt->sax->error = xmlTextReaderError;
|
reader->ctxt->sax->error = xmlTextReaderError;
|
||||||
reader->ctxt->vctxt.error = xmlTextReaderValidityError;
|
reader->ctxt->vctxt.error = xmlTextReaderValidityError;
|
||||||
@ -2375,11 +2455,18 @@ xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlTextReaderGetErrorHandler:
|
||||||
|
* @reader: the xmlTextReaderPtr used
|
||||||
|
* @f: the callback function or NULL is no callback has been registered
|
||||||
|
* @arg: a user argument
|
||||||
|
*
|
||||||
|
* Retrieve the error callback function and user argument.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
|
xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
|
||||||
xmlTextReaderErrorFunc *f,
|
xmlTextReaderErrorFunc *f,
|
||||||
void **arg)
|
void **arg) {
|
||||||
{
|
|
||||||
*f = reader->errorFunc;
|
*f = reader->errorFunc;
|
||||||
*arg = reader->errorFuncArg;
|
*arg = reader->errorFuncArg;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user