diff options
| author | Remko Tronçon <git@el-tramo.be> | 2009-06-03 19:02:50 (GMT) | 
|---|---|---|
| committer | Remko Tronçon <git@el-tramo.be> | 2009-06-03 19:03:24 (GMT) | 
| commit | cbbd005dba6f4b105a74f81c44654bb957dd044e (patch) | |
| tree | 4ef5a7abed56d32c4752eecd395dfa402360894d | |
| parent | 3dd69f2f852953638b220352b0eeee10464da5d8 (diff) | |
| download | swift-contrib-cbbd005dba6f4b105a74f81c44654bb957dd044e.zip swift-contrib-cbbd005dba6f4b105a74f81c44654bb957dd044e.tar.bz2 | |
Added bundled Expat.
30 files changed, 13285 insertions, 25 deletions
| diff --git a/3rdParty/Boost/Makefile.inc b/3rdParty/Boost/Makefile.inc index 718d91a..31bab1c 100644 --- a/3rdParty/Boost/Makefile.inc +++ b/3rdParty/Boost/Makefile.inc @@ -42,6 +42,4 @@ BOOST_OBJECTS = \  	$(BOOST_SOURCES:.cpp=.o)  CLEANFILES += \ -	$(BOOST_SOURCES:.cpp=.gcda) \ -	$(BOOST_SOURCES:.cpp=.gcno) \  	$(BOOST_OBJECTS) diff --git a/3rdParty/CppUnit/Makefile.inc b/3rdParty/CppUnit/Makefile.inc index 222f377..3c94d1f 100644 --- a/3rdParty/CppUnit/Makefile.inc +++ b/3rdParty/CppUnit/Makefile.inc @@ -39,8 +39,6 @@ CPPUNIT_OBJECTS = \  	$(CPPUNIT_SOURCES:.cpp=.o)  CLEANFILES += \ -	$(CPPUNIT_SOURCES:.cpp=.gcda) \ -	$(CPPUNIT_SOURCES:.cpp=.gcno) \  	$(CPPUNIT_OBJECTS) \  	$(CPPUNIT_TARGET) diff --git a/3rdParty/Expat/Makefile.inc b/3rdParty/Expat/Makefile.inc new file mode 100644 index 0000000..afbebe9 --- /dev/null +++ b/3rdParty/Expat/Makefile.inc @@ -0,0 +1,21 @@ +EXPAT_TARGET = 3rdParty/Expat/Expat.a + +EXPAT_SOURCES = \ +  3rdParty/Expat/src/xmltok.c \ +  3rdParty/Expat/src/xmlparse.c \ +  3rdParty/Expat/src/xmlrole.c + +EXPAT_OBJECTS = \ +	$(EXPAT_SOURCES:.c=.o) + +CLEANFILES += \ +	$(EXPAT_OBJECTS) \ +	$(EXPAT_TARGET) + +$(EXPAT_TARGET): $(EXPAT_OBJECTS) +	$(QUIET_AR)$(AR) $(ARFLAGS) $@ $(EXPAT_OBJECTS) + +ifeq ($(USE_BUNDLED_EXPAT),yes) +CPPFLAGS += -isystem 3rdParty/Expat -isystem 3rdParty/Expat/src -DHAVE_EXPAT_CONFIG_H +BUNDLED_LIBS += $(EXPAT_TARGET) +endif diff --git a/3rdParty/Expat/expat_config.h b/3rdParty/Expat/expat_config.h new file mode 100644 index 0000000..ba5f588 --- /dev/null +++ b/3rdParty/Expat/expat_config.h @@ -0,0 +1,6 @@ +#define HAVE_MEMMOVE 1 +#define XML_CONTEXT_BYTES 1024 +#define XML_NS 1 + +#include "../Boost/boost/detail/endian.hpp" +#define BYTEORDER BOOST_BYTE_ORDER diff --git a/3rdParty/Expat/src/ascii.h b/3rdParty/Expat/src/ascii.h new file mode 100755 index 0000000..d10530b --- /dev/null +++ b/3rdParty/Expat/src/ascii.h @@ -0,0 +1,92 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +#define ASCII_A 0x41 +#define ASCII_B 0x42 +#define ASCII_C 0x43 +#define ASCII_D 0x44 +#define ASCII_E 0x45 +#define ASCII_F 0x46 +#define ASCII_G 0x47 +#define ASCII_H 0x48 +#define ASCII_I 0x49 +#define ASCII_J 0x4A +#define ASCII_K 0x4B +#define ASCII_L 0x4C +#define ASCII_M 0x4D +#define ASCII_N 0x4E +#define ASCII_O 0x4F +#define ASCII_P 0x50 +#define ASCII_Q 0x51 +#define ASCII_R 0x52 +#define ASCII_S 0x53 +#define ASCII_T 0x54 +#define ASCII_U 0x55 +#define ASCII_V 0x56 +#define ASCII_W 0x57 +#define ASCII_X 0x58 +#define ASCII_Y 0x59 +#define ASCII_Z 0x5A + +#define ASCII_a 0x61 +#define ASCII_b 0x62 +#define ASCII_c 0x63 +#define ASCII_d 0x64 +#define ASCII_e 0x65 +#define ASCII_f 0x66 +#define ASCII_g 0x67 +#define ASCII_h 0x68 +#define ASCII_i 0x69 +#define ASCII_j 0x6A +#define ASCII_k 0x6B +#define ASCII_l 0x6C +#define ASCII_m 0x6D +#define ASCII_n 0x6E +#define ASCII_o 0x6F +#define ASCII_p 0x70 +#define ASCII_q 0x71 +#define ASCII_r 0x72 +#define ASCII_s 0x73 +#define ASCII_t 0x74 +#define ASCII_u 0x75 +#define ASCII_v 0x76 +#define ASCII_w 0x77 +#define ASCII_x 0x78 +#define ASCII_y 0x79 +#define ASCII_z 0x7A + +#define ASCII_0 0x30 +#define ASCII_1 0x31 +#define ASCII_2 0x32 +#define ASCII_3 0x33 +#define ASCII_4 0x34 +#define ASCII_5 0x35 +#define ASCII_6 0x36 +#define ASCII_7 0x37 +#define ASCII_8 0x38 +#define ASCII_9 0x39 + +#define ASCII_TAB 0x09 +#define ASCII_SPACE 0x20 +#define ASCII_EXCL 0x21 +#define ASCII_QUOT 0x22 +#define ASCII_AMP 0x26 +#define ASCII_APOS 0x27 +#define ASCII_MINUS 0x2D +#define ASCII_PERIOD 0x2E +#define ASCII_COLON 0x3A +#define ASCII_SEMI 0x3B +#define ASCII_LT 0x3C +#define ASCII_EQUALS 0x3D +#define ASCII_GT 0x3E +#define ASCII_LSQB 0x5B +#define ASCII_RSQB 0x5D +#define ASCII_UNDERSCORE 0x5F +#define ASCII_LPAREN 0x28 +#define ASCII_RPAREN 0x29 +#define ASCII_FF 0x0C +#define ASCII_SLASH 0x2F +#define ASCII_HASH 0x23 +#define ASCII_PIPE 0x7C +#define ASCII_COMMA 0x2C diff --git a/3rdParty/Expat/src/asciitab.h b/3rdParty/Expat/src/asciitab.h new file mode 100755 index 0000000..79a15c2 --- /dev/null +++ b/3rdParty/Expat/src/asciitab.h @@ -0,0 +1,36 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, +/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, +/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, +/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, +/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, +/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, +/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, +/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, +/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, +/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, +/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/3rdParty/Expat/src/expat.h b/3rdParty/Expat/src/expat.h new file mode 100755 index 0000000..20a8278 --- /dev/null +++ b/3rdParty/Expat/src/expat.h @@ -0,0 +1,1014 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +#ifndef Expat_INCLUDED +#define Expat_INCLUDED 1 + +#ifdef __VMS +/*      0        1         2         3      0        1         2         3 +        1234567890123456789012345678901     1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler    XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler    XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg  XML_SetExternalEntRefHandlerArg +#endif + +#include <stdlib.h> +#include "expat_external.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE   ((XML_Bool) 1) +#define XML_FALSE  ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several +   API functions.  The preprocessor #defines are included so this +   stanza can be added to code that still needs to support older +   versions of Expat 1.95.x: + +   #ifndef XML_STATUS_OK +   #define XML_STATUS_OK    1 +   #define XML_STATUS_ERROR 0 +   #endif + +   Otherwise, the #define hackery is quite ugly and would have been +   dropped. +*/ +enum XML_Status { +  XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR +  XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK +  XML_STATUS_SUSPENDED = 2 +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { +  XML_ERROR_NONE, +  XML_ERROR_NO_MEMORY, +  XML_ERROR_SYNTAX, +  XML_ERROR_NO_ELEMENTS, +  XML_ERROR_INVALID_TOKEN, +  XML_ERROR_UNCLOSED_TOKEN, +  XML_ERROR_PARTIAL_CHAR, +  XML_ERROR_TAG_MISMATCH, +  XML_ERROR_DUPLICATE_ATTRIBUTE, +  XML_ERROR_JUNK_AFTER_DOC_ELEMENT, +  XML_ERROR_PARAM_ENTITY_REF, +  XML_ERROR_UNDEFINED_ENTITY, +  XML_ERROR_RECURSIVE_ENTITY_REF, +  XML_ERROR_ASYNC_ENTITY, +  XML_ERROR_BAD_CHAR_REF, +  XML_ERROR_BINARY_ENTITY_REF, +  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, +  XML_ERROR_MISPLACED_XML_PI, +  XML_ERROR_UNKNOWN_ENCODING, +  XML_ERROR_INCORRECT_ENCODING, +  XML_ERROR_UNCLOSED_CDATA_SECTION, +  XML_ERROR_EXTERNAL_ENTITY_HANDLING, +  XML_ERROR_NOT_STANDALONE, +  XML_ERROR_UNEXPECTED_STATE, +  XML_ERROR_ENTITY_DECLARED_IN_PE, +  XML_ERROR_FEATURE_REQUIRES_XML_DTD, +  XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, +  /* Added in 1.95.7. */ +  XML_ERROR_UNBOUND_PREFIX, +  /* Added in 1.95.8. */ +  XML_ERROR_UNDECLARING_PREFIX, +  XML_ERROR_INCOMPLETE_PE, +  XML_ERROR_XML_DECL, +  XML_ERROR_TEXT_DECL, +  XML_ERROR_PUBLICID, +  XML_ERROR_SUSPENDED, +  XML_ERROR_NOT_SUSPENDED, +  XML_ERROR_ABORTED, +  XML_ERROR_FINISHED, +  XML_ERROR_SUSPEND_PE, +  /* Added in 2.0. */ +  XML_ERROR_RESERVED_PREFIX_XML, +  XML_ERROR_RESERVED_PREFIX_XMLNS, +  XML_ERROR_RESERVED_NAMESPACE_URI +}; + +enum XML_Content_Type { +  XML_CTYPE_EMPTY = 1, +  XML_CTYPE_ANY, +  XML_CTYPE_MIXED, +  XML_CTYPE_NAME, +  XML_CTYPE_CHOICE, +  XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { +  XML_CQUANT_NONE, +  XML_CQUANT_OPT, +  XML_CQUANT_REP, +  XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be +   XML_CQUANT_NONE, and the other fields will be zero or NULL. +   If type == XML_CTYPE_MIXED, then quant will be NONE or REP and +   numchildren will contain number of elements that may be mixed in +   and children point to an array of XML_Content cells that will be +   all of XML_CTYPE_NAME type with no quantification. + +   If type == XML_CTYPE_NAME, then the name points to the name, and +   the numchildren field will be zero and children will be NULL. The +   quant fields indicates any quantifiers placed on the name. + +   CHOICE and SEQ will have name NULL, the number of children in +   numchildren and children will point, recursively, to an array +   of XML_Content cells. + +   The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { +  enum XML_Content_Type         type; +  enum XML_Content_Quant        quant; +  XML_Char *                    name; +  unsigned int                  numchildren; +  XML_Content *                 children; +}; + + +/* This is called for an element declaration. See above for +   description of the model argument. It's the caller's responsibility +   to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, +                                                const XML_Char *name, +                                                XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, +                          XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So +   a single Attlist declaration with multiple attributes declared will +   generate multiple calls to this handler. The "default" parameter +   may be NULL in the case of the "#IMPLIED" or "#REQUIRED" +   keyword. The "isrequired" parameter will be true and the default +   value will be NULL in the case of "#REQUIRED". If "isrequired" is +   true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( +                                    void            *userData, +                                    const XML_Char  *elname, +                                    const XML_Char  *attname, +                                    const XML_Char  *att_type, +                                    const XML_Char  *dflt, +                                    int              isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, +                          XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations +   and text declarations. The way to distinguish is that the version +   parameter will be NULL for text declarations. The encoding +   parameter may be NULL for XML declarations. The standalone +   parameter will be -1, 0, or 1 indicating respectively that there +   was no standalone parameter in the declaration, that it was given +   as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void           *userData, +                                            const XML_Char *version, +                                            const XML_Char *encoding, +                                            int             standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, +                      XML_XmlDeclHandler xmldecl); + + +typedef struct { +  void *(*malloc_fcn)(size_t size); +  void *(*realloc_fcn)(void *ptr, size_t size); +  void (*free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the +   external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor.  Element type +   names and attribute names that belong to a namespace will be +   expanded; unprefixed attribute names are never expanded; unprefixed +   element type names are expanded only if there is a default +   namespace. The expanded name is the concatenation of the namespace +   URI, the namespace separator character, and the local part of the +   name.  If the namespace separator is '\0' then the namespace URI +   and the local part will be concatenated without any separator. +   It is a programming error to use the separator '\0' with namespace +   triplets (see XML_SetReturnNSTriplet). +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to +   by memsuite. If memsuite is NULL, then use the standard library memory +   suite. If namespaceSeparator is non-NULL it creates a parser with +   namespace processing as described above. The character pointed at +   will serve as the namespace separator. + +   All further memory operations used for the created parser will come from +   the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, +                    const XML_Memory_Handling_Suite *memsuite, +                    const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used.  This is particularly +   valuable when memory allocation overhead is disproportionatly high, +   such as when a large number of small documnents need to be parsed. +   All handlers are cleared from the parser, except for the +   unknownEncodingHandler. The parser's external state is re-initialized +   except for the values of ns and ns_triplets. + +   Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; +   names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, +                                                 const XML_Char *name, +                                                 const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, +                                               const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, +                                                  const XML_Char *s, +                                                  int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( +                                                void *userData, +                                                const XML_Char *target, +                                                const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, +                                            const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which +   there is no applicable handler.  This includes both characters that +   are part of markup which is of a kind that is not reported +   (comments, markup declarations), or characters that are part of a +   construct which could be reported but for which no handler has been +   supplied. The characters are passed exactly as they were in the XML +   document except that they will be encoded in UTF-8 or UTF-16. +   Line boundaries are not normalized. Note that a byte order mark +   character is not passed to the default handler. There are no +   guarantees about how characters are divided between calls to the +   default handler: for example, a comment might be split between +   multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, +                                            const XML_Char *s, +                                            int len); + +/* This is called for the start of the DOCTYPE declaration, before +   any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( +                                            void *userData, +                                            const XML_Char *doctypeName, +                                            const XML_Char *sysid, +                                            const XML_Char *pubid, +                                            int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the +   closing > is encountered, but after processing any external +   subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity +   argument will be non-zero if the entity is a parameter entity, zero +   otherwise. + +   For internal entities (<!ENTITY foo "bar">), value will +   be non-NULL and systemId, publicID, and notationName will be NULL. +   The value string is NOT nul-terminated; the length is provided in +   the value_length argument. Since it is legal to have zero-length +   values, do not use this argument to test for internal entities. + +   For external entities, value will be NULL and systemId will be +   non-NULL. The publicId argument will be NULL unless a public +   identifier was provided. The notationName argument will have a +   non-NULL value only for unparsed entity declarations. + +   Note that is_parameter_entity can't be changed to XML_Bool, since +   that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( +                              void *userData, +                              const XML_Char *entityName, +                              int is_parameter_entity, +                              const XML_Char *value, +                              int value_length, +                              const XML_Char *base, +                              const XML_Char *systemId, +                              const XML_Char *publicId, +                              const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, +                         XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE +   This handler has been superceded by the EntityDeclHandler above. +   It is provided here for backward compatibility. + +   This is called for a declaration of an unparsed (NDATA) entity. +   The base argument is whatever was set by XML_SetBase. The +   entityName, systemId and notationName arguments will never be +   NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( +                                    void *userData, +                                    const XML_Char *entityName, +                                    const XML_Char *base, +                                    const XML_Char *systemId, +                                    const XML_Char *publicId, +                                    const XML_Char *notationName); + +/* This is called for a declaration of notation.  The base argument is +   whatever was set by XML_SetBase. The notationName will never be +   NULL.  The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( +                                    void *userData, +                                    const XML_Char *notationName, +                                    const XML_Char *base, +                                    const XML_Char *systemId, +                                    const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for +   each namespace declaration. The call to the start and end element +   handlers occur between the calls to the start and end namespace +   declaration handlers. For an xmlns attribute, prefix will be +   NULL.  For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( +                                    void *userData, +                                    const XML_Char *prefix, +                                    const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( +                                    void *userData, +                                    const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an +   external subset or a reference to a parameter entity, but does not +   have standalone="yes". If this handler returns XML_STATUS_ERROR, +   then processing will not continue, and the parser will return a +   XML_ERROR_NOT_STANDALONE error. +   If parameter entity parsing is enabled, then in addition to the +   conditions above this handler will only be called if the referenced +   entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general +   entity.  The referenced entity is not automatically parsed.  The +   application can parse it immediately or later using +   XML_ExternalEntityParserCreate. + +   The parser argument is the parser parsing the entity containing the +   reference; it can be passed as the parser argument to +   XML_ExternalEntityParserCreate.  The systemId argument is the +   system identifier as specified in the entity declaration; it will +   not be NULL. + +   The base argument is the system identifier that should be used as +   the base for resolving systemId if systemId was relative; this is +   set by XML_SetBase; it may be NULL. + +   The publicId argument is the public identifier as specified in the +   entity declaration, or NULL if none was specified; the whitespace +   in the public identifier will have been normalized as required by +   the XML spec. + +   The context argument specifies the parsing context in the format +   expected by the context argument to XML_ExternalEntityParserCreate; +   context is valid only until the handler returns, so if the +   referenced entity is to be parsed later, it must be copied. +   context is NULL only when the entity is a parameter entity. + +   The handler should return XML_STATUS_ERROR if processing should not +   continue because of a fatal error in the handling of the external +   entity.  In this case the calling parser will return an +   XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + +   Note that unlike other handlers the first argument is the parser, +   not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( +                                    XML_Parser parser, +                                    const XML_Char *context, +                                    const XML_Char *base, +                                    const XML_Char *systemId, +                                    const XML_Char *publicId); + +/* This is called in two situations: +   1) An entity reference is encountered for which no declaration +      has been read *and* this is not an error. +   2) An internal entity reference is read, but not expanded, because +      XML_SetDefaultHandler has been called. +   Note: skipped parameter entities in declarations and skipped general +         entities in attribute values cannot be reported, because +         the event would be out of sync with the reporting of the +         declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( +                                    void *userData, +                                    const XML_Char *entityName, +                                    int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to +   provide information to the parser about encodings that are unknown +   to the parser. + +   The map[b] member gives information about byte sequences whose +   first byte is b. + +   If map[b] is c where c is >= 0, then b by itself encodes the +   Unicode scalar value c. + +   If map[b] is -1, then the byte sequence is malformed. + +   If map[b] is -n, where n >= 2, then b is the first byte of an +   n-byte sequence that encodes a single Unicode scalar value. + +   The data member will be passed as the first argument to the convert +   function. + +   The convert function is used to convert multibyte sequences; s will +   point to a n-byte sequence where map[(unsigned char)*s] == -n.  The +   convert function must return the Unicode scalar value represented +   by this byte sequence or -1 if the byte sequence is malformed. + +   The convert function may be NULL if the encoding is a single-byte +   encoding, that is if map[b] >= -1 for all bytes b. + +   When the parser is finished with the encoding, then if release is +   not NULL, it will call release passing it the data member; once +   release has been called, the convert function will not be called +   again. + +   Expat places certain restrictions on the encodings that are supported +   using this mechanism. + +   1. Every ASCII character that can appear in a well-formed XML document, +      other than the characters + +      $@\^`{}~ + +      must be represented by a single byte, and that byte must be the +      same byte that represents that character in ASCII. + +   2. No character may require more than 4 bytes to encode. + +   3. All characters encoded must have Unicode scalar values <= +      0xFFFF, (i.e., characters that would be encoded by surrogates in +      UTF-16 are  not allowed).  Note that this restriction doesn't +      apply to the built-in support for UTF-8 and UTF-16. + +   4. No Unicode character may be encoded by more than one distinct +      sequence of bytes. +*/ +typedef struct { +  int map[256]; +  void *data; +  int (XMLCALL *convert)(void *data, const char *s); +  void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + +   The encodingHandlerData argument is that which was passed as the +   second argument to XML_SetUnknownEncodingHandler. + +   The name argument gives the name of the encoding as specified in +   the encoding declaration. + +   If the callback can provide information about the encoding, it must +   fill in the XML_Encoding structure, and return XML_STATUS_OK. +   Otherwise it must return XML_STATUS_ERROR. + +   If info does not describe a suitable encoding, then the parser will +   return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( +                                    void *encodingHandlerData, +                                    const XML_Char *name, +                                    XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, +                      XML_StartElementHandler start, +                      XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, +                           XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, +                         XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, +                            XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, +                                    XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, +                      XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, +                           XML_StartCdataSectionHandler start, +                           XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, +                                XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, +                              XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of +   internal entities. These entity references will be passed to the +   default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, +                      XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of +   internal entities.  The entity reference will not be passed to the +   default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, +                            XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, +                          XML_StartDoctypeDeclHandler start, +                          XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, +                               XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, +                             XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, +                                 XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, +                           XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, +                            XML_StartNamespaceDeclHandler start, +                            XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, +                                 XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, +                               XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, +                            XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, +                                XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be +   passed as the first argument to the external entity ref handler +   instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, +                                   void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, +                            XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, +                              XML_UnknownEncodingHandler handler, +                              void *encodingHandlerData); + +/* This can be called within a handler for a start element, end +   element, processing instruction or character data.  It causes the +   corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and +   a name has a prefix (i.e. an explicit namespace qualifier) then +   that name is returned as a triplet in a single string separated by +   the separator character specified when the parser was created: URI +   + sep + local_name + sep + prefix. + +   If do_nst is zero, then namespace information is returned in the +   default manner (URI + sep + local_name) whether or not the name +   has a prefix. + +   Note: Calling XML_SetReturnNSTriplet after XML_Parse or +     XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to +   XML_ParserCreate. On success XML_SetEncoding returns non-zero, +   zero otherwise. +   Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer +     has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the +   first argument to callbacks instead of userData.  The userData will +   still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser +   will assume that there is an external subset, even if none is +   specified in the document. In such a case the parser will call the +   externalEntityRefHandler with a value of NULL for the systemId +   argument (the publicId and context arguments will be NULL as well). +   Note: For the purpose of checking WFC: Entity Declared, passing +     useDTD == XML_TRUE will make the parser behave as if the document +     had a DTD with an external subset. +   Note: If this function is called, then this must be done before +     the first call to XML_Parse or XML_ParseBuffer, since it will +     have no effect after that.  Returns +     XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. +   Note: If the document does not have a DOCTYPE declaration at all, +     then startDoctypeDeclHandler and endDoctypeDeclHandler will not +     be called, despite an external subset being parsed. +   Note: If XML_DTD is not defined when Expat is compiled, returns +     XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system +   identifiers in declarations.  Resolving relative identifiers is +   left to the application: this value will be passed through as the +   base argument to the XML_ExternalEntityRefHandler, +   XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base +   argument will be copied.  Returns XML_STATUS_ERROR if out of memory, +   XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call +   to the XML_StartElementHandler that were specified in the start-tag +   rather than defaulted. Each attribute/value pair counts as 2; thus +   this correspondds to an index into the atts array passed to the +   XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to +   XML_StartElementHandler, or -1 if there is no ID attribute.  Each +   attribute/value pair counts as 2; thus this correspondds to an +   index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is +   detected.  The last call to XML_Parse must have isFinal true; len +   may be zero for this call (or any other). + +   Though the return values for these functions has always been +   described as a Boolean value, the implementation, at least for the +   1.95.x series, has always returned exactly one of the XML_Status +   values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. +   Must be called from within a call-back handler, except when aborting +   (resumable = 0) an already suspended parser. Some call-backs may +   still follow because they would otherwise get lost. Examples: +   - endElementHandler() for empty elements when stopped in +     startElementHandler(),  +   - endNameSpaceDeclHandler() when stopped in endElementHandler(),  +   and possibly others. + +   Can be called from most handlers, including DTD related call-backs, +   except when parsing an external parameter entity and resumable != 0. +   Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. +   Possible error codes:  +   - XML_ERROR_SUSPENDED: when suspending an already suspended parser. +   - XML_ERROR_FINISHED: when the parser has already finished. +   - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + +   When resumable != 0 (true) then parsing is suspended, that is,  +   XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED.  +   Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() +   return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + +   *Note*: +   This will be applied to the current parser instance only, that is, if +   there is a parent parser then it will continue parsing when the +   externalEntityRefHandler() returns. It is up to the implementation of +   the externalEntityRefHandler() to call XML_StopParser() on the parent +   parser (recursively), if one wants to stop parsing altogether. + +   When suspended, parsing can be resumed by calling XML_ResumeParser().  +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). +   Must not be called from within a handler call-back. Returns same +   status codes as XML_Parse() or XML_ParseBuffer(). +   Additional error code XML_ERROR_NOT_SUSPENDED possible.    + +   *Note*: +   This must be called on the most deeply nested child parser instance +   first, and on its parent parser only after the child parser has finished, +   to be applied recursively until the document entity's parser is restarted. +   That is, the parent parser will not resume by itself and it is up to the +   application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { +  XML_INITIALIZED, +  XML_PARSING, +  XML_FINISHED, +  XML_SUSPENDED +}; + +typedef struct { +  enum XML_Parsing parsing; +  XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, +   finished, or suspended and processing the final buffer. +   XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, +   XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general +   entity; context is a '\0'-terminated string specifying the parse +   context; encoding is a '\0'-terminated string giving the name of +   the externally specified encoding, or NULL if there is no +   externally specified encoding.  The context string consists of a +   sequence of tokens separated by formfeeds (\f); a token consisting +   of a name specifies that the general entity of the name is open; a +   token of the form prefix=uri specifies the namespace for a +   particular prefix; a token of the form =uri specifies the default +   namespace.  This can be called at any point after the first call to +   an ExternalEntityRefHandler so longer as the parser has not yet +   been freed.  The new parser is completely independent and may +   safely be used in a separate thread.  The handlers and userData are +   initialized from the parser argument.  Returns NULL if out of memory. +   Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, +                               const XML_Char *context, +                               const XML_Char *encoding); + +enum XML_ParamEntityParsing { +  XML_PARAM_ENTITY_PARSING_NEVER, +  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, +  XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD +   subset). If parsing of parameter entities is enabled, then +   references to external parameter entities (including the external +   DTD subset) will be passed to the handler set with +   XML_SetExternalEntityRefHandler.  The context passed will be 0. + +   Unlike external general entities, external parameter entities can +   only be parsed synchronously.  If the external parameter entity is +   to be parsed, it must be parsed during the call to the external +   entity ref handler: the complete sequence of +   XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and +   XML_ParserFree calls must be made during this call.  After +   XML_ExternalEntityParserCreate has been called to create the parser +   for the external parameter entity (context must be 0 for this +   call), it is illegal to make any calls on the old parser until +   XML_ParserFree has been called on the newly created parser. +   If the library has been compiled without support for parameter +   entity parsing (ie without XML_DTD being defined), then +   XML_SetParamEntityParsing will return 0 if parsing of parameter +   entities is requested; otherwise it will return non-zero. +   Note: If XML_SetParamEntityParsing is called after XML_Parse or +      XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, +                          enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then +   XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse +   location.  They may be called from any callback called to report +   some parse event; in this case the location is the location of the +   first of the sequence of characters that generated the event.  When +   called from callbacks generated by declarations in the document +   prologue, the location identified isn't as neatly defined, but will +   be within the relevant markup.  When called outside of the callback +   functions, the position indicated will be just past the last parse +   event (regardless of whether there was an associated callback). +    +   They may also be called after returning from a call to XML_Parse +   or XML_ParseBuffer.  If the return value is XML_STATUS_ERROR then +   the location is the location of the character at which the error +   was detected; otherwise the location is the location of the last +   parse event, as described above. +*/ +XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. +   Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets +   the integer pointed to by offset to the offset within this buffer +   of the current parse position, and sets the integer pointed to by size +   to the size of this buffer (the number of input bytes). Otherwise +   returns a NULL pointer. Also returns a NULL pointer if a parse isn't +   active. + +   NOTE: The character pointer returned should not be used outside +   the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, +                    int *offset, +                    int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber   XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex    XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { +  int major; +  int minor; +  int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version +   number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { +  XML_FEATURE_END = 0, +  XML_FEATURE_UNICODE, +  XML_FEATURE_UNICODE_WCHAR_T, +  XML_FEATURE_DTD, +  XML_FEATURE_CONTEXT_BYTES, +  XML_FEATURE_MIN_SIZE, +  XML_FEATURE_SIZEOF_XML_CHAR, +  XML_FEATURE_SIZEOF_XML_LCHAR, +  XML_FEATURE_NS, +  XML_FEATURE_LARGE_SIZE +  /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { +  enum XML_FeatureEnum  feature; +  const XML_LChar       *name; +  long int              value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for +   beta/development releases and even number minor version for stable +   releases. Micro is bumped with each release, and set to 0 with each +   change to major or minor version. +*/ +#define XML_MAJOR_VERSION 2 +#define XML_MINOR_VERSION 0 +#define XML_MICRO_VERSION 1 + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_INCLUDED */ diff --git a/3rdParty/Expat/src/expat_external.h b/3rdParty/Expat/src/expat_external.h new file mode 100755 index 0000000..2c03284 --- /dev/null +++ b/3rdParty/Expat/src/expat_external.h @@ -0,0 +1,115 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +#ifndef Expat_External_INCLUDED +#define Expat_External_INCLUDED 1 + +/* External API definitions */ + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically +   defined.  There are two macros defined to control this boundary; +   each of these can be defined before including this header to +   achieve some different behavior, but doing so it not recommended or +   tested frequently. + +   XMLCALL    - The calling convention to use for all calls across the +                "library boundary."  This will default to cdecl, and +                try really hard to tell the compiler that's what we +                want. + +   XMLIMPORT  - Whatever magic is needed to note that a function is +                to be imported from a dynamically loaded library +                (.dll, .so, or .sl, depending on your platform). + +   The XMLCALL macro was added in Expat 1.95.7.  The only one which is +   expected to be directly useful in client code is XMLCALL. + +   Note that on at least some Unix versions, the Expat library must be +   compiled with the cdecl calling convention as the default since +   system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(_MSC_VER) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER) +#define XMLCALL __attribute__((cdecl)) +#else +/* For any platform which uses this definition and supports more than +   one calling convention, we need to extend this definition to +   declare the convention used on that platform, if it's possible to +   do so. + +   If this is the case for your platform, please file a bug report +   with information on how to identify your platform via the C +   pre-processor and how to specify the same calling convention as the +   platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif  /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif  /* not defined XML_STATIC */ + + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +#ifdef XML_UNICODE     /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else                  /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +#ifdef XML_LARGE_SIZE  /* Use large integers for file/stream positions. */ +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +typedef __int64 XML_Index;  +typedef unsigned __int64 XML_Size; +#else +typedef long long XML_Index; +typedef unsigned long long XML_Size; +#endif +#else +typedef long XML_Index; +typedef unsigned long XML_Size; +#endif /* XML_LARGE_SIZE */ + +#ifdef __cplusplus +} +#endif + +#endif /* not Expat_External_INCLUDED */ diff --git a/3rdParty/Expat/src/iasciitab.h b/3rdParty/Expat/src/iasciitab.h new file mode 100755 index 0000000..24a1d5c --- /dev/null +++ b/3rdParty/Expat/src/iasciitab.h @@ -0,0 +1,37 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ +/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, +/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, +/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, +/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, +/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, +/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, +/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, +/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, +/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, +/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, +/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, +/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, +/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, +/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, diff --git a/3rdParty/Expat/src/internal.h b/3rdParty/Expat/src/internal.h new file mode 100755 index 0000000..dd54548 --- /dev/null +++ b/3rdParty/Expat/src/internal.h @@ -0,0 +1,73 @@ +/* internal.h + +   Internal definitions used by Expat.  This is not needed to compile +   client code. + +   The following calling convention macros are defined for frequently +   called functions: + +   FASTCALL    - Used for those internal functions that have a simple +                 body and a low number of arguments and local variables. + +   PTRCALL     - Used for functions called though function pointers. + +   PTRFASTCALL - Like PTRCALL, but for low number of arguments. + +   inline      - Used for selected internal functions for which inlining +                 may improve performance on some platforms. + +   Note: Use of these macros is based on judgement, not hard rules, +         and therefore subject to change. +*/ + +#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__) +/* We'll use this version by default only where we know it helps. + +   regparm() generates warnings on Solaris boxes.   See SF bug #692878. + +   Instability reported with egcs on a RedHat Linux 7.3. +   Let's comment out: +   #define FASTCALL __attribute__((stdcall, regparm(3))) +   and let's try this: +*/ +#define FASTCALL __attribute__((regparm(3))) +#define PTRFASTCALL __attribute__((regparm(3))) +#endif + +/* Using __fastcall seems to have an unexpected negative effect under +   MS VC++, especially for function pointers, so we won't use it for +   now on that platform. It may be reconsidered for a future release +   if it can be made more effective. +   Likely reason: __fastcall on Windows is like stdcall, therefore +   the compiler cannot perform stack optimizations for call clusters. +*/ + +/* Make sure all of these are defined if they aren't already. */ + +#ifndef FASTCALL +#define FASTCALL +#endif + +#ifndef PTRCALL +#define PTRCALL +#endif + +#ifndef PTRFASTCALL +#define PTRFASTCALL +#endif + +#ifndef XML_MIN_SIZE +#if !defined(__cplusplus) && !defined(inline) +#ifdef __GNUC__ +#define inline __inline +#endif /* __GNUC__ */ +#endif +#endif /* XML_MIN_SIZE */ + +#ifdef __cplusplus +#define inline inline +#else +#ifndef inline +#define inline +#endif +#endif diff --git a/3rdParty/Expat/src/latin1tab.h b/3rdParty/Expat/src/latin1tab.h new file mode 100755 index 0000000..53c25d7 --- /dev/null +++ b/3rdParty/Expat/src/latin1tab.h @@ -0,0 +1,36 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, +/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, +/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, +/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, +/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, +/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, +/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, diff --git a/3rdParty/Expat/src/nametab.h b/3rdParty/Expat/src/nametab.h new file mode 100755 index 0000000..b05e62c --- /dev/null +++ b/3rdParty/Expat/src/nametab.h @@ -0,0 +1,150 @@ +static const unsigned namingBitmap[] = { +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE, +0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, +0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF, +0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, +0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, +0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, +0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, +0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, +0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, +0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000, +0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, +0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, +0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003, +0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, +0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, +0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003, +0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, +0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, +0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003, +0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000, +0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, +0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, +0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB, +0x40000000, 0xF580C900, 0x00000007, 0x02010800, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, +0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, +0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, +0x00000000, 0x00004C40, 0x00000000, 0x00000000, +0x00000007, 0x00000000, 0x00000000, 0x00000000, +0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, +0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF, +0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, +0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000, +0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, +0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, +0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, +0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, +0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, +0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, +0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, +0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, +0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, +0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, +0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, +0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF, +0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, +0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, +0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0, +0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, +0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, +0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80, +0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, +0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, +0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, +0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000, +0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, +0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, +0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, +0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF, +}; +static const unsigned char nmstrtPages[] = { +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, +0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static const unsigned char namePages[] = { +0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, +0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, +0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, +0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; diff --git a/3rdParty/Expat/src/utf8tab.h b/3rdParty/Expat/src/utf8tab.h new file mode 100755 index 0000000..7bb3e77 --- /dev/null +++ b/3rdParty/Expat/src/utf8tab.h @@ -0,0 +1,37 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + + +/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, +/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, +/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, +/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, +/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, +/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, diff --git a/3rdParty/Expat/src/xmlparse.c b/3rdParty/Expat/src/xmlparse.c new file mode 100755 index 0000000..94e31de --- /dev/null +++ b/3rdParty/Expat/src/xmlparse.c @@ -0,0 +1,6287 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +#include <stddef.h> +#include <string.h>                     /* memset(), memcpy() */ +#include <assert.h> + +#define XML_BUILDING_EXPAT 1 + +#ifdef COMPILED_FROM_DSP +#include "winconfig.h" +#elif defined(MACOS_CLASSIC) +#include "macconfig.h" +#elif defined(__amigaos4__) +#include "amigaconfig.h" +#elif defined(__WATCOMC__) +#include "watcomconfig.h" +#elif defined(HAVE_EXPAT_CONFIG_H) +#include <expat_config.h> +#endif /* ndef COMPILED_FROM_DSP */ + +#include "ascii.h" +#include "expat.h" + +#ifdef XML_UNICODE +#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX +#define XmlConvert XmlUtf16Convert +#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding +#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS +#define XmlEncode XmlUtf16Encode +/* Using pointer subtraction to convert to integer type. */ +#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1)) +typedef unsigned short ICHAR; +#else +#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX +#define XmlConvert XmlUtf8Convert +#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding +#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS +#define XmlEncode XmlUtf8Encode +#define MUST_CONVERT(enc, s) (!(enc)->isUtf8) +typedef char ICHAR; +#endif + + +#ifndef XML_NS + +#define XmlInitEncodingNS XmlInitEncoding +#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding +#undef XmlGetInternalEncodingNS +#define XmlGetInternalEncodingNS XmlGetInternalEncoding +#define XmlParseXmlDeclNS XmlParseXmlDecl + +#endif + +#ifdef XML_UNICODE + +#ifdef XML_UNICODE_WCHAR_T +#define XML_T(x) (const wchar_t)x +#define XML_L(x) L ## x +#else +#define XML_T(x) (const unsigned short)x +#define XML_L(x) x +#endif + +#else + +#define XML_T(x) x +#define XML_L(x) x + +#endif + +/* Round up n to be a multiple of sz, where sz is a power of 2. */ +#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) + +/* Handle the case where memmove() doesn't exist. */ +#ifndef HAVE_MEMMOVE +#ifdef HAVE_BCOPY +#define memmove(d,s,l) bcopy((s),(d),(l)) +#else +#error memmove does not exist on this platform, nor is a substitute available +#endif /* HAVE_BCOPY */ +#endif /* HAVE_MEMMOVE */ + +#include "internal.h" +#include "xmltok.h" +#include "xmlrole.h" + +typedef const XML_Char *KEY; + +typedef struct { +  KEY name; +} NAMED; + +typedef struct { +  NAMED **v; +  unsigned char power; +  size_t size; +  size_t used; +  const XML_Memory_Handling_Suite *mem; +} HASH_TABLE; + +/* Basic character hash algorithm, taken from Python's string hash: +   h = h * 1000003 ^ character, the constant being a prime number. + +*/ +#ifdef XML_UNICODE +#define CHAR_HASH(h, c) \ +  (((h) * 0xF4243) ^ (unsigned short)(c)) +#else +#define CHAR_HASH(h, c) \ +  (((h) * 0xF4243) ^ (unsigned char)(c)) +#endif + +/* For probing (after a collision) we need a step size relative prime +   to the hash table size, which is a power of 2. We use double-hashing, +   since we can calculate a second hash value cheaply by taking those bits +   of the first hash value that were discarded (masked out) when the table +   index was calculated: index = hash & mask, where mask = table->size - 1. +   We limit the maximum step size to table->size / 4 (mask >> 2) and make +   it odd, since odd numbers are always relative prime to a power of 2. +*/ +#define SECOND_HASH(hash, mask, power) \ +  ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2)) +#define PROBE_STEP(hash, mask, power) \ +  ((unsigned char)((SECOND_HASH(hash, mask, power)) | 1)) + +typedef struct { +  NAMED **p; +  NAMED **end; +} HASH_TABLE_ITER; + +#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */ +#define INIT_DATA_BUF_SIZE 1024 +#define INIT_ATTS_SIZE 16 +#define INIT_ATTS_VERSION 0xFFFFFFFF +#define INIT_BLOCK_SIZE 1024 +#define INIT_BUFFER_SIZE 1024 + +#define EXPAND_SPARE 24 + +typedef struct binding { +  struct prefix *prefix; +  struct binding *nextTagBinding; +  struct binding *prevPrefixBinding; +  const struct attribute_id *attId; +  XML_Char *uri; +  int uriLen; +  int uriAlloc; +} BINDING; + +typedef struct prefix { +  const XML_Char *name; +  BINDING *binding; +} PREFIX; + +typedef struct { +  const XML_Char *str; +  const XML_Char *localPart; +  const XML_Char *prefix; +  int strLen; +  int uriLen; +  int prefixLen; +} TAG_NAME; + +/* TAG represents an open element. +   The name of the element is stored in both the document and API +   encodings.  The memory buffer 'buf' is a separately-allocated +   memory area which stores the name.  During the XML_Parse()/ +   XMLParseBuffer() when the element is open, the memory for the 'raw' +   version of the name (in the document encoding) is shared with the +   document buffer.  If the element is open across calls to +   XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to +   contain the 'raw' name as well. + +   A parser re-uses these structures, maintaining a list of allocated +   TAG objects in a free list. +*/ +typedef struct tag { +  struct tag *parent;           /* parent of this element */ +  const char *rawName;          /* tagName in the original encoding */ +  int rawNameLength; +  TAG_NAME name;                /* tagName in the API encoding */ +  char *buf;                    /* buffer for name components */ +  char *bufEnd;                 /* end of the buffer */ +  BINDING *bindings; +} TAG; + +typedef struct { +  const XML_Char *name; +  const XML_Char *textPtr; +  int textLen;                  /* length in XML_Chars */ +  int processed;                /* # of processed bytes - when suspended */ +  const XML_Char *systemId; +  const XML_Char *base; +  const XML_Char *publicId; +  const XML_Char *notation; +  XML_Bool open; +  XML_Bool is_param; +  XML_Bool is_internal; /* true if declared in internal subset outside PE */ +} ENTITY; + +typedef struct { +  enum XML_Content_Type         type; +  enum XML_Content_Quant        quant; +  const XML_Char *              name; +  int                           firstchild; +  int                           lastchild; +  int                           childcnt; +  int                           nextsib; +} CONTENT_SCAFFOLD; + +#define INIT_SCAFFOLD_ELEMENTS 32 + +typedef struct block { +  struct block *next; +  int size; +  XML_Char s[1]; +} BLOCK; + +typedef struct { +  BLOCK *blocks; +  BLOCK *freeBlocks; +  const XML_Char *end; +  XML_Char *ptr; +  XML_Char *start; +  const XML_Memory_Handling_Suite *mem; +} STRING_POOL; + +/* The XML_Char before the name is used to determine whether +   an attribute has been specified. */ +typedef struct attribute_id { +  XML_Char *name; +  PREFIX *prefix; +  XML_Bool maybeTokenized; +  XML_Bool xmlns; +} ATTRIBUTE_ID; + +typedef struct { +  const ATTRIBUTE_ID *id; +  XML_Bool isCdata; +  const XML_Char *value; +} DEFAULT_ATTRIBUTE; + +typedef struct { +  unsigned long version; +  unsigned long hash; +  const XML_Char *uriName; +} NS_ATT; + +typedef struct { +  const XML_Char *name; +  PREFIX *prefix; +  const ATTRIBUTE_ID *idAtt; +  int nDefaultAtts; +  int allocDefaultAtts; +  DEFAULT_ATTRIBUTE *defaultAtts; +} ELEMENT_TYPE; + +typedef struct { +  HASH_TABLE generalEntities; +  HASH_TABLE elementTypes; +  HASH_TABLE attributeIds; +  HASH_TABLE prefixes; +  STRING_POOL pool; +  STRING_POOL entityValuePool; +  /* false once a parameter entity reference has been skipped */ +  XML_Bool keepProcessing; +  /* true once an internal or external PE reference has been encountered; +     this includes the reference to an external subset */ +  XML_Bool hasParamEntityRefs; +  XML_Bool standalone; +#ifdef XML_DTD +  /* indicates if external PE has been read */ +  XML_Bool paramEntityRead; +  HASH_TABLE paramEntities; +#endif /* XML_DTD */ +  PREFIX defaultPrefix; +  /* === scaffolding for building content model === */ +  XML_Bool in_eldecl; +  CONTENT_SCAFFOLD *scaffold; +  unsigned contentStringLen; +  unsigned scaffSize; +  unsigned scaffCount; +  int scaffLevel; +  int *scaffIndex; +} DTD; + +typedef struct open_internal_entity { +  const char *internalEventPtr; +  const char *internalEventEndPtr; +  struct open_internal_entity *next; +  ENTITY *entity; +  int startTagLevel; +  XML_Bool betweenDecl; /* WFC: PE Between Declarations */ +} OPEN_INTERNAL_ENTITY; + +typedef enum XML_Error PTRCALL Processor(XML_Parser parser, +                                         const char *start, +                                         const char *end, +                                         const char **endPtr); + +static Processor prologProcessor; +static Processor prologInitProcessor; +static Processor contentProcessor; +static Processor cdataSectionProcessor; +#ifdef XML_DTD +static Processor ignoreSectionProcessor; +static Processor externalParEntProcessor; +static Processor externalParEntInitProcessor; +static Processor entityValueProcessor; +static Processor entityValueInitProcessor; +#endif /* XML_DTD */ +static Processor epilogProcessor; +static Processor errorProcessor; +static Processor externalEntityInitProcessor; +static Processor externalEntityInitProcessor2; +static Processor externalEntityInitProcessor3; +static Processor externalEntityContentProcessor; +static Processor internalEntityProcessor; + +static enum XML_Error +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); +static enum XML_Error +processXmlDecl(XML_Parser parser, int isGeneralTextEntity, +               const char *s, const char *next); +static enum XML_Error +initializeEncoding(XML_Parser parser); +static enum XML_Error +doProlog(XML_Parser parser, const ENCODING *enc, const char *s,  +         const char *end, int tok, const char *next, const char **nextPtr,  +         XML_Bool haveMore); +static enum XML_Error +processInternalEntity(XML_Parser parser, ENTITY *entity,  +                      XML_Bool betweenDecl); +static enum XML_Error +doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, +          const char *start, const char *end, const char **endPtr,  +          XML_Bool haveMore); +static enum XML_Error +doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, +               const char *end, const char **nextPtr, XML_Bool haveMore); +#ifdef XML_DTD +static enum XML_Error +doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, +                const char *end, const char **nextPtr, XML_Bool haveMore); +#endif /* XML_DTD */ + +static enum XML_Error +storeAtts(XML_Parser parser, const ENCODING *, const char *s, +          TAG_NAME *tagNamePtr, BINDING **bindingsPtr); +static enum XML_Error +addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, +           const XML_Char *uri, BINDING **bindingsPtr); +static int +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,  +                XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser); +static enum XML_Error +storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, +                    const char *, const char *, STRING_POOL *); +static enum XML_Error +appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata, +                     const char *, const char *, STRING_POOL *); +static ATTRIBUTE_ID * +getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, +               const char *end); +static int +setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); +static enum XML_Error +storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, +                 const char *end); +static int +reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, +                            const char *start, const char *end); +static int +reportComment(XML_Parser parser, const ENCODING *enc, const char *start, +              const char *end); +static void +reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, +              const char *end); + +static const XML_Char * getContext(XML_Parser parser); +static XML_Bool +setContext(XML_Parser parser, const XML_Char *context); + +static void FASTCALL normalizePublicId(XML_Char *s); + +static DTD * dtdCreate(const XML_Memory_Handling_Suite *ms); +/* do not call if parentParser != NULL */ +static void dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms); +static void +dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms); +static int +dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms); +static int +copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *); + +static NAMED * +lookup(HASH_TABLE *table, KEY name, size_t createSize); +static void FASTCALL +hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms); +static void FASTCALL hashTableClear(HASH_TABLE *); +static void FASTCALL hashTableDestroy(HASH_TABLE *); +static void FASTCALL +hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); +static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *); + +static void FASTCALL +poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms); +static void FASTCALL poolClear(STRING_POOL *); +static void FASTCALL poolDestroy(STRING_POOL *); +static XML_Char * +poolAppend(STRING_POOL *pool, const ENCODING *enc, +           const char *ptr, const char *end); +static XML_Char * +poolStoreString(STRING_POOL *pool, const ENCODING *enc, +                const char *ptr, const char *end); +static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); +static const XML_Char * FASTCALL +poolCopyString(STRING_POOL *pool, const XML_Char *s); +static const XML_Char * +poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); +static const XML_Char * FASTCALL +poolAppendString(STRING_POOL *pool, const XML_Char *s); + +static int FASTCALL nextScaffoldPart(XML_Parser parser); +static XML_Content * build_model(XML_Parser parser); +static ELEMENT_TYPE * +getElementType(XML_Parser parser, const ENCODING *enc, +               const char *ptr, const char *end); + +static XML_Parser +parserCreate(const XML_Char *encodingName, +             const XML_Memory_Handling_Suite *memsuite, +             const XML_Char *nameSep, +             DTD *dtd); +static void +parserInit(XML_Parser parser, const XML_Char *encodingName); + +#define poolStart(pool) ((pool)->start) +#define poolEnd(pool) ((pool)->ptr) +#define poolLength(pool) ((pool)->ptr - (pool)->start) +#define poolChop(pool) ((void)--(pool->ptr)) +#define poolLastChar(pool) (((pool)->ptr)[-1]) +#define poolDiscard(pool) ((pool)->ptr = (pool)->start) +#define poolFinish(pool) ((pool)->start = (pool)->ptr) +#define poolAppendChar(pool, c) \ +  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ +   ? 0 \ +   : ((*((pool)->ptr)++ = c), 1)) + +struct XML_ParserStruct { +  /* The first member must be userData so that the XML_GetUserData +     macro works. */ +  void *m_userData; +  void *m_handlerArg; +  char *m_buffer; +  const XML_Memory_Handling_Suite m_mem; +  /* first character to be parsed */ +  const char *m_bufferPtr; +  /* past last character to be parsed */ +  char *m_bufferEnd; +  /* allocated end of buffer */ +  const char *m_bufferLim; +  XML_Index m_parseEndByteIndex; +  const char *m_parseEndPtr; +  XML_Char *m_dataBuf; +  XML_Char *m_dataBufEnd; +  XML_StartElementHandler m_startElementHandler; +  XML_EndElementHandler m_endElementHandler; +  XML_CharacterDataHandler m_characterDataHandler; +  XML_ProcessingInstructionHandler m_processingInstructionHandler; +  XML_CommentHandler m_commentHandler; +  XML_StartCdataSectionHandler m_startCdataSectionHandler; +  XML_EndCdataSectionHandler m_endCdataSectionHandler; +  XML_DefaultHandler m_defaultHandler; +  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler; +  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler; +  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; +  XML_NotationDeclHandler m_notationDeclHandler; +  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; +  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; +  XML_NotStandaloneHandler m_notStandaloneHandler; +  XML_ExternalEntityRefHandler m_externalEntityRefHandler; +  XML_Parser m_externalEntityRefHandlerArg; +  XML_SkippedEntityHandler m_skippedEntityHandler; +  XML_UnknownEncodingHandler m_unknownEncodingHandler; +  XML_ElementDeclHandler m_elementDeclHandler; +  XML_AttlistDeclHandler m_attlistDeclHandler; +  XML_EntityDeclHandler m_entityDeclHandler; +  XML_XmlDeclHandler m_xmlDeclHandler; +  const ENCODING *m_encoding; +  INIT_ENCODING m_initEncoding; +  const ENCODING *m_internalEncoding; +  const XML_Char *m_protocolEncodingName; +  XML_Bool m_ns; +  XML_Bool m_ns_triplets; +  void *m_unknownEncodingMem; +  void *m_unknownEncodingData; +  void *m_unknownEncodingHandlerData; +  void (XMLCALL *m_unknownEncodingRelease)(void *); +  PROLOG_STATE m_prologState; +  Processor *m_processor; +  enum XML_Error m_errorCode; +  const char *m_eventPtr; +  const char *m_eventEndPtr; +  const char *m_positionPtr; +  OPEN_INTERNAL_ENTITY *m_openInternalEntities; +  OPEN_INTERNAL_ENTITY *m_freeInternalEntities; +  XML_Bool m_defaultExpandInternalEntities; +  int m_tagLevel; +  ENTITY *m_declEntity; +  const XML_Char *m_doctypeName; +  const XML_Char *m_doctypeSysid; +  const XML_Char *m_doctypePubid; +  const XML_Char *m_declAttributeType; +  const XML_Char *m_declNotationName; +  const XML_Char *m_declNotationPublicId; +  ELEMENT_TYPE *m_declElementType; +  ATTRIBUTE_ID *m_declAttributeId; +  XML_Bool m_declAttributeIsCdata; +  XML_Bool m_declAttributeIsId; +  DTD *m_dtd; +  const XML_Char *m_curBase; +  TAG *m_tagStack; +  TAG *m_freeTagList; +  BINDING *m_inheritedBindings; +  BINDING *m_freeBindingList; +  int m_attsSize; +  int m_nSpecifiedAtts; +  int m_idAttIndex; +  ATTRIBUTE *m_atts; +  NS_ATT *m_nsAtts; +  unsigned long m_nsAttsVersion; +  unsigned char m_nsAttsPower; +  POSITION m_position; +  STRING_POOL m_tempPool; +  STRING_POOL m_temp2Pool; +  char *m_groupConnector; +  unsigned int m_groupSize; +  XML_Char m_namespaceSeparator; +  XML_Parser m_parentParser; +  XML_ParsingStatus m_parsingStatus; +#ifdef XML_DTD +  XML_Bool m_isParamEntity; +  XML_Bool m_useForeignDTD; +  enum XML_ParamEntityParsing m_paramEntityParsing; +#endif +}; + +#define MALLOC(s) (parser->m_mem.malloc_fcn((s))) +#define REALLOC(p,s) (parser->m_mem.realloc_fcn((p),(s))) +#define FREE(p) (parser->m_mem.free_fcn((p))) + +#define userData (parser->m_userData) +#define handlerArg (parser->m_handlerArg) +#define startElementHandler (parser->m_startElementHandler) +#define endElementHandler (parser->m_endElementHandler) +#define characterDataHandler (parser->m_characterDataHandler) +#define processingInstructionHandler \ +        (parser->m_processingInstructionHandler) +#define commentHandler (parser->m_commentHandler) +#define startCdataSectionHandler \ +        (parser->m_startCdataSectionHandler) +#define endCdataSectionHandler (parser->m_endCdataSectionHandler) +#define defaultHandler (parser->m_defaultHandler) +#define startDoctypeDeclHandler (parser->m_startDoctypeDeclHandler) +#define endDoctypeDeclHandler (parser->m_endDoctypeDeclHandler) +#define unparsedEntityDeclHandler \ +        (parser->m_unparsedEntityDeclHandler) +#define notationDeclHandler (parser->m_notationDeclHandler) +#define startNamespaceDeclHandler \ +        (parser->m_startNamespaceDeclHandler) +#define endNamespaceDeclHandler (parser->m_endNamespaceDeclHandler) +#define notStandaloneHandler (parser->m_notStandaloneHandler) +#define externalEntityRefHandler \ +        (parser->m_externalEntityRefHandler) +#define externalEntityRefHandlerArg \ +        (parser->m_externalEntityRefHandlerArg) +#define internalEntityRefHandler \ +        (parser->m_internalEntityRefHandler) +#define skippedEntityHandler (parser->m_skippedEntityHandler) +#define unknownEncodingHandler (parser->m_unknownEncodingHandler) +#define elementDeclHandler (parser->m_elementDeclHandler) +#define attlistDeclHandler (parser->m_attlistDeclHandler) +#define entityDeclHandler (parser->m_entityDeclHandler) +#define xmlDeclHandler (parser->m_xmlDeclHandler) +#define encoding (parser->m_encoding) +#define initEncoding (parser->m_initEncoding) +#define internalEncoding (parser->m_internalEncoding) +#define unknownEncodingMem (parser->m_unknownEncodingMem) +#define unknownEncodingData (parser->m_unknownEncodingData) +#define unknownEncodingHandlerData \ +  (parser->m_unknownEncodingHandlerData) +#define unknownEncodingRelease (parser->m_unknownEncodingRelease) +#define protocolEncodingName (parser->m_protocolEncodingName) +#define ns (parser->m_ns) +#define ns_triplets (parser->m_ns_triplets) +#define prologState (parser->m_prologState) +#define processor (parser->m_processor) +#define errorCode (parser->m_errorCode) +#define eventPtr (parser->m_eventPtr) +#define eventEndPtr (parser->m_eventEndPtr) +#define positionPtr (parser->m_positionPtr) +#define position (parser->m_position) +#define openInternalEntities (parser->m_openInternalEntities) +#define freeInternalEntities (parser->m_freeInternalEntities) +#define defaultExpandInternalEntities \ +        (parser->m_defaultExpandInternalEntities) +#define tagLevel (parser->m_tagLevel) +#define buffer (parser->m_buffer) +#define bufferPtr (parser->m_bufferPtr) +#define bufferEnd (parser->m_bufferEnd) +#define parseEndByteIndex (parser->m_parseEndByteIndex) +#define parseEndPtr (parser->m_parseEndPtr) +#define bufferLim (parser->m_bufferLim) +#define dataBuf (parser->m_dataBuf) +#define dataBufEnd (parser->m_dataBufEnd) +#define _dtd (parser->m_dtd) +#define curBase (parser->m_curBase) +#define declEntity (parser->m_declEntity) +#define doctypeName (parser->m_doctypeName) +#define doctypeSysid (parser->m_doctypeSysid) +#define doctypePubid (parser->m_doctypePubid) +#define declAttributeType (parser->m_declAttributeType) +#define declNotationName (parser->m_declNotationName) +#define declNotationPublicId (parser->m_declNotationPublicId) +#define declElementType (parser->m_declElementType) +#define declAttributeId (parser->m_declAttributeId) +#define declAttributeIsCdata (parser->m_declAttributeIsCdata) +#define declAttributeIsId (parser->m_declAttributeIsId) +#define freeTagList (parser->m_freeTagList) +#define freeBindingList (parser->m_freeBindingList) +#define inheritedBindings (parser->m_inheritedBindings) +#define tagStack (parser->m_tagStack) +#define atts (parser->m_atts) +#define attsSize (parser->m_attsSize) +#define nSpecifiedAtts (parser->m_nSpecifiedAtts) +#define idAttIndex (parser->m_idAttIndex) +#define nsAtts (parser->m_nsAtts) +#define nsAttsVersion (parser->m_nsAttsVersion) +#define nsAttsPower (parser->m_nsAttsPower) +#define tempPool (parser->m_tempPool) +#define temp2Pool (parser->m_temp2Pool) +#define groupConnector (parser->m_groupConnector) +#define groupSize (parser->m_groupSize) +#define namespaceSeparator (parser->m_namespaceSeparator) +#define parentParser (parser->m_parentParser) +#define ps_parsing (parser->m_parsingStatus.parsing) +#define ps_finalBuffer (parser->m_parsingStatus.finalBuffer) +#ifdef XML_DTD +#define isParamEntity (parser->m_isParamEntity) +#define useForeignDTD (parser->m_useForeignDTD) +#define paramEntityParsing (parser->m_paramEntityParsing) +#endif /* XML_DTD */ + +XML_Parser XMLCALL +XML_ParserCreate(const XML_Char *encodingName) +{ +  return XML_ParserCreate_MM(encodingName, NULL, NULL); +} + +XML_Parser XMLCALL +XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) +{ +  XML_Char tmp[2]; +  *tmp = nsSep; +  return XML_ParserCreate_MM(encodingName, NULL, tmp); +} + +static const XML_Char implicitContext[] = { +  ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p, +  ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,  +  ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g, +  ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9, +  ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e, +  ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0' +}; + +XML_Parser XMLCALL +XML_ParserCreate_MM(const XML_Char *encodingName, +                    const XML_Memory_Handling_Suite *memsuite, +                    const XML_Char *nameSep) +{ +  XML_Parser parser = parserCreate(encodingName, memsuite, nameSep, NULL); +  if (parser != NULL && ns) { +    /* implicit context only set for root parser, since child +       parsers (i.e. external entity parsers) will inherit it +    */ +    if (!setContext(parser, implicitContext)) { +      XML_ParserFree(parser); +      return NULL; +    } +  } +  return parser; +} + +static XML_Parser +parserCreate(const XML_Char *encodingName, +             const XML_Memory_Handling_Suite *memsuite, +             const XML_Char *nameSep, +             DTD *dtd) +{ +  XML_Parser parser; + +  if (memsuite) { +    XML_Memory_Handling_Suite *mtemp; +    parser = (XML_Parser) +      memsuite->malloc_fcn(sizeof(struct XML_ParserStruct)); +    if (parser != NULL) { +      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); +      mtemp->malloc_fcn = memsuite->malloc_fcn; +      mtemp->realloc_fcn = memsuite->realloc_fcn; +      mtemp->free_fcn = memsuite->free_fcn; +    } +  } +  else { +    XML_Memory_Handling_Suite *mtemp; +    parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct)); +    if (parser != NULL) { +      mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem); +      mtemp->malloc_fcn = malloc; +      mtemp->realloc_fcn = realloc; +      mtemp->free_fcn = free; +    } +  } + +  if (!parser) +    return parser; + +  buffer = NULL; +  bufferLim = NULL; + +  attsSize = INIT_ATTS_SIZE; +  atts = (ATTRIBUTE *)MALLOC(attsSize * sizeof(ATTRIBUTE)); +  if (atts == NULL) { +    FREE(parser); +    return NULL; +  } +  dataBuf = (XML_Char *)MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); +  if (dataBuf == NULL) { +    FREE(atts); +    FREE(parser); +    return NULL; +  } +  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; + +  if (dtd) +    _dtd = dtd; +  else { +    _dtd = dtdCreate(&parser->m_mem); +    if (_dtd == NULL) { +      FREE(dataBuf); +      FREE(atts); +      FREE(parser); +      return NULL; +    } +  } + +  freeBindingList = NULL; +  freeTagList = NULL; +  freeInternalEntities = NULL; + +  groupSize = 0; +  groupConnector = NULL; + +  unknownEncodingHandler = NULL; +  unknownEncodingHandlerData = NULL; + +  namespaceSeparator = ASCII_EXCL; +  ns = XML_FALSE; +  ns_triplets = XML_FALSE; + +  nsAtts = NULL; +  nsAttsVersion = 0; +  nsAttsPower = 0; + +  poolInit(&tempPool, &(parser->m_mem)); +  poolInit(&temp2Pool, &(parser->m_mem)); +  parserInit(parser, encodingName); + +  if (encodingName && !protocolEncodingName) { +    XML_ParserFree(parser); +    return NULL; +  } + +  if (nameSep) { +    ns = XML_TRUE; +    internalEncoding = XmlGetInternalEncodingNS(); +    namespaceSeparator = *nameSep; +  } +  else { +    internalEncoding = XmlGetInternalEncoding(); +  } + +  return parser; +} + +static void +parserInit(XML_Parser parser, const XML_Char *encodingName) +{ +  processor = prologInitProcessor; +  XmlPrologStateInit(&prologState); +  protocolEncodingName = (encodingName != NULL +                          ? poolCopyString(&tempPool, encodingName) +                          : NULL); +  curBase = NULL; +  XmlInitEncoding(&initEncoding, &encoding, 0); +  userData = NULL; +  handlerArg = NULL; +  startElementHandler = NULL; +  endElementHandler = NULL; +  characterDataHandler = NULL; +  processingInstructionHandler = NULL; +  commentHandler = NULL; +  startCdataSectionHandler = NULL; +  endCdataSectionHandler = NULL; +  defaultHandler = NULL; +  startDoctypeDeclHandler = NULL; +  endDoctypeDeclHandler = NULL; +  unparsedEntityDeclHandler = NULL; +  notationDeclHandler = NULL; +  startNamespaceDeclHandler = NULL; +  endNamespaceDeclHandler = NULL; +  notStandaloneHandler = NULL; +  externalEntityRefHandler = NULL; +  externalEntityRefHandlerArg = parser; +  skippedEntityHandler = NULL; +  elementDeclHandler = NULL; +  attlistDeclHandler = NULL; +  entityDeclHandler = NULL; +  xmlDeclHandler = NULL; +  bufferPtr = buffer; +  bufferEnd = buffer; +  parseEndByteIndex = 0; +  parseEndPtr = NULL; +  declElementType = NULL; +  declAttributeId = NULL; +  declEntity = NULL; +  doctypeName = NULL; +  doctypeSysid = NULL; +  doctypePubid = NULL; +  declAttributeType = NULL; +  declNotationName = NULL; +  declNotationPublicId = NULL; +  declAttributeIsCdata = XML_FALSE; +  declAttributeIsId = XML_FALSE; +  memset(&position, 0, sizeof(POSITION)); +  errorCode = XML_ERROR_NONE; +  eventPtr = NULL; +  eventEndPtr = NULL; +  positionPtr = NULL; +  openInternalEntities = NULL; +  defaultExpandInternalEntities = XML_TRUE; +  tagLevel = 0; +  tagStack = NULL; +  inheritedBindings = NULL; +  nSpecifiedAtts = 0; +  unknownEncodingMem = NULL; +  unknownEncodingRelease = NULL; +  unknownEncodingData = NULL; +  parentParser = NULL; +  ps_parsing = XML_INITIALIZED; +#ifdef XML_DTD +  isParamEntity = XML_FALSE; +  useForeignDTD = XML_FALSE; +  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +#endif +} + +/* moves list of bindings to freeBindingList */ +static void FASTCALL +moveToFreeBindingList(XML_Parser parser, BINDING *bindings) +{ +  while (bindings) { +    BINDING *b = bindings; +    bindings = bindings->nextTagBinding; +    b->nextTagBinding = freeBindingList; +    freeBindingList = b; +  } +} + +XML_Bool XMLCALL +XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) +{ +  TAG *tStk; +  OPEN_INTERNAL_ENTITY *openEntityList; +  if (parentParser) +    return XML_FALSE; +  /* move tagStack to freeTagList */ +  tStk = tagStack; +  while (tStk) { +    TAG *tag = tStk; +    tStk = tStk->parent; +    tag->parent = freeTagList; +    moveToFreeBindingList(parser, tag->bindings); +    tag->bindings = NULL; +    freeTagList = tag; +  } +  /* move openInternalEntities to freeInternalEntities */ +  openEntityList = openInternalEntities; +  while (openEntityList) { +    OPEN_INTERNAL_ENTITY *openEntity = openEntityList; +    openEntityList = openEntity->next; +    openEntity->next = freeInternalEntities; +    freeInternalEntities = openEntity; +  } +  moveToFreeBindingList(parser, inheritedBindings); +  FREE(unknownEncodingMem); +  if (unknownEncodingRelease) +    unknownEncodingRelease(unknownEncodingData); +  poolClear(&tempPool); +  poolClear(&temp2Pool); +  parserInit(parser, encodingName); +  dtdReset(_dtd, &parser->m_mem); +  return setContext(parser, implicitContext); +} + +enum XML_Status XMLCALL +XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) +{ +  /* Block after XML_Parse()/XML_ParseBuffer() has been called. +     XXX There's no way for the caller to determine which of the +     XXX possible error cases caused the XML_STATUS_ERROR return. +  */ +  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) +    return XML_STATUS_ERROR; +  if (encodingName == NULL) +    protocolEncodingName = NULL; +  else { +    protocolEncodingName = poolCopyString(&tempPool, encodingName); +    if (!protocolEncodingName) +      return XML_STATUS_ERROR; +  } +  return XML_STATUS_OK; +} + +XML_Parser XMLCALL +XML_ExternalEntityParserCreate(XML_Parser oldParser, +                               const XML_Char *context, +                               const XML_Char *encodingName) +{ +  XML_Parser parser = oldParser; +  DTD *newDtd = NULL; +  DTD *oldDtd = _dtd; +  XML_StartElementHandler oldStartElementHandler = startElementHandler; +  XML_EndElementHandler oldEndElementHandler = endElementHandler; +  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; +  XML_ProcessingInstructionHandler oldProcessingInstructionHandler +      = processingInstructionHandler; +  XML_CommentHandler oldCommentHandler = commentHandler; +  XML_StartCdataSectionHandler oldStartCdataSectionHandler +      = startCdataSectionHandler; +  XML_EndCdataSectionHandler oldEndCdataSectionHandler +      = endCdataSectionHandler; +  XML_DefaultHandler oldDefaultHandler = defaultHandler; +  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler +      = unparsedEntityDeclHandler; +  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; +  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler +      = startNamespaceDeclHandler; +  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler +      = endNamespaceDeclHandler; +  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; +  XML_ExternalEntityRefHandler oldExternalEntityRefHandler +      = externalEntityRefHandler; +  XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler; +  XML_UnknownEncodingHandler oldUnknownEncodingHandler +      = unknownEncodingHandler; +  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler; +  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler; +  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler; +  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler; +  ELEMENT_TYPE * oldDeclElementType = declElementType; + +  void *oldUserData = userData; +  void *oldHandlerArg = handlerArg; +  XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities; +  XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; +#ifdef XML_DTD +  enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing; +  int oldInEntityValue = prologState.inEntityValue; +#endif +  XML_Bool oldns_triplets = ns_triplets; + +#ifdef XML_DTD +  if (!context) +    newDtd = oldDtd; +#endif /* XML_DTD */ + +  /* Note that the magical uses of the pre-processor to make field +     access look more like C++ require that `parser' be overwritten +     here.  This makes this function more painful to follow than it +     would be otherwise. +  */ +  if (ns) { +    XML_Char tmp[2]; +    *tmp = namespaceSeparator; +    parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd); +  } +  else { +    parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd); +  } + +  if (!parser) +    return NULL; + +  startElementHandler = oldStartElementHandler; +  endElementHandler = oldEndElementHandler; +  characterDataHandler = oldCharacterDataHandler; +  processingInstructionHandler = oldProcessingInstructionHandler; +  commentHandler = oldCommentHandler; +  startCdataSectionHandler = oldStartCdataSectionHandler; +  endCdataSectionHandler = oldEndCdataSectionHandler; +  defaultHandler = oldDefaultHandler; +  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler; +  notationDeclHandler = oldNotationDeclHandler; +  startNamespaceDeclHandler = oldStartNamespaceDeclHandler; +  endNamespaceDeclHandler = oldEndNamespaceDeclHandler; +  notStandaloneHandler = oldNotStandaloneHandler; +  externalEntityRefHandler = oldExternalEntityRefHandler; +  skippedEntityHandler = oldSkippedEntityHandler; +  unknownEncodingHandler = oldUnknownEncodingHandler; +  elementDeclHandler = oldElementDeclHandler; +  attlistDeclHandler = oldAttlistDeclHandler; +  entityDeclHandler = oldEntityDeclHandler; +  xmlDeclHandler = oldXmlDeclHandler; +  declElementType = oldDeclElementType; +  userData = oldUserData; +  if (oldUserData == oldHandlerArg) +    handlerArg = userData; +  else +    handlerArg = parser; +  if (oldExternalEntityRefHandlerArg != oldParser) +    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; +  defaultExpandInternalEntities = oldDefaultExpandInternalEntities; +  ns_triplets = oldns_triplets; +  parentParser = oldParser; +#ifdef XML_DTD +  paramEntityParsing = oldParamEntityParsing; +  prologState.inEntityValue = oldInEntityValue; +  if (context) { +#endif /* XML_DTD */ +    if (!dtdCopy(_dtd, oldDtd, &parser->m_mem) +      || !setContext(parser, context)) { +      XML_ParserFree(parser); +      return NULL; +    } +    processor = externalEntityInitProcessor; +#ifdef XML_DTD +  } +  else { +    /* The DTD instance referenced by _dtd is shared between the document's +       root parser and external PE parsers, therefore one does not need to +       call setContext. In addition, one also *must* not call setContext, +       because this would overwrite existing prefix->binding pointers in +       _dtd with ones that get destroyed with the external PE parser. +       This would leave those prefixes with dangling pointers. +    */ +    isParamEntity = XML_TRUE; +    XmlPrologStateInitExternalEntity(&prologState); +    processor = externalParEntInitProcessor; +  } +#endif /* XML_DTD */ +  return parser; +} + +static void FASTCALL +destroyBindings(BINDING *bindings, XML_Parser parser) +{ +  for (;;) { +    BINDING *b = bindings; +    if (!b) +      break; +    bindings = b->nextTagBinding; +    FREE(b->uri); +    FREE(b); +  } +} + +void XMLCALL +XML_ParserFree(XML_Parser parser) +{ +  TAG *tagList; +  OPEN_INTERNAL_ENTITY *entityList; +  if (parser == NULL) +    return; +  /* free tagStack and freeTagList */ +  tagList = tagStack; +  for (;;) { +    TAG *p; +    if (tagList == NULL) { +      if (freeTagList == NULL) +        break; +      tagList = freeTagList; +      freeTagList = NULL; +    } +    p = tagList; +    tagList = tagList->parent; +    FREE(p->buf); +    destroyBindings(p->bindings, parser); +    FREE(p); +  } +  /* free openInternalEntities and freeInternalEntities */ +  entityList = openInternalEntities; +  for (;;) { +    OPEN_INTERNAL_ENTITY *openEntity; +    if (entityList == NULL) { +      if (freeInternalEntities == NULL) +        break; +      entityList = freeInternalEntities; +      freeInternalEntities = NULL; +    } +    openEntity = entityList; +    entityList = entityList->next; +    FREE(openEntity); +  } + +  destroyBindings(freeBindingList, parser); +  destroyBindings(inheritedBindings, parser); +  poolDestroy(&tempPool); +  poolDestroy(&temp2Pool); +#ifdef XML_DTD +  /* external parameter entity parsers share the DTD structure +     parser->m_dtd with the root parser, so we must not destroy it +  */ +  if (!isParamEntity && _dtd) +#else +  if (_dtd) +#endif /* XML_DTD */ +    dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem); +  FREE((void *)atts); +  FREE(groupConnector); +  FREE(buffer); +  FREE(dataBuf); +  FREE(nsAtts); +  FREE(unknownEncodingMem); +  if (unknownEncodingRelease) +    unknownEncodingRelease(unknownEncodingData); +  FREE(parser); +} + +void XMLCALL +XML_UseParserAsHandlerArg(XML_Parser parser) +{ +  handlerArg = parser; +} + +enum XML_Error XMLCALL +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) +{ +#ifdef XML_DTD +  /* block after XML_Parse()/XML_ParseBuffer() has been called */ +  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) +    return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING; +  useForeignDTD = useDTD; +  return XML_ERROR_NONE; +#else +  return XML_ERROR_FEATURE_REQUIRES_XML_DTD; +#endif +} + +void XMLCALL +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) +{ +  /* block after XML_Parse()/XML_ParseBuffer() has been called */ +  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) +    return; +  ns_triplets = do_nst ? XML_TRUE : XML_FALSE; +} + +void XMLCALL +XML_SetUserData(XML_Parser parser, void *p) +{ +  if (handlerArg == userData) +    handlerArg = userData = p; +  else +    userData = p; +} + +enum XML_Status XMLCALL +XML_SetBase(XML_Parser parser, const XML_Char *p) +{ +  if (p) { +    p = poolCopyString(&_dtd->pool, p); +    if (!p) +      return XML_STATUS_ERROR; +    curBase = p; +  } +  else +    curBase = NULL; +  return XML_STATUS_OK; +} + +const XML_Char * XMLCALL +XML_GetBase(XML_Parser parser) +{ +  return curBase; +} + +int XMLCALL +XML_GetSpecifiedAttributeCount(XML_Parser parser) +{ +  return nSpecifiedAtts; +} + +int XMLCALL +XML_GetIdAttributeIndex(XML_Parser parser) +{ +  return idAttIndex; +} + +void XMLCALL +XML_SetElementHandler(XML_Parser parser, +                      XML_StartElementHandler start, +                      XML_EndElementHandler end) +{ +  startElementHandler = start; +  endElementHandler = end; +} + +void XMLCALL +XML_SetStartElementHandler(XML_Parser parser, +                           XML_StartElementHandler start) { +  startElementHandler = start; +} + +void XMLCALL +XML_SetEndElementHandler(XML_Parser parser, +                         XML_EndElementHandler end) { +  endElementHandler = end; +} + +void XMLCALL +XML_SetCharacterDataHandler(XML_Parser parser, +                            XML_CharacterDataHandler handler) +{ +  characterDataHandler = handler; +} + +void XMLCALL +XML_SetProcessingInstructionHandler(XML_Parser parser, +                                    XML_ProcessingInstructionHandler handler) +{ +  processingInstructionHandler = handler; +} + +void XMLCALL +XML_SetCommentHandler(XML_Parser parser, +                      XML_CommentHandler handler) +{ +  commentHandler = handler; +} + +void XMLCALL +XML_SetCdataSectionHandler(XML_Parser parser, +                           XML_StartCdataSectionHandler start, +                           XML_EndCdataSectionHandler end) +{ +  startCdataSectionHandler = start; +  endCdataSectionHandler = end; +} + +void XMLCALL +XML_SetStartCdataSectionHandler(XML_Parser parser, +                                XML_StartCdataSectionHandler start) { +  startCdataSectionHandler = start; +} + +void XMLCALL +XML_SetEndCdataSectionHandler(XML_Parser parser, +                              XML_EndCdataSectionHandler end) { +  endCdataSectionHandler = end; +} + +void XMLCALL +XML_SetDefaultHandler(XML_Parser parser, +                      XML_DefaultHandler handler) +{ +  defaultHandler = handler; +  defaultExpandInternalEntities = XML_FALSE; +} + +void XMLCALL +XML_SetDefaultHandlerExpand(XML_Parser parser, +                            XML_DefaultHandler handler) +{ +  defaultHandler = handler; +  defaultExpandInternalEntities = XML_TRUE; +} + +void XMLCALL +XML_SetDoctypeDeclHandler(XML_Parser parser, +                          XML_StartDoctypeDeclHandler start, +                          XML_EndDoctypeDeclHandler end) +{ +  startDoctypeDeclHandler = start; +  endDoctypeDeclHandler = end; +} + +void XMLCALL +XML_SetStartDoctypeDeclHandler(XML_Parser parser, +                               XML_StartDoctypeDeclHandler start) { +  startDoctypeDeclHandler = start; +} + +void XMLCALL +XML_SetEndDoctypeDeclHandler(XML_Parser parser, +                             XML_EndDoctypeDeclHandler end) { +  endDoctypeDeclHandler = end; +} + +void XMLCALL +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, +                                 XML_UnparsedEntityDeclHandler handler) +{ +  unparsedEntityDeclHandler = handler; +} + +void XMLCALL +XML_SetNotationDeclHandler(XML_Parser parser, +                           XML_NotationDeclHandler handler) +{ +  notationDeclHandler = handler; +} + +void XMLCALL +XML_SetNamespaceDeclHandler(XML_Parser parser, +                            XML_StartNamespaceDeclHandler start, +                            XML_EndNamespaceDeclHandler end) +{ +  startNamespaceDeclHandler = start; +  endNamespaceDeclHandler = end; +} + +void XMLCALL +XML_SetStartNamespaceDeclHandler(XML_Parser parser, +                                 XML_StartNamespaceDeclHandler start) { +  startNamespaceDeclHandler = start; +} + +void XMLCALL +XML_SetEndNamespaceDeclHandler(XML_Parser parser, +                               XML_EndNamespaceDeclHandler end) { +  endNamespaceDeclHandler = end; +} + +void XMLCALL +XML_SetNotStandaloneHandler(XML_Parser parser, +                            XML_NotStandaloneHandler handler) +{ +  notStandaloneHandler = handler; +} + +void XMLCALL +XML_SetExternalEntityRefHandler(XML_Parser parser, +                                XML_ExternalEntityRefHandler handler) +{ +  externalEntityRefHandler = handler; +} + +void XMLCALL +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) +{ +  if (arg) +    externalEntityRefHandlerArg = (XML_Parser)arg; +  else +    externalEntityRefHandlerArg = parser; +} + +void XMLCALL +XML_SetSkippedEntityHandler(XML_Parser parser, +                            XML_SkippedEntityHandler handler) +{ +  skippedEntityHandler = handler; +} + +void XMLCALL +XML_SetUnknownEncodingHandler(XML_Parser parser, +                              XML_UnknownEncodingHandler handler, +                              void *data) +{ +  unknownEncodingHandler = handler; +  unknownEncodingHandlerData = data; +} + +void XMLCALL +XML_SetElementDeclHandler(XML_Parser parser, +                          XML_ElementDeclHandler eldecl) +{ +  elementDeclHandler = eldecl; +} + +void XMLCALL +XML_SetAttlistDeclHandler(XML_Parser parser, +                          XML_AttlistDeclHandler attdecl) +{ +  attlistDeclHandler = attdecl; +} + +void XMLCALL +XML_SetEntityDeclHandler(XML_Parser parser, +                         XML_EntityDeclHandler handler) +{ +  entityDeclHandler = handler; +} + +void XMLCALL +XML_SetXmlDeclHandler(XML_Parser parser, +                      XML_XmlDeclHandler handler) { +  xmlDeclHandler = handler; +} + +int XMLCALL +XML_SetParamEntityParsing(XML_Parser parser, +                          enum XML_ParamEntityParsing peParsing) +{ +  /* block after XML_Parse()/XML_ParseBuffer() has been called */ +  if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) +    return 0; +#ifdef XML_DTD +  paramEntityParsing = peParsing; +  return 1; +#else +  return peParsing == XML_PARAM_ENTITY_PARSING_NEVER; +#endif +} + +enum XML_Status XMLCALL +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) +{ +  switch (ps_parsing) { +  case XML_SUSPENDED: +    errorCode = XML_ERROR_SUSPENDED; +    return XML_STATUS_ERROR; +  case XML_FINISHED: +    errorCode = XML_ERROR_FINISHED; +    return XML_STATUS_ERROR; +  default: +    ps_parsing = XML_PARSING; +  } + +  if (len == 0) { +    ps_finalBuffer = (XML_Bool)isFinal; +    if (!isFinal) +      return XML_STATUS_OK; +    positionPtr = bufferPtr; +    parseEndPtr = bufferEnd; + +    /* If data are left over from last buffer, and we now know that these +       data are the final chunk of input, then we have to check them again +       to detect errors based on that fact. +    */ +    errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); + +    if (errorCode == XML_ERROR_NONE) { +      switch (ps_parsing) { +      case XML_SUSPENDED: +        XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); +        positionPtr = bufferPtr; +        return XML_STATUS_SUSPENDED; +      case XML_INITIALIZED:  +      case XML_PARSING: +        ps_parsing = XML_FINISHED; +        /* fall through */ +      default: +        return XML_STATUS_OK; +      } +    } +    eventEndPtr = eventPtr; +    processor = errorProcessor; +    return XML_STATUS_ERROR; +  } +#ifndef XML_CONTEXT_BYTES +  else if (bufferPtr == bufferEnd) { +    const char *end; +    int nLeftOver; +    enum XML_Error result; +    parseEndByteIndex += len; +    positionPtr = s; +    ps_finalBuffer = (XML_Bool)isFinal; + +    errorCode = processor(parser, s, parseEndPtr = s + len, &end); + +    if (errorCode != XML_ERROR_NONE) { +      eventEndPtr = eventPtr; +      processor = errorProcessor; +      return XML_STATUS_ERROR; +    } +    else { +      switch (ps_parsing) { +      case XML_SUSPENDED: +        result = XML_STATUS_SUSPENDED; +        break; +      case XML_INITIALIZED: +      case XML_PARSING: +        result = XML_STATUS_OK; +        if (isFinal) { +          ps_parsing = XML_FINISHED; +          return result; +        } +      } +    } + +    XmlUpdatePosition(encoding, positionPtr, end, &position); +    nLeftOver = s + len - end; +    if (nLeftOver) { +      if (buffer == NULL || nLeftOver > bufferLim - buffer) { +        /* FIXME avoid integer overflow */ +        char *temp; +        temp = (buffer == NULL +                ? (char *)MALLOC(len * 2) +                : (char *)REALLOC(buffer, len * 2)); +        if (temp == NULL) { +          errorCode = XML_ERROR_NO_MEMORY; +          return XML_STATUS_ERROR; +        } +        buffer = temp; +        if (!buffer) { +          errorCode = XML_ERROR_NO_MEMORY; +          eventPtr = eventEndPtr = NULL; +          processor = errorProcessor; +          return XML_STATUS_ERROR; +        } +        bufferLim = buffer + len * 2; +      } +      memcpy(buffer, end, nLeftOver); +    } +    bufferPtr = buffer; +    bufferEnd = buffer + nLeftOver; +    positionPtr = bufferPtr; +    parseEndPtr = bufferEnd; +    eventPtr = bufferPtr; +    eventEndPtr = bufferPtr; +    return result; +  } +#endif  /* not defined XML_CONTEXT_BYTES */ +  else { +    void *buff = XML_GetBuffer(parser, len); +    if (buff == NULL) +      return XML_STATUS_ERROR; +    else { +      memcpy(buff, s, len); +      return XML_ParseBuffer(parser, len, isFinal); +    } +  } +} + +enum XML_Status XMLCALL +XML_ParseBuffer(XML_Parser parser, int len, int isFinal) +{ +  const char *start; +  enum XML_Status result = XML_STATUS_OK; + +  switch (ps_parsing) { +  case XML_SUSPENDED: +    errorCode = XML_ERROR_SUSPENDED; +    return XML_STATUS_ERROR; +  case XML_FINISHED: +    errorCode = XML_ERROR_FINISHED; +    return XML_STATUS_ERROR; +  default: +    ps_parsing = XML_PARSING; +  } + +  start = bufferPtr; +  positionPtr = start; +  bufferEnd += len; +  parseEndPtr = bufferEnd; +  parseEndByteIndex += len; +  ps_finalBuffer = (XML_Bool)isFinal; + +  errorCode = processor(parser, start, parseEndPtr, &bufferPtr); + +  if (errorCode != XML_ERROR_NONE) { +    eventEndPtr = eventPtr; +    processor = errorProcessor; +    return XML_STATUS_ERROR; +  } +  else { +    switch (ps_parsing) { +    case XML_SUSPENDED: +      result = XML_STATUS_SUSPENDED; +      break; +    case XML_INITIALIZED:  +    case XML_PARSING: +      if (isFinal) { +        ps_parsing = XML_FINISHED; +        return result; +      } +    default: ;  /* should not happen */ +    } +  } + +  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); +  positionPtr = bufferPtr; +  return result; +} + +void * XMLCALL +XML_GetBuffer(XML_Parser parser, int len) +{ +  switch (ps_parsing) { +  case XML_SUSPENDED: +    errorCode = XML_ERROR_SUSPENDED; +    return NULL; +  case XML_FINISHED: +    errorCode = XML_ERROR_FINISHED; +    return NULL; +  default: ; +  } + +  if (len > bufferLim - bufferEnd) { +    /* FIXME avoid integer overflow */ +    int neededSize = len + (int)(bufferEnd - bufferPtr); +#ifdef XML_CONTEXT_BYTES +    int keep = (int)(bufferPtr - buffer); + +    if (keep > XML_CONTEXT_BYTES) +      keep = XML_CONTEXT_BYTES; +    neededSize += keep; +#endif  /* defined XML_CONTEXT_BYTES */ +    if (neededSize  <= bufferLim - buffer) { +#ifdef XML_CONTEXT_BYTES +      if (keep < bufferPtr - buffer) { +        int offset = (int)(bufferPtr - buffer) - keep; +        memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep); +        bufferEnd -= offset; +        bufferPtr -= offset; +      } +#else +      memmove(buffer, bufferPtr, bufferEnd - bufferPtr); +      bufferEnd = buffer + (bufferEnd - bufferPtr); +      bufferPtr = buffer; +#endif  /* not defined XML_CONTEXT_BYTES */ +    } +    else { +      char *newBuf; +      int bufferSize = (int)(bufferLim - bufferPtr); +      if (bufferSize == 0) +        bufferSize = INIT_BUFFER_SIZE; +      do { +        bufferSize *= 2; +      } while (bufferSize < neededSize); +      newBuf = (char *)MALLOC(bufferSize); +      if (newBuf == 0) { +        errorCode = XML_ERROR_NO_MEMORY; +        return NULL; +      } +      bufferLim = newBuf + bufferSize; +#ifdef XML_CONTEXT_BYTES +      if (bufferPtr) { +        int keep = (int)(bufferPtr - buffer); +        if (keep > XML_CONTEXT_BYTES) +          keep = XML_CONTEXT_BYTES; +        memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep); +        FREE(buffer); +        buffer = newBuf; +        bufferEnd = buffer + (bufferEnd - bufferPtr) + keep; +        bufferPtr = buffer + keep; +      } +      else { +        bufferEnd = newBuf + (bufferEnd - bufferPtr); +        bufferPtr = buffer = newBuf; +      } +#else +      if (bufferPtr) { +        memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); +        FREE(buffer); +      } +      bufferEnd = newBuf + (bufferEnd - bufferPtr); +      bufferPtr = buffer = newBuf; +#endif  /* not defined XML_CONTEXT_BYTES */ +    } +  } +  return bufferEnd; +} + +enum XML_Status XMLCALL +XML_StopParser(XML_Parser parser, XML_Bool resumable) +{ +  switch (ps_parsing) { +  case XML_SUSPENDED: +    if (resumable) { +      errorCode = XML_ERROR_SUSPENDED; +      return XML_STATUS_ERROR; +    } +    ps_parsing = XML_FINISHED; +    break; +  case XML_FINISHED: +    errorCode = XML_ERROR_FINISHED; +    return XML_STATUS_ERROR; +  default: +    if (resumable) { +#ifdef XML_DTD +      if (isParamEntity) { +        errorCode = XML_ERROR_SUSPEND_PE; +        return XML_STATUS_ERROR; +      } +#endif +      ps_parsing = XML_SUSPENDED; +    } +    else +      ps_parsing = XML_FINISHED; +  } +  return XML_STATUS_OK; +} + +enum XML_Status XMLCALL +XML_ResumeParser(XML_Parser parser) +{ +  enum XML_Status result = XML_STATUS_OK; + +  if (ps_parsing != XML_SUSPENDED) { +    errorCode = XML_ERROR_NOT_SUSPENDED; +    return XML_STATUS_ERROR; +  } +  ps_parsing = XML_PARSING; + +  errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr); + +  if (errorCode != XML_ERROR_NONE) { +    eventEndPtr = eventPtr; +    processor = errorProcessor; +    return XML_STATUS_ERROR; +  } +  else { +    switch (ps_parsing) { +    case XML_SUSPENDED: +      result = XML_STATUS_SUSPENDED; +      break; +    case XML_INITIALIZED:  +    case XML_PARSING: +      if (ps_finalBuffer) { +        ps_parsing = XML_FINISHED; +        return result; +      } +    default: ; +    } +  } + +  XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); +  positionPtr = bufferPtr; +  return result; +} + +void XMLCALL +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) +{ +  assert(status != NULL); +  *status = parser->m_parsingStatus; +} + +enum XML_Error XMLCALL +XML_GetErrorCode(XML_Parser parser) +{ +  return errorCode; +} + +XML_Index XMLCALL +XML_GetCurrentByteIndex(XML_Parser parser) +{ +  if (eventPtr) +    return parseEndByteIndex - (parseEndPtr - eventPtr); +  return -1; +} + +int XMLCALL +XML_GetCurrentByteCount(XML_Parser parser) +{ +  if (eventEndPtr && eventPtr) +    return (int)(eventEndPtr - eventPtr); +  return 0; +} + +const char * XMLCALL +XML_GetInputContext(XML_Parser parser, int *offset, int *size) +{ +#ifdef XML_CONTEXT_BYTES +  if (eventPtr && buffer) { +    *offset = (int)(eventPtr - buffer); +    *size   = (int)(bufferEnd - buffer); +    return buffer; +  } +#endif /* defined XML_CONTEXT_BYTES */ +  return (char *) 0; +} + +XML_Size XMLCALL +XML_GetCurrentLineNumber(XML_Parser parser) +{ +  if (eventPtr && eventPtr >= positionPtr) { +    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); +    positionPtr = eventPtr; +  } +  return position.lineNumber + 1; +} + +XML_Size XMLCALL +XML_GetCurrentColumnNumber(XML_Parser parser) +{ +  if (eventPtr && eventPtr >= positionPtr) { +    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); +    positionPtr = eventPtr; +  } +  return position.columnNumber; +} + +void XMLCALL +XML_FreeContentModel(XML_Parser parser, XML_Content *model) +{ +  FREE(model); +} + +void * XMLCALL +XML_MemMalloc(XML_Parser parser, size_t size) +{ +  return MALLOC(size); +} + +void * XMLCALL +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) +{ +  return REALLOC(ptr, size); +} + +void XMLCALL +XML_MemFree(XML_Parser parser, void *ptr) +{ +  FREE(ptr); +} + +void XMLCALL +XML_DefaultCurrent(XML_Parser parser) +{ +  if (defaultHandler) { +    if (openInternalEntities) +      reportDefault(parser, +                    internalEncoding, +                    openInternalEntities->internalEventPtr, +                    openInternalEntities->internalEventEndPtr); +    else +      reportDefault(parser, encoding, eventPtr, eventEndPtr); +  } +} + +const XML_LChar * XMLCALL +XML_ErrorString(enum XML_Error code) +{ +  static const XML_LChar* const message[] = { +    0, +    XML_L("out of memory"), +    XML_L("syntax error"), +    XML_L("no element found"), +    XML_L("not well-formed (invalid token)"), +    XML_L("unclosed token"), +    XML_L("partial character"), +    XML_L("mismatched tag"), +    XML_L("duplicate attribute"), +    XML_L("junk after document element"), +    XML_L("illegal parameter entity reference"), +    XML_L("undefined entity"), +    XML_L("recursive entity reference"), +    XML_L("asynchronous entity"), +    XML_L("reference to invalid character number"), +    XML_L("reference to binary entity"), +    XML_L("reference to external entity in attribute"), +    XML_L("XML or text declaration not at start of entity"), +    XML_L("unknown encoding"), +    XML_L("encoding specified in XML declaration is incorrect"), +    XML_L("unclosed CDATA section"), +    XML_L("error in processing external entity reference"), +    XML_L("document is not standalone"), +    XML_L("unexpected parser state - please send a bug report"), +    XML_L("entity declared in parameter entity"), +    XML_L("requested feature requires XML_DTD support in Expat"), +    XML_L("cannot change setting once parsing has begun"), +    XML_L("unbound prefix"), +    XML_L("must not undeclare prefix"), +    XML_L("incomplete markup in parameter entity"), +    XML_L("XML declaration not well-formed"), +    XML_L("text declaration not well-formed"), +    XML_L("illegal character(s) in public id"), +    XML_L("parser suspended"), +    XML_L("parser not suspended"), +    XML_L("parsing aborted"), +    XML_L("parsing finished"), +    XML_L("cannot suspend in external parameter entity"), +    XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"), +    XML_L("reserved prefix (xmlns) must not be declared or undeclared"), +    XML_L("prefix must not be bound to one of the reserved namespace names") +  }; +  if (code > 0 && code < sizeof(message)/sizeof(message[0])) +    return message[code]; +  return NULL; +} + +const XML_LChar * XMLCALL +XML_ExpatVersion(void) { + +  /* V1 is used to string-ize the version number. However, it would +     string-ize the actual version macro *names* unless we get them +     substituted before being passed to V1. CPP is defined to expand +     a macro, then rescan for more expansions. Thus, we use V2 to expand +     the version macros, then CPP will expand the resulting V1() macro +     with the correct numerals. */ +  /* ### I'm assuming cpp is portable in this respect... */ + +#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c) +#define V2(a,b,c) XML_L("expat_")V1(a,b,c) + +  return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION); + +#undef V1 +#undef V2 +} + +XML_Expat_Version XMLCALL +XML_ExpatVersionInfo(void) +{ +  XML_Expat_Version version; + +  version.major = XML_MAJOR_VERSION; +  version.minor = XML_MINOR_VERSION; +  version.micro = XML_MICRO_VERSION; + +  return version; +} + +const XML_Feature * XMLCALL +XML_GetFeatureList(void) +{ +  static const XML_Feature features[] = { +    {XML_FEATURE_SIZEOF_XML_CHAR,  XML_L("sizeof(XML_Char)"), +     sizeof(XML_Char)}, +    {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"), +     sizeof(XML_LChar)}, +#ifdef XML_UNICODE +    {XML_FEATURE_UNICODE,          XML_L("XML_UNICODE"), 0}, +#endif +#ifdef XML_UNICODE_WCHAR_T +    {XML_FEATURE_UNICODE_WCHAR_T,  XML_L("XML_UNICODE_WCHAR_T"), 0}, +#endif +#ifdef XML_DTD +    {XML_FEATURE_DTD,              XML_L("XML_DTD"), 0}, +#endif +#ifdef XML_CONTEXT_BYTES +    {XML_FEATURE_CONTEXT_BYTES,    XML_L("XML_CONTEXT_BYTES"), +     XML_CONTEXT_BYTES}, +#endif +#ifdef XML_MIN_SIZE +    {XML_FEATURE_MIN_SIZE,         XML_L("XML_MIN_SIZE"), 0}, +#endif +#ifdef XML_NS +    {XML_FEATURE_NS,               XML_L("XML_NS"), 0}, +#endif +#ifdef XML_LARGE_SIZE +    {XML_FEATURE_LARGE_SIZE,       XML_L("XML_LARGE_SIZE"), 0}, +#endif     +    {XML_FEATURE_END,              NULL, 0} +  }; + +  return features; +} + +/* Initially tag->rawName always points into the parse buffer; +   for those TAG instances opened while the current parse buffer was +   processed, and not yet closed, we need to store tag->rawName in a more +   permanent location, since the parse buffer is about to be discarded. +*/ +static XML_Bool +storeRawNames(XML_Parser parser) +{ +  TAG *tag = tagStack; +  while (tag) { +    int bufSize; +    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1); +    char *rawNameBuf = tag->buf + nameLen; +    /* Stop if already stored.  Since tagStack is a stack, we can stop +       at the first entry that has already been copied; everything +       below it in the stack is already been accounted for in a +       previous call to this function. +    */ +    if (tag->rawName == rawNameBuf) +      break; +    /* For re-use purposes we need to ensure that the +       size of tag->buf is a multiple of sizeof(XML_Char). +    */ +    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)); +    if (bufSize > tag->bufEnd - tag->buf) { +      char *temp = (char *)REALLOC(tag->buf, bufSize); +      if (temp == NULL) +        return XML_FALSE; +      /* if tag->name.str points to tag->buf (only when namespace +         processing is off) then we have to update it +      */ +      if (tag->name.str == (XML_Char *)tag->buf) +        tag->name.str = (XML_Char *)temp; +      /* if tag->name.localPart is set (when namespace processing is on) +         then update it as well, since it will always point into tag->buf +      */ +      if (tag->name.localPart) +        tag->name.localPart = (XML_Char *)temp + (tag->name.localPart - +                                                  (XML_Char *)tag->buf); +      tag->buf = temp; +      tag->bufEnd = temp + bufSize; +      rawNameBuf = temp + nameLen; +    } +    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength); +    tag->rawName = rawNameBuf; +    tag = tag->parent; +  } +  return XML_TRUE; +} + +static enum XML_Error PTRCALL +contentProcessor(XML_Parser parser, +                 const char *start, +                 const char *end, +                 const char **endPtr) +{ +  enum XML_Error result = doContent(parser, 0, encoding, start, end,  +                                    endPtr, (XML_Bool)!ps_finalBuffer); +  if (result == XML_ERROR_NONE) { +    if (!storeRawNames(parser)) +      return XML_ERROR_NO_MEMORY; +  } +  return result; +} + +static enum XML_Error PTRCALL +externalEntityInitProcessor(XML_Parser parser, +                            const char *start, +                            const char *end, +                            const char **endPtr) +{ +  enum XML_Error result = initializeEncoding(parser); +  if (result != XML_ERROR_NONE) +    return result; +  processor = externalEntityInitProcessor2; +  return externalEntityInitProcessor2(parser, start, end, endPtr); +} + +static enum XML_Error PTRCALL +externalEntityInitProcessor2(XML_Parser parser, +                             const char *start, +                             const char *end, +                             const char **endPtr) +{ +  const char *next = start; /* XmlContentTok doesn't always set the last arg */ +  int tok = XmlContentTok(encoding, start, end, &next); +  switch (tok) { +  case XML_TOK_BOM: +    /* If we are at the end of the buffer, this would cause the next stage, +       i.e. externalEntityInitProcessor3, to pass control directly to +       doContent (by detecting XML_TOK_NONE) without processing any xml text +       declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent. +    */ +    if (next == end && !ps_finalBuffer) { +      *endPtr = next; +      return XML_ERROR_NONE; +    } +    start = next; +    break; +  case XML_TOK_PARTIAL: +    if (!ps_finalBuffer) { +      *endPtr = start; +      return XML_ERROR_NONE; +    } +    eventPtr = start; +    return XML_ERROR_UNCLOSED_TOKEN; +  case XML_TOK_PARTIAL_CHAR: +    if (!ps_finalBuffer) { +      *endPtr = start; +      return XML_ERROR_NONE; +    } +    eventPtr = start; +    return XML_ERROR_PARTIAL_CHAR; +  } +  processor = externalEntityInitProcessor3; +  return externalEntityInitProcessor3(parser, start, end, endPtr); +} + +static enum XML_Error PTRCALL +externalEntityInitProcessor3(XML_Parser parser, +                             const char *start, +                             const char *end, +                             const char **endPtr) +{ +  int tok; +  const char *next = start; /* XmlContentTok doesn't always set the last arg */ +  eventPtr = start; +  tok = XmlContentTok(encoding, start, end, &next); +  eventEndPtr = next; + +  switch (tok) { +  case XML_TOK_XML_DECL: +    { +      enum XML_Error result; +      result = processXmlDecl(parser, 1, start, next); +      if (result != XML_ERROR_NONE) +        return result; +      switch (ps_parsing) { +      case XML_SUSPENDED:  +        *endPtr = next; +        return XML_ERROR_NONE; +      case XML_FINISHED: +        return XML_ERROR_ABORTED; +      default: +        start = next; +      } +    } +    break; +  case XML_TOK_PARTIAL: +    if (!ps_finalBuffer) { +      *endPtr = start; +      return XML_ERROR_NONE; +    } +    return XML_ERROR_UNCLOSED_TOKEN; +  case XML_TOK_PARTIAL_CHAR: +    if (!ps_finalBuffer) { +      *endPtr = start; +      return XML_ERROR_NONE; +    } +    return XML_ERROR_PARTIAL_CHAR; +  } +  processor = externalEntityContentProcessor; +  tagLevel = 1; +  return externalEntityContentProcessor(parser, start, end, endPtr); +} + +static enum XML_Error PTRCALL +externalEntityContentProcessor(XML_Parser parser, +                               const char *start, +                               const char *end, +                               const char **endPtr) +{ +  enum XML_Error result = doContent(parser, 1, encoding, start, end,  +                                    endPtr, (XML_Bool)!ps_finalBuffer); +  if (result == XML_ERROR_NONE) { +    if (!storeRawNames(parser)) +      return XML_ERROR_NO_MEMORY; +  } +  return result; +} + +static enum XML_Error +doContent(XML_Parser parser, +          int startTagLevel, +          const ENCODING *enc, +          const char *s, +          const char *end, +          const char **nextPtr, +          XML_Bool haveMore) +{ +  /* save one level of indirection */ +  DTD * const dtd = _dtd;   + +  const char **eventPP; +  const char **eventEndPP; +  if (enc == encoding) { +    eventPP = &eventPtr; +    eventEndPP = &eventEndPtr; +  } +  else { +    eventPP = &(openInternalEntities->internalEventPtr); +    eventEndPP = &(openInternalEntities->internalEventEndPtr); +  } +  *eventPP = s; + +  for (;;) { +    const char *next = s; /* XmlContentTok doesn't always set the last arg */ +    int tok = XmlContentTok(enc, s, end, &next); +    *eventEndPP = next; +    switch (tok) { +    case XML_TOK_TRAILING_CR: +      if (haveMore) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      *eventEndPP = end; +      if (characterDataHandler) { +        XML_Char c = 0xA; +        characterDataHandler(handlerArg, &c, 1); +      } +      else if (defaultHandler) +        reportDefault(parser, enc, s, end); +      /* We are at the end of the final buffer, should we check for  +         XML_SUSPENDED, XML_FINISHED?  +      */ +      if (startTagLevel == 0) +        return XML_ERROR_NO_ELEMENTS; +      if (tagLevel != startTagLevel) +        return XML_ERROR_ASYNC_ENTITY; +      *nextPtr = end; +      return XML_ERROR_NONE; +    case XML_TOK_NONE: +      if (haveMore) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      if (startTagLevel > 0) { +        if (tagLevel != startTagLevel) +          return XML_ERROR_ASYNC_ENTITY; +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      return XML_ERROR_NO_ELEMENTS; +    case XML_TOK_INVALID: +      *eventPP = next; +      return XML_ERROR_INVALID_TOKEN; +    case XML_TOK_PARTIAL: +      if (haveMore) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      return XML_ERROR_UNCLOSED_TOKEN; +    case XML_TOK_PARTIAL_CHAR: +      if (haveMore) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      return XML_ERROR_PARTIAL_CHAR; +    case XML_TOK_ENTITY_REF: +      { +        const XML_Char *name; +        ENTITY *entity; +        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, +                                              s + enc->minBytesPerChar, +                                              next - enc->minBytesPerChar); +        if (ch) { +          if (characterDataHandler) +            characterDataHandler(handlerArg, &ch, 1); +          else if (defaultHandler) +            reportDefault(parser, enc, s, next); +          break; +        } +        name = poolStoreString(&dtd->pool, enc, +                                s + enc->minBytesPerChar, +                                next - enc->minBytesPerChar); +        if (!name) +          return XML_ERROR_NO_MEMORY; +        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0); +        poolDiscard(&dtd->pool); +        /* First, determine if a check for an existing declaration is needed; +           if yes, check that the entity exists, and that it is internal, +           otherwise call the skipped entity or default handler. +        */ +        if (!dtd->hasParamEntityRefs || dtd->standalone) { +          if (!entity) +            return XML_ERROR_UNDEFINED_ENTITY; +          else if (!entity->is_internal) +            return XML_ERROR_ENTITY_DECLARED_IN_PE; +        } +        else if (!entity) { +          if (skippedEntityHandler) +            skippedEntityHandler(handlerArg, name, 0); +          else if (defaultHandler) +            reportDefault(parser, enc, s, next); +          break; +        } +        if (entity->open) +          return XML_ERROR_RECURSIVE_ENTITY_REF; +        if (entity->notation) +          return XML_ERROR_BINARY_ENTITY_REF; +        if (entity->textPtr) { +          enum XML_Error result; +          if (!defaultExpandInternalEntities) { +            if (skippedEntityHandler) +              skippedEntityHandler(handlerArg, entity->name, 0); +            else if (defaultHandler) +              reportDefault(parser, enc, s, next); +            break; +          } +          result = processInternalEntity(parser, entity, XML_FALSE); +          if (result != XML_ERROR_NONE) +            return result; +        } +        else if (externalEntityRefHandler) { +          const XML_Char *context; +          entity->open = XML_TRUE; +          context = getContext(parser); +          entity->open = XML_FALSE; +          if (!context) +            return XML_ERROR_NO_MEMORY; +          if (!externalEntityRefHandler(externalEntityRefHandlerArg, +                                        context, +                                        entity->base, +                                        entity->systemId, +                                        entity->publicId)) +            return XML_ERROR_EXTERNAL_ENTITY_HANDLING; +          poolDiscard(&tempPool); +        } +        else if (defaultHandler) +          reportDefault(parser, enc, s, next); +        break; +      } +    case XML_TOK_START_TAG_NO_ATTS: +      /* fall through */ +    case XML_TOK_START_TAG_WITH_ATTS: +      { +        TAG *tag; +        enum XML_Error result; +        XML_Char *toPtr; +        if (freeTagList) { +          tag = freeTagList; +          freeTagList = freeTagList->parent; +        } +        else { +          tag = (TAG *)MALLOC(sizeof(TAG)); +          if (!tag) +            return XML_ERROR_NO_MEMORY; +          tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE); +          if (!tag->buf) { +            FREE(tag); +            return XML_ERROR_NO_MEMORY; +          } +          tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; +        } +        tag->bindings = NULL; +        tag->parent = tagStack; +        tagStack = tag; +        tag->name.localPart = NULL; +        tag->name.prefix = NULL; +        tag->rawName = s + enc->minBytesPerChar; +        tag->rawNameLength = XmlNameLength(enc, tag->rawName); +        ++tagLevel; +        { +          const char *rawNameEnd = tag->rawName + tag->rawNameLength; +          const char *fromPtr = tag->rawName; +          toPtr = (XML_Char *)tag->buf; +          for (;;) { +            int bufSize; +            int convLen; +            XmlConvert(enc, +                       &fromPtr, rawNameEnd, +                       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); +            convLen = (int)(toPtr - (XML_Char *)tag->buf); +            if (fromPtr == rawNameEnd) { +              tag->name.strLen = convLen; +              break; +            } +            bufSize = (int)(tag->bufEnd - tag->buf) << 1; +            { +              char *temp = (char *)REALLOC(tag->buf, bufSize); +              if (temp == NULL) +                return XML_ERROR_NO_MEMORY; +              tag->buf = temp; +              tag->bufEnd = temp + bufSize; +              toPtr = (XML_Char *)temp + convLen; +            } +          } +        } +        tag->name.str = (XML_Char *)tag->buf; +        *toPtr = XML_T('\0'); +        result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); +        if (result) +          return result; +        if (startElementHandler) +          startElementHandler(handlerArg, tag->name.str, +                              (const XML_Char **)atts); +        else if (defaultHandler) +          reportDefault(parser, enc, s, next); +        poolClear(&tempPool); +        break; +      } +    case XML_TOK_EMPTY_ELEMENT_NO_ATTS: +      /* fall through */ +    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: +      { +        const char *rawName = s + enc->minBytesPerChar; +        enum XML_Error result; +        BINDING *bindings = NULL; +        XML_Bool noElmHandlers = XML_TRUE; +        TAG_NAME name; +        name.str = poolStoreString(&tempPool, enc, rawName, +                                   rawName + XmlNameLength(enc, rawName)); +        if (!name.str) +          return XML_ERROR_NO_MEMORY; +        poolFinish(&tempPool); +        result = storeAtts(parser, enc, s, &name, &bindings); +        if (result) +          return result; +        poolFinish(&tempPool); +        if (startElementHandler) { +          startElementHandler(handlerArg, name.str, (const XML_Char **)atts); +          noElmHandlers = XML_FALSE; +        } +        if (endElementHandler) { +          if (startElementHandler) +            *eventPP = *eventEndPP; +          endElementHandler(handlerArg, name.str); +          noElmHandlers = XML_FALSE; +        } +        if (noElmHandlers && defaultHandler) +          reportDefault(parser, enc, s, next); +        poolClear(&tempPool); +        while (bindings) { +          BINDING *b = bindings; +          if (endNamespaceDeclHandler) +            endNamespaceDeclHandler(handlerArg, b->prefix->name); +          bindings = bindings->nextTagBinding; +          b->nextTagBinding = freeBindingList; +          freeBindingList = b; +          b->prefix->binding = b->prevPrefixBinding; +        } +      } +      if (tagLevel == 0) +        return epilogProcessor(parser, next, end, nextPtr); +      break; +    case XML_TOK_END_TAG: +      if (tagLevel == startTagLevel) +        return XML_ERROR_ASYNC_ENTITY; +      else { +        int len; +        const char *rawName; +        TAG *tag = tagStack; +        tagStack = tag->parent; +        tag->parent = freeTagList; +        freeTagList = tag; +        rawName = s + enc->minBytesPerChar*2; +        len = XmlNameLength(enc, rawName); +        if (len != tag->rawNameLength +            || memcmp(tag->rawName, rawName, len) != 0) { +          *eventPP = rawName; +          return XML_ERROR_TAG_MISMATCH; +        } +        --tagLevel; +        if (endElementHandler) { +          const XML_Char *localPart; +          const XML_Char *prefix; +          XML_Char *uri; +          localPart = tag->name.localPart; +          if (ns && localPart) { +            /* localPart and prefix may have been overwritten in +               tag->name.str, since this points to the binding->uri +               buffer which gets re-used; so we have to add them again +            */ +            uri = (XML_Char *)tag->name.str + tag->name.uriLen; +            /* don't need to check for space - already done in storeAtts() */ +            while (*localPart) *uri++ = *localPart++; +            prefix = (XML_Char *)tag->name.prefix; +            if (ns_triplets && prefix) { +              *uri++ = namespaceSeparator; +              while (*prefix) *uri++ = *prefix++; +             } +            *uri = XML_T('\0'); +          } +          endElementHandler(handlerArg, tag->name.str); +        } +        else if (defaultHandler) +          reportDefault(parser, enc, s, next); +        while (tag->bindings) { +          BINDING *b = tag->bindings; +          if (endNamespaceDeclHandler) +            endNamespaceDeclHandler(handlerArg, b->prefix->name); +          tag->bindings = tag->bindings->nextTagBinding; +          b->nextTagBinding = freeBindingList; +          freeBindingList = b; +          b->prefix->binding = b->prevPrefixBinding; +        } +        if (tagLevel == 0) +          return epilogProcessor(parser, next, end, nextPtr); +      } +      break; +    case XML_TOK_CHAR_REF: +      { +        int n = XmlCharRefNumber(enc, s); +        if (n < 0) +          return XML_ERROR_BAD_CHAR_REF; +        if (characterDataHandler) { +          XML_Char buf[XML_ENCODE_MAX]; +          characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); +        } +        else if (defaultHandler) +          reportDefault(parser, enc, s, next); +      } +      break; +    case XML_TOK_XML_DECL: +      return XML_ERROR_MISPLACED_XML_PI; +    case XML_TOK_DATA_NEWLINE: +      if (characterDataHandler) { +        XML_Char c = 0xA; +        characterDataHandler(handlerArg, &c, 1); +      } +      else if (defaultHandler) +        reportDefault(parser, enc, s, next); +      break; +    case XML_TOK_CDATA_SECT_OPEN: +      { +        enum XML_Error result; +        if (startCdataSectionHandler) +          startCdataSectionHandler(handlerArg); +#if 0 +        /* Suppose you doing a transformation on a document that involves +           changing only the character data.  You set up a defaultHandler +           and a characterDataHandler.  The defaultHandler simply copies +           characters through.  The characterDataHandler does the +           transformation and writes the characters out escaping them as +           necessary.  This case will fail to work if we leave out the +           following two lines (because & and < inside CDATA sections will +           be incorrectly escaped). + +           However, now we have a start/endCdataSectionHandler, so it seems +           easier to let the user deal with this. +        */ +        else if (characterDataHandler) +          characterDataHandler(handlerArg, dataBuf, 0); +#endif +        else if (defaultHandler) +          reportDefault(parser, enc, s, next); +        result = doCdataSection(parser, enc, &next, end, nextPtr, haveMore); +        if (result != XML_ERROR_NONE) +          return result; +        else if (!next) { +          processor = cdataSectionProcessor; +          return result; +        } +      } +      break; +    case XML_TOK_TRAILING_RSQB: +      if (haveMore) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      if (characterDataHandler) { +        if (MUST_CONVERT(enc, s)) { +          ICHAR *dataPtr = (ICHAR *)dataBuf; +          XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); +          characterDataHandler(handlerArg, dataBuf, +                               (int)(dataPtr - (ICHAR *)dataBuf)); +        } +        else +          characterDataHandler(handlerArg, +                               (XML_Char *)s, +                               (int)((XML_Char *)end - (XML_Char *)s)); +      } +      else if (defaultHandler) +        reportDefault(parser, enc, s, end); +      /* We are at the end of the final buffer, should we check for  +         XML_SUSPENDED, XML_FINISHED?  +      */ +      if (startTagLevel == 0) { +        *eventPP = end; +        return XML_ERROR_NO_ELEMENTS; +      } +      if (tagLevel != startTagLevel) { +        *eventPP = end; +        return XML_ERROR_ASYNC_ENTITY; +      } +      *nextPtr = end; +      return XML_ERROR_NONE; +    case XML_TOK_DATA_CHARS:  +      { +        XML_CharacterDataHandler charDataHandler = characterDataHandler; +        if (charDataHandler) { +          if (MUST_CONVERT(enc, s)) { +            for (;;) { +              ICHAR *dataPtr = (ICHAR *)dataBuf; +              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); +              *eventEndPP = s; +              charDataHandler(handlerArg, dataBuf, +                              (int)(dataPtr - (ICHAR *)dataBuf)); +              if (s == next) +                break; +              *eventPP = s; +            } +          } +          else +            charDataHandler(handlerArg, +                            (XML_Char *)s, +                            (int)((XML_Char *)next - (XML_Char *)s)); +        } +        else if (defaultHandler) +          reportDefault(parser, enc, s, next); +      } +      break; +    case XML_TOK_PI: +      if (!reportProcessingInstruction(parser, enc, s, next)) +        return XML_ERROR_NO_MEMORY; +      break; +    case XML_TOK_COMMENT: +      if (!reportComment(parser, enc, s, next)) +        return XML_ERROR_NO_MEMORY; +      break; +    default: +      if (defaultHandler) +        reportDefault(parser, enc, s, next); +      break; +    } +    *eventPP = s = next; +    switch (ps_parsing) { +    case XML_SUSPENDED:  +      *nextPtr = next; +      return XML_ERROR_NONE; +    case XML_FINISHED: +      return XML_ERROR_ABORTED; +    default: ; +    } +  } +  /* not reached */ +} + +/* Precondition: all arguments must be non-NULL; +   Purpose: +   - normalize attributes +   - check attributes for well-formedness +   - generate namespace aware attribute names (URI, prefix) +   - build list of attributes for startElementHandler +   - default attributes +   - process namespace declarations (check and report them) +   - generate namespace aware element name (URI, prefix) +*/ +static enum XML_Error +storeAtts(XML_Parser parser, const ENCODING *enc, +          const char *attStr, TAG_NAME *tagNamePtr, +          BINDING **bindingsPtr) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  ELEMENT_TYPE *elementType; +  int nDefaultAtts; +  const XML_Char **appAtts;   /* the attribute list for the application */ +  int attIndex = 0; +  int prefixLen; +  int i; +  int n; +  XML_Char *uri; +  int nPrefixes = 0; +  BINDING *binding; +  const XML_Char *localPart; + +  /* lookup the element type name */ +  elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, tagNamePtr->str,0); +  if (!elementType) { +    const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str); +    if (!name) +      return XML_ERROR_NO_MEMORY; +    elementType = (ELEMENT_TYPE *)lookup(&dtd->elementTypes, name, +                                         sizeof(ELEMENT_TYPE)); +    if (!elementType) +      return XML_ERROR_NO_MEMORY; +    if (ns && !setElementTypePrefix(parser, elementType)) +      return XML_ERROR_NO_MEMORY; +  } +  nDefaultAtts = elementType->nDefaultAtts; + +  /* get the attributes from the tokenizer */ +  n = XmlGetAttributes(enc, attStr, attsSize, atts); +  if (n + nDefaultAtts > attsSize) { +    int oldAttsSize = attsSize; +    ATTRIBUTE *temp; +    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; +    temp = (ATTRIBUTE *)REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE)); +    if (temp == NULL) +      return XML_ERROR_NO_MEMORY; +    atts = temp; +    if (n > oldAttsSize) +      XmlGetAttributes(enc, attStr, n, atts); +  } + +  appAtts = (const XML_Char **)atts; +  for (i = 0; i < n; i++) { +    /* add the name and value to the attribute list */ +    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name, +                                         atts[i].name +                                         + XmlNameLength(enc, atts[i].name)); +    if (!attId) +      return XML_ERROR_NO_MEMORY; +    /* Detect duplicate attributes by their QNames. This does not work when +       namespace processing is turned on and different prefixes for the same +       namespace are used. For this case we have a check further down. +    */ +    if ((attId->name)[-1]) { +      if (enc == encoding) +        eventPtr = atts[i].name; +      return XML_ERROR_DUPLICATE_ATTRIBUTE; +    } +    (attId->name)[-1] = 1; +    appAtts[attIndex++] = attId->name; +    if (!atts[i].normalized) { +      enum XML_Error result; +      XML_Bool isCdata = XML_TRUE; + +      /* figure out whether declared as other than CDATA */ +      if (attId->maybeTokenized) { +        int j; +        for (j = 0; j < nDefaultAtts; j++) { +          if (attId == elementType->defaultAtts[j].id) { +            isCdata = elementType->defaultAtts[j].isCdata; +            break; +          } +        } +      } + +      /* normalize the attribute value */ +      result = storeAttributeValue(parser, enc, isCdata, +                                   atts[i].valuePtr, atts[i].valueEnd, +                                   &tempPool); +      if (result) +        return result; +      appAtts[attIndex] = poolStart(&tempPool); +      poolFinish(&tempPool); +    } +    else { +      /* the value did not need normalizing */ +      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, +                                          atts[i].valueEnd); +      if (appAtts[attIndex] == 0) +        return XML_ERROR_NO_MEMORY; +      poolFinish(&tempPool); +    } +    /* handle prefixed attribute names */ +    if (attId->prefix) { +      if (attId->xmlns) { +        /* deal with namespace declarations here */ +        enum XML_Error result = addBinding(parser, attId->prefix, attId, +                                           appAtts[attIndex], bindingsPtr); +        if (result) +          return result; +        --attIndex; +      } +      else { +        /* deal with other prefixed names later */ +        attIndex++; +        nPrefixes++; +        (attId->name)[-1] = 2; +      } +    } +    else +      attIndex++; +  } + +  /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */ +  nSpecifiedAtts = attIndex; +  if (elementType->idAtt && (elementType->idAtt->name)[-1]) { +    for (i = 0; i < attIndex; i += 2) +      if (appAtts[i] == elementType->idAtt->name) { +        idAttIndex = i; +        break; +      } +  } +  else +    idAttIndex = -1; + +  /* do attribute defaulting */ +  for (i = 0; i < nDefaultAtts; i++) { +    const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i; +    if (!(da->id->name)[-1] && da->value) { +      if (da->id->prefix) { +        if (da->id->xmlns) { +          enum XML_Error result = addBinding(parser, da->id->prefix, da->id, +                                             da->value, bindingsPtr); +          if (result) +            return result; +        } +        else { +          (da->id->name)[-1] = 2; +          nPrefixes++; +          appAtts[attIndex++] = da->id->name; +          appAtts[attIndex++] = da->value; +        } +      } +      else { +        (da->id->name)[-1] = 1; +        appAtts[attIndex++] = da->id->name; +        appAtts[attIndex++] = da->value; +      } +    } +  } +  appAtts[attIndex] = 0; + +  /* expand prefixed attribute names, check for duplicates, +     and clear flags that say whether attributes were specified */ +  i = 0; +  if (nPrefixes) { +    int j;  /* hash table index */ +    unsigned long version = nsAttsVersion; +    int nsAttsSize = (int)1 << nsAttsPower; +    /* size of hash table must be at least 2 * (# of prefixed attributes) */ +    if ((nPrefixes << 1) >> nsAttsPower) {  /* true for nsAttsPower = 0 */ +      NS_ATT *temp; +      /* hash table size must also be a power of 2 and >= 8 */ +      while (nPrefixes >> nsAttsPower++); +      if (nsAttsPower < 3) +        nsAttsPower = 3; +      nsAttsSize = (int)1 << nsAttsPower; +      temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT)); +      if (!temp) +        return XML_ERROR_NO_MEMORY; +      nsAtts = temp; +      version = 0;  /* force re-initialization of nsAtts hash table */ +    } +    /* using a version flag saves us from initializing nsAtts every time */ +    if (!version) {  /* initialize version flags when version wraps around */ +      version = INIT_ATTS_VERSION; +      for (j = nsAttsSize; j != 0; ) +        nsAtts[--j].version = version; +    } +    nsAttsVersion = --version; + +    /* expand prefixed names and check for duplicates */ +    for (; i < attIndex; i += 2) { +      const XML_Char *s = appAtts[i]; +      if (s[-1] == 2) {  /* prefixed */ +        ATTRIBUTE_ID *id; +        const BINDING *b; +        unsigned long uriHash = 0; +        ((XML_Char *)s)[-1] = 0;  /* clear flag */ +        id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, s, 0); +        b = id->prefix->binding; +        if (!b) +          return XML_ERROR_UNBOUND_PREFIX; + +        /* as we expand the name we also calculate its hash value */ +        for (j = 0; j < b->uriLen; j++) { +          const XML_Char c = b->uri[j]; +          if (!poolAppendChar(&tempPool, c)) +            return XML_ERROR_NO_MEMORY; +          uriHash = CHAR_HASH(uriHash, c); +        } +        while (*s++ != XML_T(ASCII_COLON)) +          ; +        do {  /* copies null terminator */ +          const XML_Char c = *s; +          if (!poolAppendChar(&tempPool, *s)) +            return XML_ERROR_NO_MEMORY; +          uriHash = CHAR_HASH(uriHash, c); +        } while (*s++); + +        { /* Check hash table for duplicate of expanded name (uriName). +             Derived from code in lookup(HASH_TABLE *table, ...). +          */ +          unsigned char step = 0; +          unsigned long mask = nsAttsSize - 1; +          j = uriHash & mask;  /* index into hash table */ +          while (nsAtts[j].version == version) { +            /* for speed we compare stored hash values first */ +            if (uriHash == nsAtts[j].hash) { +              const XML_Char *s1 = poolStart(&tempPool); +              const XML_Char *s2 = nsAtts[j].uriName; +              /* s1 is null terminated, but not s2 */ +              for (; *s1 == *s2 && *s1 != 0; s1++, s2++); +              if (*s1 == 0) +                return XML_ERROR_DUPLICATE_ATTRIBUTE; +            } +            if (!step) +              step = PROBE_STEP(uriHash, mask, nsAttsPower); +            j < step ? (j += nsAttsSize - step) : (j -= step); +          } +        } + +        if (ns_triplets) {  /* append namespace separator and prefix */ +          tempPool.ptr[-1] = namespaceSeparator; +          s = b->prefix->name; +          do { +            if (!poolAppendChar(&tempPool, *s)) +              return XML_ERROR_NO_MEMORY; +          } while (*s++); +        } + +        /* store expanded name in attribute list */ +        s = poolStart(&tempPool); +        poolFinish(&tempPool); +        appAtts[i] = s; + +        /* fill empty slot with new version, uriName and hash value */ +        nsAtts[j].version = version; +        nsAtts[j].hash = uriHash; +        nsAtts[j].uriName = s; + +        if (!--nPrefixes) { +          i += 2; +          break; +        } +      } +      else  /* not prefixed */ +        ((XML_Char *)s)[-1] = 0;  /* clear flag */ +    } +  } +  /* clear flags for the remaining attributes */ +  for (; i < attIndex; i += 2) +    ((XML_Char *)(appAtts[i]))[-1] = 0; +  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) +    binding->attId->name[-1] = 0; + +  if (!ns) +    return XML_ERROR_NONE; + +  /* expand the element type name */ +  if (elementType->prefix) { +    binding = elementType->prefix->binding; +    if (!binding) +      return XML_ERROR_UNBOUND_PREFIX; +    localPart = tagNamePtr->str; +    while (*localPart++ != XML_T(ASCII_COLON)) +      ; +  } +  else if (dtd->defaultPrefix.binding) { +    binding = dtd->defaultPrefix.binding; +    localPart = tagNamePtr->str; +  } +  else +    return XML_ERROR_NONE; +  prefixLen = 0; +  if (ns_triplets && binding->prefix->name) { +    for (; binding->prefix->name[prefixLen++];) +      ;  /* prefixLen includes null terminator */ +  } +  tagNamePtr->localPart = localPart; +  tagNamePtr->uriLen = binding->uriLen; +  tagNamePtr->prefix = binding->prefix->name; +  tagNamePtr->prefixLen = prefixLen; +  for (i = 0; localPart[i++];) +    ;  /* i includes null terminator */ +  n = i + binding->uriLen + prefixLen; +  if (n > binding->uriAlloc) { +    TAG *p; +    uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char)); +    if (!uri) +      return XML_ERROR_NO_MEMORY; +    binding->uriAlloc = n + EXPAND_SPARE; +    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char)); +    for (p = tagStack; p; p = p->parent) +      if (p->name.str == binding->uri) +        p->name.str = uri; +    FREE(binding->uri); +    binding->uri = uri; +  } +  /* if namespaceSeparator != '\0' then uri includes it already */ +  uri = binding->uri + binding->uriLen; +  memcpy(uri, localPart, i * sizeof(XML_Char)); +  /* we always have a namespace separator between localPart and prefix */ +  if (prefixLen) { +    uri += i - 1; +    *uri = namespaceSeparator;  /* replace null terminator */ +    memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char)); +  } +  tagNamePtr->str = binding->uri; +  return XML_ERROR_NONE; +} + +/* addBinding() overwrites the value of prefix->binding without checking. +   Therefore one must keep track of the old value outside of addBinding(). +*/ +static enum XML_Error +addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, +           const XML_Char *uri, BINDING **bindingsPtr) +{ +  static const XML_Char xmlNamespace[] = { +    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, +    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, +    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L,  +    ASCII_SLASH, ASCII_1, ASCII_9, ASCII_9, ASCII_8, ASCII_SLASH, +    ASCII_n, ASCII_a, ASCII_m, ASCII_e, ASCII_s, ASCII_p, ASCII_a, ASCII_c, +    ASCII_e, '\0' +  }; +  static const int xmlLen =  +    (int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1; +  static const XML_Char xmlnsNamespace[] = { +    ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH, +    ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, +    ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,  +    ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,  +    ASCII_SLASH, '\0' +  }; +  static const int xmlnsLen =  +    (int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1; + +  XML_Bool mustBeXML = XML_FALSE; +  XML_Bool isXML = XML_TRUE; +  XML_Bool isXMLNS = XML_TRUE; +   +  BINDING *b; +  int len; + +  /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */ +  if (*uri == XML_T('\0') && prefix->name) +    return XML_ERROR_UNDECLARING_PREFIX; + +  if (prefix->name +      && prefix->name[0] == XML_T(ASCII_x) +      && prefix->name[1] == XML_T(ASCII_m) +      && prefix->name[2] == XML_T(ASCII_l)) { + +    /* Not allowed to bind xmlns */ +    if (prefix->name[3] == XML_T(ASCII_n) +        && prefix->name[4] == XML_T(ASCII_s) +        && prefix->name[5] == XML_T('\0')) +      return XML_ERROR_RESERVED_PREFIX_XMLNS; + +    if (prefix->name[3] == XML_T('\0')) +      mustBeXML = XML_TRUE; +  } + +  for (len = 0; uri[len]; len++) { +    if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len])) +      isXML = XML_FALSE; + +    if (!mustBeXML && isXMLNS  +        && (len > xmlnsLen || uri[len] != xmlnsNamespace[len])) +      isXMLNS = XML_FALSE; +  } +  isXML = isXML && len == xmlLen; +  isXMLNS = isXMLNS && len == xmlnsLen; + +  if (mustBeXML != isXML) +    return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML +                     : XML_ERROR_RESERVED_NAMESPACE_URI; + +  if (isXMLNS) +    return XML_ERROR_RESERVED_NAMESPACE_URI; + +  if (namespaceSeparator) +    len++; +  if (freeBindingList) { +    b = freeBindingList; +    if (len > b->uriAlloc) { +      XML_Char *temp = (XML_Char *)REALLOC(b->uri, +                          sizeof(XML_Char) * (len + EXPAND_SPARE)); +      if (temp == NULL) +        return XML_ERROR_NO_MEMORY; +      b->uri = temp; +      b->uriAlloc = len + EXPAND_SPARE; +    } +    freeBindingList = b->nextTagBinding; +  } +  else { +    b = (BINDING *)MALLOC(sizeof(BINDING)); +    if (!b) +      return XML_ERROR_NO_MEMORY; +    b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE)); +    if (!b->uri) { +      FREE(b); +      return XML_ERROR_NO_MEMORY; +    } +    b->uriAlloc = len + EXPAND_SPARE; +  } +  b->uriLen = len; +  memcpy(b->uri, uri, len * sizeof(XML_Char)); +  if (namespaceSeparator) +    b->uri[len - 1] = namespaceSeparator; +  b->prefix = prefix; +  b->attId = attId; +  b->prevPrefixBinding = prefix->binding; +  /* NULL binding when default namespace undeclared */ +  if (*uri == XML_T('\0') && prefix == &_dtd->defaultPrefix) +    prefix->binding = NULL; +  else +    prefix->binding = b; +  b->nextTagBinding = *bindingsPtr; +  *bindingsPtr = b; +  /* if attId == NULL then we are not starting a namespace scope */ +  if (attId && startNamespaceDeclHandler) +    startNamespaceDeclHandler(handlerArg, prefix->name, +                              prefix->binding ? uri : 0); +  return XML_ERROR_NONE; +} + +/* The idea here is to avoid using stack for each CDATA section when +   the whole file is parsed with one call. +*/ +static enum XML_Error PTRCALL +cdataSectionProcessor(XML_Parser parser, +                      const char *start, +                      const char *end, +                      const char **endPtr) +{ +  enum XML_Error result = doCdataSection(parser, encoding, &start, end, +                                         endPtr, (XML_Bool)!ps_finalBuffer); +  if (result != XML_ERROR_NONE) +    return result; +  if (start) { +    if (parentParser) {  /* we are parsing an external entity */ +      processor = externalEntityContentProcessor; +      return externalEntityContentProcessor(parser, start, end, endPtr); +    } +    else { +      processor = contentProcessor; +      return contentProcessor(parser, start, end, endPtr); +    } +  } +  return result; +} + +/* startPtr gets set to non-null if the section is closed, and to null if +   the section is not yet closed. +*/ +static enum XML_Error +doCdataSection(XML_Parser parser, +               const ENCODING *enc, +               const char **startPtr, +               const char *end, +               const char **nextPtr, +               XML_Bool haveMore) +{ +  const char *s = *startPtr; +  const char **eventPP; +  const char **eventEndPP; +  if (enc == encoding) { +    eventPP = &eventPtr; +    *eventPP = s; +    eventEndPP = &eventEndPtr; +  } +  else { +    eventPP = &(openInternalEntities->internalEventPtr); +    eventEndPP = &(openInternalEntities->internalEventEndPtr); +  } +  *eventPP = s; +  *startPtr = NULL; + +  for (;;) { +    const char *next; +    int tok = XmlCdataSectionTok(enc, s, end, &next); +    *eventEndPP = next; +    switch (tok) { +    case XML_TOK_CDATA_SECT_CLOSE: +      if (endCdataSectionHandler) +        endCdataSectionHandler(handlerArg); +#if 0 +      /* see comment under XML_TOK_CDATA_SECT_OPEN */ +      else if (characterDataHandler) +        characterDataHandler(handlerArg, dataBuf, 0); +#endif +      else if (defaultHandler) +        reportDefault(parser, enc, s, next); +      *startPtr = next; +      *nextPtr = next; +      if (ps_parsing == XML_FINISHED) +        return XML_ERROR_ABORTED; +      else +        return XML_ERROR_NONE; +    case XML_TOK_DATA_NEWLINE: +      if (characterDataHandler) { +        XML_Char c = 0xA; +        characterDataHandler(handlerArg, &c, 1); +      } +      else if (defaultHandler) +        reportDefault(parser, enc, s, next); +      break; +    case XML_TOK_DATA_CHARS: +      { +        XML_CharacterDataHandler charDataHandler = characterDataHandler; +        if (charDataHandler) { +          if (MUST_CONVERT(enc, s)) { +            for (;;) { +              ICHAR *dataPtr = (ICHAR *)dataBuf; +              XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); +              *eventEndPP = next; +              charDataHandler(handlerArg, dataBuf, +                              (int)(dataPtr - (ICHAR *)dataBuf)); +              if (s == next) +                break; +              *eventPP = s; +            } +          } +          else +            charDataHandler(handlerArg, +                            (XML_Char *)s, +                            (int)((XML_Char *)next - (XML_Char *)s)); +        } +        else if (defaultHandler) +          reportDefault(parser, enc, s, next); +      } +      break; +    case XML_TOK_INVALID: +      *eventPP = next; +      return XML_ERROR_INVALID_TOKEN; +    case XML_TOK_PARTIAL_CHAR: +      if (haveMore) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      return XML_ERROR_PARTIAL_CHAR; +    case XML_TOK_PARTIAL: +    case XML_TOK_NONE: +      if (haveMore) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      return XML_ERROR_UNCLOSED_CDATA_SECTION; +    default: +      *eventPP = next; +      return XML_ERROR_UNEXPECTED_STATE; +    } + +    *eventPP = s = next; +    switch (ps_parsing) { +    case XML_SUSPENDED: +      *nextPtr = next; +      return XML_ERROR_NONE; +    case XML_FINISHED: +      return XML_ERROR_ABORTED; +    default: ; +    } +  } +  /* not reached */ +} + +#ifdef XML_DTD + +/* The idea here is to avoid using stack for each IGNORE section when +   the whole file is parsed with one call. +*/ +static enum XML_Error PTRCALL +ignoreSectionProcessor(XML_Parser parser, +                       const char *start, +                       const char *end, +                       const char **endPtr) +{ +  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end,  +                                          endPtr, (XML_Bool)!ps_finalBuffer); +  if (result != XML_ERROR_NONE) +    return result; +  if (start) { +    processor = prologProcessor; +    return prologProcessor(parser, start, end, endPtr); +  } +  return result; +} + +/* startPtr gets set to non-null is the section is closed, and to null +   if the section is not yet closed. +*/ +static enum XML_Error +doIgnoreSection(XML_Parser parser, +                const ENCODING *enc, +                const char **startPtr, +                const char *end, +                const char **nextPtr, +                XML_Bool haveMore) +{ +  const char *next; +  int tok; +  const char *s = *startPtr; +  const char **eventPP; +  const char **eventEndPP; +  if (enc == encoding) { +    eventPP = &eventPtr; +    *eventPP = s; +    eventEndPP = &eventEndPtr; +  } +  else { +    eventPP = &(openInternalEntities->internalEventPtr); +    eventEndPP = &(openInternalEntities->internalEventEndPtr); +  } +  *eventPP = s; +  *startPtr = NULL; +  tok = XmlIgnoreSectionTok(enc, s, end, &next); +  *eventEndPP = next; +  switch (tok) { +  case XML_TOK_IGNORE_SECT: +    if (defaultHandler) +      reportDefault(parser, enc, s, next); +    *startPtr = next; +    *nextPtr = next; +    if (ps_parsing == XML_FINISHED) +      return XML_ERROR_ABORTED; +    else +      return XML_ERROR_NONE; +  case XML_TOK_INVALID: +    *eventPP = next; +    return XML_ERROR_INVALID_TOKEN; +  case XML_TOK_PARTIAL_CHAR: +    if (haveMore) { +      *nextPtr = s; +      return XML_ERROR_NONE; +    } +    return XML_ERROR_PARTIAL_CHAR; +  case XML_TOK_PARTIAL: +  case XML_TOK_NONE: +    if (haveMore) { +      *nextPtr = s; +      return XML_ERROR_NONE; +    } +    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */ +  default: +    *eventPP = next; +    return XML_ERROR_UNEXPECTED_STATE; +  } +  /* not reached */ +} + +#endif /* XML_DTD */ + +static enum XML_Error +initializeEncoding(XML_Parser parser) +{ +  const char *s; +#ifdef XML_UNICODE +  char encodingBuf[128]; +  if (!protocolEncodingName) +    s = NULL; +  else { +    int i; +    for (i = 0; protocolEncodingName[i]; i++) { +      if (i == sizeof(encodingBuf) - 1 +          || (protocolEncodingName[i] & ~0x7f) != 0) { +        encodingBuf[0] = '\0'; +        break; +      } +      encodingBuf[i] = (char)protocolEncodingName[i]; +    } +    encodingBuf[i] = '\0'; +    s = encodingBuf; +  } +#else +  s = protocolEncodingName; +#endif +  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) +    return XML_ERROR_NONE; +  return handleUnknownEncoding(parser, protocolEncodingName); +} + +static enum XML_Error +processXmlDecl(XML_Parser parser, int isGeneralTextEntity, +               const char *s, const char *next) +{ +  const char *encodingName = NULL; +  const XML_Char *storedEncName = NULL; +  const ENCODING *newEncoding = NULL; +  const char *version = NULL; +  const char *versionend; +  const XML_Char *storedversion = NULL; +  int standalone = -1; +  if (!(ns +        ? XmlParseXmlDeclNS +        : XmlParseXmlDecl)(isGeneralTextEntity, +                           encoding, +                           s, +                           next, +                           &eventPtr, +                           &version, +                           &versionend, +                           &encodingName, +                           &newEncoding, +                           &standalone)) { +    if (isGeneralTextEntity) +      return XML_ERROR_TEXT_DECL; +    else +      return XML_ERROR_XML_DECL; +  } +  if (!isGeneralTextEntity && standalone == 1) { +    _dtd->standalone = XML_TRUE; +#ifdef XML_DTD +    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE) +      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; +#endif /* XML_DTD */ +  } +  if (xmlDeclHandler) { +    if (encodingName != NULL) { +      storedEncName = poolStoreString(&temp2Pool, +                                      encoding, +                                      encodingName, +                                      encodingName +                                      + XmlNameLength(encoding, encodingName)); +      if (!storedEncName) +              return XML_ERROR_NO_MEMORY; +      poolFinish(&temp2Pool); +    } +    if (version) { +      storedversion = poolStoreString(&temp2Pool, +                                      encoding, +                                      version, +                                      versionend - encoding->minBytesPerChar); +      if (!storedversion) +        return XML_ERROR_NO_MEMORY; +    } +    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone); +  } +  else if (defaultHandler) +    reportDefault(parser, encoding, s, next); +  if (protocolEncodingName == NULL) { +    if (newEncoding) { +      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { +        eventPtr = encodingName; +        return XML_ERROR_INCORRECT_ENCODING; +      } +      encoding = newEncoding; +    } +    else if (encodingName) { +      enum XML_Error result; +      if (!storedEncName) { +        storedEncName = poolStoreString( +          &temp2Pool, encoding, encodingName, +          encodingName + XmlNameLength(encoding, encodingName)); +        if (!storedEncName) +          return XML_ERROR_NO_MEMORY; +      } +      result = handleUnknownEncoding(parser, storedEncName); +      poolClear(&temp2Pool); +      if (result == XML_ERROR_UNKNOWN_ENCODING) +        eventPtr = encodingName; +      return result; +    } +  } + +  if (storedEncName || storedversion) +    poolClear(&temp2Pool); + +  return XML_ERROR_NONE; +} + +static enum XML_Error +handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) +{ +  if (unknownEncodingHandler) { +    XML_Encoding info; +    int i; +    for (i = 0; i < 256; i++) +      info.map[i] = -1; +    info.convert = NULL; +    info.data = NULL; +    info.release = NULL; +    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, +                               &info)) { +      ENCODING *enc; +      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding()); +      if (!unknownEncodingMem) { +        if (info.release) +          info.release(info.data); +        return XML_ERROR_NO_MEMORY; +      } +      enc = (ns +             ? XmlInitUnknownEncodingNS +             : XmlInitUnknownEncoding)(unknownEncodingMem, +                                       info.map, +                                       info.convert, +                                       info.data); +      if (enc) { +        unknownEncodingData = info.data; +        unknownEncodingRelease = info.release; +        encoding = enc; +        return XML_ERROR_NONE; +      } +    } +    if (info.release != NULL) +      info.release(info.data); +  } +  return XML_ERROR_UNKNOWN_ENCODING; +} + +static enum XML_Error PTRCALL +prologInitProcessor(XML_Parser parser, +                    const char *s, +                    const char *end, +                    const char **nextPtr) +{ +  enum XML_Error result = initializeEncoding(parser); +  if (result != XML_ERROR_NONE) +    return result; +  processor = prologProcessor; +  return prologProcessor(parser, s, end, nextPtr); +} + +#ifdef XML_DTD + +static enum XML_Error PTRCALL +externalParEntInitProcessor(XML_Parser parser, +                            const char *s, +                            const char *end, +                            const char **nextPtr) +{ +  enum XML_Error result = initializeEncoding(parser); +  if (result != XML_ERROR_NONE) +    return result; + +  /* we know now that XML_Parse(Buffer) has been called, +     so we consider the external parameter entity read */ +  _dtd->paramEntityRead = XML_TRUE; + +  if (prologState.inEntityValue) { +    processor = entityValueInitProcessor; +    return entityValueInitProcessor(parser, s, end, nextPtr); +  } +  else { +    processor = externalParEntProcessor; +    return externalParEntProcessor(parser, s, end, nextPtr); +  } +} + +static enum XML_Error PTRCALL +entityValueInitProcessor(XML_Parser parser, +                         const char *s, +                         const char *end, +                         const char **nextPtr) +{ +  int tok; +  const char *start = s; +  const char *next = start; +  eventPtr = start; + +  for (;;) {   +    tok = XmlPrologTok(encoding, start, end, &next); +    eventEndPtr = next; +    if (tok <= 0) { +      if (!ps_finalBuffer && tok != XML_TOK_INVALID) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      switch (tok) { +      case XML_TOK_INVALID: +        return XML_ERROR_INVALID_TOKEN; +      case XML_TOK_PARTIAL: +        return XML_ERROR_UNCLOSED_TOKEN; +      case XML_TOK_PARTIAL_CHAR: +        return XML_ERROR_PARTIAL_CHAR; +      case XML_TOK_NONE:   /* start == end */ +      default: +        break; +      } +      /* found end of entity value - can store it now */ +      return storeEntityValue(parser, encoding, s, end); +    } +    else if (tok == XML_TOK_XML_DECL) { +      enum XML_Error result; +      result = processXmlDecl(parser, 0, start, next); +      if (result != XML_ERROR_NONE) +        return result; +      switch (ps_parsing) { +      case XML_SUSPENDED:  +        *nextPtr = next; +        return XML_ERROR_NONE; +      case XML_FINISHED: +        return XML_ERROR_ABORTED; +      default: +        *nextPtr = next; +      } +      /* stop scanning for text declaration - we found one */ +      processor = entityValueProcessor; +      return entityValueProcessor(parser, next, end, nextPtr); +    } +    /* If we are at the end of the buffer, this would cause XmlPrologTok to +       return XML_TOK_NONE on the next call, which would then cause the +       function to exit with *nextPtr set to s - that is what we want for other +       tokens, but not for the BOM - we would rather like to skip it; +       then, when this routine is entered the next time, XmlPrologTok will +       return XML_TOK_INVALID, since the BOM is still in the buffer +    */ +    else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) { +      *nextPtr = next; +      return XML_ERROR_NONE; +    } +    start = next; +    eventPtr = start; +  } +} + +static enum XML_Error PTRCALL +externalParEntProcessor(XML_Parser parser, +                        const char *s, +                        const char *end, +                        const char **nextPtr) +{ +  const char *next = s; +  int tok; + +  tok = XmlPrologTok(encoding, s, end, &next); +  if (tok <= 0) { +    if (!ps_finalBuffer && tok != XML_TOK_INVALID) { +      *nextPtr = s; +      return XML_ERROR_NONE; +    } +    switch (tok) { +    case XML_TOK_INVALID: +      return XML_ERROR_INVALID_TOKEN; +    case XML_TOK_PARTIAL: +      return XML_ERROR_UNCLOSED_TOKEN; +    case XML_TOK_PARTIAL_CHAR: +      return XML_ERROR_PARTIAL_CHAR; +    case XML_TOK_NONE:   /* start == end */ +    default: +      break; +    } +  } +  /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM. +     However, when parsing an external subset, doProlog will not accept a BOM +     as valid, and report a syntax error, so we have to skip the BOM +  */ +  else if (tok == XML_TOK_BOM) { +    s = next; +    tok = XmlPrologTok(encoding, s, end, &next); +  } + +  processor = prologProcessor; +  return doProlog(parser, encoding, s, end, tok, next,  +                  nextPtr, (XML_Bool)!ps_finalBuffer); +} + +static enum XML_Error PTRCALL +entityValueProcessor(XML_Parser parser, +                     const char *s, +                     const char *end, +                     const char **nextPtr) +{ +  const char *start = s; +  const char *next = s; +  const ENCODING *enc = encoding; +  int tok; + +  for (;;) { +    tok = XmlPrologTok(enc, start, end, &next); +    if (tok <= 0) { +      if (!ps_finalBuffer && tok != XML_TOK_INVALID) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      switch (tok) { +      case XML_TOK_INVALID: +        return XML_ERROR_INVALID_TOKEN; +      case XML_TOK_PARTIAL: +        return XML_ERROR_UNCLOSED_TOKEN; +      case XML_TOK_PARTIAL_CHAR: +        return XML_ERROR_PARTIAL_CHAR; +      case XML_TOK_NONE:   /* start == end */ +      default: +        break; +      } +      /* found end of entity value - can store it now */ +      return storeEntityValue(parser, enc, s, end); +    } +    start = next; +  } +} + +#endif /* XML_DTD */ + +static enum XML_Error PTRCALL +prologProcessor(XML_Parser parser, +                const char *s, +                const char *end, +                const char **nextPtr) +{ +  const char *next = s; +  int tok = XmlPrologTok(encoding, s, end, &next); +  return doProlog(parser, encoding, s, end, tok, next,  +                  nextPtr, (XML_Bool)!ps_finalBuffer); +} + +static enum XML_Error +doProlog(XML_Parser parser, +         const ENCODING *enc, +         const char *s, +         const char *end, +         int tok, +         const char *next, +         const char **nextPtr, +         XML_Bool haveMore) +{ +#ifdef XML_DTD +  static const XML_Char externalSubsetName[] = { ASCII_HASH , '\0' }; +#endif /* XML_DTD */ +  static const XML_Char atypeCDATA[] =  +      { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +  static const XML_Char atypeID[] = { ASCII_I, ASCII_D, '\0' }; +  static const XML_Char atypeIDREF[] = +      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; +  static const XML_Char atypeIDREFS[] = +      { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; +  static const XML_Char atypeENTITY[] = +      { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; +  static const XML_Char atypeENTITIES[] = { ASCII_E, ASCII_N, +      ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' }; +  static const XML_Char atypeNMTOKEN[] = { +      ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; +  static const XML_Char atypeNMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, +      ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' }; +  static const XML_Char notationPrefix[] = { ASCII_N, ASCII_O, ASCII_T, +      ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, ASCII_LPAREN, '\0' }; +  static const XML_Char enumValueSep[] = { ASCII_PIPE, '\0' }; +  static const XML_Char enumValueStart[] = { ASCII_LPAREN, '\0' }; + +  /* save one level of indirection */ +  DTD * const dtd = _dtd;  + +  const char **eventPP; +  const char **eventEndPP; +  enum XML_Content_Quant quant; + +  if (enc == encoding) { +    eventPP = &eventPtr; +    eventEndPP = &eventEndPtr; +  } +  else { +    eventPP = &(openInternalEntities->internalEventPtr); +    eventEndPP = &(openInternalEntities->internalEventEndPtr); +  } + +  for (;;) { +    int role; +    XML_Bool handleDefault = XML_TRUE; +    *eventPP = s; +    *eventEndPP = next; +    if (tok <= 0) { +      if (haveMore && tok != XML_TOK_INVALID) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      switch (tok) { +      case XML_TOK_INVALID: +        *eventPP = next; +        return XML_ERROR_INVALID_TOKEN; +      case XML_TOK_PARTIAL: +        return XML_ERROR_UNCLOSED_TOKEN; +      case XML_TOK_PARTIAL_CHAR: +        return XML_ERROR_PARTIAL_CHAR; +      case XML_TOK_NONE: +#ifdef XML_DTD +        /* for internal PE NOT referenced between declarations */ +        if (enc != encoding && !openInternalEntities->betweenDecl) { +          *nextPtr = s; +          return XML_ERROR_NONE; +        } +        /* WFC: PE Between Declarations - must check that PE contains +           complete markup, not only for external PEs, but also for +           internal PEs if the reference occurs between declarations. +        */ +        if (isParamEntity || enc != encoding) { +          if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc) +              == XML_ROLE_ERROR) +            return XML_ERROR_INCOMPLETE_PE; +          *nextPtr = s; +          return XML_ERROR_NONE; +        } +#endif /* XML_DTD */ +        return XML_ERROR_NO_ELEMENTS; +      default: +        tok = -tok; +        next = end; +        break; +      } +    } +    role = XmlTokenRole(&prologState, tok, s, next, enc); +    switch (role) { +    case XML_ROLE_XML_DECL: +      { +        enum XML_Error result = processXmlDecl(parser, 0, s, next); +        if (result != XML_ERROR_NONE) +          return result; +        enc = encoding; +        handleDefault = XML_FALSE; +      } +      break; +    case XML_ROLE_DOCTYPE_NAME: +      if (startDoctypeDeclHandler) { +        doctypeName = poolStoreString(&tempPool, enc, s, next); +        if (!doctypeName) +          return XML_ERROR_NO_MEMORY; +        poolFinish(&tempPool); +        doctypePubid = NULL; +        handleDefault = XML_FALSE; +      } +      doctypeSysid = NULL; /* always initialize to NULL */ +      break; +    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET: +      if (startDoctypeDeclHandler) { +        startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid, +                                doctypePubid, 1); +        doctypeName = NULL; +        poolClear(&tempPool); +        handleDefault = XML_FALSE; +      } +      break; +#ifdef XML_DTD +    case XML_ROLE_TEXT_DECL: +      { +        enum XML_Error result = processXmlDecl(parser, 1, s, next); +        if (result != XML_ERROR_NONE) +          return result; +        enc = encoding; +        handleDefault = XML_FALSE; +      } +      break; +#endif /* XML_DTD */ +    case XML_ROLE_DOCTYPE_PUBLIC_ID: +#ifdef XML_DTD +      useForeignDTD = XML_FALSE; +      declEntity = (ENTITY *)lookup(&dtd->paramEntities, +                                    externalSubsetName, +                                    sizeof(ENTITY)); +      if (!declEntity) +        return XML_ERROR_NO_MEMORY; +#endif /* XML_DTD */ +      dtd->hasParamEntityRefs = XML_TRUE; +      if (startDoctypeDeclHandler) { +        if (!XmlIsPublicId(enc, s, next, eventPP)) +          return XML_ERROR_PUBLICID; +        doctypePubid = poolStoreString(&tempPool, enc, +                                       s + enc->minBytesPerChar, +                                       next - enc->minBytesPerChar); +        if (!doctypePubid) +          return XML_ERROR_NO_MEMORY; +        normalizePublicId((XML_Char *)doctypePubid); +        poolFinish(&tempPool); +        handleDefault = XML_FALSE; +        goto alreadyChecked; +      } +      /* fall through */ +    case XML_ROLE_ENTITY_PUBLIC_ID: +      if (!XmlIsPublicId(enc, s, next, eventPP)) +        return XML_ERROR_PUBLICID; +    alreadyChecked: +      if (dtd->keepProcessing && declEntity) { +        XML_Char *tem = poolStoreString(&dtd->pool, +                                        enc, +                                        s + enc->minBytesPerChar, +                                        next - enc->minBytesPerChar); +        if (!tem) +          return XML_ERROR_NO_MEMORY; +        normalizePublicId(tem); +        declEntity->publicId = tem; +        poolFinish(&dtd->pool); +        if (entityDeclHandler) +          handleDefault = XML_FALSE; +      } +      break; +    case XML_ROLE_DOCTYPE_CLOSE: +      if (doctypeName) { +        startDoctypeDeclHandler(handlerArg, doctypeName, +                                doctypeSysid, doctypePubid, 0); +        poolClear(&tempPool); +        handleDefault = XML_FALSE; +      } +      /* doctypeSysid will be non-NULL in the case of a previous +         XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler +         was not set, indicating an external subset +      */ +#ifdef XML_DTD +      if (doctypeSysid || useForeignDTD) { +        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; +        dtd->hasParamEntityRefs = XML_TRUE; +        if (paramEntityParsing && externalEntityRefHandler) { +          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities, +                                            externalSubsetName, +                                            sizeof(ENTITY)); +          if (!entity) +            return XML_ERROR_NO_MEMORY; +          if (useForeignDTD) +            entity->base = curBase; +          dtd->paramEntityRead = XML_FALSE; +          if (!externalEntityRefHandler(externalEntityRefHandlerArg, +                                        0, +                                        entity->base, +                                        entity->systemId, +                                        entity->publicId)) +            return XML_ERROR_EXTERNAL_ENTITY_HANDLING; +          if (dtd->paramEntityRead) { +            if (!dtd->standalone &&  +                notStandaloneHandler &&  +                !notStandaloneHandler(handlerArg)) +              return XML_ERROR_NOT_STANDALONE; +          } +          /* if we didn't read the foreign DTD then this means that there +             is no external subset and we must reset dtd->hasParamEntityRefs +          */ +          else if (!doctypeSysid) +            dtd->hasParamEntityRefs = hadParamEntityRefs; +          /* end of DTD - no need to update dtd->keepProcessing */ +        } +        useForeignDTD = XML_FALSE; +      } +#endif /* XML_DTD */ +      if (endDoctypeDeclHandler) { +        endDoctypeDeclHandler(handlerArg); +        handleDefault = XML_FALSE; +      } +      break; +    case XML_ROLE_INSTANCE_START: +#ifdef XML_DTD +      /* if there is no DOCTYPE declaration then now is the +         last chance to read the foreign DTD +      */ +      if (useForeignDTD) { +        XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs; +        dtd->hasParamEntityRefs = XML_TRUE; +        if (paramEntityParsing && externalEntityRefHandler) { +          ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities, +                                            externalSubsetName, +                                            sizeof(ENTITY)); +          if (!entity) +            return XML_ERROR_NO_MEMORY; +          entity->base = curBase; +          dtd->paramEntityRead = XML_FALSE; +          if (!externalEntityRefHandler(externalEntityRefHandlerArg, +                                        0, +                                        entity->base, +                                        entity->systemId, +                                        entity->publicId)) +            return XML_ERROR_EXTERNAL_ENTITY_HANDLING; +          if (dtd->paramEntityRead) { +            if (!dtd->standalone && +                notStandaloneHandler && +                !notStandaloneHandler(handlerArg)) +              return XML_ERROR_NOT_STANDALONE; +          } +          /* if we didn't read the foreign DTD then this means that there +             is no external subset and we must reset dtd->hasParamEntityRefs +          */ +          else +            dtd->hasParamEntityRefs = hadParamEntityRefs; +          /* end of DTD - no need to update dtd->keepProcessing */ +        } +      } +#endif /* XML_DTD */ +      processor = contentProcessor; +      return contentProcessor(parser, s, end, nextPtr); +    case XML_ROLE_ATTLIST_ELEMENT_NAME: +      declElementType = getElementType(parser, enc, s, next); +      if (!declElementType) +        return XML_ERROR_NO_MEMORY; +      goto checkAttListDeclHandler; +    case XML_ROLE_ATTRIBUTE_NAME: +      declAttributeId = getAttributeId(parser, enc, s, next); +      if (!declAttributeId) +        return XML_ERROR_NO_MEMORY; +      declAttributeIsCdata = XML_FALSE; +      declAttributeType = NULL; +      declAttributeIsId = XML_FALSE; +      goto checkAttListDeclHandler; +    case XML_ROLE_ATTRIBUTE_TYPE_CDATA: +      declAttributeIsCdata = XML_TRUE; +      declAttributeType = atypeCDATA; +      goto checkAttListDeclHandler; +    case XML_ROLE_ATTRIBUTE_TYPE_ID: +      declAttributeIsId = XML_TRUE; +      declAttributeType = atypeID; +      goto checkAttListDeclHandler; +    case XML_ROLE_ATTRIBUTE_TYPE_IDREF: +      declAttributeType = atypeIDREF; +      goto checkAttListDeclHandler; +    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS: +      declAttributeType = atypeIDREFS; +      goto checkAttListDeclHandler; +    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY: +      declAttributeType = atypeENTITY; +      goto checkAttListDeclHandler; +    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES: +      declAttributeType = atypeENTITIES; +      goto checkAttListDeclHandler; +    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN: +      declAttributeType = atypeNMTOKEN; +      goto checkAttListDeclHandler; +    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS: +      declAttributeType = atypeNMTOKENS; +    checkAttListDeclHandler: +      if (dtd->keepProcessing && attlistDeclHandler) +        handleDefault = XML_FALSE; +      break; +    case XML_ROLE_ATTRIBUTE_ENUM_VALUE: +    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE: +      if (dtd->keepProcessing && attlistDeclHandler) { +        const XML_Char *prefix; +        if (declAttributeType) { +          prefix = enumValueSep; +        } +        else { +          prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE +                    ? notationPrefix +                    : enumValueStart); +        } +        if (!poolAppendString(&tempPool, prefix)) +          return XML_ERROR_NO_MEMORY; +        if (!poolAppend(&tempPool, enc, s, next)) +          return XML_ERROR_NO_MEMORY; +        declAttributeType = tempPool.start; +        handleDefault = XML_FALSE; +      } +      break; +    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: +    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: +      if (dtd->keepProcessing) { +        if (!defineAttribute(declElementType, declAttributeId, +                             declAttributeIsCdata, declAttributeIsId, +                             0, parser)) +          return XML_ERROR_NO_MEMORY; +        if (attlistDeclHandler && declAttributeType) { +          if (*declAttributeType == XML_T(ASCII_LPAREN) +              || (*declAttributeType == XML_T(ASCII_N) +                  && declAttributeType[1] == XML_T(ASCII_O))) { +            /* Enumerated or Notation type */ +            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) +                || !poolAppendChar(&tempPool, XML_T('\0'))) +              return XML_ERROR_NO_MEMORY; +            declAttributeType = tempPool.start; +            poolFinish(&tempPool); +          } +          *eventEndPP = s; +          attlistDeclHandler(handlerArg, declElementType->name, +                             declAttributeId->name, declAttributeType, +                             0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE); +          poolClear(&tempPool); +          handleDefault = XML_FALSE; +        } +      } +      break; +    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: +    case XML_ROLE_FIXED_ATTRIBUTE_VALUE: +      if (dtd->keepProcessing) { +        const XML_Char *attVal; +        enum XML_Error result = +          storeAttributeValue(parser, enc, declAttributeIsCdata, +                              s + enc->minBytesPerChar, +                              next - enc->minBytesPerChar, +                              &dtd->pool); +        if (result) +          return result; +        attVal = poolStart(&dtd->pool); +        poolFinish(&dtd->pool); +        /* ID attributes aren't allowed to have a default */ +        if (!defineAttribute(declElementType, declAttributeId, +                             declAttributeIsCdata, XML_FALSE, attVal, parser)) +          return XML_ERROR_NO_MEMORY; +        if (attlistDeclHandler && declAttributeType) { +          if (*declAttributeType == XML_T(ASCII_LPAREN) +              || (*declAttributeType == XML_T(ASCII_N) +                  && declAttributeType[1] == XML_T(ASCII_O))) { +            /* Enumerated or Notation type */ +            if (!poolAppendChar(&tempPool, XML_T(ASCII_RPAREN)) +                || !poolAppendChar(&tempPool, XML_T('\0'))) +              return XML_ERROR_NO_MEMORY; +            declAttributeType = tempPool.start; +            poolFinish(&tempPool); +          } +          *eventEndPP = s; +          attlistDeclHandler(handlerArg, declElementType->name, +                             declAttributeId->name, declAttributeType, +                             attVal, +                             role == XML_ROLE_FIXED_ATTRIBUTE_VALUE); +          poolClear(&tempPool); +          handleDefault = XML_FALSE; +        } +      } +      break; +    case XML_ROLE_ENTITY_VALUE: +      if (dtd->keepProcessing) { +        enum XML_Error result = storeEntityValue(parser, enc, +                                            s + enc->minBytesPerChar, +                                            next - enc->minBytesPerChar); +        if (declEntity) { +          declEntity->textPtr = poolStart(&dtd->entityValuePool); +          declEntity->textLen = (int)(poolLength(&dtd->entityValuePool)); +          poolFinish(&dtd->entityValuePool); +          if (entityDeclHandler) { +            *eventEndPP = s; +            entityDeclHandler(handlerArg, +                              declEntity->name, +                              declEntity->is_param, +                              declEntity->textPtr, +                              declEntity->textLen, +                              curBase, 0, 0, 0); +            handleDefault = XML_FALSE; +          } +        } +        else +          poolDiscard(&dtd->entityValuePool); +        if (result != XML_ERROR_NONE) +          return result; +      } +      break; +    case XML_ROLE_DOCTYPE_SYSTEM_ID: +#ifdef XML_DTD +      useForeignDTD = XML_FALSE; +#endif /* XML_DTD */ +      dtd->hasParamEntityRefs = XML_TRUE; +      if (startDoctypeDeclHandler) { +        doctypeSysid = poolStoreString(&tempPool, enc, +                                       s + enc->minBytesPerChar, +                                       next - enc->minBytesPerChar); +        if (doctypeSysid == NULL) +          return XML_ERROR_NO_MEMORY; +        poolFinish(&tempPool); +        handleDefault = XML_FALSE; +      } +#ifdef XML_DTD +      else +        /* use externalSubsetName to make doctypeSysid non-NULL +           for the case where no startDoctypeDeclHandler is set */ +        doctypeSysid = externalSubsetName; +#endif /* XML_DTD */ +      if (!dtd->standalone +#ifdef XML_DTD +          && !paramEntityParsing +#endif /* XML_DTD */ +          && notStandaloneHandler +          && !notStandaloneHandler(handlerArg)) +        return XML_ERROR_NOT_STANDALONE; +#ifndef XML_DTD +      break; +#else /* XML_DTD */ +      if (!declEntity) { +        declEntity = (ENTITY *)lookup(&dtd->paramEntities, +                                      externalSubsetName, +                                      sizeof(ENTITY)); +        if (!declEntity) +          return XML_ERROR_NO_MEMORY; +        declEntity->publicId = NULL; +      } +      /* fall through */ +#endif /* XML_DTD */ +    case XML_ROLE_ENTITY_SYSTEM_ID: +      if (dtd->keepProcessing && declEntity) { +        declEntity->systemId = poolStoreString(&dtd->pool, enc, +                                               s + enc->minBytesPerChar, +                                               next - enc->minBytesPerChar); +        if (!declEntity->systemId) +          return XML_ERROR_NO_MEMORY; +        declEntity->base = curBase; +        poolFinish(&dtd->pool); +        if (entityDeclHandler) +          handleDefault = XML_FALSE; +      } +      break; +    case XML_ROLE_ENTITY_COMPLETE: +      if (dtd->keepProcessing && declEntity && entityDeclHandler) { +        *eventEndPP = s; +        entityDeclHandler(handlerArg, +                          declEntity->name, +                          declEntity->is_param, +                          0,0, +                          declEntity->base, +                          declEntity->systemId, +                          declEntity->publicId, +                          0); +        handleDefault = XML_FALSE; +      } +      break; +    case XML_ROLE_ENTITY_NOTATION_NAME: +      if (dtd->keepProcessing && declEntity) { +        declEntity->notation = poolStoreString(&dtd->pool, enc, s, next); +        if (!declEntity->notation) +          return XML_ERROR_NO_MEMORY; +        poolFinish(&dtd->pool); +        if (unparsedEntityDeclHandler) { +          *eventEndPP = s; +          unparsedEntityDeclHandler(handlerArg, +                                    declEntity->name, +                                    declEntity->base, +                                    declEntity->systemId, +                                    declEntity->publicId, +                                    declEntity->notation); +          handleDefault = XML_FALSE; +        } +        else if (entityDeclHandler) { +          *eventEndPP = s; +          entityDeclHandler(handlerArg, +                            declEntity->name, +                            0,0,0, +                            declEntity->base, +                            declEntity->systemId, +                            declEntity->publicId, +                            declEntity->notation); +          handleDefault = XML_FALSE; +        } +      } +      break; +    case XML_ROLE_GENERAL_ENTITY_NAME: +      { +        if (XmlPredefinedEntityName(enc, s, next)) { +          declEntity = NULL; +          break; +        } +        if (dtd->keepProcessing) { +          const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); +          if (!name) +            return XML_ERROR_NO_MEMORY; +          declEntity = (ENTITY *)lookup(&dtd->generalEntities, name, +                                        sizeof(ENTITY)); +          if (!declEntity) +            return XML_ERROR_NO_MEMORY; +          if (declEntity->name != name) { +            poolDiscard(&dtd->pool); +            declEntity = NULL; +          } +          else { +            poolFinish(&dtd->pool); +            declEntity->publicId = NULL; +            declEntity->is_param = XML_FALSE; +            /* if we have a parent parser or are reading an internal parameter +               entity, then the entity declaration is not considered "internal" +            */ +            declEntity->is_internal = !(parentParser || openInternalEntities); +            if (entityDeclHandler) +              handleDefault = XML_FALSE; +          } +        } +        else { +          poolDiscard(&dtd->pool); +          declEntity = NULL; +        } +      } +      break; +    case XML_ROLE_PARAM_ENTITY_NAME: +#ifdef XML_DTD +      if (dtd->keepProcessing) { +        const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next); +        if (!name) +          return XML_ERROR_NO_MEMORY; +        declEntity = (ENTITY *)lookup(&dtd->paramEntities, +                                           name, sizeof(ENTITY)); +        if (!declEntity) +          return XML_ERROR_NO_MEMORY; +        if (declEntity->name != name) { +          poolDiscard(&dtd->pool); +          declEntity = NULL; +        } +        else { +          poolFinish(&dtd->pool); +          declEntity->publicId = NULL; +          declEntity->is_param = XML_TRUE; +          /* if we have a parent parser or are reading an internal parameter +             entity, then the entity declaration is not considered "internal" +          */ +          declEntity->is_internal = !(parentParser || openInternalEntities); +          if (entityDeclHandler) +            handleDefault = XML_FALSE; +        } +      } +      else { +        poolDiscard(&dtd->pool); +        declEntity = NULL; +      } +#else /* not XML_DTD */ +      declEntity = NULL; +#endif /* XML_DTD */ +      break; +    case XML_ROLE_NOTATION_NAME: +      declNotationPublicId = NULL; +      declNotationName = NULL; +      if (notationDeclHandler) { +        declNotationName = poolStoreString(&tempPool, enc, s, next); +        if (!declNotationName) +          return XML_ERROR_NO_MEMORY; +        poolFinish(&tempPool); +        handleDefault = XML_FALSE; +      } +      break; +    case XML_ROLE_NOTATION_PUBLIC_ID: +      if (!XmlIsPublicId(enc, s, next, eventPP)) +        return XML_ERROR_PUBLICID; +      if (declNotationName) {  /* means notationDeclHandler != NULL */ +        XML_Char *tem = poolStoreString(&tempPool, +                                        enc, +                                        s + enc->minBytesPerChar, +                                        next - enc->minBytesPerChar); +        if (!tem) +          return XML_ERROR_NO_MEMORY; +        normalizePublicId(tem); +        declNotationPublicId = tem; +        poolFinish(&tempPool); +        handleDefault = XML_FALSE; +      } +      break; +    case XML_ROLE_NOTATION_SYSTEM_ID: +      if (declNotationName && notationDeclHandler) { +        const XML_Char *systemId +          = poolStoreString(&tempPool, enc, +                            s + enc->minBytesPerChar, +                            next - enc->minBytesPerChar); +        if (!systemId) +          return XML_ERROR_NO_MEMORY; +        *eventEndPP = s; +        notationDeclHandler(handlerArg, +                            declNotationName, +                            curBase, +                            systemId, +                            declNotationPublicId); +        handleDefault = XML_FALSE; +      } +      poolClear(&tempPool); +      break; +    case XML_ROLE_NOTATION_NO_SYSTEM_ID: +      if (declNotationPublicId && notationDeclHandler) { +        *eventEndPP = s; +        notationDeclHandler(handlerArg, +                            declNotationName, +                            curBase, +                            0, +                            declNotationPublicId); +        handleDefault = XML_FALSE; +      } +      poolClear(&tempPool); +      break; +    case XML_ROLE_ERROR: +      switch (tok) { +      case XML_TOK_PARAM_ENTITY_REF: +        /* PE references in internal subset are +           not allowed within declarations. */   +        return XML_ERROR_PARAM_ENTITY_REF; +      case XML_TOK_XML_DECL: +        return XML_ERROR_MISPLACED_XML_PI; +      default: +        return XML_ERROR_SYNTAX; +      } +#ifdef XML_DTD +    case XML_ROLE_IGNORE_SECT: +      { +        enum XML_Error result; +        if (defaultHandler) +          reportDefault(parser, enc, s, next); +        handleDefault = XML_FALSE; +        result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore); +        if (result != XML_ERROR_NONE) +          return result; +        else if (!next) { +          processor = ignoreSectionProcessor; +          return result; +        } +      } +      break; +#endif /* XML_DTD */ +    case XML_ROLE_GROUP_OPEN: +      if (prologState.level >= groupSize) { +        if (groupSize) { +          char *temp = (char *)REALLOC(groupConnector, groupSize *= 2); +          if (temp == NULL) +            return XML_ERROR_NO_MEMORY; +          groupConnector = temp; +          if (dtd->scaffIndex) { +            int *temp = (int *)REALLOC(dtd->scaffIndex, +                          groupSize * sizeof(int)); +            if (temp == NULL) +              return XML_ERROR_NO_MEMORY; +            dtd->scaffIndex = temp; +          } +        } +        else { +          groupConnector = (char *)MALLOC(groupSize = 32); +          if (!groupConnector) +            return XML_ERROR_NO_MEMORY; +        } +      } +      groupConnector[prologState.level] = 0; +      if (dtd->in_eldecl) { +        int myindex = nextScaffoldPart(parser); +        if (myindex < 0) +          return XML_ERROR_NO_MEMORY; +        dtd->scaffIndex[dtd->scaffLevel] = myindex; +        dtd->scaffLevel++; +        dtd->scaffold[myindex].type = XML_CTYPE_SEQ; +        if (elementDeclHandler) +          handleDefault = XML_FALSE; +      } +      break; +    case XML_ROLE_GROUP_SEQUENCE: +      if (groupConnector[prologState.level] == ASCII_PIPE) +        return XML_ERROR_SYNTAX; +      groupConnector[prologState.level] = ASCII_COMMA; +      if (dtd->in_eldecl && elementDeclHandler) +        handleDefault = XML_FALSE; +      break; +    case XML_ROLE_GROUP_CHOICE: +      if (groupConnector[prologState.level] == ASCII_COMMA) +        return XML_ERROR_SYNTAX; +      if (dtd->in_eldecl +          && !groupConnector[prologState.level] +          && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type +              != XML_CTYPE_MIXED) +          ) { +        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type +            = XML_CTYPE_CHOICE; +        if (elementDeclHandler) +          handleDefault = XML_FALSE; +      } +      groupConnector[prologState.level] = ASCII_PIPE; +      break; +    case XML_ROLE_PARAM_ENTITY_REF: +#ifdef XML_DTD +    case XML_ROLE_INNER_PARAM_ENTITY_REF: +      dtd->hasParamEntityRefs = XML_TRUE; +      if (!paramEntityParsing) +        dtd->keepProcessing = dtd->standalone; +      else { +        const XML_Char *name; +        ENTITY *entity; +        name = poolStoreString(&dtd->pool, enc, +                                s + enc->minBytesPerChar, +                                next - enc->minBytesPerChar); +        if (!name) +          return XML_ERROR_NO_MEMORY; +        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0); +        poolDiscard(&dtd->pool); +        /* first, determine if a check for an existing declaration is needed; +           if yes, check that the entity exists, and that it is internal, +           otherwise call the skipped entity handler +        */ +        if (prologState.documentEntity && +            (dtd->standalone +             ? !openInternalEntities +             : !dtd->hasParamEntityRefs)) { +          if (!entity) +            return XML_ERROR_UNDEFINED_ENTITY; +          else if (!entity->is_internal) +            return XML_ERROR_ENTITY_DECLARED_IN_PE; +        } +        else if (!entity) { +          dtd->keepProcessing = dtd->standalone; +          /* cannot report skipped entities in declarations */ +          if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) { +            skippedEntityHandler(handlerArg, name, 1); +            handleDefault = XML_FALSE; +          } +          break; +        } +        if (entity->open) +          return XML_ERROR_RECURSIVE_ENTITY_REF; +        if (entity->textPtr) { +          enum XML_Error result; +          XML_Bool betweenDecl =  +            (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE : XML_FALSE); +          result = processInternalEntity(parser, entity, betweenDecl); +          if (result != XML_ERROR_NONE) +            return result; +          handleDefault = XML_FALSE; +          break; +        } +        if (externalEntityRefHandler) { +          dtd->paramEntityRead = XML_FALSE; +          entity->open = XML_TRUE; +          if (!externalEntityRefHandler(externalEntityRefHandlerArg, +                                        0, +                                        entity->base, +                                        entity->systemId, +                                        entity->publicId)) { +            entity->open = XML_FALSE; +            return XML_ERROR_EXTERNAL_ENTITY_HANDLING; +          } +          entity->open = XML_FALSE; +          handleDefault = XML_FALSE; +          if (!dtd->paramEntityRead) { +            dtd->keepProcessing = dtd->standalone; +            break; +          } +        } +        else { +          dtd->keepProcessing = dtd->standalone; +          break; +        } +      } +#endif /* XML_DTD */ +      if (!dtd->standalone && +          notStandaloneHandler && +          !notStandaloneHandler(handlerArg)) +        return XML_ERROR_NOT_STANDALONE; +      break; + +    /* Element declaration stuff */ + +    case XML_ROLE_ELEMENT_NAME: +      if (elementDeclHandler) { +        declElementType = getElementType(parser, enc, s, next); +        if (!declElementType) +          return XML_ERROR_NO_MEMORY; +        dtd->scaffLevel = 0; +        dtd->scaffCount = 0; +        dtd->in_eldecl = XML_TRUE; +        handleDefault = XML_FALSE; +      } +      break; + +    case XML_ROLE_CONTENT_ANY: +    case XML_ROLE_CONTENT_EMPTY: +      if (dtd->in_eldecl) { +        if (elementDeclHandler) { +          XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content)); +          if (!content) +            return XML_ERROR_NO_MEMORY; +          content->quant = XML_CQUANT_NONE; +          content->name = NULL; +          content->numchildren = 0; +          content->children = NULL; +          content->type = ((role == XML_ROLE_CONTENT_ANY) ? +                           XML_CTYPE_ANY : +                           XML_CTYPE_EMPTY); +          *eventEndPP = s; +          elementDeclHandler(handlerArg, declElementType->name, content); +          handleDefault = XML_FALSE; +        } +        dtd->in_eldecl = XML_FALSE; +      } +      break; + +    case XML_ROLE_CONTENT_PCDATA: +      if (dtd->in_eldecl) { +        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type +            = XML_CTYPE_MIXED; +        if (elementDeclHandler) +          handleDefault = XML_FALSE; +      } +      break; + +    case XML_ROLE_CONTENT_ELEMENT: +      quant = XML_CQUANT_NONE; +      goto elementContent; +    case XML_ROLE_CONTENT_ELEMENT_OPT: +      quant = XML_CQUANT_OPT; +      goto elementContent; +    case XML_ROLE_CONTENT_ELEMENT_REP: +      quant = XML_CQUANT_REP; +      goto elementContent; +    case XML_ROLE_CONTENT_ELEMENT_PLUS: +      quant = XML_CQUANT_PLUS; +    elementContent: +      if (dtd->in_eldecl) { +        ELEMENT_TYPE *el; +        const XML_Char *name; +        int nameLen; +        const char *nxt = (quant == XML_CQUANT_NONE +                           ? next +                           : next - enc->minBytesPerChar); +        int myindex = nextScaffoldPart(parser); +        if (myindex < 0) +          return XML_ERROR_NO_MEMORY; +        dtd->scaffold[myindex].type = XML_CTYPE_NAME; +        dtd->scaffold[myindex].quant = quant; +        el = getElementType(parser, enc, s, nxt); +        if (!el) +          return XML_ERROR_NO_MEMORY; +        name = el->name; +        dtd->scaffold[myindex].name = name; +        nameLen = 0; +        for (; name[nameLen++]; ); +        dtd->contentStringLen +=  nameLen; +        if (elementDeclHandler) +          handleDefault = XML_FALSE; +      } +      break; + +    case XML_ROLE_GROUP_CLOSE: +      quant = XML_CQUANT_NONE; +      goto closeGroup; +    case XML_ROLE_GROUP_CLOSE_OPT: +      quant = XML_CQUANT_OPT; +      goto closeGroup; +    case XML_ROLE_GROUP_CLOSE_REP: +      quant = XML_CQUANT_REP; +      goto closeGroup; +    case XML_ROLE_GROUP_CLOSE_PLUS: +      quant = XML_CQUANT_PLUS; +    closeGroup: +      if (dtd->in_eldecl) { +        if (elementDeclHandler) +          handleDefault = XML_FALSE; +        dtd->scaffLevel--; +        dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant; +        if (dtd->scaffLevel == 0) { +          if (!handleDefault) { +            XML_Content *model = build_model(parser); +            if (!model) +              return XML_ERROR_NO_MEMORY; +            *eventEndPP = s; +            elementDeclHandler(handlerArg, declElementType->name, model); +          } +          dtd->in_eldecl = XML_FALSE; +          dtd->contentStringLen = 0; +        } +      } +      break; +      /* End element declaration stuff */ + +    case XML_ROLE_PI: +      if (!reportProcessingInstruction(parser, enc, s, next)) +        return XML_ERROR_NO_MEMORY; +      handleDefault = XML_FALSE; +      break; +    case XML_ROLE_COMMENT: +      if (!reportComment(parser, enc, s, next)) +        return XML_ERROR_NO_MEMORY; +      handleDefault = XML_FALSE; +      break; +    case XML_ROLE_NONE: +      switch (tok) { +      case XML_TOK_BOM: +        handleDefault = XML_FALSE; +        break; +      } +      break; +    case XML_ROLE_DOCTYPE_NONE: +      if (startDoctypeDeclHandler) +        handleDefault = XML_FALSE; +      break; +    case XML_ROLE_ENTITY_NONE: +      if (dtd->keepProcessing && entityDeclHandler) +        handleDefault = XML_FALSE; +      break; +    case XML_ROLE_NOTATION_NONE: +      if (notationDeclHandler) +        handleDefault = XML_FALSE; +      break; +    case XML_ROLE_ATTLIST_NONE: +      if (dtd->keepProcessing && attlistDeclHandler) +        handleDefault = XML_FALSE; +      break; +    case XML_ROLE_ELEMENT_NONE: +      if (elementDeclHandler) +        handleDefault = XML_FALSE; +      break; +    } /* end of big switch */ + +    if (handleDefault && defaultHandler) +      reportDefault(parser, enc, s, next); + +    switch (ps_parsing) { +    case XML_SUSPENDED:  +      *nextPtr = next; +      return XML_ERROR_NONE; +    case XML_FINISHED: +      return XML_ERROR_ABORTED; +    default: +      s = next; +      tok = XmlPrologTok(enc, s, end, &next); +    } +  } +  /* not reached */ +} + +static enum XML_Error PTRCALL +epilogProcessor(XML_Parser parser, +                const char *s, +                const char *end, +                const char **nextPtr) +{ +  processor = epilogProcessor; +  eventPtr = s; +  for (;;) { +    const char *next = NULL; +    int tok = XmlPrologTok(encoding, s, end, &next); +    eventEndPtr = next; +    switch (tok) { +    /* report partial linebreak - it might be the last token */ +    case -XML_TOK_PROLOG_S: +      if (defaultHandler) { +        reportDefault(parser, encoding, s, next); +        if (ps_parsing == XML_FINISHED) +          return XML_ERROR_ABORTED; +      } +      *nextPtr = next; +      return XML_ERROR_NONE; +    case XML_TOK_NONE: +      *nextPtr = s; +      return XML_ERROR_NONE; +    case XML_TOK_PROLOG_S: +      if (defaultHandler) +        reportDefault(parser, encoding, s, next); +      break; +    case XML_TOK_PI: +      if (!reportProcessingInstruction(parser, encoding, s, next)) +        return XML_ERROR_NO_MEMORY; +      break; +    case XML_TOK_COMMENT: +      if (!reportComment(parser, encoding, s, next)) +        return XML_ERROR_NO_MEMORY; +      break; +    case XML_TOK_INVALID: +      eventPtr = next; +      return XML_ERROR_INVALID_TOKEN; +    case XML_TOK_PARTIAL: +      if (!ps_finalBuffer) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      return XML_ERROR_UNCLOSED_TOKEN; +    case XML_TOK_PARTIAL_CHAR: +      if (!ps_finalBuffer) { +        *nextPtr = s; +        return XML_ERROR_NONE; +      } +      return XML_ERROR_PARTIAL_CHAR; +    default: +      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; +    } +    eventPtr = s = next; +    switch (ps_parsing) { +    case XML_SUSPENDED:  +      *nextPtr = next; +      return XML_ERROR_NONE; +    case XML_FINISHED: +      return XML_ERROR_ABORTED; +    default: ; +    } +  } +} + +static enum XML_Error +processInternalEntity(XML_Parser parser, ENTITY *entity, +                      XML_Bool betweenDecl) +{ +  const char *textStart, *textEnd; +  const char *next; +  enum XML_Error result; +  OPEN_INTERNAL_ENTITY *openEntity; + +  if (freeInternalEntities) { +    openEntity = freeInternalEntities; +    freeInternalEntities = openEntity->next; +  } +  else { +    openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY)); +    if (!openEntity) +      return XML_ERROR_NO_MEMORY; +  } +  entity->open = XML_TRUE; +  entity->processed = 0; +  openEntity->next = openInternalEntities; +  openInternalEntities = openEntity; +  openEntity->entity = entity; +  openEntity->startTagLevel = tagLevel; +  openEntity->betweenDecl = betweenDecl; +  openEntity->internalEventPtr = NULL; +  openEntity->internalEventEndPtr = NULL; +  textStart = (char *)entity->textPtr; +  textEnd = (char *)(entity->textPtr + entity->textLen); + +#ifdef XML_DTD +  if (entity->is_param) { +    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); +    result = doProlog(parser, internalEncoding, textStart, textEnd, tok,  +                      next, &next, XML_FALSE); +  } +  else  +#endif /* XML_DTD */ +    result = doContent(parser, tagLevel, internalEncoding, textStart,  +                       textEnd, &next, XML_FALSE); + +  if (result == XML_ERROR_NONE) { +    if (textEnd != next && ps_parsing == XML_SUSPENDED) { +      entity->processed = (int)(next - textStart); +      processor = internalEntityProcessor; +    } +    else { +      entity->open = XML_FALSE; +      openInternalEntities = openEntity->next; +      /* put openEntity back in list of free instances */ +      openEntity->next = freeInternalEntities; +      freeInternalEntities = openEntity; +    } +  } +  return result; +} + +static enum XML_Error PTRCALL +internalEntityProcessor(XML_Parser parser, +                        const char *s, +                        const char *end, +                        const char **nextPtr) +{ +  ENTITY *entity; +  const char *textStart, *textEnd; +  const char *next; +  enum XML_Error result; +  OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities; +  if (!openEntity) +    return XML_ERROR_UNEXPECTED_STATE; + +  entity = openEntity->entity; +  textStart = ((char *)entity->textPtr) + entity->processed; +  textEnd = (char *)(entity->textPtr + entity->textLen); + +#ifdef XML_DTD +  if (entity->is_param) { +    int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next); +    result = doProlog(parser, internalEncoding, textStart, textEnd, tok,  +                      next, &next, XML_FALSE); +  } +  else +#endif /* XML_DTD */ +    result = doContent(parser, openEntity->startTagLevel, internalEncoding,  +                       textStart, textEnd, &next, XML_FALSE);   + +  if (result != XML_ERROR_NONE) +    return result; +  else if (textEnd != next && ps_parsing == XML_SUSPENDED) { +    entity->processed = (int)(next - (char *)entity->textPtr); +    return result; +  } +  else { +    entity->open = XML_FALSE; +    openInternalEntities = openEntity->next; +    /* put openEntity back in list of free instances */ +    openEntity->next = freeInternalEntities; +    freeInternalEntities = openEntity; +  } + +#ifdef XML_DTD +  if (entity->is_param) { +    int tok; +    processor = prologProcessor; +    tok = XmlPrologTok(encoding, s, end, &next); +    return doProlog(parser, encoding, s, end, tok, next, nextPtr,  +                    (XML_Bool)!ps_finalBuffer); +  } +  else +#endif /* XML_DTD */ +  { +    processor = contentProcessor; +    /* see externalEntityContentProcessor vs contentProcessor */ +    return doContent(parser, parentParser ? 1 : 0, encoding, s, end, +                     nextPtr, (XML_Bool)!ps_finalBuffer);  +  }   +} + +static enum XML_Error PTRCALL +errorProcessor(XML_Parser parser, +               const char *s, +               const char *end, +               const char **nextPtr) +{ +  return errorCode; +} + +static enum XML_Error +storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, +                    const char *ptr, const char *end, +                    STRING_POOL *pool) +{ +  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, +                                               end, pool); +  if (result) +    return result; +  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) +    poolChop(pool); +  if (!poolAppendChar(pool, XML_T('\0'))) +    return XML_ERROR_NO_MEMORY; +  return XML_ERROR_NONE; +} + +static enum XML_Error +appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata, +                     const char *ptr, const char *end, +                     STRING_POOL *pool) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  for (;;) { +    const char *next; +    int tok = XmlAttributeValueTok(enc, ptr, end, &next); +    switch (tok) { +    case XML_TOK_NONE: +      return XML_ERROR_NONE; +    case XML_TOK_INVALID: +      if (enc == encoding) +        eventPtr = next; +      return XML_ERROR_INVALID_TOKEN; +    case XML_TOK_PARTIAL: +      if (enc == encoding) +        eventPtr = ptr; +      return XML_ERROR_INVALID_TOKEN; +    case XML_TOK_CHAR_REF: +      { +        XML_Char buf[XML_ENCODE_MAX]; +        int i; +        int n = XmlCharRefNumber(enc, ptr); +        if (n < 0) { +          if (enc == encoding) +            eventPtr = ptr; +          return XML_ERROR_BAD_CHAR_REF; +        } +        if (!isCdata +            && n == 0x20 /* space */ +            && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) +          break; +        n = XmlEncode(n, (ICHAR *)buf); +        if (!n) { +          if (enc == encoding) +            eventPtr = ptr; +          return XML_ERROR_BAD_CHAR_REF; +        } +        for (i = 0; i < n; i++) { +          if (!poolAppendChar(pool, buf[i])) +            return XML_ERROR_NO_MEMORY; +        } +      } +      break; +    case XML_TOK_DATA_CHARS: +      if (!poolAppend(pool, enc, ptr, next)) +        return XML_ERROR_NO_MEMORY; +      break; +    case XML_TOK_TRAILING_CR: +      next = ptr + enc->minBytesPerChar; +      /* fall through */ +    case XML_TOK_ATTRIBUTE_VALUE_S: +    case XML_TOK_DATA_NEWLINE: +      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) +        break; +      if (!poolAppendChar(pool, 0x20)) +        return XML_ERROR_NO_MEMORY; +      break; +    case XML_TOK_ENTITY_REF: +      { +        const XML_Char *name; +        ENTITY *entity; +        char checkEntityDecl; +        XML_Char ch = (XML_Char) XmlPredefinedEntityName(enc, +                                              ptr + enc->minBytesPerChar, +                                              next - enc->minBytesPerChar); +        if (ch) { +          if (!poolAppendChar(pool, ch)) +                return XML_ERROR_NO_MEMORY; +          break; +        } +        name = poolStoreString(&temp2Pool, enc, +                               ptr + enc->minBytesPerChar, +                               next - enc->minBytesPerChar); +        if (!name) +          return XML_ERROR_NO_MEMORY; +        entity = (ENTITY *)lookup(&dtd->generalEntities, name, 0); +        poolDiscard(&temp2Pool); +        /* First, determine if a check for an existing declaration is needed; +           if yes, check that the entity exists, and that it is internal. +        */ +        if (pool == &dtd->pool)  /* are we called from prolog? */ +          checkEntityDecl = +#ifdef XML_DTD +              prologState.documentEntity && +#endif /* XML_DTD */ +              (dtd->standalone +               ? !openInternalEntities +               : !dtd->hasParamEntityRefs); +        else /* if (pool == &tempPool): we are called from content */ +          checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone; +        if (checkEntityDecl) { +          if (!entity) +            return XML_ERROR_UNDEFINED_ENTITY; +          else if (!entity->is_internal) +            return XML_ERROR_ENTITY_DECLARED_IN_PE; +        } +        else if (!entity) { +          /* Cannot report skipped entity here - see comments on +             skippedEntityHandler. +          if (skippedEntityHandler) +            skippedEntityHandler(handlerArg, name, 0); +          */ +          /* Cannot call the default handler because this would be +             out of sync with the call to the startElementHandler. +          if ((pool == &tempPool) && defaultHandler) +            reportDefault(parser, enc, ptr, next); +          */ +          break; +        } +        if (entity->open) { +          if (enc == encoding) +            eventPtr = ptr; +          return XML_ERROR_RECURSIVE_ENTITY_REF; +        } +        if (entity->notation) { +          if (enc == encoding) +            eventPtr = ptr; +          return XML_ERROR_BINARY_ENTITY_REF; +        } +        if (!entity->textPtr) { +          if (enc == encoding) +            eventPtr = ptr; +              return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; +        } +        else { +          enum XML_Error result; +          const XML_Char *textEnd = entity->textPtr + entity->textLen; +          entity->open = XML_TRUE; +          result = appendAttributeValue(parser, internalEncoding, isCdata, +                                        (char *)entity->textPtr, +                                        (char *)textEnd, pool); +          entity->open = XML_FALSE; +          if (result) +            return result; +        } +      } +      break; +    default: +      if (enc == encoding) +        eventPtr = ptr; +      return XML_ERROR_UNEXPECTED_STATE; +    } +    ptr = next; +  } +  /* not reached */ +} + +static enum XML_Error +storeEntityValue(XML_Parser parser, +                 const ENCODING *enc, +                 const char *entityTextPtr, +                 const char *entityTextEnd) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  STRING_POOL *pool = &(dtd->entityValuePool); +  enum XML_Error result = XML_ERROR_NONE; +#ifdef XML_DTD +  int oldInEntityValue = prologState.inEntityValue; +  prologState.inEntityValue = 1; +#endif /* XML_DTD */ +  /* never return Null for the value argument in EntityDeclHandler, +     since this would indicate an external entity; therefore we +     have to make sure that entityValuePool.start is not null */ +  if (!pool->blocks) { +    if (!poolGrow(pool)) +      return XML_ERROR_NO_MEMORY; +  } + +  for (;;) { +    const char *next; +    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next); +    switch (tok) { +    case XML_TOK_PARAM_ENTITY_REF: +#ifdef XML_DTD +      if (isParamEntity || enc != encoding) { +        const XML_Char *name; +        ENTITY *entity; +        name = poolStoreString(&tempPool, enc, +                               entityTextPtr + enc->minBytesPerChar, +                               next - enc->minBytesPerChar); +        if (!name) { +          result = XML_ERROR_NO_MEMORY; +          goto endEntityValue; +        } +        entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0); +        poolDiscard(&tempPool); +        if (!entity) { +          /* not a well-formedness error - see XML 1.0: WFC Entity Declared */ +          /* cannot report skipped entity here - see comments on +             skippedEntityHandler +          if (skippedEntityHandler) +            skippedEntityHandler(handlerArg, name, 0); +          */ +          dtd->keepProcessing = dtd->standalone; +          goto endEntityValue; +        } +        if (entity->open) { +          if (enc == encoding) +            eventPtr = entityTextPtr; +          result = XML_ERROR_RECURSIVE_ENTITY_REF; +          goto endEntityValue; +        } +        if (entity->systemId) { +          if (externalEntityRefHandler) { +            dtd->paramEntityRead = XML_FALSE; +            entity->open = XML_TRUE; +            if (!externalEntityRefHandler(externalEntityRefHandlerArg, +                                          0, +                                          entity->base, +                                          entity->systemId, +                                          entity->publicId)) { +              entity->open = XML_FALSE; +              result = XML_ERROR_EXTERNAL_ENTITY_HANDLING; +              goto endEntityValue; +            } +            entity->open = XML_FALSE; +            if (!dtd->paramEntityRead) +              dtd->keepProcessing = dtd->standalone; +          } +          else +            dtd->keepProcessing = dtd->standalone; +        } +        else { +          entity->open = XML_TRUE; +          result = storeEntityValue(parser, +                                    internalEncoding, +                                    (char *)entity->textPtr, +                                    (char *)(entity->textPtr +                                             + entity->textLen)); +          entity->open = XML_FALSE; +          if (result) +            goto endEntityValue; +        } +        break; +      } +#endif /* XML_DTD */ +      /* In the internal subset, PE references are not legal +         within markup declarations, e.g entity values in this case. */ +      eventPtr = entityTextPtr; +      result = XML_ERROR_PARAM_ENTITY_REF; +      goto endEntityValue; +    case XML_TOK_NONE: +      result = XML_ERROR_NONE; +      goto endEntityValue; +    case XML_TOK_ENTITY_REF: +    case XML_TOK_DATA_CHARS: +      if (!poolAppend(pool, enc, entityTextPtr, next)) { +        result = XML_ERROR_NO_MEMORY; +        goto endEntityValue; +      } +      break; +    case XML_TOK_TRAILING_CR: +      next = entityTextPtr + enc->minBytesPerChar; +      /* fall through */ +    case XML_TOK_DATA_NEWLINE: +      if (pool->end == pool->ptr && !poolGrow(pool)) { +              result = XML_ERROR_NO_MEMORY; +        goto endEntityValue; +      } +      *(pool->ptr)++ = 0xA; +      break; +    case XML_TOK_CHAR_REF: +      { +        XML_Char buf[XML_ENCODE_MAX]; +        int i; +        int n = XmlCharRefNumber(enc, entityTextPtr); +        if (n < 0) { +          if (enc == encoding) +            eventPtr = entityTextPtr; +          result = XML_ERROR_BAD_CHAR_REF; +          goto endEntityValue; +        } +        n = XmlEncode(n, (ICHAR *)buf); +        if (!n) { +          if (enc == encoding) +            eventPtr = entityTextPtr; +          result = XML_ERROR_BAD_CHAR_REF; +          goto endEntityValue; +        } +        for (i = 0; i < n; i++) { +          if (pool->end == pool->ptr && !poolGrow(pool)) { +            result = XML_ERROR_NO_MEMORY; +            goto endEntityValue; +          } +          *(pool->ptr)++ = buf[i]; +        } +      } +      break; +    case XML_TOK_PARTIAL: +      if (enc == encoding) +        eventPtr = entityTextPtr; +      result = XML_ERROR_INVALID_TOKEN; +      goto endEntityValue; +    case XML_TOK_INVALID: +      if (enc == encoding) +        eventPtr = next; +      result = XML_ERROR_INVALID_TOKEN; +      goto endEntityValue; +    default: +      if (enc == encoding) +        eventPtr = entityTextPtr; +      result = XML_ERROR_UNEXPECTED_STATE; +      goto endEntityValue; +    } +    entityTextPtr = next; +  } +endEntityValue: +#ifdef XML_DTD +  prologState.inEntityValue = oldInEntityValue; +#endif /* XML_DTD */ +  return result; +} + +static void FASTCALL +normalizeLines(XML_Char *s) +{ +  XML_Char *p; +  for (;; s++) { +    if (*s == XML_T('\0')) +      return; +    if (*s == 0xD) +      break; +  } +  p = s; +  do { +    if (*s == 0xD) { +      *p++ = 0xA; +      if (*++s == 0xA) +        s++; +    } +    else +      *p++ = *s++; +  } while (*s); +  *p = XML_T('\0'); +} + +static int +reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, +                            const char *start, const char *end) +{ +  const XML_Char *target; +  XML_Char *data; +  const char *tem; +  if (!processingInstructionHandler) { +    if (defaultHandler) +      reportDefault(parser, enc, start, end); +    return 1; +  } +  start += enc->minBytesPerChar * 2; +  tem = start + XmlNameLength(enc, start); +  target = poolStoreString(&tempPool, enc, start, tem); +  if (!target) +    return 0; +  poolFinish(&tempPool); +  data = poolStoreString(&tempPool, enc, +                        XmlSkipS(enc, tem), +                        end - enc->minBytesPerChar*2); +  if (!data) +    return 0; +  normalizeLines(data); +  processingInstructionHandler(handlerArg, target, data); +  poolClear(&tempPool); +  return 1; +} + +static int +reportComment(XML_Parser parser, const ENCODING *enc, +              const char *start, const char *end) +{ +  XML_Char *data; +  if (!commentHandler) { +    if (defaultHandler) +      reportDefault(parser, enc, start, end); +    return 1; +  } +  data = poolStoreString(&tempPool, +                         enc, +                         start + enc->minBytesPerChar * 4, +                         end - enc->minBytesPerChar * 3); +  if (!data) +    return 0; +  normalizeLines(data); +  commentHandler(handlerArg, data); +  poolClear(&tempPool); +  return 1; +} + +static void +reportDefault(XML_Parser parser, const ENCODING *enc, +              const char *s, const char *end) +{ +  if (MUST_CONVERT(enc, s)) { +    const char **eventPP; +    const char **eventEndPP; +    if (enc == encoding) { +      eventPP = &eventPtr; +      eventEndPP = &eventEndPtr; +    } +    else { +      eventPP = &(openInternalEntities->internalEventPtr); +      eventEndPP = &(openInternalEntities->internalEventEndPtr); +    } +    do { +      ICHAR *dataPtr = (ICHAR *)dataBuf; +      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); +      *eventEndPP = s; +      defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); +      *eventPP = s; +    } while (s != end); +  } +  else +    defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); +} + + +static int +defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata, +                XML_Bool isId, const XML_Char *value, XML_Parser parser) +{ +  DEFAULT_ATTRIBUTE *att; +  if (value || isId) { +    /* The handling of default attributes gets messed up if we have +       a default which duplicates a non-default. */ +    int i; +    for (i = 0; i < type->nDefaultAtts; i++) +      if (attId == type->defaultAtts[i].id) +        return 1; +    if (isId && !type->idAtt && !attId->xmlns) +      type->idAtt = attId; +  } +  if (type->nDefaultAtts == type->allocDefaultAtts) { +    if (type->allocDefaultAtts == 0) { +      type->allocDefaultAtts = 8; +      type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts +                            * sizeof(DEFAULT_ATTRIBUTE)); +      if (!type->defaultAtts) +        return 0; +    } +    else { +      DEFAULT_ATTRIBUTE *temp; +      int count = type->allocDefaultAtts * 2; +      temp = (DEFAULT_ATTRIBUTE *) +        REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE))); +      if (temp == NULL) +        return 0; +      type->allocDefaultAtts = count; +      type->defaultAtts = temp; +    } +  } +  att = type->defaultAtts + type->nDefaultAtts; +  att->id = attId; +  att->value = value; +  att->isCdata = isCdata; +  if (!isCdata) +    attId->maybeTokenized = XML_TRUE; +  type->nDefaultAtts += 1; +  return 1; +} + +static int +setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  const XML_Char *name; +  for (name = elementType->name; *name; name++) { +    if (*name == XML_T(ASCII_COLON)) { +      PREFIX *prefix; +      const XML_Char *s; +      for (s = elementType->name; s != name; s++) { +        if (!poolAppendChar(&dtd->pool, *s)) +          return 0; +      } +      if (!poolAppendChar(&dtd->pool, XML_T('\0'))) +        return 0; +      prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), +                                sizeof(PREFIX)); +      if (!prefix) +        return 0; +      if (prefix->name == poolStart(&dtd->pool)) +        poolFinish(&dtd->pool); +      else +        poolDiscard(&dtd->pool); +      elementType->prefix = prefix; + +    } +  } +  return 1; +} + +static ATTRIBUTE_ID * +getAttributeId(XML_Parser parser, const ENCODING *enc, +               const char *start, const char *end) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  ATTRIBUTE_ID *id; +  const XML_Char *name; +  if (!poolAppendChar(&dtd->pool, XML_T('\0'))) +    return NULL; +  name = poolStoreString(&dtd->pool, enc, start, end); +  if (!name) +    return NULL; +  /* skip quotation mark - its storage will be re-used (like in name[-1]) */ +  ++name; +  id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID)); +  if (!id) +    return NULL; +  if (id->name != name) +    poolDiscard(&dtd->pool); +  else { +    poolFinish(&dtd->pool); +    if (!ns) +      ; +    else if (name[0] == XML_T(ASCII_x) +        && name[1] == XML_T(ASCII_m) +        && name[2] == XML_T(ASCII_l) +        && name[3] == XML_T(ASCII_n) +        && name[4] == XML_T(ASCII_s) +        && (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) { +      if (name[5] == XML_T('\0')) +        id->prefix = &dtd->defaultPrefix; +      else +        id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX)); +      id->xmlns = XML_TRUE; +    } +    else { +      int i; +      for (i = 0; name[i]; i++) { +        /* attributes without prefix are *not* in the default namespace */ +        if (name[i] == XML_T(ASCII_COLON)) { +          int j; +          for (j = 0; j < i; j++) { +            if (!poolAppendChar(&dtd->pool, name[j])) +              return NULL; +          } +          if (!poolAppendChar(&dtd->pool, XML_T('\0'))) +            return NULL; +          id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool), +                                        sizeof(PREFIX)); +          if (id->prefix->name == poolStart(&dtd->pool)) +            poolFinish(&dtd->pool); +          else +            poolDiscard(&dtd->pool); +          break; +        } +      } +    } +  } +  return id; +} + +#define CONTEXT_SEP XML_T(ASCII_FF) + +static const XML_Char * +getContext(XML_Parser parser) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  HASH_TABLE_ITER iter; +  XML_Bool needSep = XML_FALSE; + +  if (dtd->defaultPrefix.binding) { +    int i; +    int len; +    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) +      return NULL; +    len = dtd->defaultPrefix.binding->uriLen; +    if (namespaceSeparator) +      len--; +    for (i = 0; i < len; i++) +      if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i])) +        return NULL; +    needSep = XML_TRUE; +  } + +  hashTableIterInit(&iter, &(dtd->prefixes)); +  for (;;) { +    int i; +    int len; +    const XML_Char *s; +    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); +    if (!prefix) +      break; +    if (!prefix->binding) +      continue; +    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) +      return NULL; +    for (s = prefix->name; *s; s++) +      if (!poolAppendChar(&tempPool, *s)) +        return NULL; +    if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS))) +      return NULL; +    len = prefix->binding->uriLen; +    if (namespaceSeparator) +      len--; +    for (i = 0; i < len; i++) +      if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) +        return NULL; +    needSep = XML_TRUE; +  } + + +  hashTableIterInit(&iter, &(dtd->generalEntities)); +  for (;;) { +    const XML_Char *s; +    ENTITY *e = (ENTITY *)hashTableIterNext(&iter); +    if (!e) +      break; +    if (!e->open) +      continue; +    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) +      return NULL; +    for (s = e->name; *s; s++) +      if (!poolAppendChar(&tempPool, *s)) +        return 0; +    needSep = XML_TRUE; +  } + +  if (!poolAppendChar(&tempPool, XML_T('\0'))) +    return NULL; +  return tempPool.start; +} + +static XML_Bool +setContext(XML_Parser parser, const XML_Char *context) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  const XML_Char *s = context; + +  while (*context != XML_T('\0')) { +    if (*s == CONTEXT_SEP || *s == XML_T('\0')) { +      ENTITY *e; +      if (!poolAppendChar(&tempPool, XML_T('\0'))) +        return XML_FALSE; +      e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0); +      if (e) +        e->open = XML_TRUE; +      if (*s != XML_T('\0')) +        s++; +      context = s; +      poolDiscard(&tempPool); +    } +    else if (*s == XML_T(ASCII_EQUALS)) { +      PREFIX *prefix; +      if (poolLength(&tempPool) == 0) +        prefix = &dtd->defaultPrefix; +      else { +        if (!poolAppendChar(&tempPool, XML_T('\0'))) +          return XML_FALSE; +        prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool), +                                  sizeof(PREFIX)); +        if (!prefix) +          return XML_FALSE; +        if (prefix->name == poolStart(&tempPool)) { +          prefix->name = poolCopyString(&dtd->pool, prefix->name); +          if (!prefix->name) +            return XML_FALSE; +        } +        poolDiscard(&tempPool); +      } +      for (context = s + 1; +           *context != CONTEXT_SEP && *context != XML_T('\0'); +           context++) +        if (!poolAppendChar(&tempPool, *context)) +          return XML_FALSE; +      if (!poolAppendChar(&tempPool, XML_T('\0'))) +        return XML_FALSE; +      if (addBinding(parser, prefix, NULL, poolStart(&tempPool), +                     &inheritedBindings) != XML_ERROR_NONE) +        return XML_FALSE; +      poolDiscard(&tempPool); +      if (*context != XML_T('\0')) +        ++context; +      s = context; +    } +    else { +      if (!poolAppendChar(&tempPool, *s)) +        return XML_FALSE; +      s++; +    } +  } +  return XML_TRUE; +} + +static void FASTCALL +normalizePublicId(XML_Char *publicId) +{ +  XML_Char *p = publicId; +  XML_Char *s; +  for (s = publicId; *s; s++) { +    switch (*s) { +    case 0x20: +    case 0xD: +    case 0xA: +      if (p != publicId && p[-1] != 0x20) +        *p++ = 0x20; +      break; +    default: +      *p++ = *s; +    } +  } +  if (p != publicId && p[-1] == 0x20) +    --p; +  *p = XML_T('\0'); +} + +static DTD * +dtdCreate(const XML_Memory_Handling_Suite *ms) +{ +  DTD *p = (DTD *)ms->malloc_fcn(sizeof(DTD)); +  if (p == NULL) +    return p; +  poolInit(&(p->pool), ms); +  poolInit(&(p->entityValuePool), ms); +  hashTableInit(&(p->generalEntities), ms); +  hashTableInit(&(p->elementTypes), ms); +  hashTableInit(&(p->attributeIds), ms); +  hashTableInit(&(p->prefixes), ms); +#ifdef XML_DTD +  p->paramEntityRead = XML_FALSE; +  hashTableInit(&(p->paramEntities), ms); +#endif /* XML_DTD */ +  p->defaultPrefix.name = NULL; +  p->defaultPrefix.binding = NULL; + +  p->in_eldecl = XML_FALSE; +  p->scaffIndex = NULL; +  p->scaffold = NULL; +  p->scaffLevel = 0; +  p->scaffSize = 0; +  p->scaffCount = 0; +  p->contentStringLen = 0; + +  p->keepProcessing = XML_TRUE; +  p->hasParamEntityRefs = XML_FALSE; +  p->standalone = XML_FALSE; +  return p; +} + +static void +dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) +{ +  HASH_TABLE_ITER iter; +  hashTableIterInit(&iter, &(p->elementTypes)); +  for (;;) { +    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); +    if (!e) +      break; +    if (e->allocDefaultAtts != 0) +      ms->free_fcn(e->defaultAtts); +  } +  hashTableClear(&(p->generalEntities)); +#ifdef XML_DTD +  p->paramEntityRead = XML_FALSE; +  hashTableClear(&(p->paramEntities)); +#endif /* XML_DTD */ +  hashTableClear(&(p->elementTypes)); +  hashTableClear(&(p->attributeIds)); +  hashTableClear(&(p->prefixes)); +  poolClear(&(p->pool)); +  poolClear(&(p->entityValuePool)); +  p->defaultPrefix.name = NULL; +  p->defaultPrefix.binding = NULL; + +  p->in_eldecl = XML_FALSE; + +  ms->free_fcn(p->scaffIndex); +  p->scaffIndex = NULL; +  ms->free_fcn(p->scaffold); +  p->scaffold = NULL; + +  p->scaffLevel = 0; +  p->scaffSize = 0; +  p->scaffCount = 0; +  p->contentStringLen = 0; + +  p->keepProcessing = XML_TRUE; +  p->hasParamEntityRefs = XML_FALSE; +  p->standalone = XML_FALSE; +} + +static void +dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) +{ +  HASH_TABLE_ITER iter; +  hashTableIterInit(&iter, &(p->elementTypes)); +  for (;;) { +    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); +    if (!e) +      break; +    if (e->allocDefaultAtts != 0) +      ms->free_fcn(e->defaultAtts); +  } +  hashTableDestroy(&(p->generalEntities)); +#ifdef XML_DTD +  hashTableDestroy(&(p->paramEntities)); +#endif /* XML_DTD */ +  hashTableDestroy(&(p->elementTypes)); +  hashTableDestroy(&(p->attributeIds)); +  hashTableDestroy(&(p->prefixes)); +  poolDestroy(&(p->pool)); +  poolDestroy(&(p->entityValuePool)); +  if (isDocEntity) { +    ms->free_fcn(p->scaffIndex); +    ms->free_fcn(p->scaffold); +  } +  ms->free_fcn(p); +} + +/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise. +   The new DTD has already been initialized. +*/ +static int +dtdCopy(DTD *newDtd, const DTD *oldDtd, const XML_Memory_Handling_Suite *ms) +{ +  HASH_TABLE_ITER iter; + +  /* Copy the prefix table. */ + +  hashTableIterInit(&iter, &(oldDtd->prefixes)); +  for (;;) { +    const XML_Char *name; +    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); +    if (!oldP) +      break; +    name = poolCopyString(&(newDtd->pool), oldP->name); +    if (!name) +      return 0; +    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX))) +      return 0; +  } + +  hashTableIterInit(&iter, &(oldDtd->attributeIds)); + +  /* Copy the attribute id table. */ + +  for (;;) { +    ATTRIBUTE_ID *newA; +    const XML_Char *name; +    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); + +    if (!oldA) +      break; +    /* Remember to allocate the scratch byte before the name. */ +    if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) +      return 0; +    name = poolCopyString(&(newDtd->pool), oldA->name); +    if (!name) +      return 0; +    ++name; +    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, +                                  sizeof(ATTRIBUTE_ID)); +    if (!newA) +      return 0; +    newA->maybeTokenized = oldA->maybeTokenized; +    if (oldA->prefix) { +      newA->xmlns = oldA->xmlns; +      if (oldA->prefix == &oldDtd->defaultPrefix) +        newA->prefix = &newDtd->defaultPrefix; +      else +        newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), +                                        oldA->prefix->name, 0); +    } +  } + +  /* Copy the element type table. */ + +  hashTableIterInit(&iter, &(oldDtd->elementTypes)); + +  for (;;) { +    int i; +    ELEMENT_TYPE *newE; +    const XML_Char *name; +    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); +    if (!oldE) +      break; +    name = poolCopyString(&(newDtd->pool), oldE->name); +    if (!name) +      return 0; +    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, +                                  sizeof(ELEMENT_TYPE)); +    if (!newE) +      return 0; +    if (oldE->nDefaultAtts) { +      newE->defaultAtts = (DEFAULT_ATTRIBUTE *) +          ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); +      if (!newE->defaultAtts) { +        ms->free_fcn(newE); +        return 0; +      } +    } +    if (oldE->idAtt) +      newE->idAtt = (ATTRIBUTE_ID *) +          lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0); +    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; +    if (oldE->prefix) +      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), +                                      oldE->prefix->name, 0); +    for (i = 0; i < newE->nDefaultAtts; i++) { +      newE->defaultAtts[i].id = (ATTRIBUTE_ID *) +          lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); +      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; +      if (oldE->defaultAtts[i].value) { +        newE->defaultAtts[i].value +            = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); +        if (!newE->defaultAtts[i].value) +          return 0; +      } +      else +        newE->defaultAtts[i].value = NULL; +    } +  } + +  /* Copy the entity tables. */ +  if (!copyEntityTable(&(newDtd->generalEntities), +                       &(newDtd->pool), +                       &(oldDtd->generalEntities))) +      return 0; + +#ifdef XML_DTD +  if (!copyEntityTable(&(newDtd->paramEntities), +                       &(newDtd->pool), +                       &(oldDtd->paramEntities))) +      return 0; +  newDtd->paramEntityRead = oldDtd->paramEntityRead; +#endif /* XML_DTD */ + +  newDtd->keepProcessing = oldDtd->keepProcessing; +  newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs; +  newDtd->standalone = oldDtd->standalone; + +  /* Don't want deep copying for scaffolding */ +  newDtd->in_eldecl = oldDtd->in_eldecl; +  newDtd->scaffold = oldDtd->scaffold; +  newDtd->contentStringLen = oldDtd->contentStringLen; +  newDtd->scaffSize = oldDtd->scaffSize; +  newDtd->scaffLevel = oldDtd->scaffLevel; +  newDtd->scaffIndex = oldDtd->scaffIndex; + +  return 1; +}  /* End dtdCopy */ + +static int +copyEntityTable(HASH_TABLE *newTable, +                STRING_POOL *newPool, +                const HASH_TABLE *oldTable) +{ +  HASH_TABLE_ITER iter; +  const XML_Char *cachedOldBase = NULL; +  const XML_Char *cachedNewBase = NULL; + +  hashTableIterInit(&iter, oldTable); + +  for (;;) { +    ENTITY *newE; +    const XML_Char *name; +    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); +    if (!oldE) +      break; +    name = poolCopyString(newPool, oldE->name); +    if (!name) +      return 0; +    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY)); +    if (!newE) +      return 0; +    if (oldE->systemId) { +      const XML_Char *tem = poolCopyString(newPool, oldE->systemId); +      if (!tem) +        return 0; +      newE->systemId = tem; +      if (oldE->base) { +        if (oldE->base == cachedOldBase) +          newE->base = cachedNewBase; +        else { +          cachedOldBase = oldE->base; +          tem = poolCopyString(newPool, cachedOldBase); +          if (!tem) +            return 0; +          cachedNewBase = newE->base = tem; +        } +      } +      if (oldE->publicId) { +        tem = poolCopyString(newPool, oldE->publicId); +        if (!tem) +          return 0; +        newE->publicId = tem; +      } +    } +    else { +      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, +                                            oldE->textLen); +      if (!tem) +        return 0; +      newE->textPtr = tem; +      newE->textLen = oldE->textLen; +    } +    if (oldE->notation) { +      const XML_Char *tem = poolCopyString(newPool, oldE->notation); +      if (!tem) +        return 0; +      newE->notation = tem; +    } +    newE->is_param = oldE->is_param; +    newE->is_internal = oldE->is_internal; +  } +  return 1; +} + +#define INIT_POWER 6 + +static XML_Bool FASTCALL +keyeq(KEY s1, KEY s2) +{ +  for (; *s1 == *s2; s1++, s2++) +    if (*s1 == 0) +      return XML_TRUE; +  return XML_FALSE; +} + +static unsigned long FASTCALL +hash(KEY s) +{ +  unsigned long h = 0; +  while (*s) +    h = CHAR_HASH(h, *s++); +  return h; +} + +static NAMED * +lookup(HASH_TABLE *table, KEY name, size_t createSize) +{ +  size_t i; +  if (table->size == 0) { +    size_t tsize; +    if (!createSize) +      return NULL; +    table->power = INIT_POWER; +    /* table->size is a power of 2 */ +    table->size = (size_t)1 << INIT_POWER; +    tsize = table->size * sizeof(NAMED *); +    table->v = (NAMED **)table->mem->malloc_fcn(tsize); +    if (!table->v) { +      table->size = 0; +      return NULL; +    } +    memset(table->v, 0, tsize); +    i = hash(name) & ((unsigned long)table->size - 1); +  } +  else { +    unsigned long h = hash(name); +    unsigned long mask = (unsigned long)table->size - 1; +    unsigned char step = 0; +    i = h & mask; +    while (table->v[i]) { +      if (keyeq(name, table->v[i]->name)) +        return table->v[i]; +      if (!step) +        step = PROBE_STEP(h, mask, table->power); +      i < step ? (i += table->size - step) : (i -= step); +    } +    if (!createSize) +      return NULL; + +    /* check for overflow (table is half full) */ +    if (table->used >> (table->power - 1)) { +      unsigned char newPower = table->power + 1; +      size_t newSize = (size_t)1 << newPower; +      unsigned long newMask = (unsigned long)newSize - 1; +      size_t tsize = newSize * sizeof(NAMED *); +      NAMED **newV = (NAMED **)table->mem->malloc_fcn(tsize); +      if (!newV) +        return NULL; +      memset(newV, 0, tsize); +      for (i = 0; i < table->size; i++) +        if (table->v[i]) { +          unsigned long newHash = hash(table->v[i]->name); +          size_t j = newHash & newMask; +          step = 0; +          while (newV[j]) { +            if (!step) +              step = PROBE_STEP(newHash, newMask, newPower); +            j < step ? (j += newSize - step) : (j -= step); +          } +          newV[j] = table->v[i]; +        } +      table->mem->free_fcn(table->v); +      table->v = newV; +      table->power = newPower; +      table->size = newSize; +      i = h & newMask; +      step = 0; +      while (table->v[i]) { +        if (!step) +          step = PROBE_STEP(h, newMask, newPower); +        i < step ? (i += newSize - step) : (i -= step); +      } +    } +  } +  table->v[i] = (NAMED *)table->mem->malloc_fcn(createSize); +  if (!table->v[i]) +    return NULL; +  memset(table->v[i], 0, createSize); +  table->v[i]->name = name; +  (table->used)++; +  return table->v[i]; +} + +static void FASTCALL +hashTableClear(HASH_TABLE *table) +{ +  size_t i; +  for (i = 0; i < table->size; i++) { +    table->mem->free_fcn(table->v[i]); +    table->v[i] = NULL; +  } +  table->used = 0; +} + +static void FASTCALL +hashTableDestroy(HASH_TABLE *table) +{ +  size_t i; +  for (i = 0; i < table->size; i++) +    table->mem->free_fcn(table->v[i]); +  table->mem->free_fcn(table->v); +} + +static void FASTCALL +hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms) +{ +  p->power = 0; +  p->size = 0; +  p->used = 0; +  p->v = NULL; +  p->mem = ms; +} + +static void FASTCALL +hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) +{ +  iter->p = table->v; +  iter->end = iter->p + table->size; +} + +static NAMED * FASTCALL +hashTableIterNext(HASH_TABLE_ITER *iter) +{ +  while (iter->p != iter->end) { +    NAMED *tem = *(iter->p)++; +    if (tem) +      return tem; +  } +  return NULL; +} + +static void FASTCALL +poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms) +{ +  pool->blocks = NULL; +  pool->freeBlocks = NULL; +  pool->start = NULL; +  pool->ptr = NULL; +  pool->end = NULL; +  pool->mem = ms; +} + +static void FASTCALL +poolClear(STRING_POOL *pool) +{ +  if (!pool->freeBlocks) +    pool->freeBlocks = pool->blocks; +  else { +    BLOCK *p = pool->blocks; +    while (p) { +      BLOCK *tem = p->next; +      p->next = pool->freeBlocks; +      pool->freeBlocks = p; +      p = tem; +    } +  } +  pool->blocks = NULL; +  pool->start = NULL; +  pool->ptr = NULL; +  pool->end = NULL; +} + +static void FASTCALL +poolDestroy(STRING_POOL *pool) +{ +  BLOCK *p = pool->blocks; +  while (p) { +    BLOCK *tem = p->next; +    pool->mem->free_fcn(p); +    p = tem; +  } +  p = pool->freeBlocks; +  while (p) { +    BLOCK *tem = p->next; +    pool->mem->free_fcn(p); +    p = tem; +  } +} + +static XML_Char * +poolAppend(STRING_POOL *pool, const ENCODING *enc, +           const char *ptr, const char *end) +{ +  if (!pool->ptr && !poolGrow(pool)) +    return NULL; +  for (;;) { +    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); +    if (ptr == end) +      break; +    if (!poolGrow(pool)) +      return NULL; +  } +  return pool->start; +} + +static const XML_Char * FASTCALL +poolCopyString(STRING_POOL *pool, const XML_Char *s) +{ +  do { +    if (!poolAppendChar(pool, *s)) +      return NULL; +  } while (*s++); +  s = pool->start; +  poolFinish(pool); +  return s; +} + +static const XML_Char * +poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) +{ +  if (!pool->ptr && !poolGrow(pool)) +    return NULL; +  for (; n > 0; --n, s++) { +    if (!poolAppendChar(pool, *s)) +      return NULL; +  } +  s = pool->start; +  poolFinish(pool); +  return s; +} + +static const XML_Char * FASTCALL +poolAppendString(STRING_POOL *pool, const XML_Char *s) +{ +  while (*s) { +    if (!poolAppendChar(pool, *s)) +      return NULL; +    s++; +  } +  return pool->start; +} + +static XML_Char * +poolStoreString(STRING_POOL *pool, const ENCODING *enc, +                const char *ptr, const char *end) +{ +  if (!poolAppend(pool, enc, ptr, end)) +    return NULL; +  if (pool->ptr == pool->end && !poolGrow(pool)) +    return NULL; +  *(pool->ptr)++ = 0; +  return pool->start; +} + +static XML_Bool FASTCALL +poolGrow(STRING_POOL *pool) +{ +  if (pool->freeBlocks) { +    if (pool->start == 0) { +      pool->blocks = pool->freeBlocks; +      pool->freeBlocks = pool->freeBlocks->next; +      pool->blocks->next = NULL; +      pool->start = pool->blocks->s; +      pool->end = pool->start + pool->blocks->size; +      pool->ptr = pool->start; +      return XML_TRUE; +    } +    if (pool->end - pool->start < pool->freeBlocks->size) { +      BLOCK *tem = pool->freeBlocks->next; +      pool->freeBlocks->next = pool->blocks; +      pool->blocks = pool->freeBlocks; +      pool->freeBlocks = tem; +      memcpy(pool->blocks->s, pool->start, +             (pool->end - pool->start) * sizeof(XML_Char)); +      pool->ptr = pool->blocks->s + (pool->ptr - pool->start); +      pool->start = pool->blocks->s; +      pool->end = pool->start + pool->blocks->size; +      return XML_TRUE; +    } +  } +  if (pool->blocks && pool->start == pool->blocks->s) { +    int blockSize = (int)(pool->end - pool->start)*2; +    pool->blocks = (BLOCK *) +      pool->mem->realloc_fcn(pool->blocks, +                             (offsetof(BLOCK, s) +                              + blockSize * sizeof(XML_Char))); +    if (pool->blocks == NULL) +      return XML_FALSE; +    pool->blocks->size = blockSize; +    pool->ptr = pool->blocks->s + (pool->ptr - pool->start); +    pool->start = pool->blocks->s; +    pool->end = pool->start + blockSize; +  } +  else { +    BLOCK *tem; +    int blockSize = (int)(pool->end - pool->start); +    if (blockSize < INIT_BLOCK_SIZE) +      blockSize = INIT_BLOCK_SIZE; +    else +      blockSize *= 2; +    tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s) +                                        + blockSize * sizeof(XML_Char)); +    if (!tem) +      return XML_FALSE; +    tem->size = blockSize; +    tem->next = pool->blocks; +    pool->blocks = tem; +    if (pool->ptr != pool->start) +      memcpy(tem->s, pool->start, +             (pool->ptr - pool->start) * sizeof(XML_Char)); +    pool->ptr = tem->s + (pool->ptr - pool->start); +    pool->start = tem->s; +    pool->end = tem->s + blockSize; +  } +  return XML_TRUE; +} + +static int FASTCALL +nextScaffoldPart(XML_Parser parser) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  CONTENT_SCAFFOLD * me; +  int next; + +  if (!dtd->scaffIndex) { +    dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int)); +    if (!dtd->scaffIndex) +      return -1; +    dtd->scaffIndex[0] = 0; +  } + +  if (dtd->scaffCount >= dtd->scaffSize) { +    CONTENT_SCAFFOLD *temp; +    if (dtd->scaffold) { +      temp = (CONTENT_SCAFFOLD *) +        REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD)); +      if (temp == NULL) +        return -1; +      dtd->scaffSize *= 2; +    } +    else { +      temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS +                                        * sizeof(CONTENT_SCAFFOLD)); +      if (temp == NULL) +        return -1; +      dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS; +    } +    dtd->scaffold = temp; +  } +  next = dtd->scaffCount++; +  me = &dtd->scaffold[next]; +  if (dtd->scaffLevel) { +    CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]]; +    if (parent->lastchild) { +      dtd->scaffold[parent->lastchild].nextsib = next; +    } +    if (!parent->childcnt) +      parent->firstchild = next; +    parent->lastchild = next; +    parent->childcnt++; +  } +  me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0; +  return next; +} + +static void +build_node(XML_Parser parser, +           int src_node, +           XML_Content *dest, +           XML_Content **contpos, +           XML_Char **strpos) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  dest->type = dtd->scaffold[src_node].type; +  dest->quant = dtd->scaffold[src_node].quant; +  if (dest->type == XML_CTYPE_NAME) { +    const XML_Char *src; +    dest->name = *strpos; +    src = dtd->scaffold[src_node].name; +    for (;;) { +      *(*strpos)++ = *src; +      if (!*src) +        break; +      src++; +    } +    dest->numchildren = 0; +    dest->children = NULL; +  } +  else { +    unsigned int i; +    int cn; +    dest->numchildren = dtd->scaffold[src_node].childcnt; +    dest->children = *contpos; +    *contpos += dest->numchildren; +    for (i = 0, cn = dtd->scaffold[src_node].firstchild; +         i < dest->numchildren; +         i++, cn = dtd->scaffold[cn].nextsib) { +      build_node(parser, cn, &(dest->children[i]), contpos, strpos); +    } +    dest->name = NULL; +  } +} + +static XML_Content * +build_model (XML_Parser parser) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  XML_Content *ret; +  XML_Content *cpos; +  XML_Char * str; +  int allocsize = (dtd->scaffCount * sizeof(XML_Content) +                   + (dtd->contentStringLen * sizeof(XML_Char))); + +  ret = (XML_Content *)MALLOC(allocsize); +  if (!ret) +    return NULL; + +  str =  (XML_Char *) (&ret[dtd->scaffCount]); +  cpos = &ret[1]; + +  build_node(parser, 0, ret, &cpos, &str); +  return ret; +} + +static ELEMENT_TYPE * +getElementType(XML_Parser parser, +               const ENCODING *enc, +               const char *ptr, +               const char *end) +{ +  DTD * const dtd = _dtd;  /* save one level of indirection */ +  const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end); +  ELEMENT_TYPE *ret; + +  if (!name) +    return NULL; +  ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE)); +  if (!ret) +    return NULL; +  if (ret->name != name) +    poolDiscard(&dtd->pool); +  else { +    poolFinish(&dtd->pool); +    if (!setElementTypePrefix(parser, ret)) +      return NULL; +  } +  return ret; +} diff --git a/3rdParty/Expat/src/xmlrole.c b/3rdParty/Expat/src/xmlrole.c new file mode 100755 index 0000000..9c5e25b --- /dev/null +++ b/3rdParty/Expat/src/xmlrole.c @@ -0,0 +1,1336 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +#include <stddef.h> + +#ifdef COMPILED_FROM_DSP +#include "winconfig.h" +#elif defined(MACOS_CLASSIC) +#include "macconfig.h" +#elif defined(__amigaos4__) +#include "amigaconfig.h" +#elif defined(__WATCOMC__) +#include "watcomconfig.h" +#else +#ifdef HAVE_EXPAT_CONFIG_H +#include <expat_config.h> +#endif +#endif /* ndef COMPILED_FROM_DSP */ + +#include "expat_external.h" +#include "internal.h" +#include "xmlrole.h" +#include "ascii.h" + +/* Doesn't check: + + that ,| are not mixed in a model group + content of literals + +*/ + +static const char KW_ANY[] = { +    ASCII_A, ASCII_N, ASCII_Y, '\0' }; +static const char KW_ATTLIST[] = { +    ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' }; +static const char KW_CDATA[] = { +    ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +static const char KW_DOCTYPE[] = { +    ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' }; +static const char KW_ELEMENT[] = { +    ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' }; +static const char KW_EMPTY[] = { +    ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' }; +static const char KW_ENTITIES[] = { +    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, +    '\0' }; +static const char KW_ENTITY[] = { +    ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' }; +static const char KW_FIXED[] = { +    ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' }; +static const char KW_ID[] = { +    ASCII_I, ASCII_D, '\0' }; +static const char KW_IDREF[] = { +    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' }; +static const char KW_IDREFS[] = { +    ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' }; +#ifdef XML_DTD +static const char KW_IGNORE[] = { +    ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' }; +#endif +static const char KW_IMPLIED[] = { +    ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' }; +#ifdef XML_DTD +static const char KW_INCLUDE[] = { +    ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' }; +#endif +static const char KW_NDATA[] = { +    ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +static const char KW_NMTOKEN[] = { +    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' }; +static const char KW_NMTOKENS[] = { +    ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, +    '\0' }; +static const char KW_NOTATION[] = +    { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, +      '\0' }; +static const char KW_PCDATA[] = { +    ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' }; +static const char KW_PUBLIC[] = { +    ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' }; +static const char KW_REQUIRED[] = { +    ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, +    '\0' }; +static const char KW_SYSTEM[] = { +    ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' }; + +#ifndef MIN_BYTES_PER_CHAR +#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) +#endif + +#ifdef XML_DTD +#define setTopLevel(state) \ +  ((state)->handler = ((state)->documentEntity \ +                       ? internalSubset \ +                       : externalSubset1)) +#else /* not XML_DTD */ +#define setTopLevel(state) ((state)->handler = internalSubset) +#endif /* not XML_DTD */ + +typedef int PTRCALL PROLOG_HANDLER(PROLOG_STATE *state, +                                   int tok, +                                   const char *ptr, +                                   const char *end, +                                   const ENCODING *enc); + +static PROLOG_HANDLER +  prolog0, prolog1, prolog2, +  doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, +  internalSubset, +  entity0, entity1, entity2, entity3, entity4, entity5, entity6, +  entity7, entity8, entity9, entity10, +  notation0, notation1, notation2, notation3, notation4, +  attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, +  attlist7, attlist8, attlist9, +  element0, element1, element2, element3, element4, element5, element6, +  element7, +#ifdef XML_DTD +  externalSubset0, externalSubset1, +  condSect0, condSect1, condSect2, +#endif /* XML_DTD */ +  declClose, +  error; + +static int FASTCALL common(PROLOG_STATE *state, int tok); + +static int PTRCALL +prolog0(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    state->handler = prolog1; +    return XML_ROLE_NONE; +  case XML_TOK_XML_DECL: +    state->handler = prolog1; +    return XML_ROLE_XML_DECL; +  case XML_TOK_PI: +    state->handler = prolog1; +    return XML_ROLE_PI; +  case XML_TOK_COMMENT: +    state->handler = prolog1; +    return XML_ROLE_COMMENT; +  case XML_TOK_BOM: +    return XML_ROLE_NONE; +  case XML_TOK_DECL_OPEN: +    if (!XmlNameMatchesAscii(enc, +                             ptr + 2 * MIN_BYTES_PER_CHAR(enc), +                             end, +                             KW_DOCTYPE)) +      break; +    state->handler = doctype0; +    return XML_ROLE_DOCTYPE_NONE; +  case XML_TOK_INSTANCE_START: +    state->handler = error; +    return XML_ROLE_INSTANCE_START; +  } +  return common(state, tok); +} + +static int PTRCALL +prolog1(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NONE; +  case XML_TOK_PI: +    return XML_ROLE_PI; +  case XML_TOK_COMMENT: +    return XML_ROLE_COMMENT; +  case XML_TOK_BOM: +    return XML_ROLE_NONE; +  case XML_TOK_DECL_OPEN: +    if (!XmlNameMatchesAscii(enc, +                             ptr + 2 * MIN_BYTES_PER_CHAR(enc), +                             end, +                             KW_DOCTYPE)) +      break; +    state->handler = doctype0; +    return XML_ROLE_DOCTYPE_NONE; +  case XML_TOK_INSTANCE_START: +    state->handler = error; +    return XML_ROLE_INSTANCE_START; +  } +  return common(state, tok); +} + +static int PTRCALL +prolog2(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NONE; +  case XML_TOK_PI: +    return XML_ROLE_PI; +  case XML_TOK_COMMENT: +    return XML_ROLE_COMMENT; +  case XML_TOK_INSTANCE_START: +    state->handler = error; +    return XML_ROLE_INSTANCE_START; +  } +  return common(state, tok); +} + +static int PTRCALL +doctype0(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_DOCTYPE_NONE; +  case XML_TOK_NAME: +  case XML_TOK_PREFIXED_NAME: +    state->handler = doctype1; +    return XML_ROLE_DOCTYPE_NAME; +  } +  return common(state, tok); +} + +static int PTRCALL +doctype1(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_DOCTYPE_NONE; +  case XML_TOK_OPEN_BRACKET: +    state->handler = internalSubset; +    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; +  case XML_TOK_DECL_CLOSE: +    state->handler = prolog2; +    return XML_ROLE_DOCTYPE_CLOSE; +  case XML_TOK_NAME: +    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { +      state->handler = doctype3; +      return XML_ROLE_DOCTYPE_NONE; +    } +    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { +      state->handler = doctype2; +      return XML_ROLE_DOCTYPE_NONE; +    } +    break; +  } +  return common(state, tok); +} + +static int PTRCALL +doctype2(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_DOCTYPE_NONE; +  case XML_TOK_LITERAL: +    state->handler = doctype3; +    return XML_ROLE_DOCTYPE_PUBLIC_ID; +  } +  return common(state, tok); +} + +static int PTRCALL +doctype3(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_DOCTYPE_NONE; +  case XML_TOK_LITERAL: +    state->handler = doctype4; +    return XML_ROLE_DOCTYPE_SYSTEM_ID; +  } +  return common(state, tok); +} + +static int PTRCALL +doctype4(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_DOCTYPE_NONE; +  case XML_TOK_OPEN_BRACKET: +    state->handler = internalSubset; +    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET; +  case XML_TOK_DECL_CLOSE: +    state->handler = prolog2; +    return XML_ROLE_DOCTYPE_CLOSE; +  } +  return common(state, tok); +} + +static int PTRCALL +doctype5(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_DOCTYPE_NONE; +  case XML_TOK_DECL_CLOSE: +    state->handler = prolog2; +    return XML_ROLE_DOCTYPE_CLOSE; +  } +  return common(state, tok); +} + +static int PTRCALL +internalSubset(PROLOG_STATE *state, +               int tok, +               const char *ptr, +               const char *end, +               const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NONE; +  case XML_TOK_DECL_OPEN: +    if (XmlNameMatchesAscii(enc, +                            ptr + 2 * MIN_BYTES_PER_CHAR(enc), +                            end, +                            KW_ENTITY)) { +      state->handler = entity0; +      return XML_ROLE_ENTITY_NONE; +    } +    if (XmlNameMatchesAscii(enc, +                            ptr + 2 * MIN_BYTES_PER_CHAR(enc), +                            end, +                            KW_ATTLIST)) { +      state->handler = attlist0; +      return XML_ROLE_ATTLIST_NONE; +    } +    if (XmlNameMatchesAscii(enc, +                            ptr + 2 * MIN_BYTES_PER_CHAR(enc), +                            end, +                            KW_ELEMENT)) { +      state->handler = element0; +      return XML_ROLE_ELEMENT_NONE; +    } +    if (XmlNameMatchesAscii(enc, +                            ptr + 2 * MIN_BYTES_PER_CHAR(enc), +                            end, +                            KW_NOTATION)) { +      state->handler = notation0; +      return XML_ROLE_NOTATION_NONE; +    } +    break; +  case XML_TOK_PI: +    return XML_ROLE_PI; +  case XML_TOK_COMMENT: +    return XML_ROLE_COMMENT; +  case XML_TOK_PARAM_ENTITY_REF: +    return XML_ROLE_PARAM_ENTITY_REF; +  case XML_TOK_CLOSE_BRACKET: +    state->handler = doctype5; +    return XML_ROLE_DOCTYPE_NONE; +  case XML_TOK_NONE: +    return XML_ROLE_NONE; +  } +  return common(state, tok); +} + +#ifdef XML_DTD + +static int PTRCALL +externalSubset0(PROLOG_STATE *state, +                int tok, +                const char *ptr, +                const char *end, +                const ENCODING *enc) +{ +  state->handler = externalSubset1; +  if (tok == XML_TOK_XML_DECL) +    return XML_ROLE_TEXT_DECL; +  return externalSubset1(state, tok, ptr, end, enc); +} + +static int PTRCALL +externalSubset1(PROLOG_STATE *state, +                int tok, +                const char *ptr, +                const char *end, +                const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_COND_SECT_OPEN: +    state->handler = condSect0; +    return XML_ROLE_NONE; +  case XML_TOK_COND_SECT_CLOSE: +    if (state->includeLevel == 0) +      break; +    state->includeLevel -= 1; +    return XML_ROLE_NONE; +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NONE; +  case XML_TOK_CLOSE_BRACKET: +    break; +  case XML_TOK_NONE: +    if (state->includeLevel) +      break; +    return XML_ROLE_NONE; +  default: +    return internalSubset(state, tok, ptr, end, enc); +  } +  return common(state, tok); +} + +#endif /* XML_DTD */ + +static int PTRCALL +entity0(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_PERCENT: +    state->handler = entity1; +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_NAME: +    state->handler = entity2; +    return XML_ROLE_GENERAL_ENTITY_NAME; +  } +  return common(state, tok); +} + +static int PTRCALL +entity1(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_NAME: +    state->handler = entity7; +    return XML_ROLE_PARAM_ENTITY_NAME; +  } +  return common(state, tok); +} + +static int PTRCALL +entity2(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_NAME: +    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { +      state->handler = entity4; +      return XML_ROLE_ENTITY_NONE; +    } +    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { +      state->handler = entity3; +      return XML_ROLE_ENTITY_NONE; +    } +    break; +  case XML_TOK_LITERAL: +    state->handler = declClose; +    state->role_none = XML_ROLE_ENTITY_NONE; +    return XML_ROLE_ENTITY_VALUE; +  } +  return common(state, tok); +} + +static int PTRCALL +entity3(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_LITERAL: +    state->handler = entity4; +    return XML_ROLE_ENTITY_PUBLIC_ID; +  } +  return common(state, tok); +} + +static int PTRCALL +entity4(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_LITERAL: +    state->handler = entity5; +    return XML_ROLE_ENTITY_SYSTEM_ID; +  } +  return common(state, tok); +} + +static int PTRCALL +entity5(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_DECL_CLOSE: +    setTopLevel(state); +    return XML_ROLE_ENTITY_COMPLETE; +  case XML_TOK_NAME: +    if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) { +      state->handler = entity6; +      return XML_ROLE_ENTITY_NONE; +    } +    break; +  } +  return common(state, tok); +} + +static int PTRCALL +entity6(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_NAME: +    state->handler = declClose; +    state->role_none = XML_ROLE_ENTITY_NONE; +    return XML_ROLE_ENTITY_NOTATION_NAME; +  } +  return common(state, tok); +} + +static int PTRCALL +entity7(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_NAME: +    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { +      state->handler = entity9; +      return XML_ROLE_ENTITY_NONE; +    } +    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { +      state->handler = entity8; +      return XML_ROLE_ENTITY_NONE; +    } +    break; +  case XML_TOK_LITERAL: +    state->handler = declClose; +    state->role_none = XML_ROLE_ENTITY_NONE; +    return XML_ROLE_ENTITY_VALUE; +  } +  return common(state, tok); +} + +static int PTRCALL +entity8(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_LITERAL: +    state->handler = entity9; +    return XML_ROLE_ENTITY_PUBLIC_ID; +  } +  return common(state, tok); +} + +static int PTRCALL +entity9(PROLOG_STATE *state, +        int tok, +        const char *ptr, +        const char *end, +        const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_LITERAL: +    state->handler = entity10; +    return XML_ROLE_ENTITY_SYSTEM_ID; +  } +  return common(state, tok); +} + +static int PTRCALL +entity10(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ENTITY_NONE; +  case XML_TOK_DECL_CLOSE: +    setTopLevel(state); +    return XML_ROLE_ENTITY_COMPLETE; +  } +  return common(state, tok); +} + +static int PTRCALL +notation0(PROLOG_STATE *state, +          int tok, +          const char *ptr, +          const char *end, +          const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NOTATION_NONE; +  case XML_TOK_NAME: +    state->handler = notation1; +    return XML_ROLE_NOTATION_NAME; +  } +  return common(state, tok); +} + +static int PTRCALL +notation1(PROLOG_STATE *state, +          int tok, +          const char *ptr, +          const char *end, +          const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NOTATION_NONE; +  case XML_TOK_NAME: +    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) { +      state->handler = notation3; +      return XML_ROLE_NOTATION_NONE; +    } +    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) { +      state->handler = notation2; +      return XML_ROLE_NOTATION_NONE; +    } +    break; +  } +  return common(state, tok); +} + +static int PTRCALL +notation2(PROLOG_STATE *state, +          int tok, +          const char *ptr, +          const char *end, +          const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NOTATION_NONE; +  case XML_TOK_LITERAL: +    state->handler = notation4; +    return XML_ROLE_NOTATION_PUBLIC_ID; +  } +  return common(state, tok); +} + +static int PTRCALL +notation3(PROLOG_STATE *state, +          int tok, +          const char *ptr, +          const char *end, +          const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NOTATION_NONE; +  case XML_TOK_LITERAL: +    state->handler = declClose; +    state->role_none = XML_ROLE_NOTATION_NONE; +    return XML_ROLE_NOTATION_SYSTEM_ID; +  } +  return common(state, tok); +} + +static int PTRCALL +notation4(PROLOG_STATE *state, +          int tok, +          const char *ptr, +          const char *end, +          const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NOTATION_NONE; +  case XML_TOK_LITERAL: +    state->handler = declClose; +    state->role_none = XML_ROLE_NOTATION_NONE; +    return XML_ROLE_NOTATION_SYSTEM_ID; +  case XML_TOK_DECL_CLOSE: +    setTopLevel(state); +    return XML_ROLE_NOTATION_NO_SYSTEM_ID; +  } +  return common(state, tok); +} + +static int PTRCALL +attlist0(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_NAME: +  case XML_TOK_PREFIXED_NAME: +    state->handler = attlist1; +    return XML_ROLE_ATTLIST_ELEMENT_NAME; +  } +  return common(state, tok); +} + +static int PTRCALL +attlist1(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_DECL_CLOSE: +    setTopLevel(state); +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_NAME: +  case XML_TOK_PREFIXED_NAME: +    state->handler = attlist2; +    return XML_ROLE_ATTRIBUTE_NAME; +  } +  return common(state, tok); +} + +static int PTRCALL +attlist2(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_NAME: +    { +      static const char * const types[] = { +        KW_CDATA, +        KW_ID, +        KW_IDREF, +        KW_IDREFS, +        KW_ENTITY, +        KW_ENTITIES, +        KW_NMTOKEN, +        KW_NMTOKENS, +      }; +      int i; +      for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) +        if (XmlNameMatchesAscii(enc, ptr, end, types[i])) { +          state->handler = attlist8; +          return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; +        } +    } +    if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) { +      state->handler = attlist5; +      return XML_ROLE_ATTLIST_NONE; +    } +    break; +  case XML_TOK_OPEN_PAREN: +    state->handler = attlist3; +    return XML_ROLE_ATTLIST_NONE; +  } +  return common(state, tok); +} + +static int PTRCALL +attlist3(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_NMTOKEN: +  case XML_TOK_NAME: +  case XML_TOK_PREFIXED_NAME: +    state->handler = attlist4; +    return XML_ROLE_ATTRIBUTE_ENUM_VALUE; +  } +  return common(state, tok); +} + +static int PTRCALL +attlist4(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_CLOSE_PAREN: +    state->handler = attlist8; +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_OR: +    state->handler = attlist3; +    return XML_ROLE_ATTLIST_NONE; +  } +  return common(state, tok); +} + +static int PTRCALL +attlist5(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_OPEN_PAREN: +    state->handler = attlist6; +    return XML_ROLE_ATTLIST_NONE; +  } +  return common(state, tok); +} + +static int PTRCALL +attlist6(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_NAME: +    state->handler = attlist7; +    return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; +  } +  return common(state, tok); +} + +static int PTRCALL +attlist7(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_CLOSE_PAREN: +    state->handler = attlist8; +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_OR: +    state->handler = attlist6; +    return XML_ROLE_ATTLIST_NONE; +  } +  return common(state, tok); +} + +/* default value */ +static int PTRCALL +attlist8(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_POUND_NAME: +    if (XmlNameMatchesAscii(enc, +                            ptr + MIN_BYTES_PER_CHAR(enc), +                            end, +                            KW_IMPLIED)) { +      state->handler = attlist1; +      return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; +    } +    if (XmlNameMatchesAscii(enc, +                            ptr + MIN_BYTES_PER_CHAR(enc), +                            end, +                            KW_REQUIRED)) { +      state->handler = attlist1; +      return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; +    } +    if (XmlNameMatchesAscii(enc, +                            ptr + MIN_BYTES_PER_CHAR(enc), +                            end, +                            KW_FIXED)) { +      state->handler = attlist9; +      return XML_ROLE_ATTLIST_NONE; +    } +    break; +  case XML_TOK_LITERAL: +    state->handler = attlist1; +    return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; +  } +  return common(state, tok); +} + +static int PTRCALL +attlist9(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ATTLIST_NONE; +  case XML_TOK_LITERAL: +    state->handler = attlist1; +    return XML_ROLE_FIXED_ATTRIBUTE_VALUE; +  } +  return common(state, tok); +} + +static int PTRCALL +element0(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ELEMENT_NONE; +  case XML_TOK_NAME: +  case XML_TOK_PREFIXED_NAME: +    state->handler = element1; +    return XML_ROLE_ELEMENT_NAME; +  } +  return common(state, tok); +} + +static int PTRCALL +element1(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ELEMENT_NONE; +  case XML_TOK_NAME: +    if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) { +      state->handler = declClose; +      state->role_none = XML_ROLE_ELEMENT_NONE; +      return XML_ROLE_CONTENT_EMPTY; +    } +    if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) { +      state->handler = declClose; +      state->role_none = XML_ROLE_ELEMENT_NONE; +      return XML_ROLE_CONTENT_ANY; +    } +    break; +  case XML_TOK_OPEN_PAREN: +    state->handler = element2; +    state->level = 1; +    return XML_ROLE_GROUP_OPEN; +  } +  return common(state, tok); +} + +static int PTRCALL +element2(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ELEMENT_NONE; +  case XML_TOK_POUND_NAME: +    if (XmlNameMatchesAscii(enc, +                            ptr + MIN_BYTES_PER_CHAR(enc), +                            end, +                            KW_PCDATA)) { +      state->handler = element3; +      return XML_ROLE_CONTENT_PCDATA; +    } +    break; +  case XML_TOK_OPEN_PAREN: +    state->level = 2; +    state->handler = element6; +    return XML_ROLE_GROUP_OPEN; +  case XML_TOK_NAME: +  case XML_TOK_PREFIXED_NAME: +    state->handler = element7; +    return XML_ROLE_CONTENT_ELEMENT; +  case XML_TOK_NAME_QUESTION: +    state->handler = element7; +    return XML_ROLE_CONTENT_ELEMENT_OPT; +  case XML_TOK_NAME_ASTERISK: +    state->handler = element7; +    return XML_ROLE_CONTENT_ELEMENT_REP; +  case XML_TOK_NAME_PLUS: +    state->handler = element7; +    return XML_ROLE_CONTENT_ELEMENT_PLUS; +  } +  return common(state, tok); +} + +static int PTRCALL +element3(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ELEMENT_NONE; +  case XML_TOK_CLOSE_PAREN: +    state->handler = declClose; +    state->role_none = XML_ROLE_ELEMENT_NONE; +    return XML_ROLE_GROUP_CLOSE; +  case XML_TOK_CLOSE_PAREN_ASTERISK: +    state->handler = declClose; +    state->role_none = XML_ROLE_ELEMENT_NONE; +    return XML_ROLE_GROUP_CLOSE_REP; +  case XML_TOK_OR: +    state->handler = element4; +    return XML_ROLE_ELEMENT_NONE; +  } +  return common(state, tok); +} + +static int PTRCALL +element4(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ELEMENT_NONE; +  case XML_TOK_NAME: +  case XML_TOK_PREFIXED_NAME: +    state->handler = element5; +    return XML_ROLE_CONTENT_ELEMENT; +  } +  return common(state, tok); +} + +static int PTRCALL +element5(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ELEMENT_NONE; +  case XML_TOK_CLOSE_PAREN_ASTERISK: +    state->handler = declClose; +    state->role_none = XML_ROLE_ELEMENT_NONE; +    return XML_ROLE_GROUP_CLOSE_REP; +  case XML_TOK_OR: +    state->handler = element4; +    return XML_ROLE_ELEMENT_NONE; +  } +  return common(state, tok); +} + +static int PTRCALL +element6(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ELEMENT_NONE; +  case XML_TOK_OPEN_PAREN: +    state->level += 1; +    return XML_ROLE_GROUP_OPEN; +  case XML_TOK_NAME: +  case XML_TOK_PREFIXED_NAME: +    state->handler = element7; +    return XML_ROLE_CONTENT_ELEMENT; +  case XML_TOK_NAME_QUESTION: +    state->handler = element7; +    return XML_ROLE_CONTENT_ELEMENT_OPT; +  case XML_TOK_NAME_ASTERISK: +    state->handler = element7; +    return XML_ROLE_CONTENT_ELEMENT_REP; +  case XML_TOK_NAME_PLUS: +    state->handler = element7; +    return XML_ROLE_CONTENT_ELEMENT_PLUS; +  } +  return common(state, tok); +} + +static int PTRCALL +element7(PROLOG_STATE *state, +         int tok, +         const char *ptr, +         const char *end, +         const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_ELEMENT_NONE; +  case XML_TOK_CLOSE_PAREN: +    state->level -= 1; +    if (state->level == 0) { +      state->handler = declClose; +      state->role_none = XML_ROLE_ELEMENT_NONE; +    } +    return XML_ROLE_GROUP_CLOSE; +  case XML_TOK_CLOSE_PAREN_ASTERISK: +    state->level -= 1; +    if (state->level == 0) { +      state->handler = declClose; +      state->role_none = XML_ROLE_ELEMENT_NONE; +    } +    return XML_ROLE_GROUP_CLOSE_REP; +  case XML_TOK_CLOSE_PAREN_QUESTION: +    state->level -= 1; +    if (state->level == 0) { +      state->handler = declClose; +      state->role_none = XML_ROLE_ELEMENT_NONE; +    } +    return XML_ROLE_GROUP_CLOSE_OPT; +  case XML_TOK_CLOSE_PAREN_PLUS: +    state->level -= 1; +    if (state->level == 0) { +      state->handler = declClose; +      state->role_none = XML_ROLE_ELEMENT_NONE; +    } +    return XML_ROLE_GROUP_CLOSE_PLUS; +  case XML_TOK_COMMA: +    state->handler = element6; +    return XML_ROLE_GROUP_SEQUENCE; +  case XML_TOK_OR: +    state->handler = element6; +    return XML_ROLE_GROUP_CHOICE; +  } +  return common(state, tok); +} + +#ifdef XML_DTD + +static int PTRCALL +condSect0(PROLOG_STATE *state, +          int tok, +          const char *ptr, +          const char *end, +          const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NONE; +  case XML_TOK_NAME: +    if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) { +      state->handler = condSect1; +      return XML_ROLE_NONE; +    } +    if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) { +      state->handler = condSect2; +      return XML_ROLE_NONE; +    } +    break; +  } +  return common(state, tok); +} + +static int PTRCALL +condSect1(PROLOG_STATE *state, +          int tok, +          const char *ptr, +          const char *end, +          const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NONE; +  case XML_TOK_OPEN_BRACKET: +    state->handler = externalSubset1; +    state->includeLevel += 1; +    return XML_ROLE_NONE; +  } +  return common(state, tok); +} + +static int PTRCALL +condSect2(PROLOG_STATE *state, +          int tok, +          const char *ptr, +          const char *end, +          const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return XML_ROLE_NONE; +  case XML_TOK_OPEN_BRACKET: +    state->handler = externalSubset1; +    return XML_ROLE_IGNORE_SECT; +  } +  return common(state, tok); +} + +#endif /* XML_DTD */ + +static int PTRCALL +declClose(PROLOG_STATE *state, +          int tok, +          const char *ptr, +          const char *end, +          const ENCODING *enc) +{ +  switch (tok) { +  case XML_TOK_PROLOG_S: +    return state->role_none; +  case XML_TOK_DECL_CLOSE: +    setTopLevel(state); +    return state->role_none; +  } +  return common(state, tok); +} + +static int PTRCALL +error(PROLOG_STATE *state, +      int tok, +      const char *ptr, +      const char *end, +      const ENCODING *enc) +{ +  return XML_ROLE_NONE; +} + +static int FASTCALL +common(PROLOG_STATE *state, int tok) +{ +#ifdef XML_DTD +  if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF) +    return XML_ROLE_INNER_PARAM_ENTITY_REF; +#endif +  state->handler = error; +  return XML_ROLE_ERROR; +} + +void +XmlPrologStateInit(PROLOG_STATE *state) +{ +  state->handler = prolog0; +#ifdef XML_DTD +  state->documentEntity = 1; +  state->includeLevel = 0; +  state->inEntityValue = 0; +#endif /* XML_DTD */ +} + +#ifdef XML_DTD + +void +XmlPrologStateInitExternalEntity(PROLOG_STATE *state) +{ +  state->handler = externalSubset0; +  state->documentEntity = 0; +  state->includeLevel = 0; +} + +#endif /* XML_DTD */ diff --git a/3rdParty/Expat/src/xmlrole.h b/3rdParty/Expat/src/xmlrole.h new file mode 100755 index 0000000..4dd9f06 --- /dev/null +++ b/3rdParty/Expat/src/xmlrole.h @@ -0,0 +1,114 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +#ifndef XmlRole_INCLUDED +#define XmlRole_INCLUDED 1 + +#ifdef __VMS +/*      0        1         2         3      0        1         2         3 +        1234567890123456789012345678901     1234567890123456789012345678901 */ +#define XmlPrologStateInitExternalEntity    XmlPrologStateInitExternalEnt +#endif + +#include "xmltok.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { +  XML_ROLE_ERROR = -1, +  XML_ROLE_NONE = 0, +  XML_ROLE_XML_DECL, +  XML_ROLE_INSTANCE_START, +  XML_ROLE_DOCTYPE_NONE, +  XML_ROLE_DOCTYPE_NAME, +  XML_ROLE_DOCTYPE_SYSTEM_ID, +  XML_ROLE_DOCTYPE_PUBLIC_ID, +  XML_ROLE_DOCTYPE_INTERNAL_SUBSET, +  XML_ROLE_DOCTYPE_CLOSE, +  XML_ROLE_GENERAL_ENTITY_NAME, +  XML_ROLE_PARAM_ENTITY_NAME, +  XML_ROLE_ENTITY_NONE, +  XML_ROLE_ENTITY_VALUE, +  XML_ROLE_ENTITY_SYSTEM_ID, +  XML_ROLE_ENTITY_PUBLIC_ID, +  XML_ROLE_ENTITY_COMPLETE, +  XML_ROLE_ENTITY_NOTATION_NAME, +  XML_ROLE_NOTATION_NONE, +  XML_ROLE_NOTATION_NAME, +  XML_ROLE_NOTATION_SYSTEM_ID, +  XML_ROLE_NOTATION_NO_SYSTEM_ID, +  XML_ROLE_NOTATION_PUBLIC_ID, +  XML_ROLE_ATTRIBUTE_NAME, +  XML_ROLE_ATTRIBUTE_TYPE_CDATA, +  XML_ROLE_ATTRIBUTE_TYPE_ID, +  XML_ROLE_ATTRIBUTE_TYPE_IDREF, +  XML_ROLE_ATTRIBUTE_TYPE_IDREFS, +  XML_ROLE_ATTRIBUTE_TYPE_ENTITY, +  XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, +  XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, +  XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, +  XML_ROLE_ATTRIBUTE_ENUM_VALUE, +  XML_ROLE_ATTRIBUTE_NOTATION_VALUE, +  XML_ROLE_ATTLIST_NONE, +  XML_ROLE_ATTLIST_ELEMENT_NAME, +  XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, +  XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, +  XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, +  XML_ROLE_FIXED_ATTRIBUTE_VALUE, +  XML_ROLE_ELEMENT_NONE, +  XML_ROLE_ELEMENT_NAME, +  XML_ROLE_CONTENT_ANY, +  XML_ROLE_CONTENT_EMPTY, +  XML_ROLE_CONTENT_PCDATA, +  XML_ROLE_GROUP_OPEN, +  XML_ROLE_GROUP_CLOSE, +  XML_ROLE_GROUP_CLOSE_REP, +  XML_ROLE_GROUP_CLOSE_OPT, +  XML_ROLE_GROUP_CLOSE_PLUS, +  XML_ROLE_GROUP_CHOICE, +  XML_ROLE_GROUP_SEQUENCE, +  XML_ROLE_CONTENT_ELEMENT, +  XML_ROLE_CONTENT_ELEMENT_REP, +  XML_ROLE_CONTENT_ELEMENT_OPT, +  XML_ROLE_CONTENT_ELEMENT_PLUS, +  XML_ROLE_PI, +  XML_ROLE_COMMENT, +#ifdef XML_DTD +  XML_ROLE_TEXT_DECL, +  XML_ROLE_IGNORE_SECT, +  XML_ROLE_INNER_PARAM_ENTITY_REF, +#endif /* XML_DTD */ +  XML_ROLE_PARAM_ENTITY_REF +}; + +typedef struct prolog_state { +  int (PTRCALL *handler) (struct prolog_state *state, +                          int tok, +                          const char *ptr, +                          const char *end, +                          const ENCODING *enc); +  unsigned level; +  int role_none; +#ifdef XML_DTD +  unsigned includeLevel; +  int documentEntity; +  int inEntityValue; +#endif /* XML_DTD */ +} PROLOG_STATE; + +void XmlPrologStateInit(PROLOG_STATE *); +#ifdef XML_DTD +void XmlPrologStateInitExternalEntity(PROLOG_STATE *); +#endif /* XML_DTD */ + +#define XmlTokenRole(state, tok, ptr, end, enc) \ + (((state)->handler)(state, tok, ptr, end, enc)) + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlRole_INCLUDED */ diff --git a/3rdParty/Expat/src/xmltok.c b/3rdParty/Expat/src/xmltok.c new file mode 100755 index 0000000..068afde --- /dev/null +++ b/3rdParty/Expat/src/xmltok.c @@ -0,0 +1,1651 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +#include <stddef.h> + +#ifdef COMPILED_FROM_DSP +#include "winconfig.h" +#elif defined(MACOS_CLASSIC) +#include "macconfig.h" +#elif defined(__amigaos4__) +#include "amigaconfig.h" +#elif defined(__WATCOMC__) +#include "watcomconfig.h" +#else +#ifdef HAVE_EXPAT_CONFIG_H +#include <expat_config.h> +#endif +#endif /* ndef COMPILED_FROM_DSP */ + +#include "expat_external.h" +#include "internal.h" +#include "xmltok.h" +#include "nametab.h" + +#ifdef XML_DTD +#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok) +#else +#define IGNORE_SECTION_TOK_VTABLE /* as nothing */ +#endif + +#define VTABLE1 \ +  { PREFIX(prologTok), PREFIX(contentTok), \ +    PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \ +  { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ +  PREFIX(sameName), \ +  PREFIX(nameMatchesAscii), \ +  PREFIX(nameLength), \ +  PREFIX(skipS), \ +  PREFIX(getAtts), \ +  PREFIX(charRefNumber), \ +  PREFIX(predefinedEntityName), \ +  PREFIX(updatePosition), \ +  PREFIX(isPublicId) + +#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) + +#define UCS2_GET_NAMING(pages, hi, lo) \ +   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F))) + +/* A 2 byte UTF-8 representation splits the characters 11 bits between +   the bottom 5 and 6 bits of the bytes.  We need 8 bits to index into +   pages, 3 bits to add to that index and 5 bits to generate the mask. +*/ +#define UTF8_GET_NAMING2(pages, byte) \ +    (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ +                      + ((((byte)[0]) & 3) << 1) \ +                      + ((((byte)[1]) >> 5) & 1)] \ +         & (1 << (((byte)[1]) & 0x1F))) + +/* A 3 byte UTF-8 representation splits the characters 16 bits between +   the bottom 4, 6 and 6 bits of the bytes.  We need 8 bits to index +   into pages, 3 bits to add to that index and 5 bits to generate the +   mask. +*/ +#define UTF8_GET_NAMING3(pages, byte) \ +  (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ +                             + ((((byte)[1]) >> 2) & 0xF)] \ +                       << 3) \ +                      + ((((byte)[1]) & 3) << 1) \ +                      + ((((byte)[2]) >> 5) & 1)] \ +         & (1 << (((byte)[2]) & 0x1F))) + +#define UTF8_GET_NAMING(pages, p, n) \ +  ((n) == 2 \ +  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ +  : ((n) == 3 \ +     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \ +     : 0)) + +/* Detection of invalid UTF-8 sequences is based on Table 3.1B +   of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/ +   with the additional restriction of not allowing the Unicode +   code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE). +   Implementation details: +     (A & 0x80) == 0     means A < 0x80 +   and +     (A & 0xC0) == 0xC0  means A > 0xBF +*/ + +#define UTF8_INVALID2(p) \ +  ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0) + +#define UTF8_INVALID3(p) \ +  (((p)[2] & 0x80) == 0 \ +  || \ +  ((*p) == 0xEF && (p)[1] == 0xBF \ +    ? \ +    (p)[2] > 0xBD \ +    : \ +    ((p)[2] & 0xC0) == 0xC0) \ +  || \ +  ((*p) == 0xE0 \ +    ? \ +    (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \ +    : \ +    ((p)[1] & 0x80) == 0 \ +    || \ +    ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0))) + +#define UTF8_INVALID4(p) \ +  (((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \ +  || \ +  ((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \ +  || \ +  ((*p) == 0xF0 \ +    ? \ +    (p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \ +    : \ +    ((p)[1] & 0x80) == 0 \ +    || \ +    ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) + +static int PTRFASTCALL +isNever(const ENCODING *enc, const char *p) +{ +  return 0; +} + +static int PTRFASTCALL +utf8_isName2(const ENCODING *enc, const char *p) +{ +  return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isName3(const ENCODING *enc, const char *p) +{ +  return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); +} + +#define utf8_isName4 isNever + +static int PTRFASTCALL +utf8_isNmstrt2(const ENCODING *enc, const char *p) +{ +  return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isNmstrt3(const ENCODING *enc, const char *p) +{ +  return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); +} + +#define utf8_isNmstrt4 isNever + +static int PTRFASTCALL +utf8_isInvalid2(const ENCODING *enc, const char *p) +{ +  return UTF8_INVALID2((const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isInvalid3(const ENCODING *enc, const char *p) +{ +  return UTF8_INVALID3((const unsigned char *)p); +} + +static int PTRFASTCALL +utf8_isInvalid4(const ENCODING *enc, const char *p) +{ +  return UTF8_INVALID4((const unsigned char *)p); +} + +struct normal_encoding { +  ENCODING enc; +  unsigned char type[256]; +#ifdef XML_MIN_SIZE +  int (PTRFASTCALL *byteType)(const ENCODING *, const char *); +  int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *); +  int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *); +  int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *); +  int (PTRCALL *charMatches)(const ENCODING *, const char *, int); +#endif /* XML_MIN_SIZE */ +  int (PTRFASTCALL *isName2)(const ENCODING *, const char *); +  int (PTRFASTCALL *isName3)(const ENCODING *, const char *); +  int (PTRFASTCALL *isName4)(const ENCODING *, const char *); +  int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *); +  int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *); +  int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *); +  int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *); +  int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *); +  int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *); +}; + +#define AS_NORMAL_ENCODING(enc)   ((const struct normal_encoding *) (enc)) + +#ifdef XML_MIN_SIZE + +#define STANDARD_VTABLE(E) \ + E ## byteType, \ + E ## isNameMin, \ + E ## isNmstrtMin, \ + E ## byteToAscii, \ + E ## charMatches, + +#else + +#define STANDARD_VTABLE(E) /* as nothing */ + +#endif + +#define NORMAL_VTABLE(E) \ + E ## isName2, \ + E ## isName3, \ + E ## isName4, \ + E ## isNmstrt2, \ + E ## isNmstrt3, \ + E ## isNmstrt4, \ + E ## isInvalid2, \ + E ## isInvalid3, \ + E ## isInvalid4 + +static int FASTCALL checkCharRefNumber(int); + +#include "xmltok_impl.h" +#include "ascii.h" + +#ifdef XML_MIN_SIZE +#define sb_isNameMin isNever +#define sb_isNmstrtMin isNever +#endif + +#ifdef XML_MIN_SIZE +#define MINBPC(enc) ((enc)->minBytesPerChar) +#else +/* minimum bytes per character */ +#define MINBPC(enc) 1 +#endif + +#define SB_BYTE_TYPE(enc, p) \ +  (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) + +#ifdef XML_MIN_SIZE +static int PTRFASTCALL +sb_byteType(const ENCODING *enc, const char *p) +{ +  return SB_BYTE_TYPE(enc, p); +} +#define BYTE_TYPE(enc, p) \ + (AS_NORMAL_ENCODING(enc)->byteType(enc, p)) +#else +#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) +#endif + +#ifdef XML_MIN_SIZE +#define BYTE_TO_ASCII(enc, p) \ + (AS_NORMAL_ENCODING(enc)->byteToAscii(enc, p)) +static int PTRFASTCALL +sb_byteToAscii(const ENCODING *enc, const char *p) +{ +  return *p; +} +#else +#define BYTE_TO_ASCII(enc, p) (*(p)) +#endif + +#define IS_NAME_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isName ## n(enc, p)) +#define IS_NMSTRT_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isNmstrt ## n(enc, p)) +#define IS_INVALID_CHAR(enc, p, n) \ + (AS_NORMAL_ENCODING(enc)->isInvalid ## n(enc, p)) + +#ifdef XML_MIN_SIZE +#define IS_NAME_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNameMin(enc, p)) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) \ + (AS_NORMAL_ENCODING(enc)->isNmstrtMin(enc, p)) +#else +#define IS_NAME_CHAR_MINBPC(enc, p) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) +#endif + +#ifdef XML_MIN_SIZE +#define CHAR_MATCHES(enc, p, c) \ + (AS_NORMAL_ENCODING(enc)->charMatches(enc, p, c)) +static int PTRCALL +sb_charMatches(const ENCODING *enc, const char *p, int c) +{ +  return *p == c; +} +#else +/* c is an ASCII character */ +#define CHAR_MATCHES(enc, p, c) (*(p) == c) +#endif + +#define PREFIX(ident) normal_ ## ident +#define XML_TOK_IMPL_C +#include "xmltok_impl.c" +#undef XML_TOK_IMPL_C + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */ +  UTF8_cval1 = 0x00, +  UTF8_cval2 = 0xc0, +  UTF8_cval3 = 0xe0, +  UTF8_cval4 = 0xf0 +}; + +static void PTRCALL +utf8_toUtf8(const ENCODING *enc, +            const char **fromP, const char *fromLim, +            char **toP, const char *toLim) +{ +  char *to; +  const char *from; +  if (fromLim - *fromP > toLim - *toP) { +    /* Avoid copying partial characters. */ +    for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--) +      if (((unsigned char)fromLim[-1] & 0xc0) != 0x80) +        break; +  } +  for (to = *toP, from = *fromP; from != fromLim; from++, to++) +    *to = *from; +  *fromP = from; +  *toP = to; +} + +static void PTRCALL +utf8_toUtf16(const ENCODING *enc, +             const char **fromP, const char *fromLim, +             unsigned short **toP, const unsigned short *toLim) +{ +  unsigned short *to = *toP; +  const char *from = *fromP; +  while (from != fromLim && to != toLim) { +    switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { +    case BT_LEAD2: +      *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); +      from += 2; +      break; +    case BT_LEAD3: +      *to++ = (unsigned short)(((from[0] & 0xf) << 12) +                               | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); +      from += 3; +      break; +    case BT_LEAD4: +      { +        unsigned long n; +        if (to + 1 == toLim) +          goto after; +        n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) +            | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); +        n -= 0x10000; +        to[0] = (unsigned short)((n >> 10) | 0xD800); +        to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); +        to += 2; +        from += 4; +      } +      break; +    default: +      *to++ = *from++; +      break; +    } +  } +after: +  *fromP = from; +  *toP = to; +} + +#ifdef XML_NS +static const struct normal_encoding utf8_encoding_ns = { +  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, +  { +#include "asciitab.h" +#include "utf8tab.h" +  }, +  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; +#endif + +static const struct normal_encoding utf8_encoding = { +  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, +  { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "utf8tab.h" +  }, +  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + +#ifdef XML_NS + +static const struct normal_encoding internal_utf8_encoding_ns = { +  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, +  { +#include "iasciitab.h" +#include "utf8tab.h" +  }, +  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + +#endif + +static const struct normal_encoding internal_utf8_encoding = { +  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, +  { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "utf8tab.h" +  }, +  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) +}; + +static void PTRCALL +latin1_toUtf8(const ENCODING *enc, +              const char **fromP, const char *fromLim, +              char **toP, const char *toLim) +{ +  for (;;) { +    unsigned char c; +    if (*fromP == fromLim) +      break; +    c = (unsigned char)**fromP; +    if (c & 0x80) { +      if (toLim - *toP < 2) +        break; +      *(*toP)++ = (char)((c >> 6) | UTF8_cval2); +      *(*toP)++ = (char)((c & 0x3f) | 0x80); +      (*fromP)++; +    } +    else { +      if (*toP == toLim) +        break; +      *(*toP)++ = *(*fromP)++; +    } +  } +} + +static void PTRCALL +latin1_toUtf16(const ENCODING *enc, +               const char **fromP, const char *fromLim, +               unsigned short **toP, const unsigned short *toLim) +{ +  while (*fromP != fromLim && *toP != toLim) +    *(*toP)++ = (unsigned char)*(*fromP)++; +} + +#ifdef XML_NS + +static const struct normal_encoding latin1_encoding_ns = { +  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, +  { +#include "asciitab.h" +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(sb_) +}; + +#endif + +static const struct normal_encoding latin1_encoding = { +  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, +  { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(sb_) +}; + +static void PTRCALL +ascii_toUtf8(const ENCODING *enc, +             const char **fromP, const char *fromLim, +             char **toP, const char *toLim) +{ +  while (*fromP != fromLim && *toP != toLim) +    *(*toP)++ = *(*fromP)++; +} + +#ifdef XML_NS + +static const struct normal_encoding ascii_encoding_ns = { +  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, +  { +#include "asciitab.h" +/* BT_NONXML == 0 */ +  }, +  STANDARD_VTABLE(sb_) +}; + +#endif + +static const struct normal_encoding ascii_encoding = { +  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, +  { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +/* BT_NONXML == 0 */ +  }, +  STANDARD_VTABLE(sb_) +}; + +static int PTRFASTCALL +unicode_byte_type(char hi, char lo) +{ +  switch ((unsigned char)hi) { +  case 0xD8: case 0xD9: case 0xDA: case 0xDB: +    return BT_LEAD4; +  case 0xDC: case 0xDD: case 0xDE: case 0xDF: +    return BT_TRAIL; +  case 0xFF: +    switch ((unsigned char)lo) { +    case 0xFF: +    case 0xFE: +      return BT_NONXML; +    } +    break; +  } +  return BT_NONASCII; +} + +#define DEFINE_UTF16_TO_UTF8(E) \ +static void  PTRCALL \ +E ## toUtf8(const ENCODING *enc, \ +            const char **fromP, const char *fromLim, \ +            char **toP, const char *toLim) \ +{ \ +  const char *from; \ +  for (from = *fromP; from != fromLim; from += 2) { \ +    int plane; \ +    unsigned char lo2; \ +    unsigned char lo = GET_LO(from); \ +    unsigned char hi = GET_HI(from); \ +    switch (hi) { \ +    case 0: \ +      if (lo < 0x80) { \ +        if (*toP == toLim) { \ +          *fromP = from; \ +          return; \ +        } \ +        *(*toP)++ = lo; \ +        break; \ +      } \ +      /* fall through */ \ +    case 0x1: case 0x2: case 0x3: \ +    case 0x4: case 0x5: case 0x6: case 0x7: \ +      if (toLim -  *toP < 2) { \ +        *fromP = from; \ +        return; \ +      } \ +      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \ +      *(*toP)++ = ((lo & 0x3f) | 0x80); \ +      break; \ +    default: \ +      if (toLim -  *toP < 3)  { \ +        *fromP = from; \ +        return; \ +      } \ +      /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ +      *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ +      *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ +      *(*toP)++ = ((lo & 0x3f) | 0x80); \ +      break; \ +    case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ +      if (toLim -  *toP < 4) { \ +        *fromP = from; \ +        return; \ +      } \ +      plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ +      *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ +      *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ +      from += 2; \ +      lo2 = GET_LO(from); \ +      *(*toP)++ = (((lo & 0x3) << 4) \ +                   | ((GET_HI(from) & 0x3) << 2) \ +                   | (lo2 >> 6) \ +                   | 0x80); \ +      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ +      break; \ +    } \ +  } \ +  *fromP = from; \ +} + +#define DEFINE_UTF16_TO_UTF16(E) \ +static void  PTRCALL \ +E ## toUtf16(const ENCODING *enc, \ +             const char **fromP, const char *fromLim, \ +             unsigned short **toP, const unsigned short *toLim) \ +{ \ +  /* Avoid copying first half only of surrogate */ \ +  if (fromLim - *fromP > ((toLim - *toP) << 1) \ +      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \ +    fromLim -= 2; \ +  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \ +    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ +} + +#define SET2(ptr, ch) \ +  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8))) +#define GET_LO(ptr) ((unsigned char)(ptr)[0]) +#define GET_HI(ptr) ((unsigned char)(ptr)[1]) + +DEFINE_UTF16_TO_UTF8(little2_) +DEFINE_UTF16_TO_UTF16(little2_) + +#undef SET2 +#undef GET_LO +#undef GET_HI + +#define SET2(ptr, ch) \ +  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF))) +#define GET_LO(ptr) ((unsigned char)(ptr)[1]) +#define GET_HI(ptr) ((unsigned char)(ptr)[0]) + +DEFINE_UTF16_TO_UTF8(big2_) +DEFINE_UTF16_TO_UTF16(big2_) + +#undef SET2 +#undef GET_LO +#undef GET_HI + +#define LITTLE2_BYTE_TYPE(enc, p) \ + ((p)[1] == 0 \ +  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ +  : unicode_byte_type((p)[1], (p)[0])) +#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1) +#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c) +#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \ +  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) +#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ +  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) + +#ifdef XML_MIN_SIZE + +static int PTRFASTCALL +little2_byteType(const ENCODING *enc, const char *p) +{ +  return LITTLE2_BYTE_TYPE(enc, p); +} + +static int PTRFASTCALL +little2_byteToAscii(const ENCODING *enc, const char *p) +{ +  return LITTLE2_BYTE_TO_ASCII(enc, p); +} + +static int PTRCALL +little2_charMatches(const ENCODING *enc, const char *p, int c) +{ +  return LITTLE2_CHAR_MATCHES(enc, p, c); +} + +static int PTRFASTCALL +little2_isNameMin(const ENCODING *enc, const char *p) +{ +  return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p); +} + +static int PTRFASTCALL +little2_isNmstrtMin(const ENCODING *enc, const char *p) +{ +  return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p); +} + +#undef VTABLE +#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +#undef PREFIX +#define PREFIX(ident) little2_ ## ident +#define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) +#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) +#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c) +#define IS_NAME_CHAR(enc, p, n) 0 +#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) +#define IS_NMSTRT_CHAR(enc, p, n) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) + +#define XML_TOK_IMPL_C +#include "xmltok_impl.c" +#undef XML_TOK_IMPL_C + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +#ifdef XML_NS + +static const struct normal_encoding little2_encoding_ns = { +  { VTABLE, 2, 0, +#if BYTEORDER == 1234 +    1 +#else +    0 +#endif +  }, +  { +#include "asciitab.h" +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(little2_) +}; + +#endif + +static const struct normal_encoding little2_encoding = { +  { VTABLE, 2, 0, +#if BYTEORDER == 1234 +    1 +#else +    0 +#endif +  }, +  { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(little2_) +}; + +#if BYTEORDER != 4321 + +#ifdef XML_NS + +static const struct normal_encoding internal_little2_encoding_ns = { +  { VTABLE, 2, 0, 1 }, +  { +#include "iasciitab.h" +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(little2_) +}; + +#endif + +static const struct normal_encoding internal_little2_encoding = { +  { VTABLE, 2, 0, 1 }, +  { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(little2_) +}; + +#endif + + +#define BIG2_BYTE_TYPE(enc, p) \ + ((p)[0] == 0 \ +  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ +  : unicode_byte_type((p)[0], (p)[1])) +#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1) +#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c) +#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \ +  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) +#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ +  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) + +#ifdef XML_MIN_SIZE + +static int PTRFASTCALL +big2_byteType(const ENCODING *enc, const char *p) +{ +  return BIG2_BYTE_TYPE(enc, p); +} + +static int PTRFASTCALL +big2_byteToAscii(const ENCODING *enc, const char *p) +{ +  return BIG2_BYTE_TO_ASCII(enc, p); +} + +static int PTRCALL +big2_charMatches(const ENCODING *enc, const char *p, int c) +{ +  return BIG2_CHAR_MATCHES(enc, p, c); +} + +static int PTRFASTCALL +big2_isNameMin(const ENCODING *enc, const char *p) +{ +  return BIG2_IS_NAME_CHAR_MINBPC(enc, p); +} + +static int PTRFASTCALL +big2_isNmstrtMin(const ENCODING *enc, const char *p) +{ +  return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p); +} + +#undef VTABLE +#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 + +#else /* not XML_MIN_SIZE */ + +#undef PREFIX +#define PREFIX(ident) big2_ ## ident +#define MINBPC(enc) 2 +/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ +#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) +#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) +#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c) +#define IS_NAME_CHAR(enc, p, n) 0 +#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p) +#define IS_NMSTRT_CHAR(enc, p, n) (0) +#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) + +#define XML_TOK_IMPL_C +#include "xmltok_impl.c" +#undef XML_TOK_IMPL_C + +#undef MINBPC +#undef BYTE_TYPE +#undef BYTE_TO_ASCII +#undef CHAR_MATCHES +#undef IS_NAME_CHAR +#undef IS_NAME_CHAR_MINBPC +#undef IS_NMSTRT_CHAR +#undef IS_NMSTRT_CHAR_MINBPC +#undef IS_INVALID_CHAR + +#endif /* not XML_MIN_SIZE */ + +#ifdef XML_NS + +static const struct normal_encoding big2_encoding_ns = { +  { VTABLE, 2, 0, +#if BYTEORDER == 4321 +  1 +#else +  0 +#endif +  }, +  { +#include "asciitab.h" +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(big2_) +}; + +#endif + +static const struct normal_encoding big2_encoding = { +  { VTABLE, 2, 0, +#if BYTEORDER == 4321 +  1 +#else +  0 +#endif +  }, +  { +#define BT_COLON BT_NMSTRT +#include "asciitab.h" +#undef BT_COLON +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(big2_) +}; + +#if BYTEORDER != 1234 + +#ifdef XML_NS + +static const struct normal_encoding internal_big2_encoding_ns = { +  { VTABLE, 2, 0, 1 }, +  { +#include "iasciitab.h" +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(big2_) +}; + +#endif + +static const struct normal_encoding internal_big2_encoding = { +  { VTABLE, 2, 0, 1 }, +  { +#define BT_COLON BT_NMSTRT +#include "iasciitab.h" +#undef BT_COLON +#include "latin1tab.h" +  }, +  STANDARD_VTABLE(big2_) +}; + +#endif + +#undef PREFIX + +static int FASTCALL +streqci(const char *s1, const char *s2) +{ +  for (;;) { +    char c1 = *s1++; +    char c2 = *s2++; +    if (ASCII_a <= c1 && c1 <= ASCII_z) +      c1 += ASCII_A - ASCII_a; +    if (ASCII_a <= c2 && c2 <= ASCII_z) +      c2 += ASCII_A - ASCII_a; +    if (c1 != c2) +      return 0; +    if (!c1) +      break; +  } +  return 1; +} + +static void PTRCALL +initUpdatePosition(const ENCODING *enc, const char *ptr, +                   const char *end, POSITION *pos) +{ +  normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); +} + +static int +toAscii(const ENCODING *enc, const char *ptr, const char *end) +{ +  char buf[1]; +  char *p = buf; +  XmlUtf8Convert(enc, &ptr, end, &p, p + 1); +  if (p == buf) +    return -1; +  else +    return buf[0]; +} + +static int FASTCALL +isSpace(int c) +{ +  switch (c) { +  case 0x20: +  case 0xD: +  case 0xA: +  case 0x9: +    return 1; +  } +  return 0; +} + +/* Return 1 if there's just optional white space or there's an S +   followed by name=val. +*/ +static int +parsePseudoAttribute(const ENCODING *enc, +                     const char *ptr, +                     const char *end, +                     const char **namePtr, +                     const char **nameEndPtr, +                     const char **valPtr, +                     const char **nextTokPtr) +{ +  int c; +  char open; +  if (ptr == end) { +    *namePtr = NULL; +    return 1; +  } +  if (!isSpace(toAscii(enc, ptr, end))) { +    *nextTokPtr = ptr; +    return 0; +  } +  do { +    ptr += enc->minBytesPerChar; +  } while (isSpace(toAscii(enc, ptr, end))); +  if (ptr == end) { +    *namePtr = NULL; +    return 1; +  } +  *namePtr = ptr; +  for (;;) { +    c = toAscii(enc, ptr, end); +    if (c == -1) { +      *nextTokPtr = ptr; +      return 0; +    } +    if (c == ASCII_EQUALS) { +      *nameEndPtr = ptr; +      break; +    } +    if (isSpace(c)) { +      *nameEndPtr = ptr; +      do { +        ptr += enc->minBytesPerChar; +      } while (isSpace(c = toAscii(enc, ptr, end))); +      if (c != ASCII_EQUALS) { +        *nextTokPtr = ptr; +        return 0; +      } +      break; +    } +    ptr += enc->minBytesPerChar; +  } +  if (ptr == *namePtr) { +    *nextTokPtr = ptr; +    return 0; +  } +  ptr += enc->minBytesPerChar; +  c = toAscii(enc, ptr, end); +  while (isSpace(c)) { +    ptr += enc->minBytesPerChar; +    c = toAscii(enc, ptr, end); +  } +  if (c != ASCII_QUOT && c != ASCII_APOS) { +    *nextTokPtr = ptr; +    return 0; +  } +  open = (char)c; +  ptr += enc->minBytesPerChar; +  *valPtr = ptr; +  for (;; ptr += enc->minBytesPerChar) { +    c = toAscii(enc, ptr, end); +    if (c == open) +      break; +    if (!(ASCII_a <= c && c <= ASCII_z) +        && !(ASCII_A <= c && c <= ASCII_Z) +        && !(ASCII_0 <= c && c <= ASCII_9) +        && c != ASCII_PERIOD +        && c != ASCII_MINUS +        && c != ASCII_UNDERSCORE) { +      *nextTokPtr = ptr; +      return 0; +    } +  } +  *nextTokPtr = ptr + enc->minBytesPerChar; +  return 1; +} + +static const char KW_version[] = { +  ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0' +}; + +static const char KW_encoding[] = { +  ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0' +}; + +static const char KW_standalone[] = { +  ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, +  ASCII_n, ASCII_e, '\0' +}; + +static const char KW_yes[] = { +  ASCII_y, ASCII_e, ASCII_s,  '\0' +}; + +static const char KW_no[] = { +  ASCII_n, ASCII_o,  '\0' +}; + +static int +doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, +                                                 const char *, +                                                 const char *), +               int isGeneralTextEntity, +               const ENCODING *enc, +               const char *ptr, +               const char *end, +               const char **badPtr, +               const char **versionPtr, +               const char **versionEndPtr, +               const char **encodingName, +               const ENCODING **encoding, +               int *standalone) +{ +  const char *val = NULL; +  const char *name = NULL; +  const char *nameEnd = NULL; +  ptr += 5 * enc->minBytesPerChar; +  end -= 2 * enc->minBytesPerChar; +  if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) +      || !name) { +    *badPtr = ptr; +    return 0; +  } +  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) { +    if (!isGeneralTextEntity) { +      *badPtr = name; +      return 0; +    } +  } +  else { +    if (versionPtr) +      *versionPtr = val; +    if (versionEndPtr) +      *versionEndPtr = ptr; +    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { +      *badPtr = ptr; +      return 0; +    } +    if (!name) { +      if (isGeneralTextEntity) { +        /* a TextDecl must have an EncodingDecl */ +        *badPtr = ptr; +        return 0; +      } +      return 1; +    } +  } +  if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) { +    int c = toAscii(enc, val, end); +    if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) { +      *badPtr = val; +      return 0; +    } +    if (encodingName) +      *encodingName = val; +    if (encoding) +      *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); +    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) { +      *badPtr = ptr; +      return 0; +    } +    if (!name) +      return 1; +  } +  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) +      || isGeneralTextEntity) { +    *badPtr = name; +    return 0; +  } +  if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) { +    if (standalone) +      *standalone = 1; +  } +  else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) { +    if (standalone) +      *standalone = 0; +  } +  else { +    *badPtr = val; +    return 0; +  } +  while (isSpace(toAscii(enc, ptr, end))) +    ptr += enc->minBytesPerChar; +  if (ptr != end) { +    *badPtr = ptr; +    return 0; +  } +  return 1; +} + +static int FASTCALL +checkCharRefNumber(int result) +{ +  switch (result >> 8) { +  case 0xD8: case 0xD9: case 0xDA: case 0xDB: +  case 0xDC: case 0xDD: case 0xDE: case 0xDF: +    return -1; +  case 0: +    if (latin1_encoding.type[result] == BT_NONXML) +      return -1; +    break; +  case 0xFF: +    if (result == 0xFFFE || result == 0xFFFF) +      return -1; +    break; +  } +  return result; +} + +int FASTCALL +XmlUtf8Encode(int c, char *buf) +{ +  enum { +    /* minN is minimum legal resulting value for N byte sequence */ +    min2 = 0x80, +    min3 = 0x800, +    min4 = 0x10000 +  }; + +  if (c < 0) +    return 0; +  if (c < min2) { +    buf[0] = (char)(c | UTF8_cval1); +    return 1; +  } +  if (c < min3) { +    buf[0] = (char)((c >> 6) | UTF8_cval2); +    buf[1] = (char)((c & 0x3f) | 0x80); +    return 2; +  } +  if (c < min4) { +    buf[0] = (char)((c >> 12) | UTF8_cval3); +    buf[1] = (char)(((c >> 6) & 0x3f) | 0x80); +    buf[2] = (char)((c & 0x3f) | 0x80); +    return 3; +  } +  if (c < 0x110000) { +    buf[0] = (char)((c >> 18) | UTF8_cval4); +    buf[1] = (char)(((c >> 12) & 0x3f) | 0x80); +    buf[2] = (char)(((c >> 6) & 0x3f) | 0x80); +    buf[3] = (char)((c & 0x3f) | 0x80); +    return 4; +  } +  return 0; +} + +int FASTCALL +XmlUtf16Encode(int charNum, unsigned short *buf) +{ +  if (charNum < 0) +    return 0; +  if (charNum < 0x10000) { +    buf[0] = (unsigned short)charNum; +    return 1; +  } +  if (charNum < 0x110000) { +    charNum -= 0x10000; +    buf[0] = (unsigned short)((charNum >> 10) + 0xD800); +    buf[1] = (unsigned short)((charNum & 0x3FF) + 0xDC00); +    return 2; +  } +  return 0; +} + +struct unknown_encoding { +  struct normal_encoding normal; +  CONVERTER convert; +  void *userData; +  unsigned short utf16[256]; +  char utf8[256][4]; +}; + +#define AS_UNKNOWN_ENCODING(enc)  ((const struct unknown_encoding *) (enc)) + +int +XmlSizeOfUnknownEncoding(void) +{ +  return sizeof(struct unknown_encoding); +} + +static int PTRFASTCALL +unknown_isName(const ENCODING *enc, const char *p) +{ +  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); +  int c = uenc->convert(uenc->userData, p); +  if (c & ~0xFFFF) +    return 0; +  return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); +} + +static int PTRFASTCALL +unknown_isNmstrt(const ENCODING *enc, const char *p) +{ +  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); +  int c = uenc->convert(uenc->userData, p); +  if (c & ~0xFFFF) +    return 0; +  return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); +} + +static int PTRFASTCALL +unknown_isInvalid(const ENCODING *enc, const char *p) +{ +  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); +  int c = uenc->convert(uenc->userData, p); +  return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; +} + +static void PTRCALL +unknown_toUtf8(const ENCODING *enc, +               const char **fromP, const char *fromLim, +               char **toP, const char *toLim) +{ +  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); +  char buf[XML_UTF8_ENCODE_MAX]; +  for (;;) { +    const char *utf8; +    int n; +    if (*fromP == fromLim) +      break; +    utf8 = uenc->utf8[(unsigned char)**fromP]; +    n = *utf8++; +    if (n == 0) { +      int c = uenc->convert(uenc->userData, *fromP); +      n = XmlUtf8Encode(c, buf); +      if (n > toLim - *toP) +        break; +      utf8 = buf; +      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] +                 - (BT_LEAD2 - 2)); +    } +    else { +      if (n > toLim - *toP) +        break; +      (*fromP)++; +    } +    do { +      *(*toP)++ = *utf8++; +    } while (--n != 0); +  } +} + +static void PTRCALL +unknown_toUtf16(const ENCODING *enc, +                const char **fromP, const char *fromLim, +                unsigned short **toP, const unsigned short *toLim) +{ +  const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); +  while (*fromP != fromLim && *toP != toLim) { +    unsigned short c = uenc->utf16[(unsigned char)**fromP]; +    if (c == 0) { +      c = (unsigned short) +          uenc->convert(uenc->userData, *fromP); +      *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] +                 - (BT_LEAD2 - 2)); +    } +    else +      (*fromP)++; +    *(*toP)++ = c; +  } +} + +ENCODING * +XmlInitUnknownEncoding(void *mem, +                       int *table, +                       CONVERTER convert,  +                       void *userData) +{ +  int i; +  struct unknown_encoding *e = (struct unknown_encoding *)mem; +  for (i = 0; i < (int)sizeof(struct normal_encoding); i++) +    ((char *)mem)[i] = ((char *)&latin1_encoding)[i]; +  for (i = 0; i < 128; i++) +    if (latin1_encoding.type[i] != BT_OTHER +        && latin1_encoding.type[i] != BT_NONXML +        && table[i] != i) +      return 0; +  for (i = 0; i < 256; i++) { +    int c = table[i]; +    if (c == -1) { +      e->normal.type[i] = BT_MALFORM; +      /* This shouldn't really get used. */ +      e->utf16[i] = 0xFFFF; +      e->utf8[i][0] = 1; +      e->utf8[i][1] = 0; +    } +    else if (c < 0) { +      if (c < -4) +        return 0; +      e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2)); +      e->utf8[i][0] = 0; +      e->utf16[i] = 0; +    } +    else if (c < 0x80) { +      if (latin1_encoding.type[c] != BT_OTHER +          && latin1_encoding.type[c] != BT_NONXML +          && c != i) +        return 0; +      e->normal.type[i] = latin1_encoding.type[c]; +      e->utf8[i][0] = 1; +      e->utf8[i][1] = (char)c; +      e->utf16[i] = (unsigned short)(c == 0 ? 0xFFFF : c); +    } +    else if (checkCharRefNumber(c) < 0) { +      e->normal.type[i] = BT_NONXML; +      /* This shouldn't really get used. */ +      e->utf16[i] = 0xFFFF; +      e->utf8[i][0] = 1; +      e->utf8[i][1] = 0; +    } +    else { +      if (c > 0xFFFF) +        return 0; +      if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) +        e->normal.type[i] = BT_NMSTRT; +      else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) +        e->normal.type[i] = BT_NAME; +      else +        e->normal.type[i] = BT_OTHER; +      e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); +      e->utf16[i] = (unsigned short)c; +    } +  } +  e->userData = userData; +  e->convert = convert; +  if (convert) { +    e->normal.isName2 = unknown_isName; +    e->normal.isName3 = unknown_isName; +    e->normal.isName4 = unknown_isName; +    e->normal.isNmstrt2 = unknown_isNmstrt; +    e->normal.isNmstrt3 = unknown_isNmstrt; +    e->normal.isNmstrt4 = unknown_isNmstrt; +    e->normal.isInvalid2 = unknown_isInvalid; +    e->normal.isInvalid3 = unknown_isInvalid; +    e->normal.isInvalid4 = unknown_isInvalid; +  } +  e->normal.enc.utf8Convert = unknown_toUtf8; +  e->normal.enc.utf16Convert = unknown_toUtf16; +  return &(e->normal.enc); +} + +/* If this enumeration is changed, getEncodingIndex and encodings +must also be changed. */ +enum { +  UNKNOWN_ENC = -1, +  ISO_8859_1_ENC = 0, +  US_ASCII_ENC, +  UTF_8_ENC, +  UTF_16_ENC, +  UTF_16BE_ENC, +  UTF_16LE_ENC, +  /* must match encodingNames up to here */ +  NO_ENC +}; + +static const char KW_ISO_8859_1[] = { +  ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, +  ASCII_MINUS, ASCII_1, '\0' +}; +static const char KW_US_ASCII[] = { +  ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, +  '\0' +}; +static const char KW_UTF_8[] =  { +  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0' +}; +static const char KW_UTF_16[] = { +  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0' +}; +static const char KW_UTF_16BE[] = { +  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, +  '\0' +}; +static const char KW_UTF_16LE[] = { +  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, +  '\0' +}; + +static int FASTCALL +getEncodingIndex(const char *name) +{ +  static const char * const encodingNames[] = { +    KW_ISO_8859_1, +    KW_US_ASCII, +    KW_UTF_8, +    KW_UTF_16, +    KW_UTF_16BE, +    KW_UTF_16LE, +  }; +  int i; +  if (name == NULL) +    return NO_ENC; +  for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++) +    if (streqci(name, encodingNames[i])) +      return i; +  return UNKNOWN_ENC; +} + +/* For binary compatibility, we store the index of the encoding +   specified at initialization in the isUtf16 member. +*/ + +#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16) +#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i) + +/* This is what detects the encoding.  encodingTable maps from +   encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of +   the external (protocol) specified encoding; state is +   XML_CONTENT_STATE if we're parsing an external text entity, and +   XML_PROLOG_STATE otherwise. +*/ + + +static int +initScan(const ENCODING * const *encodingTable, +         const INIT_ENCODING *enc, +         int state, +         const char *ptr, +         const char *end, +         const char **nextTokPtr) +{ +  const ENCODING **encPtr; + +  if (ptr == end) +    return XML_TOK_NONE; +  encPtr = enc->encPtr; +  if (ptr + 1 == end) { +    /* only a single byte available for auto-detection */ +#ifndef XML_DTD /* FIXME */ +    /* a well-formed document entity must have more than one byte */ +    if (state != XML_CONTENT_STATE) +      return XML_TOK_PARTIAL; +#endif +    /* so we're parsing an external text entity... */ +    /* if UTF-16 was externally specified, then we need at least 2 bytes */ +    switch (INIT_ENC_INDEX(enc)) { +    case UTF_16_ENC: +    case UTF_16LE_ENC: +    case UTF_16BE_ENC: +      return XML_TOK_PARTIAL; +    } +    switch ((unsigned char)*ptr) { +    case 0xFE: +    case 0xFF: +    case 0xEF: /* possibly first byte of UTF-8 BOM */ +      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC +          && state == XML_CONTENT_STATE) +        break; +      /* fall through */ +    case 0x00: +    case 0x3C: +      return XML_TOK_PARTIAL; +    } +  } +  else { +    switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { +    case 0xFEFF: +      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC +          && state == XML_CONTENT_STATE) +        break; +      *nextTokPtr = ptr + 2; +      *encPtr = encodingTable[UTF_16BE_ENC]; +      return XML_TOK_BOM; +    /* 00 3C is handled in the default case */ +    case 0x3C00: +      if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC +           || INIT_ENC_INDEX(enc) == UTF_16_ENC) +          && state == XML_CONTENT_STATE) +        break; +      *encPtr = encodingTable[UTF_16LE_ENC]; +      return XmlTok(*encPtr, state, ptr, end, nextTokPtr); +    case 0xFFFE: +      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC +          && state == XML_CONTENT_STATE) +        break; +      *nextTokPtr = ptr + 2; +      *encPtr = encodingTable[UTF_16LE_ENC]; +      return XML_TOK_BOM; +    case 0xEFBB: +      /* Maybe a UTF-8 BOM (EF BB BF) */ +      /* If there's an explicitly specified (external) encoding +         of ISO-8859-1 or some flavour of UTF-16 +         and this is an external text entity, +         don't look for the BOM, +         because it might be a legal data. +      */ +      if (state == XML_CONTENT_STATE) { +        int e = INIT_ENC_INDEX(enc); +        if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC +            || e == UTF_16LE_ENC || e == UTF_16_ENC) +          break; +      } +      if (ptr + 2 == end) +        return XML_TOK_PARTIAL; +      if ((unsigned char)ptr[2] == 0xBF) { +        *nextTokPtr = ptr + 3; +        *encPtr = encodingTable[UTF_8_ENC]; +        return XML_TOK_BOM; +      } +      break; +    default: +      if (ptr[0] == '\0') { +        /* 0 isn't a legal data character. Furthermore a document +           entity can only start with ASCII characters.  So the only +           way this can fail to be big-endian UTF-16 if it it's an +           external parsed general entity that's labelled as +           UTF-16LE. +        */ +        if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) +          break; +        *encPtr = encodingTable[UTF_16BE_ENC]; +        return XmlTok(*encPtr, state, ptr, end, nextTokPtr); +      } +      else if (ptr[1] == '\0') { +        /* We could recover here in the case: +            - parsing an external entity +            - second byte is 0 +            - no externally specified encoding +            - no encoding declaration +           by assuming UTF-16LE.  But we don't, because this would mean when +           presented just with a single byte, we couldn't reliably determine +           whether we needed further bytes. +        */ +        if (state == XML_CONTENT_STATE) +          break; +        *encPtr = encodingTable[UTF_16LE_ENC]; +        return XmlTok(*encPtr, state, ptr, end, nextTokPtr); +      } +      break; +    } +  } +  *encPtr = encodingTable[INIT_ENC_INDEX(enc)]; +  return XmlTok(*encPtr, state, ptr, end, nextTokPtr); +} + + +#define NS(x) x +#define ns(x) x +#define XML_TOK_NS_C +#include "xmltok_ns.c" +#undef XML_TOK_NS_C +#undef NS +#undef ns + +#ifdef XML_NS + +#define NS(x) x ## NS +#define ns(x) x ## _ns + +#define XML_TOK_NS_C +#include "xmltok_ns.c" +#undef XML_TOK_NS_C + +#undef NS +#undef ns + +ENCODING * +XmlInitUnknownEncodingNS(void *mem, +                         int *table, +                         CONVERTER convert,  +                         void *userData) +{ +  ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); +  if (enc) +    ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON; +  return enc; +} + +#endif /* XML_NS */ diff --git a/3rdParty/Expat/src/xmltok.h b/3rdParty/Expat/src/xmltok.h new file mode 100755 index 0000000..ca867aa --- /dev/null +++ b/3rdParty/Expat/src/xmltok.h @@ -0,0 +1,316 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +#ifndef XmlTok_INCLUDED +#define XmlTok_INCLUDED 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* The following token may be returned by XmlContentTok */ +#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be +                                    start of illegal ]]> sequence */ +/* The following tokens may be returned by both XmlPrologTok and +   XmlContentTok. +*/ +#define XML_TOK_NONE -4          /* The string to be scanned is empty */ +#define XML_TOK_TRAILING_CR -3   /* A CR at the end of the scan; +                                    might be part of CRLF sequence */ +#define XML_TOK_PARTIAL_CHAR -2  /* only part of a multibyte sequence */ +#define XML_TOK_PARTIAL -1       /* only part of a token */ +#define XML_TOK_INVALID 0 + +/* The following tokens are returned by XmlContentTok; some are also +   returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok. +*/ +#define XML_TOK_START_TAG_WITH_ATTS 1 +#define XML_TOK_START_TAG_NO_ATTS 2 +#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */ +#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 +#define XML_TOK_END_TAG 5 +#define XML_TOK_DATA_CHARS 6 +#define XML_TOK_DATA_NEWLINE 7 +#define XML_TOK_CDATA_SECT_OPEN 8 +#define XML_TOK_ENTITY_REF 9 +#define XML_TOK_CHAR_REF 10               /* numeric character reference */ + +/* The following tokens may be returned by both XmlPrologTok and +   XmlContentTok. +*/ +#define XML_TOK_PI 11                     /* processing instruction */ +#define XML_TOK_XML_DECL 12               /* XML decl or text decl */ +#define XML_TOK_COMMENT 13 +#define XML_TOK_BOM 14                    /* Byte order mark */ + +/* The following tokens are returned only by XmlPrologTok */ +#define XML_TOK_PROLOG_S 15 +#define XML_TOK_DECL_OPEN 16              /* <!foo */ +#define XML_TOK_DECL_CLOSE 17             /* > */ +#define XML_TOK_NAME 18 +#define XML_TOK_NMTOKEN 19 +#define XML_TOK_POUND_NAME 20             /* #name */ +#define XML_TOK_OR 21                     /* | */ +#define XML_TOK_PERCENT 22 +#define XML_TOK_OPEN_PAREN 23 +#define XML_TOK_CLOSE_PAREN 24 +#define XML_TOK_OPEN_BRACKET 25 +#define XML_TOK_CLOSE_BRACKET 26 +#define XML_TOK_LITERAL 27 +#define XML_TOK_PARAM_ENTITY_REF 28 +#define XML_TOK_INSTANCE_START 29 + +/* The following occur only in element type declarations */ +#define XML_TOK_NAME_QUESTION 30          /* name? */ +#define XML_TOK_NAME_ASTERISK 31          /* name* */ +#define XML_TOK_NAME_PLUS 32              /* name+ */ +#define XML_TOK_COND_SECT_OPEN 33         /* <![ */ +#define XML_TOK_COND_SECT_CLOSE 34        /* ]]> */ +#define XML_TOK_CLOSE_PAREN_QUESTION 35   /* )? */ +#define XML_TOK_CLOSE_PAREN_ASTERISK 36   /* )* */ +#define XML_TOK_CLOSE_PAREN_PLUS 37       /* )+ */ +#define XML_TOK_COMMA 38 + +/* The following token is returned only by XmlAttributeValueTok */ +#define XML_TOK_ATTRIBUTE_VALUE_S 39 + +/* The following token is returned only by XmlCdataSectionTok */ +#define XML_TOK_CDATA_SECT_CLOSE 40 + +/* With namespace processing this is returned by XmlPrologTok for a +   name with a colon. +*/ +#define XML_TOK_PREFIXED_NAME 41 + +#ifdef XML_DTD +#define XML_TOK_IGNORE_SECT 42 +#endif /* XML_DTD */ + +#ifdef XML_DTD +#define XML_N_STATES 4 +#else /* not XML_DTD */ +#define XML_N_STATES 3 +#endif /* not XML_DTD */ + +#define XML_PROLOG_STATE 0 +#define XML_CONTENT_STATE 1 +#define XML_CDATA_SECTION_STATE 2 +#ifdef XML_DTD +#define XML_IGNORE_SECTION_STATE 3 +#endif /* XML_DTD */ + +#define XML_N_LITERAL_TYPES 2 +#define XML_ATTRIBUTE_VALUE_LITERAL 0 +#define XML_ENTITY_VALUE_LITERAL 1 + +/* The size of the buffer passed to XmlUtf8Encode must be at least this. */ +#define XML_UTF8_ENCODE_MAX 4 +/* The size of the buffer passed to XmlUtf16Encode must be at least this. */ +#define XML_UTF16_ENCODE_MAX 2 + +typedef struct position { +  /* first line and first column are 0 not 1 */ +  XML_Size lineNumber; +  XML_Size columnNumber; +} POSITION; + +typedef struct { +  const char *name; +  const char *valuePtr; +  const char *valueEnd; +  char normalized; +} ATTRIBUTE; + +struct encoding; +typedef struct encoding ENCODING; + +typedef int (PTRCALL *SCANNER)(const ENCODING *, +                               const char *, +                               const char *, +                               const char **); + +struct encoding { +  SCANNER scanners[XML_N_STATES]; +  SCANNER literalScanners[XML_N_LITERAL_TYPES]; +  int (PTRCALL *sameName)(const ENCODING *, +                          const char *, +                          const char *); +  int (PTRCALL *nameMatchesAscii)(const ENCODING *, +                                  const char *, +                                  const char *, +                                  const char *); +  int (PTRFASTCALL *nameLength)(const ENCODING *, const char *); +  const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *); +  int (PTRCALL *getAtts)(const ENCODING *enc, +                         const char *ptr, +                         int attsMax, +                         ATTRIBUTE *atts); +  int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr); +  int (PTRCALL *predefinedEntityName)(const ENCODING *, +                                      const char *, +                                      const char *); +  void (PTRCALL *updatePosition)(const ENCODING *, +                                 const char *ptr, +                                 const char *end, +                                 POSITION *); +  int (PTRCALL *isPublicId)(const ENCODING *enc, +                            const char *ptr, +                            const char *end, +                            const char **badPtr); +  void (PTRCALL *utf8Convert)(const ENCODING *enc, +                              const char **fromP, +                              const char *fromLim, +                              char **toP, +                              const char *toLim); +  void (PTRCALL *utf16Convert)(const ENCODING *enc, +                               const char **fromP, +                               const char *fromLim, +                               unsigned short **toP, +                               const unsigned short *toLim); +  int minBytesPerChar; +  char isUtf8; +  char isUtf16; +}; + +/* Scan the string starting at ptr until the end of the next complete +   token, but do not scan past eptr.  Return an integer giving the +   type of token. + +   Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. + +   Return XML_TOK_PARTIAL when the string does not contain a complete +   token; nextTokPtr will not be set. + +   Return XML_TOK_INVALID when the string does not start a valid +   token; nextTokPtr will be set to point to the character which made +   the token invalid. + +   Otherwise the string starts with a valid token; nextTokPtr will be +   set to point to the character following the end of that token. + +   Each data character counts as a single token, but adjacent data +   characters may be returned together.  Similarly for characters in +   the prolog outside literals, comments and processing instructions. +*/ + + +#define XmlTok(enc, state, ptr, end, nextTokPtr) \ +  (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) + +#define XmlPrologTok(enc, ptr, end, nextTokPtr) \ +   XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) + +#define XmlContentTok(enc, ptr, end, nextTokPtr) \ +   XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) + +#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ +   XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) + +#ifdef XML_DTD + +#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \ +   XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr) + +#endif /* XML_DTD */ + +/* This is used for performing a 2nd-level tokenization on the content +   of a literal that has already been returned by XmlTok. +*/ +#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ +  (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) + +#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ +   XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ +   XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) + +#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) + +#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \ +  (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2)) + +#define XmlNameLength(enc, ptr) \ +  (((enc)->nameLength)(enc, ptr)) + +#define XmlSkipS(enc, ptr) \ +  (((enc)->skipS)(enc, ptr)) + +#define XmlGetAttributes(enc, ptr, attsMax, atts) \ +  (((enc)->getAtts)(enc, ptr, attsMax, atts)) + +#define XmlCharRefNumber(enc, ptr) \ +  (((enc)->charRefNumber)(enc, ptr)) + +#define XmlPredefinedEntityName(enc, ptr, end) \ +  (((enc)->predefinedEntityName)(enc, ptr, end)) + +#define XmlUpdatePosition(enc, ptr, end, pos) \ +  (((enc)->updatePosition)(enc, ptr, end, pos)) + +#define XmlIsPublicId(enc, ptr, end, badPtr) \ +  (((enc)->isPublicId)(enc, ptr, end, badPtr)) + +#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ +  (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) + +#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ +  (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) + +typedef struct { +  ENCODING initEnc; +  const ENCODING **encPtr; +} INIT_ENCODING; + +int XmlParseXmlDecl(int isGeneralTextEntity, +                    const ENCODING *enc, +                    const char *ptr, +                    const char *end, +                    const char **badPtr, +                    const char **versionPtr, +                    const char **versionEndPtr, +                    const char **encodingNamePtr, +                    const ENCODING **namedEncodingPtr, +                    int *standalonePtr); + +int XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); +const ENCODING *XmlGetUtf8InternalEncoding(void); +const ENCODING *XmlGetUtf16InternalEncoding(void); +int FASTCALL XmlUtf8Encode(int charNumber, char *buf); +int FASTCALL XmlUtf16Encode(int charNumber, unsigned short *buf); +int XmlSizeOfUnknownEncoding(void); + + +typedef int (XMLCALL *CONVERTER) (void *userData, const char *p); + +ENCODING * +XmlInitUnknownEncoding(void *mem, +                       int *table, +                       CONVERTER convert, +                       void *userData); + +int XmlParseXmlDeclNS(int isGeneralTextEntity, +                      const ENCODING *enc, +                      const char *ptr, +                      const char *end, +                      const char **badPtr, +                      const char **versionPtr, +                      const char **versionEndPtr, +                      const char **encodingNamePtr, +                      const ENCODING **namedEncodingPtr, +                      int *standalonePtr); + +int XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name); +const ENCODING *XmlGetUtf8InternalEncodingNS(void); +const ENCODING *XmlGetUtf16InternalEncodingNS(void); +ENCODING * +XmlInitUnknownEncodingNS(void *mem, +                         int *table, +                         CONVERTER convert, +                         void *userData); +#ifdef __cplusplus +} +#endif + +#endif /* not XmlTok_INCLUDED */ diff --git a/3rdParty/Expat/src/xmltok_impl.c b/3rdParty/Expat/src/xmltok_impl.c new file mode 100755 index 0000000..1268819 --- /dev/null +++ b/3rdParty/Expat/src/xmltok_impl.c @@ -0,0 +1,1783 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +/* This file is included! */ +#ifdef XML_TOK_IMPL_C + +#ifndef IS_INVALID_CHAR +#define IS_INVALID_CHAR(enc, ptr, n) (0) +#endif + +#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ +    case BT_LEAD ## n: \ +      if (end - ptr < n) \ +        return XML_TOK_PARTIAL_CHAR; \ +      if (IS_INVALID_CHAR(enc, ptr, n)) { \ +        *(nextTokPtr) = (ptr); \ +        return XML_TOK_INVALID; \ +      } \ +      ptr += n; \ +      break; + +#define INVALID_CASES(ptr, nextTokPtr) \ +  INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ +  INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ +  INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ +  case BT_NONXML: \ +  case BT_MALFORM: \ +  case BT_TRAIL: \ +    *(nextTokPtr) = (ptr); \ +    return XML_TOK_INVALID; + +#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ +   case BT_LEAD ## n: \ +     if (end - ptr < n) \ +       return XML_TOK_PARTIAL_CHAR; \ +     if (!IS_NAME_CHAR(enc, ptr, n)) { \ +       *nextTokPtr = ptr; \ +       return XML_TOK_INVALID; \ +     } \ +     ptr += n; \ +     break; + +#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ +  case BT_NONASCII: \ +    if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \ +      *nextTokPtr = ptr; \ +      return XML_TOK_INVALID; \ +    } \ +  case BT_NMSTRT: \ +  case BT_HEX: \ +  case BT_DIGIT: \ +  case BT_NAME: \ +  case BT_MINUS: \ +    ptr += MINBPC(enc); \ +    break; \ +  CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ +  CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ +  CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) + +#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ +   case BT_LEAD ## n: \ +     if (end - ptr < n) \ +       return XML_TOK_PARTIAL_CHAR; \ +     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \ +       *nextTokPtr = ptr; \ +       return XML_TOK_INVALID; \ +     } \ +     ptr += n; \ +     break; + +#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ +  case BT_NONASCII: \ +    if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ +      *nextTokPtr = ptr; \ +      return XML_TOK_INVALID; \ +    } \ +  case BT_NMSTRT: \ +  case BT_HEX: \ +    ptr += MINBPC(enc); \ +    break; \ +  CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ +  CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ +  CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) + +#ifndef PREFIX +#define PREFIX(ident) ident +#endif + +/* ptr points to character following "<!-" */ + +static int PTRCALL +PREFIX(scanComment)(const ENCODING *enc, const char *ptr, +                    const char *end, const char **nextTokPtr) +{ +  if (ptr != end) { +    if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +    ptr += MINBPC(enc); +    while (ptr != end) { +      switch (BYTE_TYPE(enc, ptr)) { +      INVALID_CASES(ptr, nextTokPtr) +      case BT_MINUS: +        if ((ptr += MINBPC(enc)) == end) +          return XML_TOK_PARTIAL; +        if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { +          if ((ptr += MINBPC(enc)) == end) +            return XML_TOK_PARTIAL; +          if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { +            *nextTokPtr = ptr; +            return XML_TOK_INVALID; +          } +          *nextTokPtr = ptr + MINBPC(enc); +          return XML_TOK_COMMENT; +        } +        break; +      default: +        ptr += MINBPC(enc); +        break; +      } +    } +  } +  return XML_TOK_PARTIAL; +} + +/* ptr points to character following "<!" */ + +static int PTRCALL +PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, +                 const char *end, const char **nextTokPtr) +{ +  if (ptr == end) +    return XML_TOK_PARTIAL; +  switch (BYTE_TYPE(enc, ptr)) { +  case BT_MINUS: +    return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr); +  case BT_LSQB: +    *nextTokPtr = ptr + MINBPC(enc); +    return XML_TOK_COND_SECT_OPEN; +  case BT_NMSTRT: +  case BT_HEX: +    ptr += MINBPC(enc); +    break; +  default: +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    case BT_PERCNT: +      if (ptr + MINBPC(enc) == end) +        return XML_TOK_PARTIAL; +      /* don't allow <!ENTITY% foo "whatever"> */ +      switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { +      case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      /* fall through */ +    case BT_S: case BT_CR: case BT_LF: +      *nextTokPtr = ptr; +      return XML_TOK_DECL_OPEN; +    case BT_NMSTRT: +    case BT_HEX: +      ptr += MINBPC(enc); +      break; +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, +                      const char *end, int *tokPtr) +{ +  int upper = 0; +  *tokPtr = XML_TOK_PI; +  if (end - ptr != MINBPC(enc)*3) +    return 1; +  switch (BYTE_TO_ASCII(enc, ptr)) { +  case ASCII_x: +    break; +  case ASCII_X: +    upper = 1; +    break; +  default: +    return 1; +  } +  ptr += MINBPC(enc); +  switch (BYTE_TO_ASCII(enc, ptr)) { +  case ASCII_m: +    break; +  case ASCII_M: +    upper = 1; +    break; +  default: +    return 1; +  } +  ptr += MINBPC(enc); +  switch (BYTE_TO_ASCII(enc, ptr)) { +  case ASCII_l: +    break; +  case ASCII_L: +    upper = 1; +    break; +  default: +    return 1; +  } +  if (upper) +    return 0; +  *tokPtr = XML_TOK_XML_DECL; +  return 1; +} + +/* ptr points to character following "<?" */ + +static int PTRCALL +PREFIX(scanPi)(const ENCODING *enc, const char *ptr, +               const char *end, const char **nextTokPtr) +{ +  int tok; +  const char *target = ptr; +  if (ptr == end) +    return XML_TOK_PARTIAL; +  switch (BYTE_TYPE(enc, ptr)) { +  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +  default: +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) +    case BT_S: case BT_CR: case BT_LF: +      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      ptr += MINBPC(enc); +      while (ptr != end) { +        switch (BYTE_TYPE(enc, ptr)) { +        INVALID_CASES(ptr, nextTokPtr) +        case BT_QUEST: +          ptr += MINBPC(enc); +          if (ptr == end) +            return XML_TOK_PARTIAL; +          if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { +            *nextTokPtr = ptr + MINBPC(enc); +            return tok; +          } +          break; +        default: +          ptr += MINBPC(enc); +          break; +        } +      } +      return XML_TOK_PARTIAL; +    case BT_QUEST: +      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      ptr += MINBPC(enc); +      if (ptr == end) +        return XML_TOK_PARTIAL; +      if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { +        *nextTokPtr = ptr + MINBPC(enc); +        return tok; +      } +      /* fall through */ +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, +                         const char *end, const char **nextTokPtr) +{ +  static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, +                                     ASCII_T, ASCII_A, ASCII_LSQB }; +  int i; +  /* CDATA[ */ +  if (end - ptr < 6 * MINBPC(enc)) +    return XML_TOK_PARTIAL; +  for (i = 0; i < 6; i++, ptr += MINBPC(enc)) { +    if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) { +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  *nextTokPtr = ptr; +  return XML_TOK_CDATA_SECT_OPEN; +} + +static int PTRCALL +PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, +                        const char *end, const char **nextTokPtr) +{ +  if (ptr == end) +    return XML_TOK_NONE; +  if (MINBPC(enc) > 1) { +    size_t n = end - ptr; +    if (n & (MINBPC(enc) - 1)) { +      n &= ~(MINBPC(enc) - 1); +      if (n == 0) +        return XML_TOK_PARTIAL; +      end = ptr + n; +    } +  } +  switch (BYTE_TYPE(enc, ptr)) { +  case BT_RSQB: +    ptr += MINBPC(enc); +    if (ptr == end) +      return XML_TOK_PARTIAL; +    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) +      break; +    ptr += MINBPC(enc); +    if (ptr == end) +      return XML_TOK_PARTIAL; +    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { +      ptr -= MINBPC(enc); +      break; +    } +    *nextTokPtr = ptr + MINBPC(enc); +    return XML_TOK_CDATA_SECT_CLOSE; +  case BT_CR: +    ptr += MINBPC(enc); +    if (ptr == end) +      return XML_TOK_PARTIAL; +    if (BYTE_TYPE(enc, ptr) == BT_LF) +      ptr += MINBPC(enc); +    *nextTokPtr = ptr; +    return XML_TOK_DATA_NEWLINE; +  case BT_LF: +    *nextTokPtr = ptr + MINBPC(enc); +    return XML_TOK_DATA_NEWLINE; +  INVALID_CASES(ptr, nextTokPtr) +  default: +    ptr += MINBPC(enc); +    break; +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ +    case BT_LEAD ## n: \ +      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ +        *nextTokPtr = ptr; \ +        return XML_TOK_DATA_CHARS; \ +      } \ +      ptr += n; \ +      break; +    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE +    case BT_NONXML: +    case BT_MALFORM: +    case BT_TRAIL: +    case BT_CR: +    case BT_LF: +    case BT_RSQB: +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    default: +      ptr += MINBPC(enc); +      break; +    } +  } +  *nextTokPtr = ptr; +  return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following "</" */ + +static int PTRCALL +PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, +                   const char *end, const char **nextTokPtr) +{ +  if (ptr == end) +    return XML_TOK_PARTIAL; +  switch (BYTE_TYPE(enc, ptr)) { +  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +  default: +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) +    case BT_S: case BT_CR: case BT_LF: +      for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { +        switch (BYTE_TYPE(enc, ptr)) { +        case BT_S: case BT_CR: case BT_LF: +          break; +        case BT_GT: +          *nextTokPtr = ptr + MINBPC(enc); +          return XML_TOK_END_TAG; +        default: +          *nextTokPtr = ptr; +          return XML_TOK_INVALID; +        } +      } +      return XML_TOK_PARTIAL; +#ifdef XML_NS +    case BT_COLON: +      /* no need to check qname syntax here, +         since end-tag must match exactly */ +      ptr += MINBPC(enc); +      break; +#endif +    case BT_GT: +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_END_TAG; +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  return XML_TOK_PARTIAL; +} + +/* ptr points to character following "&#X" */ + +static int PTRCALL +PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, +                       const char *end, const char **nextTokPtr) +{ +  if (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    case BT_DIGIT: +    case BT_HEX: +      break; +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { +      switch (BYTE_TYPE(enc, ptr)) { +      case BT_DIGIT: +      case BT_HEX: +        break; +      case BT_SEMI: +        *nextTokPtr = ptr + MINBPC(enc); +        return XML_TOK_CHAR_REF; +      default: +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +    } +  } +  return XML_TOK_PARTIAL; +} + +/* ptr points to character following "&#" */ + +static int PTRCALL +PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, +                    const char *end, const char **nextTokPtr) +{ +  if (ptr != end) { +    if (CHAR_MATCHES(enc, ptr, ASCII_x)) +      return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); +    switch (BYTE_TYPE(enc, ptr)) { +    case BT_DIGIT: +      break; +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { +      switch (BYTE_TYPE(enc, ptr)) { +      case BT_DIGIT: +        break; +      case BT_SEMI: +        *nextTokPtr = ptr + MINBPC(enc); +        return XML_TOK_CHAR_REF; +      default: +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +    } +  } +  return XML_TOK_PARTIAL; +} + +/* ptr points to character following "&" */ + +static int PTRCALL +PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, +                const char **nextTokPtr) +{ +  if (ptr == end) +    return XML_TOK_PARTIAL; +  switch (BYTE_TYPE(enc, ptr)) { +  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +  case BT_NUM: +    return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); +  default: +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) +    case BT_SEMI: +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_ENTITY_REF; +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  return XML_TOK_PARTIAL; +} + +/* ptr points to character following first character of attribute name */ + +static int PTRCALL +PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, +                 const char **nextTokPtr) +{ +#ifdef XML_NS +  int hadColon = 0; +#endif +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) +#ifdef XML_NS +    case BT_COLON: +      if (hadColon) { +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      hadColon = 1; +      ptr += MINBPC(enc); +      if (ptr == end) +        return XML_TOK_PARTIAL; +      switch (BYTE_TYPE(enc, ptr)) { +      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +      default: +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      break; +#endif +    case BT_S: case BT_CR: case BT_LF: +      for (;;) { +        int t; + +        ptr += MINBPC(enc); +        if (ptr == end) +          return XML_TOK_PARTIAL; +        t = BYTE_TYPE(enc, ptr); +        if (t == BT_EQUALS) +          break; +        switch (t) { +        case BT_S: +        case BT_LF: +        case BT_CR: +          break; +        default: +          *nextTokPtr = ptr; +          return XML_TOK_INVALID; +        } +      } +    /* fall through */ +    case BT_EQUALS: +      { +        int open; +#ifdef XML_NS +        hadColon = 0; +#endif +        for (;;) { +          ptr += MINBPC(enc); +          if (ptr == end) +            return XML_TOK_PARTIAL; +          open = BYTE_TYPE(enc, ptr); +          if (open == BT_QUOT || open == BT_APOS) +            break; +          switch (open) { +          case BT_S: +          case BT_LF: +          case BT_CR: +            break; +          default: +            *nextTokPtr = ptr; +            return XML_TOK_INVALID; +          } +        } +        ptr += MINBPC(enc); +        /* in attribute value */ +        for (;;) { +          int t; +          if (ptr == end) +            return XML_TOK_PARTIAL; +          t = BYTE_TYPE(enc, ptr); +          if (t == open) +            break; +          switch (t) { +          INVALID_CASES(ptr, nextTokPtr) +          case BT_AMP: +            { +              int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr); +              if (tok <= 0) { +                if (tok == XML_TOK_INVALID) +                  *nextTokPtr = ptr; +                return tok; +              } +              break; +            } +          case BT_LT: +            *nextTokPtr = ptr; +            return XML_TOK_INVALID; +          default: +            ptr += MINBPC(enc); +            break; +          } +        } +        ptr += MINBPC(enc); +        if (ptr == end) +          return XML_TOK_PARTIAL; +        switch (BYTE_TYPE(enc, ptr)) { +        case BT_S: +        case BT_CR: +        case BT_LF: +          break; +        case BT_SOL: +          goto sol; +        case BT_GT: +          goto gt; +        default: +          *nextTokPtr = ptr; +          return XML_TOK_INVALID; +        } +        /* ptr points to closing quote */ +        for (;;) { +          ptr += MINBPC(enc); +          if (ptr == end) +            return XML_TOK_PARTIAL; +          switch (BYTE_TYPE(enc, ptr)) { +          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +          case BT_S: case BT_CR: case BT_LF: +            continue; +          case BT_GT: +          gt: +            *nextTokPtr = ptr + MINBPC(enc); +            return XML_TOK_START_TAG_WITH_ATTS; +          case BT_SOL: +          sol: +            ptr += MINBPC(enc); +            if (ptr == end) +              return XML_TOK_PARTIAL; +            if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { +              *nextTokPtr = ptr; +              return XML_TOK_INVALID; +            } +            *nextTokPtr = ptr + MINBPC(enc); +            return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; +          default: +            *nextTokPtr = ptr; +            return XML_TOK_INVALID; +          } +          break; +        } +        break; +      } +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  return XML_TOK_PARTIAL; +} + +/* ptr points to character following "<" */ + +static int PTRCALL +PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, +               const char **nextTokPtr) +{ +#ifdef XML_NS +  int hadColon; +#endif +  if (ptr == end) +    return XML_TOK_PARTIAL; +  switch (BYTE_TYPE(enc, ptr)) { +  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +  case BT_EXCL: +    if ((ptr += MINBPC(enc)) == end) +      return XML_TOK_PARTIAL; +    switch (BYTE_TYPE(enc, ptr)) { +    case BT_MINUS: +      return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr); +    case BT_LSQB: +      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), +                                      end, nextTokPtr); +    } +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  case BT_QUEST: +    return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); +  case BT_SOL: +    return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr); +  default: +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  } +#ifdef XML_NS +  hadColon = 0; +#endif +  /* we have a start-tag */ +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) +#ifdef XML_NS +    case BT_COLON: +      if (hadColon) { +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      hadColon = 1; +      ptr += MINBPC(enc); +      if (ptr == end) +        return XML_TOK_PARTIAL; +      switch (BYTE_TYPE(enc, ptr)) { +      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +      default: +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      break; +#endif +    case BT_S: case BT_CR: case BT_LF: +      { +        ptr += MINBPC(enc); +        while (ptr != end) { +          switch (BYTE_TYPE(enc, ptr)) { +          CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +          case BT_GT: +            goto gt; +          case BT_SOL: +            goto sol; +          case BT_S: case BT_CR: case BT_LF: +            ptr += MINBPC(enc); +            continue; +          default: +            *nextTokPtr = ptr; +            return XML_TOK_INVALID; +          } +          return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); +        } +        return XML_TOK_PARTIAL; +      } +    case BT_GT: +    gt: +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_START_TAG_NO_ATTS; +    case BT_SOL: +    sol: +      ptr += MINBPC(enc); +      if (ptr == end) +        return XML_TOK_PARTIAL; +      if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_EMPTY_ELEMENT_NO_ATTS; +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, +                   const char **nextTokPtr) +{ +  if (ptr == end) +    return XML_TOK_NONE; +  if (MINBPC(enc) > 1) { +    size_t n = end - ptr; +    if (n & (MINBPC(enc) - 1)) { +      n &= ~(MINBPC(enc) - 1); +      if (n == 0) +        return XML_TOK_PARTIAL; +      end = ptr + n; +    } +  } +  switch (BYTE_TYPE(enc, ptr)) { +  case BT_LT: +    return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); +  case BT_AMP: +    return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); +  case BT_CR: +    ptr += MINBPC(enc); +    if (ptr == end) +      return XML_TOK_TRAILING_CR; +    if (BYTE_TYPE(enc, ptr) == BT_LF) +      ptr += MINBPC(enc); +    *nextTokPtr = ptr; +    return XML_TOK_DATA_NEWLINE; +  case BT_LF: +    *nextTokPtr = ptr + MINBPC(enc); +    return XML_TOK_DATA_NEWLINE; +  case BT_RSQB: +    ptr += MINBPC(enc); +    if (ptr == end) +      return XML_TOK_TRAILING_RSQB; +    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) +      break; +    ptr += MINBPC(enc); +    if (ptr == end) +      return XML_TOK_TRAILING_RSQB; +    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { +      ptr -= MINBPC(enc); +      break; +    } +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  INVALID_CASES(ptr, nextTokPtr) +  default: +    ptr += MINBPC(enc); +    break; +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ +    case BT_LEAD ## n: \ +      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ +        *nextTokPtr = ptr; \ +        return XML_TOK_DATA_CHARS; \ +      } \ +      ptr += n; \ +      break; +    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE +    case BT_RSQB: +      if (ptr + MINBPC(enc) != end) { +         if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { +           ptr += MINBPC(enc); +           break; +         } +         if (ptr + 2*MINBPC(enc) != end) { +           if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) { +             ptr += MINBPC(enc); +             break; +           } +           *nextTokPtr = ptr + 2*MINBPC(enc); +           return XML_TOK_INVALID; +         } +      } +      /* fall through */ +    case BT_AMP: +    case BT_LT: +    case BT_NONXML: +    case BT_MALFORM: +    case BT_TRAIL: +    case BT_CR: +    case BT_LF: +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    default: +      ptr += MINBPC(enc); +      break; +    } +  } +  *nextTokPtr = ptr; +  return XML_TOK_DATA_CHARS; +} + +/* ptr points to character following "%" */ + +static int PTRCALL +PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, +                    const char **nextTokPtr) +{ +  if (ptr == end) +    return -XML_TOK_PERCENT; +  switch (BYTE_TYPE(enc, ptr)) { +  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +  case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: +    *nextTokPtr = ptr; +    return XML_TOK_PERCENT; +  default: +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) +    case BT_SEMI: +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_PARAM_ENTITY_REF; +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, +                      const char **nextTokPtr) +{ +  if (ptr == end) +    return XML_TOK_PARTIAL; +  switch (BYTE_TYPE(enc, ptr)) { +  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) +  default: +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) +    case BT_CR: case BT_LF: case BT_S: +    case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: +      *nextTokPtr = ptr; +      return XML_TOK_POUND_NAME; +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  return -XML_TOK_POUND_NAME; +} + +static int PTRCALL +PREFIX(scanLit)(int open, const ENCODING *enc, +                const char *ptr, const char *end, +                const char **nextTokPtr) +{ +  while (ptr != end) { +    int t = BYTE_TYPE(enc, ptr); +    switch (t) { +    INVALID_CASES(ptr, nextTokPtr) +    case BT_QUOT: +    case BT_APOS: +      ptr += MINBPC(enc); +      if (t != open) +        break; +      if (ptr == end) +        return -XML_TOK_LITERAL; +      *nextTokPtr = ptr; +      switch (BYTE_TYPE(enc, ptr)) { +      case BT_S: case BT_CR: case BT_LF: +      case BT_GT: case BT_PERCNT: case BT_LSQB: +        return XML_TOK_LITERAL; +      default: +        return XML_TOK_INVALID; +      } +    default: +      ptr += MINBPC(enc); +      break; +    } +  } +  return XML_TOK_PARTIAL; +} + +static int PTRCALL +PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, +                  const char **nextTokPtr) +{ +  int tok; +  if (ptr == end) +    return XML_TOK_NONE; +  if (MINBPC(enc) > 1) { +    size_t n = end - ptr; +    if (n & (MINBPC(enc) - 1)) { +      n &= ~(MINBPC(enc) - 1); +      if (n == 0) +        return XML_TOK_PARTIAL; +      end = ptr + n; +    } +  } +  switch (BYTE_TYPE(enc, ptr)) { +  case BT_QUOT: +    return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); +  case BT_APOS: +    return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); +  case BT_LT: +    { +      ptr += MINBPC(enc); +      if (ptr == end) +        return XML_TOK_PARTIAL; +      switch (BYTE_TYPE(enc, ptr)) { +      case BT_EXCL: +        return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); +      case BT_QUEST: +        return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); +      case BT_NMSTRT: +      case BT_HEX: +      case BT_NONASCII: +      case BT_LEAD2: +      case BT_LEAD3: +      case BT_LEAD4: +        *nextTokPtr = ptr - MINBPC(enc); +        return XML_TOK_INSTANCE_START; +      } +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  case BT_CR: +    if (ptr + MINBPC(enc) == end) { +      *nextTokPtr = end; +      /* indicate that this might be part of a CR/LF pair */ +      return -XML_TOK_PROLOG_S; +    } +    /* fall through */ +  case BT_S: case BT_LF: +    for (;;) { +      ptr += MINBPC(enc); +      if (ptr == end) +        break; +      switch (BYTE_TYPE(enc, ptr)) { +      case BT_S: case BT_LF: +        break; +      case BT_CR: +        /* don't split CR/LF pair */ +        if (ptr + MINBPC(enc) != end) +          break; +        /* fall through */ +      default: +        *nextTokPtr = ptr; +        return XML_TOK_PROLOG_S; +      } +    } +    *nextTokPtr = ptr; +    return XML_TOK_PROLOG_S; +  case BT_PERCNT: +    return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); +  case BT_COMMA: +    *nextTokPtr = ptr + MINBPC(enc); +    return XML_TOK_COMMA; +  case BT_LSQB: +    *nextTokPtr = ptr + MINBPC(enc); +    return XML_TOK_OPEN_BRACKET; +  case BT_RSQB: +    ptr += MINBPC(enc); +    if (ptr == end) +      return -XML_TOK_CLOSE_BRACKET; +    if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { +      if (ptr + MINBPC(enc) == end) +        return XML_TOK_PARTIAL; +      if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { +        *nextTokPtr = ptr + 2*MINBPC(enc); +        return XML_TOK_COND_SECT_CLOSE; +      } +    } +    *nextTokPtr = ptr; +    return XML_TOK_CLOSE_BRACKET; +  case BT_LPAR: +    *nextTokPtr = ptr + MINBPC(enc); +    return XML_TOK_OPEN_PAREN; +  case BT_RPAR: +    ptr += MINBPC(enc); +    if (ptr == end) +      return -XML_TOK_CLOSE_PAREN; +    switch (BYTE_TYPE(enc, ptr)) { +    case BT_AST: +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_CLOSE_PAREN_ASTERISK; +    case BT_QUEST: +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_CLOSE_PAREN_QUESTION; +    case BT_PLUS: +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_CLOSE_PAREN_PLUS; +    case BT_CR: case BT_LF: case BT_S: +    case BT_GT: case BT_COMMA: case BT_VERBAR: +    case BT_RPAR: +      *nextTokPtr = ptr; +      return XML_TOK_CLOSE_PAREN; +    } +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  case BT_VERBAR: +    *nextTokPtr = ptr + MINBPC(enc); +    return XML_TOK_OR; +  case BT_GT: +    *nextTokPtr = ptr + MINBPC(enc); +    return XML_TOK_DECL_CLOSE; +  case BT_NUM: +    return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); +#define LEAD_CASE(n) \ +  case BT_LEAD ## n: \ +    if (end - ptr < n) \ +      return XML_TOK_PARTIAL_CHAR; \ +    if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ +      ptr += n; \ +      tok = XML_TOK_NAME; \ +      break; \ +    } \ +    if (IS_NAME_CHAR(enc, ptr, n)) { \ +      ptr += n; \ +      tok = XML_TOK_NMTOKEN; \ +      break; \ +    } \ +    *nextTokPtr = ptr; \ +    return XML_TOK_INVALID; +    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE +  case BT_NMSTRT: +  case BT_HEX: +    tok = XML_TOK_NAME; +    ptr += MINBPC(enc); +    break; +  case BT_DIGIT: +  case BT_NAME: +  case BT_MINUS: +#ifdef XML_NS +  case BT_COLON: +#endif +    tok = XML_TOK_NMTOKEN; +    ptr += MINBPC(enc); +    break; +  case BT_NONASCII: +    if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { +      ptr += MINBPC(enc); +      tok = XML_TOK_NAME; +      break; +    } +    if (IS_NAME_CHAR_MINBPC(enc, ptr)) { +      ptr += MINBPC(enc); +      tok = XML_TOK_NMTOKEN; +      break; +    } +    /* fall through */ +  default: +    *nextTokPtr = ptr; +    return XML_TOK_INVALID; +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) +    case BT_GT: case BT_RPAR: case BT_COMMA: +    case BT_VERBAR: case BT_LSQB: case BT_PERCNT: +    case BT_S: case BT_CR: case BT_LF: +      *nextTokPtr = ptr; +      return tok; +#ifdef XML_NS +    case BT_COLON: +      ptr += MINBPC(enc); +      switch (tok) { +      case XML_TOK_NAME: +        if (ptr == end) +          return XML_TOK_PARTIAL; +        tok = XML_TOK_PREFIXED_NAME; +        switch (BYTE_TYPE(enc, ptr)) { +        CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) +        default: +          tok = XML_TOK_NMTOKEN; +          break; +        } +        break; +      case XML_TOK_PREFIXED_NAME: +        tok = XML_TOK_NMTOKEN; +        break; +      } +      break; +#endif +    case BT_PLUS: +      if (tok == XML_TOK_NMTOKEN)  { +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_NAME_PLUS; +    case BT_AST: +      if (tok == XML_TOK_NMTOKEN)  { +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_NAME_ASTERISK; +    case BT_QUEST: +      if (tok == XML_TOK_NMTOKEN)  { +        *nextTokPtr = ptr; +        return XML_TOK_INVALID; +      } +      *nextTokPtr = ptr + MINBPC(enc); +      return XML_TOK_NAME_QUESTION; +    default: +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    } +  } +  return -tok; +} + +static int PTRCALL +PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, +                          const char *end, const char **nextTokPtr) +{ +  const char *start; +  if (ptr == end) +    return XML_TOK_NONE; +  start = ptr; +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ +    case BT_LEAD ## n: ptr += n; break; +    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE +    case BT_AMP: +      if (ptr == start) +        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    case BT_LT: +      /* this is for inside entity references */ +      *nextTokPtr = ptr; +      return XML_TOK_INVALID; +    case BT_LF: +      if (ptr == start) { +        *nextTokPtr = ptr + MINBPC(enc); +        return XML_TOK_DATA_NEWLINE; +      } +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    case BT_CR: +      if (ptr == start) { +        ptr += MINBPC(enc); +        if (ptr == end) +          return XML_TOK_TRAILING_CR; +        if (BYTE_TYPE(enc, ptr) == BT_LF) +          ptr += MINBPC(enc); +        *nextTokPtr = ptr; +        return XML_TOK_DATA_NEWLINE; +      } +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    case BT_S: +      if (ptr == start) { +        *nextTokPtr = ptr + MINBPC(enc); +        return XML_TOK_ATTRIBUTE_VALUE_S; +      } +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    default: +      ptr += MINBPC(enc); +      break; +    } +  } +  *nextTokPtr = ptr; +  return XML_TOK_DATA_CHARS; +} + +static int PTRCALL +PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, +                       const char *end, const char **nextTokPtr) +{ +  const char *start; +  if (ptr == end) +    return XML_TOK_NONE; +  start = ptr; +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ +    case BT_LEAD ## n: ptr += n; break; +    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE +    case BT_AMP: +      if (ptr == start) +        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    case BT_PERCNT: +      if (ptr == start) { +        int tok =  PREFIX(scanPercent)(enc, ptr + MINBPC(enc), +                                       end, nextTokPtr); +        return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok; +      } +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    case BT_LF: +      if (ptr == start) { +        *nextTokPtr = ptr + MINBPC(enc); +        return XML_TOK_DATA_NEWLINE; +      } +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    case BT_CR: +      if (ptr == start) { +        ptr += MINBPC(enc); +        if (ptr == end) +          return XML_TOK_TRAILING_CR; +        if (BYTE_TYPE(enc, ptr) == BT_LF) +          ptr += MINBPC(enc); +        *nextTokPtr = ptr; +        return XML_TOK_DATA_NEWLINE; +      } +      *nextTokPtr = ptr; +      return XML_TOK_DATA_CHARS; +    default: +      ptr += MINBPC(enc); +      break; +    } +  } +  *nextTokPtr = ptr; +  return XML_TOK_DATA_CHARS; +} + +#ifdef XML_DTD + +static int PTRCALL +PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, +                         const char *end, const char **nextTokPtr) +{ +  int level = 0; +  if (MINBPC(enc) > 1) { +    size_t n = end - ptr; +    if (n & (MINBPC(enc) - 1)) { +      n &= ~(MINBPC(enc) - 1); +      end = ptr + n; +    } +  } +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +    INVALID_CASES(ptr, nextTokPtr) +    case BT_LT: +      if ((ptr += MINBPC(enc)) == end) +        return XML_TOK_PARTIAL; +      if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { +        if ((ptr += MINBPC(enc)) == end) +          return XML_TOK_PARTIAL; +        if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { +          ++level; +          ptr += MINBPC(enc); +        } +      } +      break; +    case BT_RSQB: +      if ((ptr += MINBPC(enc)) == end) +        return XML_TOK_PARTIAL; +      if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { +        if ((ptr += MINBPC(enc)) == end) +          return XML_TOK_PARTIAL; +        if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { +          ptr += MINBPC(enc); +          if (level == 0) { +            *nextTokPtr = ptr; +            return XML_TOK_IGNORE_SECT; +          } +          --level; +        } +      } +      break; +    default: +      ptr += MINBPC(enc); +      break; +    } +  } +  return XML_TOK_PARTIAL; +} + +#endif /* XML_DTD */ + +static int PTRCALL +PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, +                   const char **badPtr) +{ +  ptr += MINBPC(enc); +  end -= MINBPC(enc); +  for (; ptr != end; ptr += MINBPC(enc)) { +    switch (BYTE_TYPE(enc, ptr)) { +    case BT_DIGIT: +    case BT_HEX: +    case BT_MINUS: +    case BT_APOS: +    case BT_LPAR: +    case BT_RPAR: +    case BT_PLUS: +    case BT_COMMA: +    case BT_SOL: +    case BT_EQUALS: +    case BT_QUEST: +    case BT_CR: +    case BT_LF: +    case BT_SEMI: +    case BT_EXCL: +    case BT_AST: +    case BT_PERCNT: +    case BT_NUM: +#ifdef XML_NS +    case BT_COLON: +#endif +      break; +    case BT_S: +      if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) { +        *badPtr = ptr; +        return 0; +      } +      break; +    case BT_NAME: +    case BT_NMSTRT: +      if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) +        break; +    default: +      switch (BYTE_TO_ASCII(enc, ptr)) { +      case 0x24: /* $ */ +      case 0x40: /* @ */ +        break; +      default: +        *badPtr = ptr; +        return 0; +      } +      break; +    } +  } +  return 1; +} + +/* This must only be called for a well-formed start-tag or empty +   element tag.  Returns the number of attributes.  Pointers to the +   first attsMax attributes are stored in atts. +*/ + +static int PTRCALL +PREFIX(getAtts)(const ENCODING *enc, const char *ptr, +                int attsMax, ATTRIBUTE *atts) +{ +  enum { other, inName, inValue } state = inName; +  int nAtts = 0; +  int open = 0; /* defined when state == inValue; +                   initialization just to shut up compilers */ + +  for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { +    switch (BYTE_TYPE(enc, ptr)) { +#define START_NAME \ +      if (state == other) { \ +        if (nAtts < attsMax) { \ +          atts[nAtts].name = ptr; \ +          atts[nAtts].normalized = 1; \ +        } \ +        state = inName; \ +      } +#define LEAD_CASE(n) \ +    case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; +    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE +    case BT_NONASCII: +    case BT_NMSTRT: +    case BT_HEX: +      START_NAME +      break; +#undef START_NAME +    case BT_QUOT: +      if (state != inValue) { +        if (nAtts < attsMax) +          atts[nAtts].valuePtr = ptr + MINBPC(enc); +        state = inValue; +        open = BT_QUOT; +      } +      else if (open == BT_QUOT) { +        state = other; +        if (nAtts < attsMax) +          atts[nAtts].valueEnd = ptr; +        nAtts++; +      } +      break; +    case BT_APOS: +      if (state != inValue) { +        if (nAtts < attsMax) +          atts[nAtts].valuePtr = ptr + MINBPC(enc); +        state = inValue; +        open = BT_APOS; +      } +      else if (open == BT_APOS) { +        state = other; +        if (nAtts < attsMax) +          atts[nAtts].valueEnd = ptr; +        nAtts++; +      } +      break; +    case BT_AMP: +      if (nAtts < attsMax) +        atts[nAtts].normalized = 0; +      break; +    case BT_S: +      if (state == inName) +        state = other; +      else if (state == inValue +               && nAtts < attsMax +               && atts[nAtts].normalized +               && (ptr == atts[nAtts].valuePtr +                   || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE +                   || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE +                   || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) +        atts[nAtts].normalized = 0; +      break; +    case BT_CR: case BT_LF: +      /* This case ensures that the first attribute name is counted +         Apart from that we could just change state on the quote. */ +      if (state == inName) +        state = other; +      else if (state == inValue && nAtts < attsMax) +        atts[nAtts].normalized = 0; +      break; +    case BT_GT: +    case BT_SOL: +      if (state != inValue) +        return nAtts; +      break; +    default: +      break; +    } +  } +  /* not reached */ +} + +static int PTRFASTCALL +PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) +{ +  int result = 0; +  /* skip &# */ +  ptr += 2*MINBPC(enc); +  if (CHAR_MATCHES(enc, ptr, ASCII_x)) { +    for (ptr += MINBPC(enc); +         !CHAR_MATCHES(enc, ptr, ASCII_SEMI); +         ptr += MINBPC(enc)) { +      int c = BYTE_TO_ASCII(enc, ptr); +      switch (c) { +      case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4: +      case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9: +        result <<= 4; +        result |= (c - ASCII_0); +        break; +      case ASCII_A: case ASCII_B: case ASCII_C: +      case ASCII_D: case ASCII_E: case ASCII_F: +        result <<= 4; +        result += 10 + (c - ASCII_A); +        break; +      case ASCII_a: case ASCII_b: case ASCII_c: +      case ASCII_d: case ASCII_e: case ASCII_f: +        result <<= 4; +        result += 10 + (c - ASCII_a); +        break; +      } +      if (result >= 0x110000) +        return -1; +    } +  } +  else { +    for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) { +      int c = BYTE_TO_ASCII(enc, ptr); +      result *= 10; +      result += (c - ASCII_0); +      if (result >= 0x110000) +        return -1; +    } +  } +  return checkCharRefNumber(result); +} + +static int PTRCALL +PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, +                             const char *end) +{ +  switch ((end - ptr)/MINBPC(enc)) { +  case 2: +    if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) { +      switch (BYTE_TO_ASCII(enc, ptr)) { +      case ASCII_l: +        return ASCII_LT; +      case ASCII_g: +        return ASCII_GT; +      } +    } +    break; +  case 3: +    if (CHAR_MATCHES(enc, ptr, ASCII_a)) { +      ptr += MINBPC(enc); +      if (CHAR_MATCHES(enc, ptr, ASCII_m)) { +        ptr += MINBPC(enc); +        if (CHAR_MATCHES(enc, ptr, ASCII_p)) +          return ASCII_AMP; +      } +    } +    break; +  case 4: +    switch (BYTE_TO_ASCII(enc, ptr)) { +    case ASCII_q: +      ptr += MINBPC(enc); +      if (CHAR_MATCHES(enc, ptr, ASCII_u)) { +        ptr += MINBPC(enc); +        if (CHAR_MATCHES(enc, ptr, ASCII_o)) { +          ptr += MINBPC(enc); +          if (CHAR_MATCHES(enc, ptr, ASCII_t)) +            return ASCII_QUOT; +        } +      } +      break; +    case ASCII_a: +      ptr += MINBPC(enc); +      if (CHAR_MATCHES(enc, ptr, ASCII_p)) { +        ptr += MINBPC(enc); +        if (CHAR_MATCHES(enc, ptr, ASCII_o)) { +          ptr += MINBPC(enc); +          if (CHAR_MATCHES(enc, ptr, ASCII_s)) +            return ASCII_APOS; +        } +      } +      break; +    } +  } +  return 0; +} + +static int PTRCALL +PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) +{ +  for (;;) { +    switch (BYTE_TYPE(enc, ptr1)) { +#define LEAD_CASE(n) \ +    case BT_LEAD ## n: \ +      if (*ptr1++ != *ptr2++) \ +        return 0; +    LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) +#undef LEAD_CASE +      /* fall through */ +      if (*ptr1++ != *ptr2++) +        return 0; +      break; +    case BT_NONASCII: +    case BT_NMSTRT: +#ifdef XML_NS +    case BT_COLON: +#endif +    case BT_HEX: +    case BT_DIGIT: +    case BT_NAME: +    case BT_MINUS: +      if (*ptr2++ != *ptr1++) +        return 0; +      if (MINBPC(enc) > 1) { +        if (*ptr2++ != *ptr1++) +          return 0; +        if (MINBPC(enc) > 2) { +          if (*ptr2++ != *ptr1++) +            return 0; +          if (MINBPC(enc) > 3) { +            if (*ptr2++ != *ptr1++) +              return 0; +          } +        } +      } +      break; +    default: +      if (MINBPC(enc) == 1 && *ptr1 == *ptr2) +        return 1; +      switch (BYTE_TYPE(enc, ptr2)) { +      case BT_LEAD2: +      case BT_LEAD3: +      case BT_LEAD4: +      case BT_NONASCII: +      case BT_NMSTRT: +#ifdef XML_NS +      case BT_COLON: +#endif +      case BT_HEX: +      case BT_DIGIT: +      case BT_NAME: +      case BT_MINUS: +        return 0; +      default: +        return 1; +      } +    } +  } +  /* not reached */ +} + +static int PTRCALL +PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, +                         const char *end1, const char *ptr2) +{ +  for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { +    if (ptr1 == end1) +      return 0; +    if (!CHAR_MATCHES(enc, ptr1, *ptr2)) +      return 0; +  } +  return ptr1 == end1; +} + +static int PTRFASTCALL +PREFIX(nameLength)(const ENCODING *enc, const char *ptr) +{ +  const char *start = ptr; +  for (;;) { +    switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ +    case BT_LEAD ## n: ptr += n; break; +    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE +    case BT_NONASCII: +    case BT_NMSTRT: +#ifdef XML_NS +    case BT_COLON: +#endif +    case BT_HEX: +    case BT_DIGIT: +    case BT_NAME: +    case BT_MINUS: +      ptr += MINBPC(enc); +      break; +    default: +      return (int)(ptr - start); +    } +  } +} + +static const char * PTRFASTCALL +PREFIX(skipS)(const ENCODING *enc, const char *ptr) +{ +  for (;;) { +    switch (BYTE_TYPE(enc, ptr)) { +    case BT_LF: +    case BT_CR: +    case BT_S: +      ptr += MINBPC(enc); +      break; +    default: +      return ptr; +    } +  } +} + +static void PTRCALL +PREFIX(updatePosition)(const ENCODING *enc, +                       const char *ptr, +                       const char *end, +                       POSITION *pos) +{ +  while (ptr != end) { +    switch (BYTE_TYPE(enc, ptr)) { +#define LEAD_CASE(n) \ +    case BT_LEAD ## n: \ +      ptr += n; \ +      break; +    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) +#undef LEAD_CASE +    case BT_LF: +      pos->columnNumber = (XML_Size)-1; +      pos->lineNumber++; +      ptr += MINBPC(enc); +      break; +    case BT_CR: +      pos->lineNumber++; +      ptr += MINBPC(enc); +      if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) +        ptr += MINBPC(enc); +      pos->columnNumber = (XML_Size)-1; +      break; +    default: +      ptr += MINBPC(enc); +      break; +    } +    pos->columnNumber++; +  } +} + +#undef DO_LEAD_CASE +#undef MULTIBYTE_CASES +#undef INVALID_CASES +#undef CHECK_NAME_CASE +#undef CHECK_NAME_CASES +#undef CHECK_NMSTRT_CASE +#undef CHECK_NMSTRT_CASES + +#endif /* XML_TOK_IMPL_C */ diff --git a/3rdParty/Expat/src/xmltok_impl.h b/3rdParty/Expat/src/xmltok_impl.h new file mode 100755 index 0000000..da0ea60 --- /dev/null +++ b/3rdParty/Expat/src/xmltok_impl.h @@ -0,0 +1,46 @@ +/* +Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +See the file COPYING for copying permission. +*/ + +enum { +  BT_NONXML, +  BT_MALFORM, +  BT_LT, +  BT_AMP, +  BT_RSQB, +  BT_LEAD2, +  BT_LEAD3, +  BT_LEAD4, +  BT_TRAIL, +  BT_CR, +  BT_LF, +  BT_GT, +  BT_QUOT, +  BT_APOS, +  BT_EQUALS, +  BT_QUEST, +  BT_EXCL, +  BT_SOL, +  BT_SEMI, +  BT_NUM, +  BT_LSQB, +  BT_S, +  BT_NMSTRT, +  BT_COLON, +  BT_HEX, +  BT_DIGIT, +  BT_NAME, +  BT_MINUS, +  BT_OTHER, /* known not to be a name or name start character */ +  BT_NONASCII, /* might be a name or name start character */ +  BT_PERCNT, +  BT_LPAR, +  BT_RPAR, +  BT_AST, +  BT_PLUS, +  BT_COMMA, +  BT_VERBAR +}; + +#include <stddef.h> diff --git a/3rdParty/Expat/src/xmltok_ns.c b/3rdParty/Expat/src/xmltok_ns.c new file mode 100755 index 0000000..c3b88fd --- /dev/null +++ b/3rdParty/Expat/src/xmltok_ns.c @@ -0,0 +1,115 @@ +/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd +   See the file COPYING for copying permission. +*/ + +/* This file is included! */ +#ifdef XML_TOK_NS_C + +const ENCODING * +NS(XmlGetUtf8InternalEncoding)(void) +{ +  return &ns(internal_utf8_encoding).enc; +} + +const ENCODING * +NS(XmlGetUtf16InternalEncoding)(void) +{ +#if BYTEORDER == 1234 +  return &ns(internal_little2_encoding).enc; +#elif BYTEORDER == 4321 +  return &ns(internal_big2_encoding).enc; +#else +  const short n = 1; +  return (*(const char *)&n +          ? &ns(internal_little2_encoding).enc +          : &ns(internal_big2_encoding).enc); +#endif +} + +static const ENCODING * const NS(encodings)[] = { +  &ns(latin1_encoding).enc, +  &ns(ascii_encoding).enc, +  &ns(utf8_encoding).enc, +  &ns(big2_encoding).enc, +  &ns(big2_encoding).enc, +  &ns(little2_encoding).enc, +  &ns(utf8_encoding).enc /* NO_ENC */ +}; + +static int PTRCALL +NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, +                   const char **nextTokPtr) +{ +  return initScan(NS(encodings), (const INIT_ENCODING *)enc, +                  XML_PROLOG_STATE, ptr, end, nextTokPtr); +} + +static int PTRCALL +NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, +                    const char **nextTokPtr) +{ +  return initScan(NS(encodings), (const INIT_ENCODING *)enc, +                  XML_CONTENT_STATE, ptr, end, nextTokPtr); +} + +int +NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, +                    const char *name) +{ +  int i = getEncodingIndex(name); +  if (i == UNKNOWN_ENC) +    return 0; +  SET_INIT_ENC_INDEX(p, i); +  p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); +  p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); +  p->initEnc.updatePosition = initUpdatePosition; +  p->encPtr = encPtr; +  *encPtr = &(p->initEnc); +  return 1; +} + +static const ENCODING * +NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) +{ +#define ENCODING_MAX 128 +  char buf[ENCODING_MAX]; +  char *p = buf; +  int i; +  XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); +  if (ptr != end) +    return 0; +  *p = 0; +  if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2) +    return enc; +  i = getEncodingIndex(buf); +  if (i == UNKNOWN_ENC) +    return 0; +  return NS(encodings)[i]; +} + +int +NS(XmlParseXmlDecl)(int isGeneralTextEntity, +                    const ENCODING *enc, +                    const char *ptr, +                    const char *end, +                    const char **badPtr, +                    const char **versionPtr, +                    const char **versionEndPtr, +                    const char **encodingName, +                    const ENCODING **encoding, +                    int *standalone) +{ +  return doParseXmlDecl(NS(findEncoding), +                        isGeneralTextEntity, +                        enc, +                        ptr, +                        end, +                        badPtr, +                        versionPtr, +                        versionEndPtr, +                        encodingName, +                        encoding, +                        standalone); +} + +#endif /* XML_TOK_NS_C */ diff --git a/3rdParty/LibIDN/Makefile.inc b/3rdParty/LibIDN/Makefile.inc index 6f0e367..f0f64ac 100644 --- a/3rdParty/LibIDN/Makefile.inc +++ b/3rdParty/LibIDN/Makefile.inc @@ -20,8 +20,6 @@ LIBIDN_OBJECTS = \  	$(LIBIDN_SOURCES:.c=.o)  CLEANFILES += \ -	$(LIBIDN_SOURCES:.c=.gcda) \ -	$(LIBIDN_SOURCES:.c=.gcno) \  	$(LIBIDN_OBJECTS) diff --git a/3rdParty/ZLib/Makefile.inc b/3rdParty/ZLib/Makefile.inc index 479a883..dccfcf4 100644 --- a/3rdParty/ZLib/Makefile.inc +++ b/3rdParty/ZLib/Makefile.inc @@ -19,6 +19,4 @@ ZLIB_OBJECTS = \  	$(ZLIB_SOURCES:.c=.o)  CLEANFILES += \ -	$(ZLIB_SOURCES:.c=.gcda) \ -	$(ZLIB_SOURCES:.c=.gcno) \  	$(ZLIB_OBJECTS) @@ -40,6 +40,7 @@ include 3rdParty/Boost/Makefile.inc  include 3rdParty/CppUnit/Makefile.inc  include 3rdParty/LibIDN/Makefile.inc  include 3rdParty/ZLib/Makefile.inc +include 3rdParty/Expat/Makefile.inc  include Swiften/Makefile.inc  include UI/Qt/Makefile.inc @@ -56,12 +57,9 @@ coverage:  .PHONY: clean  clean: clean-deps $(CLEAN_TARGETS) -	-$(RM) $(CLEANFILES) \ -		$(SWIFTEN_SOURCES:.cpp=.gcda) \ -		$(SWIFTEN_SOURCES:.cpp=.gcno) \ -		$(UNITTEST_SOURCES:.cpp=.gcda) \ -		$(UNITTEST_SOURCES:.cpp=.gcno) \ -		*.gcov +	-$(RM) $(CLEANFILES) *.gcov +	-find . -name "*.gcda" -exec rm {} \; +	-find . -name "*.gcno" -exec rm {} \;  .PHONY: clean-deps  clean-deps: diff --git a/Makefile.config.in b/Makefile.config.in index e0170be..c71334d 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -9,7 +9,8 @@ CC=@CONFIG_CC@  CFLAGS=@CONFIG_CFLAGS@  LDFLAGS=@CONFIG_LDFLAGS@  LIBS=@CONFIG_LIBS@ -HAVE_EXPAT=@CONFIG_HAVE_EXPAT@ +HAVE_EXPAT=@HAVE_EXPAT@ +USE_BUNDLED_EXPAT=@USE_BUNDLED_EXPAT@  HAVE_LIBXML=@CONFIG_HAVE_LIBXML@  HAVE_OPENSSL=@CONFIG_HAVE_OPENSSL@  WIN32=@CONFIG_WIN32@ diff --git a/Swiften/EventLoop/MainEventLoop.cpp b/Swiften/EventLoop/MainEventLoop.cpp index afaab42..c306d3f 100644 --- a/Swiften/EventLoop/MainEventLoop.cpp +++ b/Swiften/EventLoop/MainEventLoop.cpp @@ -1,6 +1,7 @@  #include "Swiften/EventLoop/MainEventLoop.h"  #include <iostream> +#include <typeinfo>  namespace Swift { diff --git a/Swiften/QA/ClientTest/Makefile.inc b/Swiften/QA/ClientTest/Makefile.inc index d01ccf8..08a9b5b 100644 --- a/Swiften/QA/ClientTest/Makefile.inc +++ b/Swiften/QA/ClientTest/Makefile.inc @@ -8,8 +8,8 @@ TEST_TARGETS += ClientTest  CLEANFILES += $(CLIENTTEST_OBJECTS) $(CLIENTTEST_TARGET) -$(CLIENTTEST_TARGET): $(SWIFTEN_TARGET) $(CLIENTTEST_OBJECTS) -	$(QUIET_LINK)$(CXX) -o $(CLIENTTEST_TARGET) $(CLIENTTEST_OBJECTS) $(LDFLAGS) $(CPPCLIENT_LDFLAGS) $(SWIFTEN_TARGET) $(LIBS) +$(CLIENTTEST_TARGET): $(SWIFTEN_TARGET) $(CLIENTTEST_OBJECTS) $(BUNDLED_LIBS) +	$(QUIET_LINK)$(CXX) -o $(CLIENTTEST_TARGET) $(CLIENTTEST_OBJECTS) $(LDFLAGS) $(CPPCLIENT_LDFLAGS) $(SWIFTEN_TARGET) $(BUNDLED_LIBS) $(LIBS)  .PHONY: ClientTest  ClientTest: $(CLIENTTEST_TARGET) diff --git a/Swiften/QA/NetworkTest/Makefile.inc b/Swiften/QA/NetworkTest/Makefile.inc index 6924a70..3638f2f 100644 --- a/Swiften/QA/NetworkTest/Makefile.inc +++ b/Swiften/QA/NetworkTest/Makefile.inc @@ -10,8 +10,8 @@ TEST_TARGETS += NetworkTest  CLEANFILES += $(NETWORKTEST_OBJECTS) $(NETWORKTEST_TARGET) -$(NETWORKTEST_TARGET): $(SWIFTEN_TARGET) $(CPPUNIT_TARGET) $(NETWORKTEST_OBJECTS) -	$(QUIET_LINK)$(CXX) -o $(NETWORKTEST_TARGET) $(NETWORKTEST_OBJECTS) $(LDFLAGS) $(CPPNETWORK_LDFLAGS) $(SWIFTEN_TARGET) $(CPPUNIT_TARGET) $(LIBS) +$(NETWORKTEST_TARGET): $(SWIFTEN_TARGET) $(CPPUNIT_TARGET) $(NETWORKTEST_OBJECTS) $(BUNDLED_LIBS) +	$(QUIET_LINK)$(CXX) -o $(NETWORKTEST_TARGET) $(NETWORKTEST_OBJECTS) $(LDFLAGS) $(CPPNETWORK_LDFLAGS) $(SWIFTEN_TARGET) $(CPPUNIT_TARGET) $(BUNDLED_LIBS) $(LIBS)  .PHONY: NetworkTest  NetworkTest: $(NETWORKTEST_TARGET) diff --git a/Swiften/QA/UnitTest/Makefile.inc b/Swiften/QA/UnitTest/Makefile.inc index 5b456db..7f31da3 100644 --- a/Swiften/QA/UnitTest/Makefile.inc +++ b/Swiften/QA/UnitTest/Makefile.inc @@ -12,6 +12,6 @@ CLEANFILES += $(UNITTEST_OBJECTS) $(UNITTEST_TARGET)  check: $(UNITTEST_TARGET)  	$(TEST_RUNNER) ./$(UNITTEST_TARGET) -$(UNITTEST_TARGET): $(SWIFTEN_TARGET) $(CPPUNIT_TARGET) $(UNITTEST_OBJECTS) -	$(QUIET_LINK)$(CXX) -o $(UNITTEST_TARGET) $(UNITTEST_OBJECTS) $(LDFLAGS) $(SWIFTEN_TARGET) $(CPPUNIT_TARGET) $(LIBS) +$(UNITTEST_TARGET): $(SWIFTEN_TARGET) $(CPPUNIT_TARGET) $(UNITTEST_OBJECTS) $(BUNDLED_LIBS) +	$(QUIET_LINK)$(CXX) -o $(UNITTEST_TARGET) $(UNITTEST_OBJECTS) $(LDFLAGS) $(SWIFTEN_TARGET) $(CPPUNIT_TARGET) $(BUNDLED_LIBS) $(LIBS) diff --git a/configure.in b/configure.in index ac92694..5866b63 100644 --- a/configure.in +++ b/configure.in @@ -109,7 +109,6 @@ CONFIG_CXX="$CXX"  # Expat  AX_LIB_EXPAT() -CONFIG_HAVE_EXPAT="$HAVE_EXPAT"  if test "$HAVE_EXPAT" = yes; then  	CONFIG_CXXFLAGS="$CONFIG_CXXFLAGS $EXPAT_CFLAGS"  	CONFIG_LDFLAGS="$CONFIG_LDFLAGS $EXPAT_LDFLAGS" @@ -127,9 +126,11 @@ if test "$HAVE_LIBXML" = yes; then  	AC_DEFINE(HAVE_LIBXML)  fi -# Test whether we have *a* parser +# Test whether we have *a* parser, and use bundled Expat if necessary  if test "$HAVE_EXPAT" != yes -a "$HAVE_LIBXML" != yes; then -	AC_MSG_ERROR([Expat or LibXML XML Parser is required]) +  AC_MSG_NOTICE([No installed XML parser found. Using bundled Expat]) +  HAVE_EXPAT=yes +  USE_BUNDLED_EXPAT=yes  fi  # OpenSSL @@ -152,6 +153,7 @@ echo "    -------------------"  TEXT_XML_PARSERS=  if test "$HAVE_LIBXML" == "yes"; then TEXT_XML_PARSERS="LibXML"; fi +if test "$USE_BUNDLED_EXPAT" == "yes"; then TEXT_XML_PARSERS="(Bundled)"; fi  if test "$HAVE_EXPAT" == "yes"; then TEXT_XML_PARSERS="Expat $TEXT_XML_PARSERS"; fi  echo "    XML Parser(s): $TEXT_XML_PARSERS" @@ -165,6 +167,7 @@ echo  ################################################################################  AC_SUBST(SET_MAKE) +AC_SUBST(HAVE_EXPAT)  AC_SUBST(CONFIG_CXX)  AC_SUBST(CONFIG_CXXFLAGS)  AC_SUBST(CONFIG_CC) @@ -174,7 +177,7 @@ AC_SUBST(CONFIG_LIBS)  AC_SUBST(CONFIG_WIN32)  AC_SUBST(CONFIG_MACOSX)  AC_SUBST(CONFIG_HAVE_OPENSSL) -AC_SUBST(CONFIG_HAVE_EXPAT) +AC_SUBST(USE_BUNDLED_EXPAT)  AC_SUBST(CONFIG_HAVE_LIBXML)  AC_CONFIG_FILES([Makefile.config]) | 
 Swift
 Swift