diff --git a/HTMLparser.c b/HTMLparser.c index e48f240a..f8ff2d2a 100644 --- a/HTMLparser.c +++ b/HTMLparser.c @@ -5028,6 +5028,8 @@ htmlParseDocument(htmlParserCtxtPtr ctxt) { /** * htmlInitParserCtxt: * @ctxt: an HTML parser context + * @sax: SAX handler + * @userData: user data * * Initialize a parser context * @@ -5035,10 +5037,8 @@ htmlParseDocument(htmlParserCtxtPtr ctxt) { */ static int -htmlInitParserCtxt(htmlParserCtxtPtr ctxt) +htmlInitParserCtxt(htmlParserCtxtPtr ctxt, htmlSAXHandler *sax, void *userData) { - htmlSAXHandler *sax; - if (ctxt == NULL) return(-1); memset(ctxt, 0, sizeof(htmlParserCtxt)); @@ -5047,12 +5047,21 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt) htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n"); return(-1); } - sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler)); - if (sax == NULL) { + + if (ctxt->sax == NULL) + ctxt->sax = (htmlSAXHandler *) xmlMalloc(sizeof(htmlSAXHandler)); + if (ctxt->sax == NULL) { htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n"); return(-1); } - memset(sax, 0, sizeof(htmlSAXHandler)); + if (sax == NULL) { + memset(ctxt->sax, 0, sizeof(htmlSAXHandler)); + xmlSAX2InitHtmlDefaultSAXHandler(ctxt->sax); + ctxt->userData = ctxt; + } else { + memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler)); + ctxt->userData = userData ? userData : ctxt; + } /* Allocate the Input stack */ ctxt->inputTab = (htmlParserInputPtr *) @@ -5111,10 +5120,6 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt) ctxt->nodeInfoNr = 0; ctxt->nodeInfoMax = 0; - ctxt->sax = sax; - xmlSAX2InitHtmlDefaultSAXHandler(sax); - - ctxt->userData = ctxt; ctxt->myDoc = NULL; ctxt->wellFormed = 1; ctxt->replaceEntities = 0; @@ -5157,6 +5162,22 @@ htmlFreeParserCtxt(htmlParserCtxtPtr ctxt) htmlParserCtxtPtr htmlNewParserCtxt(void) +{ + return(htmlNewSAXParserCtxt(NULL, NULL)); +} + +/** + * htmlNewSAXParserCtxt: + * @sax: SAX handler + * @userData: user data + * + * Allocate and initialize a new parser context. + * + * Returns the htmlParserCtxtPtr or NULL in case of allocation error + */ + +htmlParserCtxtPtr +htmlNewSAXParserCtxt(htmlSAXHandlerPtr sax, void *userData) { xmlParserCtxtPtr ctxt; @@ -5166,7 +5187,7 @@ htmlNewParserCtxt(void) return(NULL); } memset(ctxt, 0, sizeof(xmlParserCtxt)); - if (htmlInitParserCtxt(ctxt) < 0) { + if (htmlInitParserCtxt(ctxt, sax, userData) < 0) { htmlFreeParserCtxt(ctxt); return(NULL); } @@ -6326,28 +6347,13 @@ htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data, buf = xmlAllocParserInputBuffer(enc); if (buf == NULL) return(NULL); - ctxt = htmlNewParserCtxt(); + ctxt = htmlNewSAXParserCtxt(sax, user_data); if (ctxt == NULL) { xmlFreeParserInputBuffer(buf); return(NULL); } if(enc==XML_CHAR_ENCODING_UTF8 || buf->encoder) ctxt->charset=XML_CHAR_ENCODING_UTF8; - if (sax != NULL) { -#ifdef LIBXML_SAX1_ENABLED - if (ctxt->sax != (xmlSAXHandlerPtr) &htmlDefaultSAXHandler) -#endif - xmlFree(ctxt->sax); - ctxt->sax = (htmlSAXHandlerPtr) xmlMalloc(sizeof(htmlSAXHandler)); - if (ctxt->sax == NULL) { - xmlFree(buf); - xmlFree(ctxt); - return(NULL); - } - memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler)); - if (user_data != NULL) - ctxt->userData = user_data; - } if (filename == NULL) { ctxt->directory = NULL; } else { diff --git a/doc/devhelp/libxml2-HTMLparser.html b/doc/devhelp/libxml2-HTMLparser.html index 306b7c3d..d128cbe0 100644 --- a/doc/devhelp/libxml2-HTMLparser.html +++ b/doc/devhelp/libxml2-HTMLparser.html @@ -78,6 +78,7 @@ int htmlHandleOmittedElem (int val); int htmlIsAutoClosed (htmlDocPtr doc,
htmlNodePtr elem); int htmlIsScriptAttribute (const xmlChar * name); htmlParserCtxtPtr htmlNewParserCtxt (void); +htmlParserCtxtPtr htmlNewSAXParserCtxt (htmlSAXHandlerPtr sax,
void * userData); htmlStatus htmlNodeStatus (const htmlNodePtr node,
int legacy); int htmlParseCharRef (htmlParserCtxtPtr ctxt); int htmlParseChunk (htmlParserCtxtPtr ctxt,
const char * chunk,
int size,
int terminate); @@ -297,6 +298,10 @@ const htmlElemDesc *

htmlNewParserCtxt ()

htmlParserCtxtPtr	htmlNewParserCtxt	(void)

Allocate and initialize a new parser context.

Returns:the htmlParserCtxtPtr or NULL in case of allocation error
+
+

htmlNewSAXParserCtxt ()

htmlParserCtxtPtr	htmlNewSAXParserCtxt	(htmlSAXHandlerPtr sax, 
void * userData)
+

Allocate and initialize a new parser context.

+
sax:SAX handler
userData:user data
Returns:the htmlParserCtxtPtr or NULL in case of allocation error

htmlNodeStatus ()

htmlStatus	htmlNodeStatus		(const htmlNodePtr node, 
int legacy)

Checks whether the tree node is valid. Experimental (the author only uses the HTML enhancements in a SAX parser)

diff --git a/doc/devhelp/libxml2-parser.html b/doc/devhelp/libxml2-parser.html index f0266a0f..3234fc2b 100644 --- a/doc/devhelp/libxml2-parser.html +++ b/doc/devhelp/libxml2-parser.html @@ -119,6 +119,7 @@ int xmlLineNumbersDefault (int val); xmlParserInputPtr xmlLoadExternalEntity (const char * URL,
const char * ID,
xmlParserCtxtPtr ctxt); xmlParserInputPtr xmlNewIOInputStream (xmlParserCtxtPtr ctxt,
xmlParserInputBufferPtr input,
xmlCharEncoding enc); xmlParserCtxtPtr xmlNewParserCtxt (void); +xmlParserCtxtPtr xmlNewSAXParserCtxt (xmlSAXHandlerPtr sax,
void * userData); int xmlParseBalancedChunkMemory (xmlDocPtr doc,
xmlSAXHandlerPtr sax,
void * user_data,
int depth,
const xmlChar * string,
xmlNodePtr * lst); int xmlParseBalancedChunkMemoryRecover (xmlDocPtr doc,
xmlSAXHandlerPtr sax,
void * user_data,
int depth,
const xmlChar * string,
xmlNodePtr * lst,
int recover); int xmlParseChunk (xmlParserCtxtPtr ctxt,
const char * chunk,
int size,
int terminate); @@ -580,7 +581,7 @@ The content of this structure is not made public by the API.

xmlInitParserCtxt ()

int	xmlInitParserCtxt		(xmlParserCtxtPtr ctxt)
-

Initialize a parser context

+

DEPRECATED: Internal function which will be made private in a future version. Initialize a parser context

ctxt:an XML parser context
Returns:0 in case of success and -1 in case of error

xmlKeepBlanksDefault ()

int	xmlKeepBlanksDefault		(int val)
@@ -602,6 +603,10 @@ The content of this structure is not made public by the API.

xmlNewParserCtxt ()

xmlParserCtxtPtr	xmlNewParserCtxt	(void)

Allocate and initialize a new parser context.

Returns:the xmlParserCtxtPtr or NULL
+
+

xmlNewSAXParserCtxt ()

xmlParserCtxtPtr	xmlNewSAXParserCtxt	(xmlSAXHandlerPtr sax, 
void * userData)
+

Allocate and initialize a new SAX parser context.

+
sax:SAX handler
userData:user data
Returns:the xmlParserCtxtPtr or NULL

xmlParseBalancedChunkMemory ()

int	xmlParseBalancedChunkMemory	(xmlDocPtr doc, 
xmlSAXHandlerPtr sax,
void * user_data,
int depth,
const xmlChar * string,
xmlNodePtr * lst)

Parse a well-balanced chunk of an XML document called by the parser The allowed sequence for the Well Balanced Chunk is the one defined by the content production in the XML grammar: [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*

diff --git a/doc/devhelp/libxml2.devhelp2 b/doc/devhelp/libxml2.devhelp2 index 2789154d..515d0654 100644 --- a/doc/devhelp/libxml2.devhelp2 +++ b/doc/devhelp/libxml2.devhelp2 @@ -1997,6 +1997,7 @@ + @@ -2563,6 +2564,7 @@ + diff --git a/doc/libxml2-api.xml b/doc/libxml2-api.xml index a59d4dd3..92dadf00 100644 --- a/doc/libxml2-api.xml +++ b/doc/libxml2-api.xml @@ -62,6 +62,7 @@ + @@ -813,6 +814,7 @@ + @@ -7628,6 +7630,13 @@ Could we use @subtypes for this?'/> Allocate and initialize a new parser context. + + defined(LIBXML_HTML_ENABLED) + Allocate and initialize a new parser context. + + + + defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED) Dump an HTML node, recursive behaviour,children are printed too, and formatting returns are added. @@ -10582,7 +10591,7 @@ Could we use @subtypes for this?'/> - Initialize a parser context + DEPRECATED: Internal function which will be made private in a future version. Initialize a parser context @@ -11596,6 +11605,12 @@ Could we use @subtypes for this?'/> + + Allocate and initialize a new SAX parser context. + + + + Create a new input stream based on a memory buffer. diff --git a/doc/symbols.xml b/doc/symbols.xml index 2b667e0a..4a311fda 100644 --- a/doc/symbols.xml +++ b/doc/symbols.xml @@ -1771,4 +1771,8 @@ xmlPopOutputCallbacks + + htmlNewSAXParserCtxt + xmlNewSAXParserCtxt + diff --git a/include/libxml/HTMLparser.h b/include/libxml/HTMLparser.h index 1d4fec2f..29316abf 100644 --- a/include/libxml/HTMLparser.h +++ b/include/libxml/HTMLparser.h @@ -107,6 +107,9 @@ XMLPUBFUN void XMLCALL XMLPUBFUN htmlParserCtxtPtr XMLCALL htmlNewParserCtxt(void); +XMLPUBFUN htmlParserCtxtPtr XMLCALL + htmlNewSAXParserCtxt(htmlSAXHandlerPtr sax, + void *userData); XMLPUBFUN htmlParserCtxtPtr XMLCALL htmlCreateMemoryParserCtxt(const char *buffer, diff --git a/include/libxml/parser.h b/include/libxml/parser.h index 82c61d67..fc8f2f47 100644 --- a/include/libxml/parser.h +++ b/include/libxml/parser.h @@ -975,6 +975,8 @@ XMLPUBFUN int XMLCALL */ XMLPUBFUN xmlParserCtxtPtr XMLCALL xmlNewParserCtxt (void); +XMLPUBFUN xmlParserCtxtPtr XMLCALL + xmlNewSAXParserCtxt (xmlSAXHandlerPtr sax, void *userData); XMLPUBFUN int XMLCALL xmlInitParserCtxt (xmlParserCtxtPtr ctxt); XMLPUBFUN void XMLCALL diff --git a/libxml2.syms b/libxml2.syms index f692a1c7..7da59a19 100644 --- a/libxml2.syms +++ b/libxml2.syms @@ -2293,3 +2293,13 @@ LIBXML2_2.9.11 { xmlPopOutputCallbacks; } LIBXML2_2.9.8; +LIBXML2_2.11.0 { + global: + +# HTMLparser + htmlNewSAXParserCtxt; + +# parser + xmlNewSAXParserCtxt; +} LIBXML2_2.9.11; + diff --git a/parser.c b/parser.c index 93f031be..63ec95ff 100644 --- a/parser.c +++ b/parser.c @@ -85,8 +85,9 @@ static void xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info); static xmlParserCtxtPtr -xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID, - const xmlChar *base, xmlParserCtxtPtr pctx); +xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData, + const xmlChar *URL, const xmlChar *ID, const xmlChar *base, + xmlParserCtxtPtr pctx); static void xmlHaltParser(xmlParserCtxtPtr ctxt); @@ -12447,33 +12448,13 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data, buf = xmlAllocParserInputBuffer(enc); if (buf == NULL) return(NULL); - ctxt = xmlNewParserCtxt(); + ctxt = xmlNewSAXParserCtxt(sax, user_data); if (ctxt == NULL) { xmlErrMemory(NULL, "creating parser: out of memory\n"); xmlFreeParserInputBuffer(buf); return(NULL); } ctxt->dictNames = 1; - if (sax != NULL) { -#ifdef LIBXML_SAX1_ENABLED - if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler) -#endif /* LIBXML_SAX1_ENABLED */ - xmlFree(ctxt->sax); - ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler)); - if (ctxt->sax == NULL) { - xmlErrMemory(ctxt, NULL); - xmlFreeParserInputBuffer(buf); - xmlFreeParserCtxt(ctxt); - return(NULL); - } - memset(ctxt->sax, 0, sizeof(xmlSAXHandler)); - if (sax->initialized == XML_SAX2_MAGIC) - memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler)); - else - memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1)); - if (user_data != NULL) - ctxt->userData = user_data; - } if (filename == NULL) { ctxt->directory = NULL; } else { @@ -12609,31 +12590,11 @@ xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data, return (NULL); } - ctxt = xmlNewParserCtxt(); + ctxt = xmlNewSAXParserCtxt(sax, user_data); if (ctxt == NULL) { xmlFreeParserInputBuffer(buf); return(NULL); } - if (sax != NULL) { -#ifdef LIBXML_SAX1_ENABLED - if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler) -#endif /* LIBXML_SAX1_ENABLED */ - xmlFree(ctxt->sax); - ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler)); - if (ctxt->sax == NULL) { - xmlFreeParserInputBuffer(buf); - xmlErrMemory(ctxt, NULL); - xmlFreeParserCtxt(ctxt); - return(NULL); - } - memset(ctxt->sax, 0, sizeof(xmlSAXHandler)); - if (sax->initialized == XML_SAX2_MAGIC) - memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler)); - else - memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1)); - if (user_data != NULL) - ctxt->userData = user_data; - } inputStream = xmlNewIOInputStream(ctxt, buf, enc); if (inputStream == NULL) { @@ -12675,7 +12636,7 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input, if (input == NULL) return(NULL); - ctxt = xmlNewParserCtxt(); + ctxt = xmlNewSAXParserCtxt(sax, NULL); if (ctxt == NULL) { xmlFreeParserInputBuffer(input); return(NULL); @@ -12684,15 +12645,6 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input, /* We are loading a DTD */ ctxt->options |= XML_PARSE_DTDLOAD; - /* - * Set-up the SAX context - */ - if (sax != NULL) { - if (ctxt->sax != NULL) - xmlFree(ctxt->sax); - ctxt->sax = sax; - ctxt->userData = ctxt; - } xmlDetectSAX2(ctxt); /* @@ -12701,7 +12653,6 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input, pinput = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); if (pinput == NULL) { - if (sax != NULL) ctxt->sax = NULL; xmlFreeParserInputBuffer(input); xmlFreeParserCtxt(ctxt); return(NULL); @@ -12711,7 +12662,6 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input, * plug some encoding conversion routines here. */ if (xmlPushInput(ctxt, pinput) < 0) { - if (sax != NULL) ctxt->sax = NULL; xmlFreeParserCtxt(ctxt); return(NULL); } @@ -12778,7 +12728,6 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input, xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL; } - if (sax != NULL) ctxt->sax = NULL; xmlFreeParserCtxt(ctxt); return(ret); @@ -12806,7 +12755,7 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID, if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL); - ctxt = xmlNewParserCtxt(); + ctxt = xmlNewSAXParserCtxt(sax, NULL); if (ctxt == NULL) { return(NULL); } @@ -12814,16 +12763,6 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID, /* We are loading a DTD */ ctxt->options |= XML_PARSE_DTDLOAD; - /* - * Set-up the SAX context - */ - if (sax != NULL) { - if (ctxt->sax != NULL) - xmlFree(ctxt->sax); - ctxt->sax = sax; - ctxt->userData = ctxt; - } - /* * Canonicalise the system ID */ @@ -12841,7 +12780,6 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID, input = ctxt->sax->resolveEntity(ctxt->userData, ExternalID, systemIdCanonic); if (input == NULL) { - if (sax != NULL) ctxt->sax = NULL; xmlFreeParserCtxt(ctxt); if (systemIdCanonic != NULL) xmlFree(systemIdCanonic); @@ -12852,7 +12790,6 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID, * plug some encoding conversion routines here. */ if (xmlPushInput(ctxt, input) < 0) { - if (sax != NULL) ctxt->sax = NULL; xmlFreeParserCtxt(ctxt); if (systemIdCanonic != NULL) xmlFree(systemIdCanonic); @@ -12880,7 +12817,6 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID, ctxt->myDoc = xmlNewDoc(BAD_CAST "1.0"); if (ctxt->myDoc == NULL) { xmlErrMemory(ctxt, "New Doc failed"); - if (sax != NULL) ctxt->sax = NULL; xmlFreeParserCtxt(ctxt); return(NULL); } @@ -12909,7 +12845,6 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID, xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL; } - if (sax != NULL) ctxt->sax = NULL; xmlFreeParserCtxt(ctxt); return(ret); @@ -13000,7 +12935,6 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, xmlParserCtxtPtr ctxt; xmlDocPtr newDoc; xmlNodePtr newRoot; - xmlSAXHandlerPtr oldsax = NULL; xmlParserErrors ret = XML_ERR_OK; xmlChar start[4]; xmlCharEncoding enc; @@ -13018,17 +12952,11 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, if (doc == NULL) return(XML_ERR_INTERNAL_ERROR); - - ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt); + ctxt = xmlCreateEntityParserCtxtInternal(sax, user_data, URL, ID, NULL, + oldctxt); if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY); - ctxt->userData = ctxt; - if (sax != NULL) { - oldsax = ctxt->sax; - ctxt->sax = sax; - if (user_data != NULL) - ctxt->userData = user_data; - } xmlDetectSAX2(ctxt); + newDoc = xmlNewDoc(BAD_CAST "1.0"); if (newDoc == NULL) { xmlFreeParserCtxt(ctxt); @@ -13049,7 +12977,6 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, newRoot = xmlNewDocNode(newDoc, NULL, BAD_CAST "pseudoroot", NULL); if (newRoot == NULL) { if (sax != NULL) - ctxt->sax = oldsax; xmlFreeParserCtxt(ctxt); newDoc->intSubset = NULL; newDoc->extSubset = NULL; @@ -13190,8 +13117,6 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, if ((oldctxt != NULL) && (ctxt->lastError.code != XML_ERR_OK)) xmlCopyError(&ctxt->lastError, &oldctxt->lastError); - if (sax != NULL) - ctxt->sax = oldsax; if (oldctxt != NULL) { ctxt->dict = NULL; ctxt->attsDefault = NULL; @@ -13942,14 +13867,15 @@ xmlParseEntity(const char *filename) { * Returns the new parser context or NULL */ static xmlParserCtxtPtr -xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID, - const xmlChar *base, xmlParserCtxtPtr pctx) { +xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData, + const xmlChar *URL, const xmlChar *ID, const xmlChar *base, + xmlParserCtxtPtr pctx) { xmlParserCtxtPtr ctxt; xmlParserInputPtr inputStream; char *directory = NULL; xmlChar *uri; - ctxt = xmlNewParserCtxt(); + ctxt = xmlNewSAXParserCtxt(sax, userData); if (ctxt == NULL) { return(NULL); } @@ -14017,7 +13943,7 @@ xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID, xmlParserCtxtPtr xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID, const xmlChar *base) { - return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL); + return xmlCreateEntityParserCtxtInternal(NULL, NULL, URL, ID, base, NULL); } diff --git a/parserInternals.c b/parserInternals.c index c3a14ac0..7e3126c9 100644 --- a/parserInternals.c +++ b/parserInternals.c @@ -1439,16 +1439,19 @@ xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) { ************************************************************************/ /** - * xmlInitParserCtxt: - * @ctxt: an XML parser context + * xmlInitSAXParserCtxt: + * @ctxt: XML parser context + * @sax: SAX handlert + * @userData: user data * - * Initialize a parser context + * Initialize a SAX parser context * * Returns 0 in case of success and -1 in case of error */ -int -xmlInitParserCtxt(xmlParserCtxtPtr ctxt) +static int +xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, xmlSAXHandlerPtr sax, + void *userData) { xmlParserInputPtr input; @@ -1473,8 +1476,19 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt) xmlErrMemory(NULL, "cannot initialize parser context\n"); return(-1); } - else + if (sax == NULL) { + memset(ctxt->sax, 0, sizeof(xmlSAXHandler)); xmlSAXVersion(ctxt->sax, 2); + ctxt->userData = ctxt; + } else { + if (sax->initialized == XML_SAX2_MAGIC) { + memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler)); + } else { + memset(ctxt->sax, 0, sizeof(xmlSAXHandler)); + memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1)); + } + ctxt->userData = userData ? userData : ctxt; + } ctxt->maxatts = 0; ctxt->atts = NULL; @@ -1572,7 +1586,6 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt) ctxt->spaceMax = 10; ctxt->spaceTab[0] = -1; ctxt->space = &ctxt->spaceTab[0]; - ctxt->userData = ctxt; ctxt->myDoc = NULL; ctxt->wellFormed = 1; ctxt->nsWellFormed = 1; @@ -1624,6 +1637,24 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt) return(0); } +/** + * xmlInitParserCtxt: + * @ctxt: an XML parser context + * + * DEPRECATED: Internal function which will be made private in a future + * version. + * + * Initialize a parser context + * + * Returns 0 in case of success and -1 in case of error + */ + +int +xmlInitParserCtxt(xmlParserCtxtPtr ctxt) +{ + return(xmlInitSAXParserCtxt(ctxt, NULL, NULL)); +} + /** * xmlFreeParserCtxt: * @ctxt: an XML parser context @@ -1720,6 +1751,22 @@ xmlFreeParserCtxt(xmlParserCtxtPtr ctxt) xmlParserCtxtPtr xmlNewParserCtxt(void) +{ + return(xmlNewSAXParserCtxt(NULL, NULL)); +} + +/** + * xmlNewSAXParserCtxt: + * @sax: SAX handler + * @userData: user data + * + * Allocate and initialize a new SAX parser context. + * + * Returns the xmlParserCtxtPtr or NULL + */ + +xmlParserCtxtPtr +xmlNewSAXParserCtxt(xmlSAXHandlerPtr sax, void *userData) { xmlParserCtxtPtr ctxt; @@ -1729,7 +1776,7 @@ xmlNewParserCtxt(void) return(NULL); } memset(ctxt, 0, sizeof(xmlParserCtxt)); - if (xmlInitParserCtxt(ctxt) < 0) { + if (xmlInitSAXParserCtxt(ctxt, sax, userData) < 0) { xmlFreeParserCtxt(ctxt); return(NULL); } diff --git a/testapi.c b/testapi.c index 769fda6e..e4c25c9d 100644 --- a/testapi.c +++ b/testapi.c @@ -464,8 +464,6 @@ static void des_xmlParserCtxtPtr(int no ATTRIBUTE_UNUSED, xmlParserCtxtPtr val, xmlFreeParserCtxt(val); } -#if defined(LIBXML_PUSH_ENABLED) || defined(LIBXML_SAX1_ENABLED) || \ - defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_VALID_ENABLED) #define gen_nb_xmlSAXHandlerPtr 2 static xmlSAXHandlerPtr gen_xmlSAXHandlerPtr(int no, int nr ATTRIBUTE_UNUSED) { (void) no; @@ -476,7 +474,6 @@ static xmlSAXHandlerPtr gen_xmlSAXHandlerPtr(int no, int nr ATTRIBUTE_UNUSED) { } static void des_xmlSAXHandlerPtr(int no ATTRIBUTE_UNUSED, xmlSAXHandlerPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) { } -#endif #define gen_nb_xmlValidCtxtPtr 2 static xmlValidCtxtPtr gen_xmlValidCtxtPtr(int no, int nr ATTRIBUTE_UNUSED) { @@ -2181,6 +2178,47 @@ test_htmlNewParserCtxt(void) { } +static int +test_htmlNewSAXParserCtxt(void) { + int test_ret = 0; + +#if defined(LIBXML_HTML_ENABLED) + int mem_base; + htmlParserCtxtPtr ret_val; + htmlSAXHandlerPtr sax; /* SAX handler */ + int n_sax; + void * userData; /* user data */ + int n_userData; + + for (n_sax = 0;n_sax < gen_nb_htmlSAXHandlerPtr;n_sax++) { + for (n_userData = 0;n_userData < gen_nb_userdata;n_userData++) { + mem_base = xmlMemBlocks(); + sax = gen_htmlSAXHandlerPtr(n_sax, 0); + userData = gen_userdata(n_userData, 1); + + ret_val = htmlNewSAXParserCtxt(sax, userData); + desret_htmlParserCtxtPtr(ret_val); + call_tests++; + des_htmlSAXHandlerPtr(n_sax, sax, 0); + des_userdata(n_userData, userData, 1); + xmlResetLastError(); + if (mem_base != xmlMemBlocks()) { + printf("Leak of %d blocks found in htmlNewSAXParserCtxt", + xmlMemBlocks() - mem_base); + test_ret++; + printf(" %d", n_sax); + printf(" %d", n_userData); + printf("\n"); + } + } + } + function_tests++; +#endif + + return(test_ret); +} + + static int test_htmlNodeStatus(void) { int test_ret = 0; @@ -2786,7 +2824,7 @@ static int test_HTMLparser(void) { int test_ret = 0; - if (quiet == 0) printf("Testing HTMLparser : 32 of 38 functions ...\n"); + if (quiet == 0) printf("Testing HTMLparser : 33 of 39 functions ...\n"); test_ret += test_UTF8ToHtml(); test_ret += test_htmlAttrAllowed(); test_ret += test_htmlAutoCloseTag(); @@ -2806,6 +2844,7 @@ test_HTMLparser(void) { test_ret += test_htmlIsAutoClosed(); test_ret += test_htmlIsScriptAttribute(); test_ret += test_htmlNewParserCtxt(); + test_ret += test_htmlNewSAXParserCtxt(); test_ret += test_htmlNodeStatus(); test_ret += test_htmlParseCharRef(); test_ret += test_htmlParseChunk(); @@ -12764,6 +12803,45 @@ test_xmlNewParserCtxt(void) { } +static int +test_xmlNewSAXParserCtxt(void) { + int test_ret = 0; + + int mem_base; + xmlParserCtxtPtr ret_val; + xmlSAXHandlerPtr sax; /* SAX handler */ + int n_sax; + void * userData; /* user data */ + int n_userData; + + for (n_sax = 0;n_sax < gen_nb_xmlSAXHandlerPtr;n_sax++) { + for (n_userData = 0;n_userData < gen_nb_userdata;n_userData++) { + mem_base = xmlMemBlocks(); + sax = gen_xmlSAXHandlerPtr(n_sax, 0); + userData = gen_userdata(n_userData, 1); + + ret_val = xmlNewSAXParserCtxt(sax, userData); + desret_xmlParserCtxtPtr(ret_val); + call_tests++; + des_xmlSAXHandlerPtr(n_sax, sax, 0); + des_userdata(n_userData, userData, 1); + xmlResetLastError(); + if (mem_base != xmlMemBlocks()) { + printf("Leak of %d blocks found in xmlNewSAXParserCtxt", + xmlMemBlocks() - mem_base); + test_ret++; + printf(" %d", n_sax); + printf(" %d", n_userData); + printf("\n"); + } + } + } + function_tests++; + + return(test_ret); +} + + #define gen_nb_xmlNodePtr_ptr 1 #define gen_xmlNodePtr_ptr(no, nr) NULL #define des_xmlNodePtr_ptr(no, val, nr) @@ -14587,7 +14665,7 @@ static int test_parser(void) { int test_ret = 0; - if (quiet == 0) printf("Testing parser : 58 of 70 functions ...\n"); + if (quiet == 0) printf("Testing parser : 59 of 71 functions ...\n"); test_ret += test_xmlByteConsumed(); test_ret += test_xmlClearNodeInfoSeq(); test_ret += test_xmlClearParserCtxt(); @@ -14610,6 +14688,7 @@ test_parser(void) { test_ret += test_xmlLoadExternalEntity(); test_ret += test_xmlNewIOInputStream(); test_ret += test_xmlNewParserCtxt(); + test_ret += test_xmlNewSAXParserCtxt(); test_ret += test_xmlParseBalancedChunkMemory(); test_ret += test_xmlParseBalancedChunkMemoryRecover(); test_ret += test_xmlParseChunk(); diff --git a/testlimits.c b/testlimits.c index 0b045eac..a5ed231f 100644 --- a/testlimits.c +++ b/testlimits.c @@ -1261,19 +1261,15 @@ saxTest(const char *filename, size_t limit, int options, int fail) { int res = 0; xmlParserCtxtPtr ctxt; xmlDocPtr doc; - xmlSAXHandlerPtr old_sax; nb_tests++; maxlen = limit; - ctxt = xmlNewParserCtxt(); + ctxt = xmlNewSAXParserCtxt(callbackSAX2Handler, NULL); if (ctxt == NULL) { fprintf(stderr, "Failed to create parser context\n"); return(1); } - old_sax = ctxt->sax; - ctxt->sax = callbackSAX2Handler; - ctxt->userData = NULL; doc = xmlCtxtReadFile(ctxt, filename, NULL, options); if (doc != NULL) { @@ -1296,7 +1292,6 @@ saxTest(const char *filename, size_t limit, int options, int fail) { } else res = 0; } - ctxt->sax = old_sax; xmlFreeParserCtxt(ctxt); return(res); diff --git a/win32/libxml2.def.src b/win32/libxml2.def.src index d83dbf4a..d28fd50d 100644 --- a/win32/libxml2.def.src +++ b/win32/libxml2.def.src @@ -297,6 +297,9 @@ htmlNewDocNoDtD htmlNewParserCtxt #endif #ifdef LIBXML_HTML_ENABLED +htmlNewSAXParserCtxt +#endif +#ifdef LIBXML_HTML_ENABLED htmlNodeDump #endif #ifdef LIBXML_HTML_ENABLED @@ -1214,6 +1217,7 @@ xmlNewParserCtxt xmlNewProp xmlNewRMutex xmlNewReference +xmlNewSAXParserCtxt xmlNewStringInputStream xmlNewText xmlNewTextChild diff --git a/xmllint.c b/xmllint.c index b5dfbd03..0da4a9d8 100644 --- a/xmllint.c +++ b/xmllint.c @@ -1586,10 +1586,6 @@ static void testSAX(const char *filename) { xmlSAXHandlerPtr handler; const char *user_data = "user_data"; /* mostly for debugging */ - xmlParserInputBufferPtr buf = NULL; - xmlParserInputPtr inputStream; - xmlParserCtxtPtr ctxt = NULL; - xmlSAXHandlerPtr old_sax = NULL; callbacks = 0; @@ -1603,24 +1599,22 @@ testSAX(const char *filename) { handler = debugSAX2Handler; } - /* - * it's not the simplest code but the most generic in term of I/O - */ - buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE); - if (buf == NULL) { - goto error; - } - #ifdef LIBXML_SCHEMAS_ENABLED if (wxschemas != NULL) { int ret; xmlSchemaValidCtxtPtr vctxt; + xmlParserInputBufferPtr buf; + + buf = xmlParserInputBufferCreateFilename(filename, + XML_CHAR_ENCODING_NONE); + if (buf == NULL) + return; vctxt = xmlSchemaNewValidCtxt(wxschemas); if (vctxt == NULL) { progresult = XMLLINT_ERR_MEM; xmlFreeParserInputBuffer(buf); - goto error; + return; } xmlSchemaSetValidErrors(vctxt, xmlGenericError, xmlGenericError, NULL); xmlSchemaValidateSetFilename(vctxt, filename); @@ -1645,38 +1639,23 @@ testSAX(const char *filename) { } else #endif { + xmlParserCtxtPtr ctxt = NULL; + /* * Create the parser context amd hook the input */ - ctxt = xmlNewParserCtxt(); + ctxt = xmlNewSAXParserCtxt(handler, (void *) user_data); if (ctxt == NULL) { progresult = XMLLINT_ERR_MEM; - xmlFreeParserInputBuffer(buf); - goto error; + return; } - old_sax = ctxt->sax; - ctxt->sax = handler; - ctxt->userData = (void *) user_data; - inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE); - if (inputStream == NULL) { - xmlFreeParserInputBuffer(buf); - goto error; - } - inputPush(ctxt, inputStream); - - /* do the parsing */ - xmlParseDocument(ctxt); + xmlCtxtReadFile(ctxt, filename, NULL, options); if (ctxt->myDoc != NULL) { fprintf(stderr, "SAX generated a doc !\n"); xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL; } - } - -error: - if (ctxt != NULL) { - ctxt->sax = old_sax; xmlFreeParserCtxt(ctxt); } } diff --git a/xmlschemas.c b/xmlschemas.c index f31d3d1f..ccbd3ea3 100644 --- a/xmlschemas.c +++ b/xmlschemas.c @@ -29063,7 +29063,6 @@ xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, xmlSAXHandlerPtr sax, void *user_data) { xmlSchemaSAXPlugPtr plug = NULL; - xmlSAXHandlerPtr old_sax = NULL; xmlParserCtxtPtr pctxt = NULL; xmlParserInputPtr inputStream = NULL; int ret; @@ -29074,12 +29073,9 @@ xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt, /* * prepare the parser */ - pctxt = xmlNewParserCtxt(); + pctxt = xmlNewSAXParserCtxt(sax, user_data); if (pctxt == NULL) return (-1); - old_sax = pctxt->sax; - pctxt->sax = sax; - pctxt->userData = user_data; #if 0 if (options) xmlCtxtUseOptions(pctxt, options); @@ -29125,7 +29121,6 @@ done: } /* cleanup */ if (pctxt != NULL) { - pctxt->sax = old_sax; xmlFreeParserCtxt(pctxt); } return (ret);