diff --git a/ChangeLog b/ChangeLog index f23bea5b..173a0c53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +Tue Sep 23 23:07:45 CEST 2003 Daniel Veillard + + * parser.c include/libxml/parser.h: adding a new set of + API for parsing xmlReadDoc() xmlReadFile() ... xmlReadIO() + and xmlCtxtReadDoc() ... xmlCtxtReadIO(). That with + a clear define of xmlParserOption, xmlCtxtUseOptions() + should simplify custom parsing without being tempted to + use global variables, and xmlCtxtReset() should allow reuse + of a context for multiple parsing. + * xmllint.c: switched to use xmlReadXXX, allow options to + be used simultaneously with less troubles. + * tree.c: simple warning removal + * doc/apibuild.py: small fix + * doc/libxml2-api.xml win32/libxml2.def.src: updated + Tue Sep 23 11:15:23 CEST 2003 Daniel Veillard * parser.c: revert xmlCreateDocParserCtxt() since this break diff --git a/doc/apibuild.py b/doc/apibuild.py index 4b12d09a..59cc0cf2 100755 --- a/doc/apibuild.py +++ b/doc/apibuild.py @@ -1325,7 +1325,11 @@ class docBuilder: if id.info != None: info = id.info if info[0] != None and info[0] != '': - output.write(" value='%s'" % info[0]); + try: + val = eval(info[0]) + except: + val = info[0] + output.write(" value='%s'" % (val)); if info[2] != None and info[2] != '': output.write(" type='%s'" % info[2]); if info[1] != None and info[1] != '': diff --git a/doc/libxml2-api.xml b/doc/libxml2-api.xml index d6811813..344009e3 100644 --- a/doc/libxml2-api.xml +++ b/doc/libxml2-api.xml @@ -1053,6 +1053,18 @@ + + + + + + + + + + + + @@ -1099,12 +1111,18 @@ + + + + + + + - @@ -1136,8 +1154,13 @@ - + + + + + + @@ -1170,7 +1193,6 @@ - @@ -1300,6 +1322,7 @@ + @@ -2654,11 +2677,11 @@ Check if the current value on the XPath stack is a node set or an XSLT value tree. Returns true if the current object on the stack is a node-set. - - + + - - + + @@ -2746,7 +2769,7 @@ - + @@ -2757,17 +2780,17 @@ - + - - + + - - + + @@ -2775,7 +2798,7 @@ - + @@ -2783,16 +2806,16 @@ - - - + + + - + - + @@ -2800,14 +2823,14 @@ - + - + - - + + @@ -2820,15 +2843,15 @@ - + - + - - + + - + @@ -2836,10 +2859,10 @@ - + - + @@ -2879,6 +2902,18 @@ + + + + + + + + + + + + @@ -3511,6 +3546,7 @@ actually an xmlCharEncoding'/> + @@ -3852,7 +3888,7 @@ actually an xmlCharEncoding'/> - + @@ -3861,7 +3897,7 @@ actually an xmlCharEncoding'/> - + @@ -3869,7 +3905,7 @@ actually an xmlCharEncoding'/> - + @@ -5606,7 +5642,7 @@ actually an xmlCharEncoding'/> Creates a parser context for an XML in-memory document. - + create and initialize an empty entities hash table. @@ -5666,6 +5702,60 @@ actually an xmlCharEncoding'/> Simply creates an empty xmlURI + + parse an XML in-memory document and build a tree. This reuses the existing @ctxt parser context + + + + + + + + parse an XML from a file descriptor and build a tree. This reuses the existing @ctxt parser context + + + + + + + + parse an XML file from the filesystem or the network. This reuses the existing @ctxt parser context + + + + + + + + parse an XML document from I/O functions and source and build a tree. This reuses the existing @ctxt parser context + + + + + + + + + + parse an XML in-memory document and build a tree. This reuses the existing @ctxt parser context + + + + + + + + + Reset a parser context + + + + + Applies the options to the parser context + + + + The current char value, if using UTF-8 this may actually span multiple bytes in the input buffer. Implement the end of line normalization: 2.11 End-of-Line Handling Wherever an external parsed entity or the literal entity value of an internal parsed entity contains either the literal two-character sequence "#xD#xA" or a standalone literal #xD, an XML processor must pass to the application the single character #xA. This behavior can conveniently be produced by normalizing all line breaks to #xA on input, before parsing.) @@ -7615,7 +7705,7 @@ actually an xmlCharEncoding'/> Set (or reset) the base URI of a node, i.e. the value of the xml:base attribute. - + Replace the content of a node. @@ -8264,6 +8354,44 @@ actually an xmlCharEncoding'/> + + parse an XML in-memory document and build a tree. + + + + + + + parse an XML from a file descriptor and build a tree. + + + + + + + parse an XML file from the filesystem or the network. + + + + + + + parse an XML document from I/O functions and source and build a tree. + + + + + + + + + parse an XML in-memory document and build a tree. + + + + + + Signature for a realloc() implementation. @@ -9569,6 +9697,12 @@ actually an xmlCharEncoding'/> + + Get an interned string from the reader, allows for example to speedup string name comparisons + + + + diff --git a/include/libxml/parser.h b/include/libxml/parser.h index 974d0d0e..4ddaa69f 100644 --- a/include/libxml/parser.h +++ b/include/libxml/parser.h @@ -725,30 +725,6 @@ typedef xmlParserInputPtr (*xmlExternalEntityLoader) (const char *URL, const char *ID, xmlParserCtxtPtr context); -/* - * Global variables: just the default SAX interface tables and XML - * version infos. - */ -#if 0 -LIBXML_DLL_IMPORT extern const char *xmlParserVersion; -#endif - -/* -LIBXML_DLL_IMPORT extern xmlSAXLocator xmlDefaultSAXLocator; -LIBXML_DLL_IMPORT extern xmlSAXHandler xmlDefaultSAXHandler; -LIBXML_DLL_IMPORT extern xmlSAXHandler htmlDefaultSAXHandler; -LIBXML_DLL_IMPORT extern xmlSAXHandler docbDefaultSAXHandler; - */ - -/* - * Entity substitution default behavior. - */ - -#if 0 -LIBXML_DLL_IMPORT extern int xmlSubstituteEntitiesDefaultValue; -LIBXML_DLL_IMPORT extern int xmlGetWarningsDefaultValue; -#endif - #ifdef __cplusplus } #endif @@ -968,7 +944,7 @@ XMLPUBFUN void XMLCALL const xmlChar* buffer, const char *filename); XMLPUBFUN xmlParserCtxtPtr XMLCALL - xmlCreateDocParserCtxt (xmlChar *cur); + xmlCreateDocParserCtxt (const xmlChar *cur); /* * Reading/setting optional parsing features. @@ -1047,6 +1023,86 @@ XMLPUBFUN xmlParserInputPtr XMLCALL xmlLoadExternalEntity (const char *URL, const char *ID, xmlParserCtxtPtr ctxt); +/* + * New set of simpler/more flexible APIs + */ +/** + * xmlParserOption: + * + * This is the set of XML parser options that can be passed down + * to the xmlReadDoc() and similar calls. + */ +typedef enum { + XML_PARSE_RECOVER = 1<<0, /* recover on errors */ + XML_PARSE_NOENT = 1<<1, /* substitute entities */ + XML_PARSE_DTDLOAD = 1<<2, /* load the external subset */ + XML_PARSE_DTDATTR = 1<<3, /* default DTD attributes */ + XML_PARSE_DTDVALID = 1<<4, /* validate with the DTD */ + XML_PARSE_NOERROR = 1<<5, /* suppress error reports */ + XML_PARSE_NOWARNING = 1<<6, /* suppress warning reports */ + XML_PARSE_PEDANTIC = 1<<7, /* pedantic error reporting */ + XML_PARSE_NOBLANKS = 1<<8, /* remove blank nodes */ + XML_PARSE_SAX1 = 1<<9, /* use the SAX1 interface internally */ + XML_PARSE_XINCLUDE = 1<<10,/* Implement XInclude substitition */ + XML_PARSE_NONET = 1<<11 /* Forbid network access */ +} xmlParserOption; + +XMLPUBFUN void XMLCALL + xmlCtxtReset (xmlParserCtxtPtr ctxt); +XMLPUBFUN int XMLCALL + xmlCtxtUseOptions (xmlParserCtxtPtr ctxt, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlReadDoc (const xmlChar *cur, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlReadFile (const char *filename, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlReadMemory (const char *buffer, + int size, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlReadFd (int fd, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlReadIO (xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlCtxtReadDoc (xmlParserCtxtPtr ctxt, + const xmlChar *cur, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlCtxtReadFile (xmlParserCtxtPtr ctxt, + const char *filename, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlCtxtReadMemory (xmlParserCtxtPtr ctxt, + const char *buffer, + int size, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlCtxtReadFd (xmlParserCtxtPtr ctxt, + int fd, + const char *encoding, + int options); +XMLPUBFUN xmlDocPtr XMLCALL + xmlCtxtReadIO (xmlParserCtxtPtr ctxt, + xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, + void *ioctx, + const char *encoding, + int options); #ifdef __cplusplus } diff --git a/parser.c b/parser.c index f3b72e3d..deace020 100644 --- a/parser.c +++ b/parser.c @@ -11740,13 +11740,13 @@ int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data, * Returns the new parser context or NULL */ xmlParserCtxtPtr -xmlCreateDocParserCtxt(xmlChar *cur) { +xmlCreateDocParserCtxt(const xmlChar *cur) { int len; if (cur == NULL) return(NULL); len = xmlStrlen(cur); - return(xmlCreateMemoryParserCtxt((char *)cur, len)); + return(xmlCreateMemoryParserCtxt((const char *)cur, len)); } /** @@ -11918,3 +11918,525 @@ xmlCleanupParser(void) { xmlCleanupGlobals(); xmlParserInitialized = 0; } + +/************************************************************************ + * * + * New set (2.6.0) of simpler and more flexible APIs * + * * + ************************************************************************/ + +/** + * xmlCtxtReset: + * @ctxt: an XML parser context + * + * Reset a parser context + */ +void +xmlCtxtReset(xmlParserCtxtPtr ctxt) +{ + xmlParserInputPtr input; + + while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */ + xmlFreeInputStream(input); + } + ctxt->inputNr = 0; + ctxt->input = NULL; + + ctxt->spaceNr = 0; + ctxt->spaceTab[0] = -1; + ctxt->space = &ctxt->spaceTab[0]; + + + ctxt->nodeNr = 0; + ctxt->node = NULL; + + ctxt->nameNr = 0; + ctxt->name = NULL; + + ctxt->version = NULL; + ctxt->encoding = NULL; + ctxt->standalone = -1; + ctxt->hasExternalSubset = 0; + ctxt->hasPErefs = 0; + ctxt->html = 0; + ctxt->external = 0; + ctxt->instate = XML_PARSER_START; + ctxt->token = 0; + ctxt->directory = NULL; + + ctxt->myDoc = NULL; + ctxt->wellFormed = 1; + ctxt->nsWellFormed = 1; + ctxt->valid = 1; + ctxt->vctxt.userData = ctxt; + ctxt->vctxt.error = xmlParserValidityError; + ctxt->vctxt.warning = xmlParserValidityWarning; + ctxt->record_info = 0; + ctxt->nbChars = 0; + ctxt->checkIndex = 0; + ctxt->inSubset = 0; + ctxt->errNo = XML_ERR_OK; + ctxt->depth = 0; + ctxt->charset = XML_CHAR_ENCODING_UTF8; + ctxt->catalogs = NULL; + xmlInitNodeInfoSeq(&ctxt->node_seq); + + if (ctxt->attsDefault != NULL) { + xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree); + ctxt->attsDefault = NULL; + } + if (ctxt->attsSpecial != NULL) { + xmlHashFree(ctxt->attsSpecial, NULL); + ctxt->attsSpecial = NULL; + } + + if (ctxt->catalogs != NULL) + xmlCatalogFreeLocal(ctxt->catalogs); +} + +/** + * xmlCtxtUseOptions: + * @ctxt: an XML parser context + * @options: a combination of xmlParserOption(s) + * + * Applies the options to the parser context + * + * Returns 0 in case of success, the set of unknown or unimplemented options + * in case of error. + */ +int +xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options) +{ + if (options & XML_PARSE_RECOVER) { + ctxt->recovery = 1; + options -= XML_PARSE_RECOVER; + } else + ctxt->recovery = 0; + if (options & XML_PARSE_DTDLOAD) { + ctxt->loadsubset = XML_DETECT_IDS; + options -= XML_PARSE_DTDLOAD; + } else + ctxt->loadsubset = 0; + if (options & XML_PARSE_DTDATTR) { + ctxt->loadsubset |= XML_COMPLETE_ATTRS; + options -= XML_PARSE_DTDATTR; + } + if (options & XML_PARSE_NOENT) { + ctxt->replaceEntities = 1; + /* ctxt->loadsubset |= XML_DETECT_IDS; */ + options -= XML_PARSE_NOENT; + } else + ctxt->replaceEntities = 0; + if (options & XML_PARSE_NOWARNING) { + ctxt->sax->warning = NULL; + options -= XML_PARSE_NOWARNING; + } + if (options & XML_PARSE_NOERROR) { + ctxt->sax->error = NULL; + ctxt->sax->fatalError = NULL; + options -= XML_PARSE_NOERROR; + } + if (options & XML_PARSE_PEDANTIC) { + ctxt->pedantic = 1; + options -= XML_PARSE_PEDANTIC; + } else + ctxt->pedantic = 0; + if (options & XML_PARSE_NOBLANKS) { + ctxt->keepBlanks = 0; + ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace; + options -= XML_PARSE_NOBLANKS; + } else + ctxt->keepBlanks = 1; + if (options & XML_PARSE_DTDVALID) { + ctxt->validate = 1; + if (options & XML_PARSE_NOWARNING) + ctxt->vctxt.warning = NULL; + if (options & XML_PARSE_NOERROR) + ctxt->vctxt.error = NULL; + options -= XML_PARSE_DTDVALID; + } else + ctxt->validate = 0; + if (options & XML_PARSE_SAX1) { + ctxt->sax->startElement = xmlSAX2StartElement; + ctxt->sax->endElement = xmlSAX2EndElement; + ctxt->sax->startElementNs = NULL; + ctxt->sax->endElementNs = NULL; + ctxt->sax->initialized = 1; + options -= XML_PARSE_SAX1; + } + return (options); +} + +/** + * xmlDoRead: + * @ctxt: an XML parser context + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * @reuse: keep the context for reuse + * + * Common front-end for the xmlRead functions + * + * Returns the resulting document tree or NULL + */ +static xmlDocPtr +xmlDoRead(xmlParserCtxtPtr ctxt, const char *encoding, int options, int reuse) +{ + xmlDocPtr ret; + + xmlCtxtUseOptions(ctxt, options); + if (encoding != NULL) { + xmlCharEncodingHandlerPtr hdlr; + + hdlr = xmlFindCharEncodingHandler(encoding); + if (hdlr != NULL) + xmlSwitchToEncoding(ctxt, hdlr); + } + xmlParseDocument(ctxt); + if ((ctxt->wellFormed) || ctxt->recovery) + ret = ctxt->myDoc; + else { + ret = NULL; + xmlFreeDoc(ctxt->myDoc); + ctxt->myDoc = NULL; + } + if (!reuse) + xmlFreeParserCtxt(ctxt); + + return (ret); +} + +/** + * xmlReadDoc: + * @cur: a pointer to a zero terminated string + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML in-memory document and build a tree. + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlReadDoc(const xmlChar * cur, const char *encoding, int options) +{ + xmlParserCtxtPtr ctxt; + + if (cur == NULL) + return (NULL); + + ctxt = xmlCreateDocParserCtxt(cur); + if (ctxt == NULL) + return (NULL); + return (xmlDoRead(ctxt, encoding, options, 0)); +} + +/** + * xmlReadFile: + * @filename: a file or URL + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML file from the filesystem or the network. + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlReadFile(const char *filename, const char *encoding, int options) +{ + xmlParserCtxtPtr ctxt; + + ctxt = xmlCreateFileParserCtxt(filename); + if (ctxt == NULL) + return (NULL); + return (xmlDoRead(ctxt, encoding, options, 0)); +} + +/** + * xmlReadMemory: + * @buffer: a pointer to a char array + * @size: the size of the array + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML in-memory document and build a tree. + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlReadMemory(const char *buffer, int size, const char *encoding, int options) +{ + xmlParserCtxtPtr ctxt; + + ctxt = xmlCreateMemoryParserCtxt(buffer, size); + if (ctxt == NULL) + return (NULL); + return (xmlDoRead(ctxt, encoding, options, 0)); +} + +/** + * xmlReadFd: + * @fd: an open file descriptor + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML from a file descriptor and build a tree. + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlReadFd(int fd, const char *encoding, int options) +{ + xmlParserCtxtPtr ctxt; + xmlParserInputBufferPtr input; + xmlParserInputPtr stream; + + if (fd < 0) + return (NULL); + + input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE); + if (input == NULL) + return (NULL); + ctxt = xmlNewParserCtxt(); + if (ctxt == NULL) { + xmlFreeParserInputBuffer(input); + return (NULL); + } + stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); + if (stream == NULL) { + xmlFreeParserInputBuffer(input); + xmlFreeParserCtxt(ctxt); + return (NULL); + } + inputPush(ctxt, stream); + return (xmlDoRead(ctxt, encoding, options, 0)); +} + +/** + * xmlReadIO: + * @ioread: an I/O read function + * @ioclose: an I/O close function + * @ioctx: an I/O handler + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML document from I/O functions and source and build a tree. + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose, + void *ioctx, const char *encoding, int options) +{ + xmlParserCtxtPtr ctxt; + xmlParserInputBufferPtr input; + xmlParserInputPtr stream; + + if (ioread == NULL) + return (NULL); + + input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, + XML_CHAR_ENCODING_NONE); + if (input == NULL) + return (NULL); + ctxt = xmlNewParserCtxt(); + if (ctxt == NULL) { + xmlFreeParserInputBuffer(input); + return (NULL); + } + stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); + if (stream == NULL) { + xmlFreeParserInputBuffer(input); + xmlFreeParserCtxt(ctxt); + return (NULL); + } + inputPush(ctxt, stream); + return (xmlDoRead(ctxt, encoding, options, 0)); +} + +/** + * xmlCtxtReadDoc: + * @ctxt: an XML parser context + * @cur: a pointer to a zero terminated string + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML in-memory document and build a tree. + * This reuses the existing @ctxt parser context + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur, + const char *encoding, int options) +{ + xmlParserInputPtr stream; + + if (cur == NULL) + return (NULL); + if (ctxt == NULL) + return (NULL); + + xmlCtxtReset(ctxt); + + stream = xmlNewStringInputStream(ctxt, cur); + if (stream == NULL) { + return (NULL); + } + inputPush(ctxt, stream); + return (xmlDoRead(ctxt, encoding, options, 1)); +} + +/** + * xmlCtxtReadFile: + * @ctxt: an XML parser context + * @filename: a file or URL + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML file from the filesystem or the network. + * This reuses the existing @ctxt parser context + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlCtxtReadFile(xmlParserCtxtPtr ctxt, const char *filename, + const char *encoding, int options) +{ + xmlParserInputPtr stream; + + if (filename == NULL) + return (NULL); + if (ctxt == NULL) + return (NULL); + + xmlCtxtReset(ctxt); + + stream = xmlNewInputFromFile(ctxt, filename); + if (stream == NULL) { + return (NULL); + } + inputPush(ctxt, stream); + return (xmlDoRead(ctxt, encoding, options, 1)); +} + +/** + * xmlCtxtReadMemory: + * @ctxt: an XML parser context + * @buffer: a pointer to a char array + * @size: the size of the array + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML in-memory document and build a tree. + * This reuses the existing @ctxt parser context + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size, + const char *encoding, int options) +{ + xmlParserInputBufferPtr input; + xmlParserInputPtr stream; + + if (ctxt == NULL) + return (NULL); + if (buffer == NULL) + return (NULL); + + xmlCtxtReset(ctxt); + + input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE); + if (input == NULL) { + return(NULL); + } + + stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); + if (stream == NULL) { + xmlFreeParserInputBuffer(input); + return(NULL); + } + + inputPush(ctxt, stream); + return (xmlDoRead(ctxt, encoding, options, 1)); +} + +/** + * xmlCtxtReadFd: + * @ctxt: an XML parser context + * @fd: an open file descriptor + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML from a file descriptor and build a tree. + * This reuses the existing @ctxt parser context + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlCtxtReadFd(xmlParserCtxtPtr ctxt, int fd, const char *encoding, + int options) +{ + xmlParserInputBufferPtr input; + xmlParserInputPtr stream; + + if (fd < 0) + return (NULL); + if (ctxt == NULL) + return (NULL); + + xmlCtxtReset(ctxt); + + + input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE); + if (input == NULL) + return (NULL); + stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); + if (stream == NULL) { + xmlFreeParserInputBuffer(input); + return (NULL); + } + inputPush(ctxt, stream); + return (xmlDoRead(ctxt, encoding, options, 1)); +} + +/** + * xmlCtxtReadIO: + * @ctxt: an XML parser context + * @ioread: an I/O read function + * @ioclose: an I/O close function + * @ioctx: an I/O handler + * @encoding: the document encoding, or NULL + * @options: a combination of xmlParserOption(s) + * + * parse an XML document from I/O functions and source and build a tree. + * This reuses the existing @ctxt parser context + * + * Returns the resulting document tree + */ +xmlDocPtr +xmlCtxtReadIO(xmlParserCtxtPtr ctxt, xmlInputReadCallback ioread, + xmlInputCloseCallback ioclose, void *ioctx, + const char *encoding, int options) +{ + xmlParserInputBufferPtr input; + xmlParserInputPtr stream; + + if (ioread == NULL) + return (NULL); + if (ctxt == NULL) + return (NULL); + + xmlCtxtReset(ctxt); + + input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx, + XML_CHAR_ENCODING_NONE); + if (input == NULL) + return (NULL); + stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); + if (stream == NULL) { + xmlFreeParserInputBuffer(input); + return (NULL); + } + inputPush(ctxt, stream); + return (xmlDoRead(ctxt, encoding, options, 1)); +} diff --git a/python/libxml2class.txt b/python/libxml2class.txt index 639d4089..2bb38c5d 100644 --- a/python/libxml2class.txt +++ b/python/libxml2class.txt @@ -110,6 +110,10 @@ parseEntity() parseFile() parseMemory() pedanticParserDefault() +readDoc() +readFd() +readFile() +readMemory() recoverDoc() recoverFile() recoverMemory() @@ -655,6 +659,7 @@ Class xmlTextReader(xmlTextReaderCore) ConstName() ConstNamespaceUri() ConstPrefix() + ConstString() ConstXmlLang() CurrentDoc() CurrentNode() @@ -815,6 +820,12 @@ Class parserCtxt(parserCtxtCore) # functions from module parser clearParserCtxt() + ctxtReadDoc() + ctxtReadFd() + ctxtReadFile() + ctxtReadMemory() + ctxtReset() + ctxtUseOptions() initParserCtxt() parseChunk() parseDocument() diff --git a/tree.c b/tree.c index 8fc7e854..0fcfedfc 100644 --- a/tree.c +++ b/tree.c @@ -6406,7 +6406,7 @@ xmlBufferEmpty(xmlBufferPtr buf) { if (buf->content == NULL) return; buf->use = 0; if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) { - buf->content = ""; + buf->content = BAD_CAST ""; } else { memset(buf->content, 0, buf->size); } diff --git a/win32/libxml2.def.src b/win32/libxml2.def.src index 68a00cd0..7710eb05 100644 --- a/win32/libxml2.def.src +++ b/win32/libxml2.def.src @@ -489,6 +489,7 @@ xmlBufferCat xmlBufferContent xmlBufferCreate xmlBufferCreateSize +xmlBufferCreateStatic xmlBufferDump xmlBufferEmpty xmlBufferFree @@ -624,6 +625,13 @@ xmlCreateIntSubset xmlCreateMemoryParserCtxt xmlCreatePushParserCtxt xmlCreateURI +xmlCtxtReadDoc +xmlCtxtReadFd +xmlCtxtReadFile +xmlCtxtReadIO +xmlCtxtReadMemory +xmlCtxtReset +xmlCtxtUseOptions xmlCurrentChar #ifdef LIBXML_DEBUG_ENABLED xmlDebugDumpAttr @@ -663,6 +671,8 @@ xmlDetectCharEncoding xmlDictCreate xmlDictFree xmlDictLookup +xmlDictOwns +xmlDictQLookup xmlDictSize xmlDocCopyNode xmlDocDump @@ -765,6 +775,9 @@ xmlHashFree xmlHashLookup xmlHashLookup2 xmlHashLookup3 +xmlHashQLookup +xmlHashQLookup2 +xmlHashQLookup3 xmlHashRemoveEntry xmlHashRemoveEntry2 xmlHashRemoveEntry3 @@ -1160,6 +1173,7 @@ xmlParserInputBufferCreateFile xmlParserInputBufferCreateFilename xmlParserInputBufferCreateIO xmlParserInputBufferCreateMem +xmlParserInputBufferCreateStatic xmlParserInputBufferGrow xmlParserInputBufferPush xmlParserInputBufferRead @@ -1177,6 +1191,11 @@ xmlPrintURI xmlPushInput xmlRMutexLock xmlRMutexUnlock +xmlReadDoc +xmlReadFd +xmlReadFile +xmlReadIO +xmlReadMemory #ifdef DEBUG_MEMORY_LOCATION xmlReallocLoc #endif @@ -1284,6 +1303,45 @@ xmlRemoveID xmlRemoveProp xmlRemoveRef xmlReplaceNode +xmlSAX2AttributeDecl +xmlSAX2CDataBlock +xmlSAX2Characters +xmlSAX2CheckNamespace +xmlSAX2Comment +xmlSAX2ElementDecl +xmlSAX2EndDocument +xmlSAX2EndElement +xmlSAX2EndElementNs +xmlSAX2EntityDecl +xmlSAX2ExternalSubset +xmlSAX2GetColumnNumber +xmlSAX2GetEntity +xmlSAX2GetLineNumber +xmlSAX2GetNamespace +xmlSAX2GetParameterEntity +xmlSAX2GetPublicId +xmlSAX2GetSystemId +xmlSAX2GlobalNamespace +xmlSAX2HasExternalSubset +xmlSAX2HasInternalSubset +xmlSAX2IgnorableWhitespace +xmlSAX2InitDefaultSAXHandler +xmlSAX2InitDocbDefaultSAXHandler +xmlSAX2InitHtmlDefaultSAXHandler +xmlSAX2InternalSubset +xmlSAX2IsStandalone +xmlSAX2NamespaceDecl +xmlSAX2NotationDecl +xmlSAX2ProcessingInstruction +xmlSAX2Reference +xmlSAX2ResolveEntity +xmlSAX2SetDocumentLocator +xmlSAX2SetNamespace +xmlSAX2StartDocument +xmlSAX2StartElement +xmlSAX2StartElementNs +xmlSAX2UnparsedEntityDecl +xmlSAXDefaultVersion xmlSAXParseDTD xmlSAXParseDoc xmlSAXParseEntity @@ -1293,6 +1351,7 @@ xmlSAXParseMemory xmlSAXParseMemoryWithData xmlSAXUserParseFile xmlSAXUserParseMemory +xmlSAXVersion xmlSaveFile xmlSaveFileEnc xmlSaveFileTo @@ -1436,6 +1495,7 @@ xmlSplitQName3 xmlSprintfElementContent xmlStopParser xmlStrEqual +xmlStrQEqual xmlStrcasecmp xmlStrcasestr xmlStrcat @@ -1445,6 +1505,7 @@ xmlStrdup xmlStringCurrentChar xmlStringDecodeEntities xmlStringGetNodeList +xmlStringLenDecodeEntities xmlStringLenGetNodeList xmlStrlen xmlStrncasecmp @@ -1461,6 +1522,13 @@ xmlTextMerge xmlTextReaderAttributeCount xmlTextReaderBaseUri xmlTextReaderClose +xmlTextReaderConstBaseUri +xmlTextReaderConstLocalName +xmlTextReaderConstName +xmlTextReaderConstNamespaceUri +xmlTextReaderConstPrefix +xmlTextReaderConstString +xmlTextReaderConstXmlLang xmlTextReaderCurrentDoc xmlTextReaderCurrentNode xmlTextReaderDepth diff --git a/xmllint.c b/xmllint.c index a734ff05..5f6893b4 100644 --- a/xmllint.c +++ b/xmllint.c @@ -144,6 +144,7 @@ static int stream = 0; static int chkregister = 0; static int sax1 = 0; static const char *output = NULL; +static int options = 0; /* * Internal timing routines to remove the necessity to have unix-specific @@ -804,73 +805,34 @@ static void parseAndPrintFile(char *filename) { } } } else if (testIO) { - int ret; - FILE *f; - - /* '-' Usually means stdin - */ if ((filename[0] == '-') && (filename[1] == 0)) { - f = stdin; + doc = xmlReadFd(0, NULL, options); } else { - f = fopen(filename, "r"); - } - if (f != NULL) { - xmlParserCtxtPtr ctxt; + FILE *f; - ctxt = xmlCreateIOParserCtxt(NULL, NULL, - (xmlInputReadCallback) myRead, - (xmlInputCloseCallback) myClose, - f, XML_CHAR_ENCODING_NONE); - xmlParseDocument(ctxt); - - ret = ctxt->wellFormed; - doc = ctxt->myDoc; - xmlFreeParserCtxt(ctxt); - if (!ret) { - xmlFreeDoc(doc); + f = fopen(filename, "r"); + if (f != NULL) + doc = xmlReadIO((xmlInputReadCallback) myRead, + (xmlInputCloseCallback) myClose, f, + NULL, options); + else doc = NULL; - } } - } else if (recovery) { - doc = xmlRecoverFile(filename); } else if (htmlout) { - int ret; xmlParserCtxtPtr ctxt; - xmlSAXHandler silent, *old; - - ctxt = xmlCreateFileParserCtxt(filename); + ctxt = xmlNewParserCtxt(); if (ctxt == NULL) { - /* If xmlCreateFileParserCtxt() return NULL something - strange happened so we don't want to do anything. Do - we want to print an error message here? - */ - doc = NULL; + doc = NULL; } else { - memcpy(&silent, ctxt->sax, sizeof(silent)); - old = ctxt->sax; - silent.error = xmlHTMLError; - if (xmlGetWarningsDefaultValue) - silent.warning = xmlHTMLWarning; - else - silent.warning = NULL; - silent.fatalError = xmlHTMLError; - ctxt->sax = &silent; - ctxt->vctxt.error = xmlHTMLValidityError; - if (xmlGetWarningsDefaultValue) - ctxt->vctxt.warning = xmlHTMLValidityWarning; - else - ctxt->vctxt.warning = NULL; + ctxt->sax->error = xmlHTMLError; + ctxt->sax->warning = xmlHTMLWarning; + ctxt->vctxt.error = xmlHTMLValidityError; + ctxt->vctxt.warning = xmlHTMLValidityWarning; - xmlParseDocument(ctxt); + doc = xmlCtxtReadFile(ctxt, filename, NULL, options); - ret = ctxt->wellFormed; - doc = ctxt->myDoc; - ctxt->sax = old; - xmlFreeParserCtxt(ctxt); - if (!ret) { - xmlFreeDoc(doc); - doc = NULL; - } + xmlFreeParserCtxt(ctxt); } #ifdef HAVE_SYS_MMAN_H } else if (memory) { @@ -885,31 +847,24 @@ static void parseAndPrintFile(char *filename) { if (base == (void *) MAP_FAILED) return; - doc = xmlParseMemory((char *) base, info.st_size); + doc = xmlReadMemory((char *) base, info.st_size, NULL, options); munmap((char *) base, info.st_size); #endif } else if (valid) { - int ret; xmlParserCtxtPtr ctxt; - ctxt = xmlCreateFileParserCtxt(filename); - + ctxt = xmlNewParserCtxt(); if (ctxt == NULL) { - doc = NULL; + doc = NULL; } else { - xmlParseDocument(ctxt); - if (ctxt->valid == 0) - progresult = 4; - ret = ctxt->wellFormed; - doc = ctxt->myDoc; - xmlFreeParserCtxt(ctxt); - if (!ret) { - xmlFreeDoc(doc); - doc = NULL; - } + doc = xmlCtxtReadFile(ctxt, filename, NULL, options); + + if (ctxt->valid == 0) + progresult = 4; + xmlFreeParserCtxt(ctxt); } } else { - doc = xmlParseFile(filename); + doc = xmlReadFile(filename, NULL, options); } } @@ -1385,12 +1340,14 @@ main(int argc, char **argv) { if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy"))) copy++; else if ((!strcmp(argv[i], "-recover")) || - (!strcmp(argv[i], "--recover"))) + (!strcmp(argv[i], "--recover"))) { recovery++; - else if ((!strcmp(argv[i], "-noent")) || - (!strcmp(argv[i], "--noent"))) + options |= XML_PARSE_RECOVER; + } else if ((!strcmp(argv[i], "-noent")) || + (!strcmp(argv[i], "--noent"))) { noent++; - else if ((!strcmp(argv[i], "-version")) || + options |= XML_PARSE_NOENT; + } else if ((!strcmp(argv[i], "-version")) || (!strcmp(argv[i], "--version"))) { showVersion(argv[0]); version = 1; @@ -1416,16 +1373,19 @@ main(int argc, char **argv) { (!strcmp(argv[i], "--nowrap"))) nowrap++; else if ((!strcmp(argv[i], "-loaddtd")) || - (!strcmp(argv[i], "--loaddtd"))) + (!strcmp(argv[i], "--loaddtd"))) { loaddtd++; - else if ((!strcmp(argv[i], "-dtdattr")) || + options |= XML_PARSE_DTDLOAD; + } else if ((!strcmp(argv[i], "-dtdattr")) || (!strcmp(argv[i], "--dtdattr"))) { loaddtd++; dtdattrs++; + options |= XML_PARSE_DTDATTR; } else if ((!strcmp(argv[i], "-valid")) || - (!strcmp(argv[i], "--valid"))) + (!strcmp(argv[i], "--valid"))) { valid++; - else if ((!strcmp(argv[i], "-postvalid")) || + options |= XML_PARSE_DTDVALID; + } else if ((!strcmp(argv[i], "-postvalid")) || (!strcmp(argv[i], "--postvalid"))) { postvalid++; loaddtd++; @@ -1471,8 +1431,10 @@ main(int argc, char **argv) { testIO++; #ifdef LIBXML_XINCLUDE_ENABLED else if ((!strcmp(argv[i], "-xinclude")) || - (!strcmp(argv[i], "--xinclude"))) + (!strcmp(argv[i], "--xinclude"))) { xinclude++; + /* options |= XML_PARSE_XINCLUDE; */ + } #endif #ifdef HAVE_ZLIB_H else if ((!strcmp(argv[i], "-compress")) || @@ -1485,11 +1447,13 @@ main(int argc, char **argv) { (!strcmp(argv[i], "--nowarning"))) { xmlGetWarningsDefaultValue = 0; xmlPedanticParserDefault(0); + options |= XML_PARSE_NOWARNING; } else if ((!strcmp(argv[i], "-pedantic")) || (!strcmp(argv[i], "--pedantic"))) { xmlGetWarningsDefaultValue = 1; xmlPedanticParserDefault(1); + options |= XML_PARSE_PEDANTIC; } #ifdef LIBXML_DEBUG_ENABLED else if ((!strcmp(argv[i], "-debugent")) || @@ -1544,6 +1508,7 @@ main(int argc, char **argv) { i++; relaxng = argv[i]; noent++; + options |= XML_PARSE_NOENT; } else if ((!strcmp(argv[i], "-schema")) || (!strcmp(argv[i], "--schema"))) { i++; @@ -1617,6 +1582,7 @@ main(int argc, char **argv) { /* forces loading the DTDs */ xmlLoadExtDtdDefaultValue |= 1; + options |= XML_PARSE_DTDLOAD; if (timing) { startTimer(); }