summaryrefslogtreecommitdiff
path: root/bindings/xml
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2007-09-16 17:02:20 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2007-09-16 17:02:20 +0000
commit56e984e3a255e439e32ac32e131fd79aa61fad0f (patch)
tree1554b63ea339f423c659ccf1fc706a2f5cdd847b /bindings/xml
parent2a1201a40dd9645dba1b19fb085d3897615e6427 (diff)
downloadlibdom-56e984e3a255e439e32ac32e131fd79aa61fad0f.tar.gz
libdom-56e984e3a255e439e32ac32e131fd79aa61fad0f.tar.bz2
Add callback for informational messaging (with variable severity, a la syslog)
Use it to log interesting things during parsing. This needs to grow some i18n at some point. svn path=/trunk/dom/; revision=3540
Diffstat (limited to 'bindings/xml')
-rw-r--r--bindings/xml/functypes.h20
-rw-r--r--bindings/xml/xmlparser.c120
-rw-r--r--bindings/xml/xmlparser.h2
3 files changed, 99 insertions, 43 deletions
diff --git a/bindings/xml/functypes.h b/bindings/xml/functypes.h
index d0706b8..9cb15ee 100644
--- a/bindings/xml/functypes.h
+++ b/bindings/xml/functypes.h
@@ -13,4 +13,24 @@
*/
typedef void *(*xml_alloc)(void *ptr, size_t len, void *pw);
+/**
+ * Severity levels for xml_msg function, based on syslog(3)
+ */
+enum {
+ XML_MSG_DEBUG,
+ XML_MSG_INFO,
+ XML_MSG_NOTICE,
+ XML_MSG_WARNING,
+ XML_MSG_ERROR,
+ XML_MSG_CRITICAL,
+ XML_MSG_ALERT,
+ XML_MSG_EMERGENCY
+};
+
+/**
+ * Type of XML parser message function
+ */
+typedef void (*xml_msg)(uint32_t severity, void *ctx, const char *msg, ...);
+
#endif
+
diff --git a/bindings/xml/xmlparser.c b/bindings/xml/xmlparser.c
index e140399..555cf3a 100644
--- a/bindings/xml/xmlparser.c
+++ b/bindings/xml/xmlparser.c
@@ -6,7 +6,6 @@
*/
#include <stdbool.h>
-#include <stdio.h>
#include <string.h>
#include <libxml/parser.h>
@@ -95,44 +94,47 @@ struct xml_parser {
xml_alloc alloc; /**< Memory (de)allocation function */
void *pw; /**< Pointer to client data */
+
+ xml_msg msg; /**< Informational message function */
+ void *mctx; /**< Pointer to client data */
};
/**
* SAX callback dispatch table
*/
static xmlSAXHandler sax_handler = {
- .internalSubset = xml_parser_internal_subset,
- .isStandalone = xml_parser_is_standalone,
- .hasInternalSubset = xml_parser_has_internal_subset,
- .hasExternalSubset = xml_parser_has_external_subset,
- .resolveEntity = xml_parser_resolve_entity,
- .getEntity = xml_parser_get_entity,
- .entityDecl = xml_parser_entity_decl,
- .notationDecl = xml_parser_notation_decl,
- .attributeDecl = xml_parser_attribute_decl,
- .elementDecl = xml_parser_element_decl,
- .unparsedEntityDecl = xml_parser_unparsed_entity_decl,
- .setDocumentLocator = xml_parser_set_document_locator,
- .startDocument = xml_parser_start_document,
- .endDocument = xml_parser_end_document,
- .startElement = NULL,
- .endElement = NULL,
- .reference = xml_parser_reference,
- .characters = xml_parser_characters,
- .ignorableWhitespace = xml_parser_characters,
- .processingInstruction = NULL,
- .comment = xml_parser_comment,
- .warning = NULL,
- .error = NULL,
- .fatalError = NULL,
- .getParameterEntity = xml_parser_get_parameter_entity,
- .cdataBlock = xml_parser_cdata_block,
- .externalSubset = xml_parser_external_subset,
- .initialized = XML_SAX2_MAGIC,
- ._private = NULL,
- .startElementNs = xml_parser_start_element_ns,
- .endElementNs = xml_parser_end_element_ns,
- .serror = NULL
+ .internalSubset = xml_parser_internal_subset,
+ .isStandalone = xml_parser_is_standalone,
+ .hasInternalSubset = xml_parser_has_internal_subset,
+ .hasExternalSubset = xml_parser_has_external_subset,
+ .resolveEntity = xml_parser_resolve_entity,
+ .getEntity = xml_parser_get_entity,
+ .entityDecl = xml_parser_entity_decl,
+ .notationDecl = xml_parser_notation_decl,
+ .attributeDecl = xml_parser_attribute_decl,
+ .elementDecl = xml_parser_element_decl,
+ .unparsedEntityDecl = xml_parser_unparsed_entity_decl,
+ .setDocumentLocator = xml_parser_set_document_locator,
+ .startDocument = xml_parser_start_document,
+ .endDocument = xml_parser_end_document,
+ .startElement = NULL,
+ .endElement = NULL,
+ .reference = xml_parser_reference,
+ .characters = xml_parser_characters,
+ .ignorableWhitespace = xml_parser_characters,
+ .processingInstruction = NULL,
+ .comment = xml_parser_comment,
+ .warning = NULL,
+ .error = NULL,
+ .fatalError = NULL,
+ .getParameterEntity = xml_parser_get_parameter_entity,
+ .cdataBlock = xml_parser_cdata_block,
+ .externalSubset = xml_parser_external_subset,
+ .initialized = XML_SAX2_MAGIC,
+ ._private = NULL,
+ .startElementNs = xml_parser_start_element_ns,
+ .endElementNs = xml_parser_end_element_ns,
+ .serror = NULL
};
/**
@@ -142,6 +144,8 @@ static xmlSAXHandler sax_handler = {
* \param int_enc Desired charset of document buffer (UTF-8 or UTF-16)
* \param alloc Memory (de)allocation function
* \param pw Pointer to client-specific private data
+ * \param msg Informational message function
+ * \param mctx Pointer to client-specific private data
* \return Pointer to instance, or NULL on memory exhaustion
*
* Neither ::enc nor ::int_enc are used here.
@@ -149,7 +153,7 @@ static xmlSAXHandler sax_handler = {
* parser encoding is not yet implemented
*/
xml_parser *xml_parser_create(const char *enc, const char *int_enc,
- xml_alloc alloc, void *pw)
+ xml_alloc alloc, void *pw, xml_msg msg, void *mctx)
{
xml_parser *parser;
struct dom_string *features;
@@ -159,13 +163,16 @@ xml_parser *xml_parser_create(const char *enc, const char *int_enc,
UNUSED(int_enc);
parser = alloc(NULL, sizeof(xml_parser), pw);
- if (parser == NULL)
+ if (parser == NULL) {
+ msg(XML_MSG_CRITICAL, mctx, "No memory for parser");
return NULL;
+ }
parser->xml_ctx =
xmlCreatePushParserCtxt(&sax_handler, parser, "", 0, NULL);
if (parser->xml_ctx == NULL) {
alloc(parser, 0, pw);
+ msg(XML_MSG_CRITICAL, mctx, "Failed to create XML parser");
return NULL;
}
@@ -180,6 +187,7 @@ xml_parser *xml_parser_create(const char *enc, const char *int_enc,
if (err != DOM_NO_ERR) {
xmlFreeParserCtxt(parser->xml_ctx);
alloc(parser, 0, pw);
+ msg(XML_MSG_CRITICAL, mctx, "No memory for userdata key");
return NULL;
}
@@ -191,6 +199,7 @@ xml_parser *xml_parser_create(const char *enc, const char *int_enc,
dom_string_unref(parser->udkey);
xmlFreeParserCtxt(parser->xml_ctx);
alloc(parser, 0, pw);
+ msg(XML_MSG_CRITICAL, mctx, "No memory for feature string");
return NULL;
}
@@ -202,6 +211,7 @@ xml_parser *xml_parser_create(const char *enc, const char *int_enc,
dom_string_unref(parser->udkey);
xmlFreeParserCtxt(parser->xml_ctx);
alloc(parser, 0, pw);
+ msg(XML_MSG_ERROR, mctx, "No suitable DOMImplementation");
return NULL;
}
@@ -211,6 +221,9 @@ xml_parser *xml_parser_create(const char *enc, const char *int_enc,
parser->alloc = alloc;
parser->pw = pw;
+ parser->msg = msg;
+ parser->mctx = mctx;
+
return parser;
}
@@ -248,8 +261,11 @@ xml_error xml_parser_parse_chunk(xml_parser *parser,
xmlParserErrors err;
err = xmlParseChunk(parser->xml_ctx, (char *) data, len, 0);
- if (err != XML_ERR_OK)
+ if (err != XML_ERR_OK) {
+ parser->msg(XML_MSG_ERROR, parser->mctx,
+ "xmlParseChunk failed: %d", err);
return XML_LIBXML_ERR | err;
+ }
return XML_OK;
}
@@ -267,8 +283,11 @@ xml_error xml_parser_completed(xml_parser *parser)
xmlParserErrors err;
err = xmlParseChunk(parser->xml_ctx, "", 0, 1);
- if (err != XML_ERR_OK)
+ if (err != XML_ERR_OK) {
+ parser->msg(XML_MSG_ERROR, parser->mctx,
+ "xmlParseChunk failed: %d", err);
return XML_LIBXML_ERR | err;
+ }
parser->complete = true;
@@ -311,6 +330,8 @@ void xml_parser_start_document(void *ctx)
(dom_alloc) parser->alloc,
parser->pw);
if (err != DOM_NO_ERR) {
+ parser->msg(XML_MSG_CRITICAL, parser->mctx,
+ "Failed creating document");
return;
}
@@ -342,8 +363,11 @@ void xml_parser_end_document(void *ctx)
xmlSAX2EndDocument(parser->xml_ctx);
/* If there is no document, we can't do anything */
- if (parser->doc == NULL)
+ if (parser->doc == NULL) {
+ parser->msg(XML_MSG_WARNING, parser->mctx,
+ "No document in end_document");
return;
+ }
/* We need to mirror any child nodes at the end of the list of
* children which occur after the last Element node in the list */
@@ -352,6 +376,8 @@ void xml_parser_end_document(void *ctx)
err = dom_node_get_user_data((struct dom_node *) parser->doc,
parser->udkey, (void **) &node);
if (err != DOM_NO_ERR) {
+ parser->msg(XML_MSG_WARNING, parser->mctx,
+ "Failed finding XML node");
return;
}
@@ -407,8 +433,11 @@ void xml_parser_start_element_ns(void *ctx, const xmlChar *localname,
nb_defaulted, attributes);
/* If there is no document, we can't do anything */
- if (parser->doc == NULL)
+ if (parser->doc == NULL) {
+ parser->msg(XML_MSG_WARNING, parser->mctx,
+ "No document in start_element_ns");
return;
+ }
if (parent == NULL) {
/* No parent; use document */
@@ -471,8 +500,11 @@ void xml_parser_end_element_ns(void *ctx, const xmlChar *localname,
xmlSAX2EndElementNs(parser->xml_ctx, localname, prefix, URI);
/* If there is no document, we can't do anything */
- if (parser->doc == NULL)
+ if (parser->doc == NULL) {
+ parser->msg(XML_MSG_WARNING, parser->mctx,
+ "No document in end_element_ns");
return;
+ }
/* We need to mirror any child nodes at the end of the list of
* children which occur after the last Element node in the list */
@@ -515,8 +547,11 @@ dom_exception xml_parser_link_nodes(xml_parser *parser, struct dom_node *dom,
/* Register XML node as user data for DOM node */
err = dom_node_set_user_data(dom, parser->udkey, xml, NULL,
&prev_data);
- if (err != DOM_NO_ERR)
+ if (err != DOM_NO_ERR) {
+ parser->msg(XML_MSG_ERROR, parser->mctx,
+ "Failed setting user data: %d", err);
return err;
+ }
/* Register DOM node with the XML node */
xml->_private = dom;
@@ -579,7 +614,8 @@ void xml_parser_add_node(xml_parser *parser, struct dom_node *parent,
xml_parser_add_document_type(parser, parent, child);
break;
default:
- fprintf(stderr, "Unsupported node type: %s\n",
+ parser->msg(XML_MSG_NOTICE, parser->mctx,
+ "Unsupported node type: %s",
node_types[child->type]);
}
}
diff --git a/bindings/xml/xmlparser.h b/bindings/xml/xmlparser.h
index e8cff7e..d9eb240 100644
--- a/bindings/xml/xmlparser.h
+++ b/bindings/xml/xmlparser.h
@@ -20,7 +20,7 @@ typedef struct xml_parser xml_parser;
/* Create an XML parser instance */
xml_parser *xml_parser_create(const char *enc, const char *int_enc,
- xml_alloc alloc, void *pw);
+ xml_alloc alloc, void *pw, xml_msg msg, void *mctx);
/* Destroy an XML parser instance */
void xml_parser_destroy(xml_parser *parser);