mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-28 04:09:35 +03:00
Drop old expat sources to make room for a fresh import
This commit is contained in:
@@ -1 +0,0 @@
|
||||
# do not do coverage in this directory
|
||||
@@ -1,34 +0,0 @@
|
||||
PROJECT(CMEXPAT)
|
||||
|
||||
SET(expat_SRCS
|
||||
xmlparse.c
|
||||
xmltok.c
|
||||
xmlrole.c
|
||||
)
|
||||
|
||||
INCLUDE(${CMAKE_ROOT}/Modules/TestBigEndian.cmake)
|
||||
TEST_BIG_ENDIAN(CMEXPAT_BIGENDIAN)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
"${CMEXPAT_BINARY_DIR}/.."
|
||||
)
|
||||
|
||||
IF(WIN32)
|
||||
IF(NOT BUILD_SHARED_LIBS)
|
||||
SET (CM_EXPAT_STATIC 1)
|
||||
ENDIF(NOT BUILD_SHARED_LIBS)
|
||||
ENDIF(WIN32)
|
||||
|
||||
CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/expatConfig.h.in
|
||||
${CMEXPAT_BINARY_DIR}/expatConfig.h)
|
||||
CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/expatDllConfig.h.in
|
||||
${CMEXPAT_BINARY_DIR}/expatDllConfig.h)
|
||||
CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/.NoDartCoverage
|
||||
${CMEXPAT_BINARY_DIR}/.NoDartCoverage)
|
||||
CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/cm_expat_mangle.h
|
||||
${CMEXPAT_BINARY_DIR}/cm_expat_mangle.h)
|
||||
CONFIGURE_FILE(${CMEXPAT_SOURCE_DIR}/expat.h
|
||||
${CMEXPAT_BINARY_DIR}/expat.h)
|
||||
|
||||
ADD_LIBRARY(cmexpat ${expat_SRCS})
|
||||
INSTALL(FILES COPYING DESTINATION ${CMAKE_DOC_DIR}/cmexpat)
|
||||
@@ -1,21 +0,0 @@
|
||||
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
|
||||
and Clark Cooper
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
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,
|
||||
@@ -1,87 +0,0 @@
|
||||
#ifndef cm_expat_mangle_h
|
||||
#define cm_expat_mangle_h
|
||||
|
||||
/*
|
||||
|
||||
This header file mangles all symbols exported from the expat library.
|
||||
It is included in all files while building the expat library. Due to
|
||||
namespace pollution, no expat headers should be included in .h files in
|
||||
CMake.
|
||||
|
||||
The following command was used to obtain the symbol list:
|
||||
|
||||
nm libcmexpat.a |grep " T "
|
||||
|
||||
*/
|
||||
|
||||
#define XML_DefaultCurrent cm_expat_XML_DefaultCurrent
|
||||
#define XML_ErrorString cm_expat_XML_ErrorString
|
||||
#define XML_ExpatVersion cm_expat_XML_ExpatVersion
|
||||
#define XML_ExpatVersionInfo cm_expat_XML_ExpatVersionInfo
|
||||
#define XML_ExternalEntityParserCreate cm_expat_XML_ExternalEntityParserCreate
|
||||
#define XML_GetBase cm_expat_XML_GetBase
|
||||
#define XML_GetBuffer cm_expat_XML_GetBuffer
|
||||
#define XML_GetCurrentByteCount cm_expat_XML_GetCurrentByteCount
|
||||
#define XML_GetCurrentByteIndex cm_expat_XML_GetCurrentByteIndex
|
||||
#define XML_GetCurrentColumnNumber cm_expat_XML_GetCurrentColumnNumber
|
||||
#define XML_GetCurrentLineNumber cm_expat_XML_GetCurrentLineNumber
|
||||
#define XML_GetErrorCode cm_expat_XML_GetErrorCode
|
||||
#define XML_GetIdAttributeIndex cm_expat_XML_GetIdAttributeIndex
|
||||
#define XML_GetInputContext cm_expat_XML_GetInputContext
|
||||
#define XML_GetSpecifiedAttributeCount cm_expat_XML_GetSpecifiedAttributeCount
|
||||
#define XML_Parse cm_expat_XML_Parse
|
||||
#define XML_ParseBuffer cm_expat_XML_ParseBuffer
|
||||
#define XML_ParserCreate cm_expat_XML_ParserCreate
|
||||
#define XML_ParserCreateNS cm_expat_XML_ParserCreateNS
|
||||
#define XML_ParserCreate_MM cm_expat_XML_ParserCreate_MM
|
||||
#define XML_ParserFree cm_expat_XML_ParserFree
|
||||
#define XML_SetAttlistDeclHandler cm_expat_XML_SetAttlistDeclHandler
|
||||
#define XML_SetBase cm_expat_XML_SetBase
|
||||
#define XML_SetCdataSectionHandler cm_expat_XML_SetCdataSectionHandler
|
||||
#define XML_SetCharacterDataHandler cm_expat_XML_SetCharacterDataHandler
|
||||
#define XML_SetCommentHandler cm_expat_XML_SetCommentHandler
|
||||
#define XML_SetDefaultHandler cm_expat_XML_SetDefaultHandler
|
||||
#define XML_SetDefaultHandlerExpand cm_expat_XML_SetDefaultHandlerExpand
|
||||
#define XML_SetDoctypeDeclHandler cm_expat_XML_SetDoctypeDeclHandler
|
||||
#define XML_SetElementDeclHandler cm_expat_XML_SetElementDeclHandler
|
||||
#define XML_SetElementHandler cm_expat_XML_SetElementHandler
|
||||
#define XML_SetEncoding cm_expat_XML_SetEncoding
|
||||
#define XML_SetEndCdataSectionHandler cm_expat_XML_SetEndCdataSectionHandler
|
||||
#define XML_SetEndDoctypeDeclHandler cm_expat_XML_SetEndDoctypeDeclHandler
|
||||
#define XML_SetEndElementHandler cm_expat_XML_SetEndElementHandler
|
||||
#define XML_SetEndNamespaceDeclHandler cm_expat_XML_SetEndNamespaceDeclHandler
|
||||
#define XML_SetEntityDeclHandler cm_expat_XML_SetEntityDeclHandler
|
||||
#define XML_SetExternalEntityRefHandler cm_expat_XML_SetExternalEntityRefHandler
|
||||
#define XML_SetExternalEntityRefHandlerArg cm_expat_XML_SetExternalEntityRefHandlerArg
|
||||
#define XML_SetNamespaceDeclHandler cm_expat_XML_SetNamespaceDeclHandler
|
||||
#define XML_SetNotStandaloneHandler cm_expat_XML_SetNotStandaloneHandler
|
||||
#define XML_SetNotationDeclHandler cm_expat_XML_SetNotationDeclHandler
|
||||
#define XML_SetParamEntityParsing cm_expat_XML_SetParamEntityParsing
|
||||
#define XML_SetProcessingInstructionHandler cm_expat_XML_SetProcessingInstructionHandler
|
||||
#define XML_SetReturnNSTriplet cm_expat_XML_SetReturnNSTriplet
|
||||
#define XML_SetStartCdataSectionHandler cm_expat_XML_SetStartCdataSectionHandler
|
||||
#define XML_SetStartDoctypeDeclHandler cm_expat_XML_SetStartDoctypeDeclHandler
|
||||
#define XML_SetStartElementHandler cm_expat_XML_SetStartElementHandler
|
||||
#define XML_SetStartNamespaceDeclHandler cm_expat_XML_SetStartNamespaceDeclHandler
|
||||
#define XML_SetUnknownEncodingHandler cm_expat_XML_SetUnknownEncodingHandler
|
||||
#define XML_SetUnparsedEntityDeclHandler cm_expat_XML_SetUnparsedEntityDeclHandler
|
||||
#define XML_SetUserData cm_expat_XML_SetUserData
|
||||
#define XML_SetXmlDeclHandler cm_expat_XML_SetXmlDeclHandler
|
||||
#define XML_UseParserAsHandlerArg cm_expat_XML_UseParserAsHandlerArg
|
||||
#define XmlGetUtf16InternalEncoding cm_expat_XmlGetUtf16InternalEncoding
|
||||
#define XmlGetUtf16InternalEncodingNS cm_expat_XmlGetUtf16InternalEncodingNS
|
||||
#define XmlGetUtf8InternalEncoding cm_expat_XmlGetUtf8InternalEncoding
|
||||
#define XmlGetUtf8InternalEncodingNS cm_expat_XmlGetUtf8InternalEncodingNS
|
||||
#define XmlInitEncoding cm_expat_XmlInitEncoding
|
||||
#define XmlInitEncodingNS cm_expat_XmlInitEncodingNS
|
||||
#define XmlInitUnknownEncoding cm_expat_XmlInitUnknownEncoding
|
||||
#define XmlInitUnknownEncodingNS cm_expat_XmlInitUnknownEncodingNS
|
||||
#define XmlParseXmlDecl cm_expat_XmlParseXmlDecl
|
||||
#define XmlParseXmlDeclNS cm_expat_XmlParseXmlDeclNS
|
||||
#define XmlSizeOfUnknownEncoding cm_expat_XmlSizeOfUnknownEncoding
|
||||
#define XmlUtf16Encode cm_expat_XmlUtf16Encode
|
||||
#define XmlUtf8Encode cm_expat_XmlUtf8Encode
|
||||
#define XmlPrologStateInit cm_expat_XmlPrologStateInit
|
||||
#define XmlPrologStateInitExternalEntity cm_expat_XmlPrologStateInitExternalEntity
|
||||
|
||||
#endif
|
||||
@@ -1,740 +0,0 @@
|
||||
#include "cm_expat_mangle.h"
|
||||
/*
|
||||
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#ifndef XmlParse_INCLUDED
|
||||
#define XmlParse_INCLUDED 1
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <cmexpat/expatDllConfig.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(CM_EXPAT_STATIC)
|
||||
# if defined(cmexpat_EXPORTS)
|
||||
# define XMLPARSEAPI(type) __declspec( dllexport ) type __cdecl
|
||||
# else
|
||||
# define XMLPARSEAPI(type) __declspec( dllimport ) type __cdecl
|
||||
# endif
|
||||
#else
|
||||
# define XMLPARSEAPI(type) type
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void *XML_Parser;
|
||||
|
||||
/* Information is UTF-8 encoded. */
|
||||
typedef char XML_Char;
|
||||
typedef char XML_LChar;
|
||||
|
||||
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 (*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 (*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 (*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. When a namespace is not declared,
|
||||
the name and prefix will be passed through without expansion. */
|
||||
|
||||
XMLPARSEAPI(XML_Parser)
|
||||
XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
|
||||
|
||||
|
||||
/* Constructs a new parser using the memory management suit 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);
|
||||
|
||||
/* atts is array of name/value pairs, terminated by 0;
|
||||
names and values are 0 terminated. */
|
||||
|
||||
typedef void (*XML_StartElementHandler)(void *userData,
|
||||
const XML_Char *name,
|
||||
const XML_Char **atts);
|
||||
|
||||
typedef void (*XML_EndElementHandler)(void *userData,
|
||||
const XML_Char *name);
|
||||
|
||||
|
||||
/* s is not 0 terminated. */
|
||||
typedef void (*XML_CharacterDataHandler)(void *userData,
|
||||
const XML_Char *s,
|
||||
int len);
|
||||
|
||||
/* target and data are 0 terminated */
|
||||
typedef void (*XML_ProcessingInstructionHandler)(void *userData,
|
||||
const XML_Char *target,
|
||||
const XML_Char *data);
|
||||
|
||||
/* data is 0 terminated */
|
||||
typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
|
||||
|
||||
typedef void (*XML_StartCdataSectionHandler)(void *userData);
|
||||
typedef void (*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. 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 (*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 (*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 (*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 null 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.
|
||||
*/
|
||||
|
||||
typedef void (*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 (*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 (*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 (*XML_StartNamespaceDeclHandler)(void *userData,
|
||||
const XML_Char *prefix,
|
||||
const XML_Char *uri);
|
||||
|
||||
typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
|
||||
const XML_Char *prefix);
|
||||
|
||||
/* This is called if the document is not standalone (it has an
|
||||
external subset or a reference to a parameter entity, but does not
|
||||
have standalone="yes"). If this handler returns 0, then processing
|
||||
will not continue, and the parser will return a
|
||||
XML_ERROR_NOT_STANDALONE error. */
|
||||
|
||||
typedef int (*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.
|
||||
The handler should return 0 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 (*XML_ExternalEntityRefHandler)(XML_Parser parser,
|
||||
const XML_Char *context,
|
||||
const XML_Char *base,
|
||||
const XML_Char *systemId,
|
||||
const XML_Char *publicId);
|
||||
|
||||
/* 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 (*convert)(void *data, const char *s);
|
||||
void (*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 1.
|
||||
Otherwise it must return 0.
|
||||
If info does not describe a suitable encoding,
|
||||
then the parser will return an XML_UNKNOWN_ENCODING error. */
|
||||
|
||||
typedef int (*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, XML_StartElementHandler);
|
||||
|
||||
XMLPARSEAPI(void)
|
||||
XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler);
|
||||
|
||||
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. The entity reference will be passed to the default
|
||||
handler. */
|
||||
|
||||
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, void *arg);
|
||||
|
||||
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 names
|
||||
has a prefix.
|
||||
*/
|
||||
|
||||
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. It must not be called after XML_Parse
|
||||
or XML_ParseBuffer. */
|
||||
|
||||
XMLPARSEAPI(int)
|
||||
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);
|
||||
|
||||
/* 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 zero if out of memory, non-zero otherwise. */
|
||||
|
||||
XMLPARSEAPI(int)
|
||||
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 0 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). */
|
||||
XMLPARSEAPI(int)
|
||||
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
|
||||
|
||||
XMLPARSEAPI(void *)
|
||||
XML_GetBuffer(XML_Parser parser, int len);
|
||||
|
||||
XMLPARSEAPI(int)
|
||||
XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
|
||||
|
||||
/* 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 0 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. */
|
||||
|
||||
XMLPARSEAPI(int)
|
||||
XML_SetParamEntityParsing(XML_Parser parser,
|
||||
enum XML_ParamEntityParsing parsing);
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
/* If XML_Parse or XML_ParseBuffer have returned 0, 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 when XML_Parse or XML_ParseBuffer return 0;
|
||||
in this case the location is the location of the character at which
|
||||
the error was detected.
|
||||
They may also be called from any other callback called to report
|
||||
some parse event; in this the location is the location of the first
|
||||
of the sequence of characters that generated the event. */
|
||||
|
||||
XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser);
|
||||
XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser);
|
||||
XMLPARSEAPI(long) 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 memory used by the parser. */
|
||||
XMLPARSEAPI(void)
|
||||
XML_ParserFree(XML_Parser parser);
|
||||
|
||||
/* Returns a string describing the error. */
|
||||
XMLPARSEAPI(const XML_LChar *)
|
||||
XML_ErrorString(int 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);
|
||||
|
||||
#define XML_MAJOR_VERSION 1
|
||||
#define XML_MINOR_VERSION 95
|
||||
#define XML_MICRO_VERSION 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not XmlParse_INCLUDED */
|
||||
@@ -1,43 +0,0 @@
|
||||
#include "cm_expat_mangle.h"
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#define XML_BYTE_ORDER 12
|
||||
|
||||
#else
|
||||
|
||||
#cmakedefine CMEXPAT_BIGENDIAN
|
||||
#ifdef CMEXPAT_BIGENDIAN
|
||||
# define XML_BYTE_ORDER 21
|
||||
#else
|
||||
# define XML_BYTE_ORDER 12
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define XML_NS
|
||||
#define XML_DTD
|
||||
#define XML_CONTEXT_BYTES 1024
|
||||
|
||||
#if defined ( _MSC_VER )
|
||||
#pragma warning ( disable : 4100 )
|
||||
#pragma warning ( disable : 4127 )
|
||||
#pragma warning ( disable : 4244 )
|
||||
#pragma warning ( disable : 4251 )
|
||||
#pragma warning ( disable : 4305 )
|
||||
#pragma warning ( disable : 4309 )
|
||||
#pragma warning ( disable : 4702 )
|
||||
#pragma warning ( disable : 4706 )
|
||||
#pragma warning ( disable : 4786 )
|
||||
#pragma warning ( disable : 4057 )
|
||||
#pragma warning ( disable : 4189 )
|
||||
#pragma warning ( disable : 4505 )
|
||||
#endif
|
||||
|
||||
#define VERSION "1.95.2"
|
||||
|
||||
#define cmExpatUnused(x) (void)x
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef _expatDllConfig_h
|
||||
#define _expatDllConfig_h
|
||||
|
||||
#cmakedefine CM_EXPAT_STATIC
|
||||
|
||||
#endif
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
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,
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
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,
|
||||
@@ -1,150 +0,0 @@
|
||||
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,
|
||||
};
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
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,
|
||||
@@ -1,4622 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#include <cmexpat/expatConfig.h>
|
||||
#include <cmexpat/expat.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef XML_UNICODE
|
||||
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
|
||||
#define XmlConvert XmlUtf16Convert
|
||||
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
|
||||
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
|
||||
#define XmlEncode XmlUtf16Encode
|
||||
#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 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_WCHAR_T
|
||||
#define XML_T(x) L ## x
|
||||
#else
|
||||
#define XML_T(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))
|
||||
|
||||
#include "xmltok.h"
|
||||
#include "xmlrole.h"
|
||||
|
||||
typedef const XML_Char *KEY;
|
||||
|
||||
typedef struct {
|
||||
KEY name;
|
||||
} NAMED;
|
||||
|
||||
typedef struct {
|
||||
NAMED **v;
|
||||
size_t size;
|
||||
size_t used;
|
||||
size_t usedLim;
|
||||
XML_Memory_Handling_Suite *mem;
|
||||
} HASH_TABLE;
|
||||
|
||||
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_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;
|
||||
int uriLen;
|
||||
} TAG_NAME;
|
||||
|
||||
typedef struct tag {
|
||||
struct tag *parent;
|
||||
const char *rawName;
|
||||
int rawNameLength;
|
||||
TAG_NAME name;
|
||||
char *buf;
|
||||
char *bufEnd;
|
||||
BINDING *bindings;
|
||||
} TAG;
|
||||
|
||||
typedef struct {
|
||||
const XML_Char *name;
|
||||
const XML_Char *textPtr;
|
||||
int textLen;
|
||||
const XML_Char *systemId;
|
||||
const XML_Char *base;
|
||||
const XML_Char *publicId;
|
||||
const XML_Char *notation;
|
||||
char open;
|
||||
char is_param;
|
||||
} 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;
|
||||
|
||||
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;
|
||||
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;
|
||||
char maybeTokenized;
|
||||
char xmlns;
|
||||
} ATTRIBUTE_ID;
|
||||
|
||||
typedef struct {
|
||||
const ATTRIBUTE_ID *id;
|
||||
char isCdata;
|
||||
const XML_Char *value;
|
||||
} DEFAULT_ATTRIBUTE;
|
||||
|
||||
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;
|
||||
int complete;
|
||||
int standalone;
|
||||
#ifdef XML_DTD
|
||||
HASH_TABLE paramEntities;
|
||||
#endif /* XML_DTD */
|
||||
PREFIX defaultPrefix;
|
||||
/* === scaffolding for building content model === */
|
||||
int 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;
|
||||
} OPEN_INTERNAL_ENTITY;
|
||||
|
||||
typedef enum XML_Error 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;
|
||||
#endif /* XML_DTD */
|
||||
static Processor epilogProcessor;
|
||||
static Processor errorProcessor;
|
||||
static Processor externalEntityInitProcessor;
|
||||
static Processor externalEntityInitProcessor2;
|
||||
static Processor externalEntityInitProcessor3;
|
||||
static Processor externalEntityContentProcessor;
|
||||
|
||||
static enum XML_Error
|
||||
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
|
||||
static enum XML_Error
|
||||
processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
|
||||
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);
|
||||
static enum XML_Error
|
||||
processInternalParamEntity(XML_Parser parser, ENTITY *entity);
|
||||
static enum XML_Error
|
||||
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
|
||||
const char *start, const char *end, const char **endPtr);
|
||||
static enum XML_Error
|
||||
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
|
||||
#ifdef XML_DTD
|
||||
static enum XML_Error
|
||||
doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
|
||||
#endif /* XML_DTD */
|
||||
static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
|
||||
TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
|
||||
static
|
||||
int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
|
||||
|
||||
static int
|
||||
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
|
||||
int isCdata, int isId, const XML_Char *dfltValue,
|
||||
XML_Parser parser);
|
||||
|
||||
static enum XML_Error
|
||||
storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
|
||||
STRING_POOL *);
|
||||
static enum XML_Error
|
||||
appendAttributeValue(XML_Parser parser, const ENCODING *, int 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 int setContext(XML_Parser parser, const XML_Char *context);
|
||||
static void normalizePublicId(XML_Char *s);
|
||||
static int dtdInit(DTD *, XML_Parser parser);
|
||||
|
||||
static void dtdDestroy(DTD *, XML_Parser parser);
|
||||
|
||||
static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
|
||||
|
||||
static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
|
||||
XML_Parser parser);
|
||||
|
||||
#ifdef XML_DTD
|
||||
static void dtdSwap(DTD *, DTD *);
|
||||
#endif /* XML_DTD */
|
||||
|
||||
static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
|
||||
|
||||
static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
|
||||
|
||||
static void hashTableDestroy(HASH_TABLE *);
|
||||
static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
|
||||
static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
|
||||
static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
|
||||
static void poolClear(STRING_POOL *);
|
||||
static void 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 int poolGrow(STRING_POOL *pool);
|
||||
|
||||
static int nextScaffoldPart(XML_Parser parser);
|
||||
static XML_Content *build_model(XML_Parser parser);
|
||||
|
||||
static const XML_Char *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 *poolAppendString(STRING_POOL *pool, const XML_Char *s);
|
||||
static ELEMENT_TYPE * getElementType(XML_Parser Paraser,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end);
|
||||
|
||||
#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))
|
||||
|
||||
typedef struct {
|
||||
/* The first member must be userData so that the XML_GetUserData macro works. */
|
||||
void *m_userData;
|
||||
void *m_handlerArg;
|
||||
char *m_buffer;
|
||||
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;
|
||||
long 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;
|
||||
void *m_externalEntityRefHandlerArg;
|
||||
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;
|
||||
int m_ns;
|
||||
int m_ns_triplets;
|
||||
void *m_unknownEncodingMem;
|
||||
void *m_unknownEncodingData;
|
||||
void *m_unknownEncodingHandlerData;
|
||||
void (*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;
|
||||
int 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;
|
||||
char m_declAttributeIsCdata;
|
||||
char 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;
|
||||
POSITION m_position;
|
||||
STRING_POOL m_tempPool;
|
||||
STRING_POOL m_temp2Pool;
|
||||
char *m_groupConnector;
|
||||
unsigned m_groupSize;
|
||||
int m_hadExternalDoctype;
|
||||
XML_Char m_namespaceSeparator;
|
||||
#ifdef XML_DTD
|
||||
enum XML_ParamEntityParsing m_paramEntityParsing;
|
||||
XML_Parser m_parentParser;
|
||||
#endif
|
||||
} Parser;
|
||||
|
||||
#define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
|
||||
#define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
|
||||
#define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
|
||||
|
||||
#define userData (((Parser *)parser)->m_userData)
|
||||
#define handlerArg (((Parser *)parser)->m_handlerArg)
|
||||
#define startElementHandler (((Parser *)parser)->m_startElementHandler)
|
||||
#define endElementHandler (((Parser *)parser)->m_endElementHandler)
|
||||
#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
|
||||
#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
|
||||
#define commentHandler (((Parser *)parser)->m_commentHandler)
|
||||
#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
|
||||
#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
|
||||
#define defaultHandler (((Parser *)parser)->m_defaultHandler)
|
||||
#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
|
||||
#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
|
||||
#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
|
||||
#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
|
||||
#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
|
||||
#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
|
||||
#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
|
||||
#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
|
||||
#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
|
||||
#define internalEntityRefHandler (((Parser *)parser)->m_internalEntityRefHandler)
|
||||
#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
|
||||
#define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
|
||||
#define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
|
||||
#define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
|
||||
#define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
|
||||
#define encoding (((Parser *)parser)->m_encoding)
|
||||
#define initEncoding (((Parser *)parser)->m_initEncoding)
|
||||
#define internalEncoding (((Parser *)parser)->m_internalEncoding)
|
||||
#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
|
||||
#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
|
||||
#define unknownEncodingHandlerData \
|
||||
(((Parser *)parser)->m_unknownEncodingHandlerData)
|
||||
#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
|
||||
#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
|
||||
#define ns (((Parser *)parser)->m_ns)
|
||||
#define ns_triplets (((Parser *)parser)->m_ns_triplets)
|
||||
#define prologState (((Parser *)parser)->m_prologState)
|
||||
#define processor (((Parser *)parser)->m_processor)
|
||||
#define errorCode (((Parser *)parser)->m_errorCode)
|
||||
#define eventPtr (((Parser *)parser)->m_eventPtr)
|
||||
#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
|
||||
#define positionPtr (((Parser *)parser)->m_positionPtr)
|
||||
#define position (((Parser *)parser)->m_position)
|
||||
#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
|
||||
#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
|
||||
#define tagLevel (((Parser *)parser)->m_tagLevel)
|
||||
#define buffer (((Parser *)parser)->m_buffer)
|
||||
#define bufferPtr (((Parser *)parser)->m_bufferPtr)
|
||||
#define bufferEnd (((Parser *)parser)->m_bufferEnd)
|
||||
#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
|
||||
#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
|
||||
#define bufferLim (((Parser *)parser)->m_bufferLim)
|
||||
#define dataBuf (((Parser *)parser)->m_dataBuf)
|
||||
#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
|
||||
#define dtd (((Parser *)parser)->m_dtd)
|
||||
#define curBase (((Parser *)parser)->m_curBase)
|
||||
#define declEntity (((Parser *)parser)->m_declEntity)
|
||||
#define doctypeName (((Parser *)parser)->m_doctypeName)
|
||||
#define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
|
||||
#define doctypePubid (((Parser *)parser)->m_doctypePubid)
|
||||
#define declAttributeType (((Parser *)parser)->m_declAttributeType)
|
||||
#define declNotationName (((Parser *)parser)->m_declNotationName)
|
||||
#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
|
||||
#define declElementType (((Parser *)parser)->m_declElementType)
|
||||
#define declAttributeId (((Parser *)parser)->m_declAttributeId)
|
||||
#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
|
||||
#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
|
||||
#define freeTagList (((Parser *)parser)->m_freeTagList)
|
||||
#define freeBindingList (((Parser *)parser)->m_freeBindingList)
|
||||
#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
|
||||
#define tagStack (((Parser *)parser)->m_tagStack)
|
||||
#define atts (((Parser *)parser)->m_atts)
|
||||
#define attsSize (((Parser *)parser)->m_attsSize)
|
||||
#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
|
||||
#define idAttIndex (((Parser *)parser)->m_idAttIndex)
|
||||
#define tempPool (((Parser *)parser)->m_tempPool)
|
||||
#define temp2Pool (((Parser *)parser)->m_temp2Pool)
|
||||
#define groupConnector (((Parser *)parser)->m_groupConnector)
|
||||
#define groupSize (((Parser *)parser)->m_groupSize)
|
||||
#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
|
||||
#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
|
||||
#ifdef XML_DTD
|
||||
#define parentParser (((Parser *)parser)->m_parentParser)
|
||||
#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
|
||||
#endif /* XML_DTD */
|
||||
|
||||
#ifdef COMPILED_FROM_DSP
|
||||
BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* def COMPILED_FROM_DSP */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _DEBUG
|
||||
Parser *asParser(XML_Parser parser)
|
||||
{
|
||||
return parser;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
XML_Parser XML_ParserCreate(const XML_Char *encodingName)
|
||||
{
|
||||
return XML_ParserCreate_MM(encodingName, NULL, NULL);
|
||||
}
|
||||
|
||||
XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
|
||||
{
|
||||
XML_Char tmp[2];
|
||||
*tmp = nsSep;
|
||||
return XML_ParserCreate_MM(encodingName, NULL, tmp);
|
||||
}
|
||||
|
||||
XML_Parser
|
||||
XML_ParserCreate_MM(const XML_Char *encodingName,
|
||||
const XML_Memory_Handling_Suite *memsuite,
|
||||
const XML_Char *nameSep) {
|
||||
|
||||
XML_Parser parser;
|
||||
static
|
||||
const XML_Char implicitContext[] = {
|
||||
XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
|
||||
XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
|
||||
XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
|
||||
XML_T('.'), XML_T('w'), XML_T('3'),
|
||||
XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
|
||||
XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
|
||||
XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
|
||||
XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
|
||||
XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
|
||||
XML_T('\0')
|
||||
};
|
||||
|
||||
|
||||
if (memsuite) {
|
||||
XML_Memory_Handling_Suite *mtemp;
|
||||
parser = memsuite->malloc_fcn(sizeof(Parser));
|
||||
mtemp = &(((Parser *) 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 = malloc(sizeof(Parser));
|
||||
mtemp = &(((Parser *) parser)->m_mem);
|
||||
mtemp->malloc_fcn = malloc;
|
||||
mtemp->realloc_fcn = realloc;
|
||||
mtemp->free_fcn = free;
|
||||
}
|
||||
|
||||
if (!parser)
|
||||
return parser;
|
||||
processor = prologInitProcessor;
|
||||
XmlPrologStateInit(&prologState);
|
||||
userData = 0;
|
||||
handlerArg = 0;
|
||||
startElementHandler = 0;
|
||||
endElementHandler = 0;
|
||||
characterDataHandler = 0;
|
||||
processingInstructionHandler = 0;
|
||||
commentHandler = 0;
|
||||
startCdataSectionHandler = 0;
|
||||
endCdataSectionHandler = 0;
|
||||
defaultHandler = 0;
|
||||
startDoctypeDeclHandler = 0;
|
||||
endDoctypeDeclHandler = 0;
|
||||
unparsedEntityDeclHandler = 0;
|
||||
notationDeclHandler = 0;
|
||||
startNamespaceDeclHandler = 0;
|
||||
endNamespaceDeclHandler = 0;
|
||||
notStandaloneHandler = 0;
|
||||
externalEntityRefHandler = 0;
|
||||
externalEntityRefHandlerArg = parser;
|
||||
unknownEncodingHandler = 0;
|
||||
elementDeclHandler = 0;
|
||||
attlistDeclHandler = 0;
|
||||
entityDeclHandler = 0;
|
||||
xmlDeclHandler = 0;
|
||||
buffer = 0;
|
||||
bufferPtr = 0;
|
||||
bufferEnd = 0;
|
||||
parseEndByteIndex = 0;
|
||||
parseEndPtr = 0;
|
||||
bufferLim = 0;
|
||||
declElementType = 0;
|
||||
declAttributeId = 0;
|
||||
declEntity = 0;
|
||||
doctypeName = 0;
|
||||
doctypeSysid = 0;
|
||||
doctypePubid = 0;
|
||||
declAttributeType = 0;
|
||||
declNotationName = 0;
|
||||
declNotationPublicId = 0;
|
||||
memset(&position, 0, sizeof(POSITION));
|
||||
errorCode = XML_ERROR_NONE;
|
||||
eventPtr = 0;
|
||||
eventEndPtr = 0;
|
||||
positionPtr = 0;
|
||||
openInternalEntities = 0;
|
||||
tagLevel = 0;
|
||||
tagStack = 0;
|
||||
freeTagList = 0;
|
||||
freeBindingList = 0;
|
||||
inheritedBindings = 0;
|
||||
attsSize = INIT_ATTS_SIZE;
|
||||
atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
|
||||
nSpecifiedAtts = 0;
|
||||
dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
|
||||
groupSize = 0;
|
||||
groupConnector = 0;
|
||||
hadExternalDoctype = 0;
|
||||
unknownEncodingMem = 0;
|
||||
unknownEncodingRelease = 0;
|
||||
unknownEncodingData = 0;
|
||||
unknownEncodingHandlerData = 0;
|
||||
namespaceSeparator = '!';
|
||||
#ifdef XML_DTD
|
||||
parentParser = 0;
|
||||
paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
|
||||
#endif
|
||||
ns = 0;
|
||||
ns_triplets = 0;
|
||||
poolInit(&tempPool, &(((Parser *) parser)->m_mem));
|
||||
poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
|
||||
protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
|
||||
curBase = 0;
|
||||
if (!dtdInit(&dtd, parser) || !atts || !dataBuf
|
||||
|| (encodingName && !protocolEncodingName)) {
|
||||
XML_ParserFree(parser);
|
||||
return 0;
|
||||
}
|
||||
dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
|
||||
|
||||
if (nameSep) {
|
||||
XmlInitEncodingNS(&initEncoding, &encoding, 0);
|
||||
ns = 1;
|
||||
internalEncoding = XmlGetInternalEncodingNS();
|
||||
namespaceSeparator = *nameSep;
|
||||
|
||||
if (! setContext(parser, implicitContext)) {
|
||||
XML_ParserFree(parser);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
XmlInitEncoding(&initEncoding, &encoding, 0);
|
||||
internalEncoding = XmlGetInternalEncoding();
|
||||
}
|
||||
|
||||
return parser;
|
||||
} /* End XML_ParserCreate_MM */
|
||||
|
||||
int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
|
||||
{
|
||||
if (!encodingName)
|
||||
protocolEncodingName = 0;
|
||||
else {
|
||||
protocolEncodingName = poolCopyString(&tempPool, encodingName);
|
||||
if (!protocolEncodingName)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
|
||||
const XML_Char *context,
|
||||
const XML_Char *encodingName)
|
||||
{
|
||||
XML_Parser parser = oldParser;
|
||||
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_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;
|
||||
int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
|
||||
void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
|
||||
#ifdef XML_DTD
|
||||
enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
|
||||
#endif
|
||||
int oldns_triplets = ns_triplets;
|
||||
|
||||
if (ns) {
|
||||
XML_Char tmp[2];
|
||||
|
||||
*tmp = namespaceSeparator;
|
||||
parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
|
||||
tmp);
|
||||
}
|
||||
else {
|
||||
parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!parser)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
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;
|
||||
#ifdef XML_DTD
|
||||
paramEntityParsing = oldParamEntityParsing;
|
||||
if (context) {
|
||||
#endif /* XML_DTD */
|
||||
if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
|
||||
XML_ParserFree(parser);
|
||||
return 0;
|
||||
}
|
||||
processor = externalEntityInitProcessor;
|
||||
#ifdef XML_DTD
|
||||
}
|
||||
else {
|
||||
dtdSwap(&dtd, oldDtd);
|
||||
parentParser = oldParser;
|
||||
XmlPrologStateInitExternalEntity(&prologState);
|
||||
dtd.complete = 1;
|
||||
hadExternalDoctype = 1;
|
||||
}
|
||||
#endif /* XML_DTD */
|
||||
return parser;
|
||||
}
|
||||
|
||||
static
|
||||
void destroyBindings(BINDING *bindings, XML_Parser parser)
|
||||
{
|
||||
for (;;) {
|
||||
BINDING *b = bindings;
|
||||
if (!b)
|
||||
break;
|
||||
bindings = b->nextTagBinding;
|
||||
FREE(b->uri);
|
||||
FREE(b);
|
||||
}
|
||||
}
|
||||
|
||||
void XML_ParserFree(XML_Parser parser)
|
||||
{
|
||||
for (;;) {
|
||||
TAG *p;
|
||||
if (tagStack == 0) {
|
||||
if (freeTagList == 0)
|
||||
break;
|
||||
tagStack = freeTagList;
|
||||
freeTagList = 0;
|
||||
}
|
||||
p = tagStack;
|
||||
tagStack = tagStack->parent;
|
||||
FREE(p->buf);
|
||||
destroyBindings(p->bindings, parser);
|
||||
FREE(p);
|
||||
}
|
||||
destroyBindings(freeBindingList, parser);
|
||||
destroyBindings(inheritedBindings, parser);
|
||||
poolDestroy(&tempPool);
|
||||
poolDestroy(&temp2Pool);
|
||||
#ifdef XML_DTD
|
||||
if (parentParser) {
|
||||
if (hadExternalDoctype)
|
||||
dtd.complete = 0;
|
||||
dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
|
||||
}
|
||||
#endif /* XML_DTD */
|
||||
dtdDestroy(&dtd, parser);
|
||||
FREE((void *)atts);
|
||||
if (groupConnector)
|
||||
FREE(groupConnector);
|
||||
if (buffer)
|
||||
FREE(buffer);
|
||||
FREE(dataBuf);
|
||||
if (unknownEncodingMem)
|
||||
FREE(unknownEncodingMem);
|
||||
if (unknownEncodingRelease)
|
||||
unknownEncodingRelease(unknownEncodingData);
|
||||
FREE(parser);
|
||||
}
|
||||
|
||||
void XML_UseParserAsHandlerArg(XML_Parser parser)
|
||||
{
|
||||
handlerArg = parser;
|
||||
}
|
||||
|
||||
void
|
||||
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
|
||||
ns_triplets = do_nst;
|
||||
}
|
||||
|
||||
void XML_SetUserData(XML_Parser parser, void *p)
|
||||
{
|
||||
if (handlerArg == userData)
|
||||
handlerArg = userData = p;
|
||||
else
|
||||
userData = p;
|
||||
}
|
||||
|
||||
int XML_SetBase(XML_Parser parser, const XML_Char *p)
|
||||
{
|
||||
if (p) {
|
||||
p = poolCopyString(&dtd.pool, p);
|
||||
if (!p)
|
||||
return 0;
|
||||
curBase = p;
|
||||
}
|
||||
else
|
||||
curBase = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const XML_Char *XML_GetBase(XML_Parser parser)
|
||||
{
|
||||
return curBase;
|
||||
}
|
||||
|
||||
int XML_GetSpecifiedAttributeCount(XML_Parser parser)
|
||||
{
|
||||
return nSpecifiedAtts;
|
||||
}
|
||||
|
||||
int XML_GetIdAttributeIndex(XML_Parser parser)
|
||||
{
|
||||
return idAttIndex;
|
||||
}
|
||||
|
||||
void XML_SetElementHandler(XML_Parser parser,
|
||||
XML_StartElementHandler start,
|
||||
XML_EndElementHandler end)
|
||||
{
|
||||
startElementHandler = start;
|
||||
endElementHandler = end;
|
||||
}
|
||||
|
||||
void XML_SetStartElementHandler(XML_Parser parser,
|
||||
XML_StartElementHandler start) {
|
||||
startElementHandler = start;
|
||||
}
|
||||
|
||||
void XML_SetEndElementHandler(XML_Parser parser,
|
||||
XML_EndElementHandler end) {
|
||||
endElementHandler = end;
|
||||
}
|
||||
|
||||
void XML_SetCharacterDataHandler(XML_Parser parser,
|
||||
XML_CharacterDataHandler handler)
|
||||
{
|
||||
characterDataHandler = handler;
|
||||
}
|
||||
|
||||
void XML_SetProcessingInstructionHandler(XML_Parser parser,
|
||||
XML_ProcessingInstructionHandler handler)
|
||||
{
|
||||
processingInstructionHandler = handler;
|
||||
}
|
||||
|
||||
void XML_SetCommentHandler(XML_Parser parser,
|
||||
XML_CommentHandler handler)
|
||||
{
|
||||
commentHandler = handler;
|
||||
}
|
||||
|
||||
void XML_SetCdataSectionHandler(XML_Parser parser,
|
||||
XML_StartCdataSectionHandler start,
|
||||
XML_EndCdataSectionHandler end)
|
||||
{
|
||||
startCdataSectionHandler = start;
|
||||
endCdataSectionHandler = end;
|
||||
}
|
||||
|
||||
void XML_SetStartCdataSectionHandler(XML_Parser parser,
|
||||
XML_StartCdataSectionHandler start) {
|
||||
startCdataSectionHandler = start;
|
||||
}
|
||||
|
||||
void XML_SetEndCdataSectionHandler(XML_Parser parser,
|
||||
XML_EndCdataSectionHandler end) {
|
||||
endCdataSectionHandler = end;
|
||||
}
|
||||
|
||||
void XML_SetDefaultHandler(XML_Parser parser,
|
||||
XML_DefaultHandler handler)
|
||||
{
|
||||
defaultHandler = handler;
|
||||
defaultExpandInternalEntities = 0;
|
||||
}
|
||||
|
||||
void XML_SetDefaultHandlerExpand(XML_Parser parser,
|
||||
XML_DefaultHandler handler)
|
||||
{
|
||||
defaultHandler = handler;
|
||||
defaultExpandInternalEntities = 1;
|
||||
}
|
||||
|
||||
void XML_SetDoctypeDeclHandler(XML_Parser parser,
|
||||
XML_StartDoctypeDeclHandler start,
|
||||
XML_EndDoctypeDeclHandler end)
|
||||
{
|
||||
startDoctypeDeclHandler = start;
|
||||
endDoctypeDeclHandler = end;
|
||||
}
|
||||
|
||||
void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
|
||||
XML_StartDoctypeDeclHandler start) {
|
||||
startDoctypeDeclHandler = start;
|
||||
}
|
||||
|
||||
void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
|
||||
XML_EndDoctypeDeclHandler end) {
|
||||
endDoctypeDeclHandler = end;
|
||||
}
|
||||
|
||||
void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
|
||||
XML_UnparsedEntityDeclHandler handler)
|
||||
{
|
||||
unparsedEntityDeclHandler = handler;
|
||||
}
|
||||
|
||||
void XML_SetNotationDeclHandler(XML_Parser parser,
|
||||
XML_NotationDeclHandler handler)
|
||||
{
|
||||
notationDeclHandler = handler;
|
||||
}
|
||||
|
||||
void XML_SetNamespaceDeclHandler(XML_Parser parser,
|
||||
XML_StartNamespaceDeclHandler start,
|
||||
XML_EndNamespaceDeclHandler end)
|
||||
{
|
||||
startNamespaceDeclHandler = start;
|
||||
endNamespaceDeclHandler = end;
|
||||
}
|
||||
|
||||
void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
|
||||
XML_StartNamespaceDeclHandler start) {
|
||||
startNamespaceDeclHandler = start;
|
||||
}
|
||||
|
||||
void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
|
||||
XML_EndNamespaceDeclHandler end) {
|
||||
endNamespaceDeclHandler = end;
|
||||
}
|
||||
|
||||
|
||||
void XML_SetNotStandaloneHandler(XML_Parser parser,
|
||||
XML_NotStandaloneHandler handler)
|
||||
{
|
||||
notStandaloneHandler = handler;
|
||||
}
|
||||
|
||||
void XML_SetExternalEntityRefHandler(XML_Parser parser,
|
||||
XML_ExternalEntityRefHandler handler)
|
||||
{
|
||||
externalEntityRefHandler = handler;
|
||||
}
|
||||
|
||||
void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
|
||||
{
|
||||
if (arg)
|
||||
externalEntityRefHandlerArg = arg;
|
||||
else
|
||||
externalEntityRefHandlerArg = parser;
|
||||
}
|
||||
|
||||
void XML_SetUnknownEncodingHandler(XML_Parser parser,
|
||||
XML_UnknownEncodingHandler handler,
|
||||
void *data)
|
||||
{
|
||||
unknownEncodingHandler = handler;
|
||||
unknownEncodingHandlerData = data;
|
||||
}
|
||||
|
||||
void XML_SetElementDeclHandler(XML_Parser parser,
|
||||
XML_ElementDeclHandler eldecl)
|
||||
{
|
||||
elementDeclHandler = eldecl;
|
||||
}
|
||||
|
||||
void XML_SetAttlistDeclHandler(XML_Parser parser,
|
||||
XML_AttlistDeclHandler attdecl)
|
||||
{
|
||||
attlistDeclHandler = attdecl;
|
||||
}
|
||||
|
||||
void XML_SetEntityDeclHandler(XML_Parser parser,
|
||||
XML_EntityDeclHandler handler)
|
||||
{
|
||||
entityDeclHandler = handler;
|
||||
}
|
||||
|
||||
void XML_SetXmlDeclHandler(XML_Parser parser,
|
||||
XML_XmlDeclHandler handler) {
|
||||
xmlDeclHandler = handler;
|
||||
}
|
||||
|
||||
int XML_SetParamEntityParsing(XML_Parser parser,
|
||||
enum XML_ParamEntityParsing parsing)
|
||||
{
|
||||
#ifdef XML_DTD
|
||||
paramEntityParsing = parsing;
|
||||
return 1;
|
||||
#else
|
||||
return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
|
||||
#endif
|
||||
}
|
||||
|
||||
int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
|
||||
{
|
||||
if (len == 0) {
|
||||
if (!isFinal)
|
||||
return 1;
|
||||
positionPtr = bufferPtr;
|
||||
errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
|
||||
if (errorCode == XML_ERROR_NONE)
|
||||
return 1;
|
||||
eventEndPtr = eventPtr;
|
||||
processor = errorProcessor;
|
||||
return 0;
|
||||
}
|
||||
#ifndef XML_CONTEXT_BYTES
|
||||
else if (bufferPtr == bufferEnd) {
|
||||
const char *end;
|
||||
int nLeftOver;
|
||||
parseEndByteIndex += len;
|
||||
positionPtr = s;
|
||||
if (isFinal) {
|
||||
errorCode = processor(parser, s, parseEndPtr = s + len, 0);
|
||||
if (errorCode == XML_ERROR_NONE)
|
||||
return 1;
|
||||
eventEndPtr = eventPtr;
|
||||
processor = errorProcessor;
|
||||
return 0;
|
||||
}
|
||||
errorCode = processor(parser, s, parseEndPtr = s + len, &end);
|
||||
if (errorCode != XML_ERROR_NONE) {
|
||||
eventEndPtr = eventPtr;
|
||||
processor = errorProcessor;
|
||||
return 0;
|
||||
}
|
||||
XmlUpdatePosition(encoding, positionPtr, end, &position);
|
||||
nLeftOver = s + len - end;
|
||||
if (nLeftOver) {
|
||||
if (buffer == 0 || nLeftOver > bufferLim - buffer) {
|
||||
/* FIXME avoid integer overflow */
|
||||
buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
|
||||
/* FIXME storage leak if realloc fails */
|
||||
if (!buffer) {
|
||||
errorCode = XML_ERROR_NO_MEMORY;
|
||||
eventPtr = eventEndPtr = 0;
|
||||
processor = errorProcessor;
|
||||
return 0;
|
||||
}
|
||||
bufferLim = buffer + len * 2;
|
||||
}
|
||||
memcpy(buffer, end, nLeftOver);
|
||||
bufferPtr = buffer;
|
||||
bufferEnd = buffer + nLeftOver;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif /* not defined XML_CONTEXT_BYTES */
|
||||
else {
|
||||
memcpy(XML_GetBuffer(parser, len), s, len);
|
||||
return XML_ParseBuffer(parser, len, isFinal);
|
||||
}
|
||||
}
|
||||
|
||||
int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
|
||||
{
|
||||
const char *start = bufferPtr;
|
||||
positionPtr = start;
|
||||
bufferEnd += len;
|
||||
parseEndByteIndex += len;
|
||||
errorCode = processor(parser, start, parseEndPtr = bufferEnd,
|
||||
isFinal ? (const char **)0 : &bufferPtr);
|
||||
if (errorCode == XML_ERROR_NONE) {
|
||||
if (!isFinal)
|
||||
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
eventEndPtr = eventPtr;
|
||||
processor = errorProcessor;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *XML_GetBuffer(XML_Parser parser, int len)
|
||||
{
|
||||
if (len > bufferLim - bufferEnd) {
|
||||
/* FIXME avoid integer overflow */
|
||||
int neededSize = len + (bufferEnd - bufferPtr);
|
||||
#ifdef XML_CONTEXT_BYTES
|
||||
int keep = 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 = (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 = bufferLim - bufferPtr;
|
||||
if (bufferSize == 0)
|
||||
bufferSize = INIT_BUFFER_SIZE;
|
||||
do {
|
||||
bufferSize *= 2;
|
||||
} while (bufferSize < neededSize);
|
||||
newBuf = MALLOC(bufferSize);
|
||||
if (newBuf == 0) {
|
||||
errorCode = XML_ERROR_NO_MEMORY;
|
||||
return 0;
|
||||
}
|
||||
bufferLim = newBuf + bufferSize;
|
||||
#ifdef XML_CONTEXT_BYTES
|
||||
if (bufferPtr) {
|
||||
int xmKeep = bufferPtr - buffer;
|
||||
if (xmKeep > XML_CONTEXT_BYTES)
|
||||
xmKeep = XML_CONTEXT_BYTES;
|
||||
memcpy(newBuf, &bufferPtr[-xmKeep], bufferEnd - bufferPtr + xmKeep);
|
||||
FREE(buffer);
|
||||
buffer = newBuf;
|
||||
bufferEnd = buffer + (bufferEnd - bufferPtr) + xmKeep;
|
||||
bufferPtr = buffer + xmKeep;
|
||||
}
|
||||
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_Error XML_GetErrorCode(XML_Parser parser)
|
||||
{
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
long XML_GetCurrentByteIndex(XML_Parser parser)
|
||||
{
|
||||
if (eventPtr)
|
||||
return parseEndByteIndex - (parseEndPtr - eventPtr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int XML_GetCurrentByteCount(XML_Parser parser)
|
||||
{
|
||||
if (eventEndPtr && eventPtr)
|
||||
return eventEndPtr - eventPtr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
|
||||
{
|
||||
#ifdef XML_CONTEXT_BYTES
|
||||
if (eventPtr && buffer) {
|
||||
*offset = eventPtr - buffer;
|
||||
*size = bufferEnd - buffer;
|
||||
return buffer;
|
||||
}
|
||||
#endif /* defined XML_CONTEXT_BYTES */
|
||||
return (char *) 0;
|
||||
}
|
||||
|
||||
int XML_GetCurrentLineNumber(XML_Parser parser)
|
||||
{
|
||||
if (eventPtr) {
|
||||
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
|
||||
positionPtr = eventPtr;
|
||||
}
|
||||
return position.lineNumber + 1;
|
||||
}
|
||||
|
||||
int XML_GetCurrentColumnNumber(XML_Parser parser)
|
||||
{
|
||||
if (eventPtr) {
|
||||
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
|
||||
positionPtr = eventPtr;
|
||||
}
|
||||
return position.columnNumber;
|
||||
}
|
||||
|
||||
void 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 *XML_ErrorString(int code)
|
||||
{
|
||||
static const XML_LChar *message[] = {
|
||||
0,
|
||||
XML_T("out of memory"),
|
||||
XML_T("syntax error"),
|
||||
XML_T("no element found"),
|
||||
XML_T("not well-formed (invalid token)"),
|
||||
XML_T("unclosed token"),
|
||||
XML_T("unclosed token"),
|
||||
XML_T("mismatched tag"),
|
||||
XML_T("duplicate attribute"),
|
||||
XML_T("junk after document element"),
|
||||
XML_T("illegal parameter entity reference"),
|
||||
XML_T("undefined entity"),
|
||||
XML_T("recursive entity reference"),
|
||||
XML_T("asynchronous entity"),
|
||||
XML_T("reference to invalid character number"),
|
||||
XML_T("reference to binary entity"),
|
||||
XML_T("reference to external entity in attribute"),
|
||||
XML_T("xml processing instruction not at start of external entity"),
|
||||
XML_T("unknown encoding"),
|
||||
XML_T("encoding specified in XML declaration is incorrect"),
|
||||
XML_T("unclosed CDATA section"),
|
||||
XML_T("error in processing external entity reference"),
|
||||
XML_T("document is not standalone"),
|
||||
XML_T("unexpected parser state - please send a bug report")
|
||||
};
|
||||
if (code > 0 && code < (int)(sizeof(message)/sizeof(message[0])))
|
||||
return message[code];
|
||||
return 0;
|
||||
}
|
||||
|
||||
const XML_LChar *
|
||||
XML_ExpatVersion(void) {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
XML_Expat_Version
|
||||
XML_ExpatVersionInfo(void) {
|
||||
XML_Expat_Version version;
|
||||
|
||||
version.major = XML_MAJOR_VERSION;
|
||||
version.minor = XML_MINOR_VERSION;
|
||||
version.micro = XML_MICRO_VERSION;
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
static
|
||||
enum XML_Error contentProcessor(XML_Parser parser,
|
||||
const char *start,
|
||||
const char *end,
|
||||
const char **endPtr)
|
||||
{
|
||||
return doContent(parser, 0, encoding, start, end, endPtr);
|
||||
}
|
||||
|
||||
static
|
||||
enum XML_Error 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 externalEntityInitProcessor2(XML_Parser parser,
|
||||
const char *start,
|
||||
const char *end,
|
||||
const char **endPtr)
|
||||
{
|
||||
const char *next;
|
||||
int tok = XmlContentTok(encoding, start, end, &next);
|
||||
switch (tok) {
|
||||
case XML_TOK_BOM:
|
||||
start = next;
|
||||
break;
|
||||
case XML_TOK_PARTIAL:
|
||||
if (endPtr) {
|
||||
*endPtr = start;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
eventPtr = start;
|
||||
return XML_ERROR_UNCLOSED_TOKEN;
|
||||
case XML_TOK_PARTIAL_CHAR:
|
||||
if (endPtr) {
|
||||
*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 externalEntityInitProcessor3(XML_Parser parser,
|
||||
const char *start,
|
||||
const char *end,
|
||||
const char **endPtr)
|
||||
{
|
||||
const char *next;
|
||||
int tok = XmlContentTok(encoding, start, end, &next);
|
||||
switch (tok) {
|
||||
case XML_TOK_XML_DECL:
|
||||
{
|
||||
enum XML_Error result = processXmlDecl(parser, 1, start, next);
|
||||
if (result != XML_ERROR_NONE)
|
||||
return result;
|
||||
start = next;
|
||||
}
|
||||
break;
|
||||
case XML_TOK_PARTIAL:
|
||||
if (endPtr) {
|
||||
*endPtr = start;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
eventPtr = start;
|
||||
return XML_ERROR_UNCLOSED_TOKEN;
|
||||
case XML_TOK_PARTIAL_CHAR:
|
||||
if (endPtr) {
|
||||
*endPtr = start;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
eventPtr = start;
|
||||
return XML_ERROR_PARTIAL_CHAR;
|
||||
}
|
||||
processor = externalEntityContentProcessor;
|
||||
tagLevel = 1;
|
||||
return doContent(parser, 1, encoding, start, end, endPtr);
|
||||
}
|
||||
|
||||
static
|
||||
enum XML_Error externalEntityContentProcessor(XML_Parser parser,
|
||||
const char *start,
|
||||
const char *end,
|
||||
const char **endPtr)
|
||||
{
|
||||
return doContent(parser, 1, encoding, start, end, endPtr);
|
||||
}
|
||||
|
||||
static enum XML_Error
|
||||
doContent(XML_Parser parser,
|
||||
int startTagLevel,
|
||||
const ENCODING *enc,
|
||||
const char *s,
|
||||
const char *end,
|
||||
const char **nextPtr)
|
||||
{
|
||||
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 (nextPtr) {
|
||||
*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);
|
||||
if (startTagLevel == 0)
|
||||
return XML_ERROR_NO_ELEMENTS;
|
||||
if (tagLevel != startTagLevel)
|
||||
return XML_ERROR_ASYNC_ENTITY;
|
||||
return XML_ERROR_NONE;
|
||||
case XML_TOK_NONE:
|
||||
if (nextPtr) {
|
||||
*nextPtr = s;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
if (startTagLevel > 0) {
|
||||
if (tagLevel != startTagLevel)
|
||||
return XML_ERROR_ASYNC_ENTITY;
|
||||
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 (nextPtr) {
|
||||
*nextPtr = s;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
return XML_ERROR_UNCLOSED_TOKEN;
|
||||
case XML_TOK_PARTIAL_CHAR:
|
||||
if (nextPtr) {
|
||||
*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 = 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);
|
||||
if (!entity) {
|
||||
if (dtd.complete || dtd.standalone)
|
||||
return XML_ERROR_UNDEFINED_ENTITY;
|
||||
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) {
|
||||
if (entity->textPtr) {
|
||||
enum XML_Error result;
|
||||
OPEN_INTERNAL_ENTITY openEntity;
|
||||
if (defaultHandler && !defaultExpandInternalEntities) {
|
||||
reportDefault(parser, enc, s, next);
|
||||
break;
|
||||
}
|
||||
entity->open = 1;
|
||||
openEntity.next = openInternalEntities;
|
||||
openInternalEntities = &openEntity;
|
||||
openEntity.entity = entity;
|
||||
openEntity.internalEventPtr = 0;
|
||||
openEntity.internalEventEndPtr = 0;
|
||||
result = doContent(parser,
|
||||
tagLevel,
|
||||
internalEncoding,
|
||||
(char *)entity->textPtr,
|
||||
(char *)(entity->textPtr + entity->textLen),
|
||||
0);
|
||||
entity->open = 0;
|
||||
openInternalEntities = openEntity.next;
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
else if (externalEntityRefHandler) {
|
||||
const XML_Char *context;
|
||||
entity->open = 1;
|
||||
context = getContext(parser);
|
||||
entity->open = 0;
|
||||
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_WITH_ATTS:
|
||||
if (!startElementHandler) {
|
||||
enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
/* fall through */
|
||||
case XML_TOK_START_TAG_NO_ATTS:
|
||||
{
|
||||
TAG *tag;
|
||||
if (freeTagList) {
|
||||
tag = freeTagList;
|
||||
freeTagList = freeTagList->parent;
|
||||
}
|
||||
else {
|
||||
tag = MALLOC(sizeof(TAG));
|
||||
if (!tag)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
|
||||
if (!tag->buf)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
|
||||
}
|
||||
tag->bindings = 0;
|
||||
tag->parent = tagStack;
|
||||
tagStack = tag;
|
||||
tag->name.localPart = 0;
|
||||
tag->rawName = s + enc->minBytesPerChar;
|
||||
tag->rawNameLength = XmlNameLength(enc, tag->rawName);
|
||||
if (nextPtr) {
|
||||
/* Need to guarantee that:
|
||||
tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
|
||||
if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
|
||||
int bufSize = tag->rawNameLength * 4;
|
||||
bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
|
||||
tag->buf = REALLOC(tag->buf, bufSize);
|
||||
if (!tag->buf)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
tag->bufEnd = tag->buf + bufSize;
|
||||
}
|
||||
memcpy(tag->buf, tag->rawName, tag->rawNameLength);
|
||||
tag->rawName = tag->buf;
|
||||
}
|
||||
++tagLevel;
|
||||
if (startElementHandler) {
|
||||
enum XML_Error result;
|
||||
XML_Char *toPtr;
|
||||
for (;;) {
|
||||
const char *rawNameEnd = tag->rawName + tag->rawNameLength;
|
||||
const char *fromPtr = tag->rawName;
|
||||
int bufSize;
|
||||
if (nextPtr)
|
||||
toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
|
||||
else
|
||||
toPtr = (XML_Char *)tag->buf;
|
||||
tag->name.str = toPtr;
|
||||
XmlConvert(enc,
|
||||
&fromPtr, rawNameEnd,
|
||||
(ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
|
||||
if (fromPtr == rawNameEnd)
|
||||
break;
|
||||
bufSize = (tag->bufEnd - tag->buf) << 1;
|
||||
tag->buf = REALLOC(tag->buf, bufSize);
|
||||
if (!tag->buf)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
tag->bufEnd = tag->buf + bufSize;
|
||||
if (nextPtr)
|
||||
tag->rawName = tag->buf;
|
||||
}
|
||||
*toPtr = XML_T('\0');
|
||||
result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
|
||||
if (result)
|
||||
return result;
|
||||
startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
|
||||
poolClear(&tempPool);
|
||||
}
|
||||
else {
|
||||
tag->name.str = 0;
|
||||
if (defaultHandler)
|
||||
reportDefault(parser, enc, s, next);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
|
||||
if (!startElementHandler) {
|
||||
enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
/* fall through */
|
||||
case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
|
||||
if (startElementHandler || endElementHandler) {
|
||||
const char *rawName = s + enc->minBytesPerChar;
|
||||
enum XML_Error result;
|
||||
BINDING *bindings = 0;
|
||||
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);
|
||||
if (endElementHandler) {
|
||||
if (startElementHandler)
|
||||
*eventPP = *eventEndPP;
|
||||
endElementHandler(handlerArg, name.str);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if (defaultHandler)
|
||||
reportDefault(parser, enc, s, next);
|
||||
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 && tag->name.str) {
|
||||
if (tag->name.localPart) {
|
||||
XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
|
||||
const XML_Char *from = tag->name.localPart;
|
||||
while ((*to++ = *from++) != 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);
|
||||
if (!next) {
|
||||
processor = cdataSectionProcessor;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XML_TOK_TRAILING_RSQB:
|
||||
if (nextPtr) {
|
||||
*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, dataPtr - (ICHAR *)dataBuf);
|
||||
}
|
||||
else
|
||||
characterDataHandler(handlerArg,
|
||||
(XML_Char *)s,
|
||||
(XML_Char *)end - (XML_Char *)s);
|
||||
}
|
||||
else if (defaultHandler)
|
||||
reportDefault(parser, enc, s, end);
|
||||
if (startTagLevel == 0) {
|
||||
*eventPP = end;
|
||||
return XML_ERROR_NO_ELEMENTS;
|
||||
}
|
||||
if (tagLevel != startTagLevel) {
|
||||
*eventPP = end;
|
||||
return XML_ERROR_ASYNC_ENTITY;
|
||||
}
|
||||
return XML_ERROR_NONE;
|
||||
case XML_TOK_DATA_CHARS:
|
||||
if (characterDataHandler) {
|
||||
if (MUST_CONVERT(enc, s)) {
|
||||
for (;;) {
|
||||
ICHAR *dataPtr = (ICHAR *)dataBuf;
|
||||
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
|
||||
*eventEndPP = s;
|
||||
characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
|
||||
if (s == next)
|
||||
break;
|
||||
*eventPP = s;
|
||||
}
|
||||
}
|
||||
else
|
||||
characterDataHandler(handlerArg,
|
||||
(XML_Char *)s,
|
||||
(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;
|
||||
}
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
/* If tagNamePtr is non-null, build a real list of attributes,
|
||||
otherwise just check the attributes for well-formedness. */
|
||||
|
||||
static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
|
||||
const char *attStr, TAG_NAME *tagNamePtr,
|
||||
BINDING **bindingsPtr)
|
||||
{
|
||||
ELEMENT_TYPE *elementType = 0;
|
||||
int nDefaultAtts = 0;
|
||||
const XML_Char **appAtts; /* the attribute list to pass to the application */
|
||||
int attIndex = 0;
|
||||
int i;
|
||||
int n;
|
||||
int nPrefixes = 0;
|
||||
BINDING *binding;
|
||||
const XML_Char *localPart;
|
||||
|
||||
/* lookup the element type name */
|
||||
if (tagNamePtr) {
|
||||
elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
|
||||
if (!elementType) {
|
||||
tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
|
||||
if (!tagNamePtr->str)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 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;
|
||||
attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
|
||||
atts = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
|
||||
if (!atts)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
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 */
|
||||
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;
|
||||
int isCdata = 1;
|
||||
|
||||
/* 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;
|
||||
if (tagNamePtr) {
|
||||
appAtts[attIndex] = poolStart(&tempPool);
|
||||
poolFinish(&tempPool);
|
||||
}
|
||||
else
|
||||
poolDiscard(&tempPool);
|
||||
}
|
||||
else if (tagNamePtr) {
|
||||
/* 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 && tagNamePtr) {
|
||||
if (attId->xmlns) {
|
||||
/* deal with namespace declarations here */
|
||||
if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
--attIndex;
|
||||
}
|
||||
else {
|
||||
/* deal with other prefixed names later */
|
||||
attIndex++;
|
||||
nPrefixes++;
|
||||
(attId->name)[-1] = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
attIndex++;
|
||||
}
|
||||
if (tagNamePtr) {
|
||||
int j;
|
||||
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 (j = 0; j < nDefaultAtts; j++) {
|
||||
const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
|
||||
if (!(da->id->name)[-1] && da->value) {
|
||||
if (da->id->prefix) {
|
||||
if (da->id->xmlns) {
|
||||
if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
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;
|
||||
}
|
||||
i = 0;
|
||||
if (nPrefixes) {
|
||||
/* expand prefixed attribute names */
|
||||
for (; i < attIndex; i += 2) {
|
||||
if (appAtts[i][-1] == 2) {
|
||||
ATTRIBUTE_ID *id;
|
||||
((XML_Char *)(appAtts[i]))[-1] = 0;
|
||||
id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
|
||||
if (id->prefix->binding) {
|
||||
int j;
|
||||
const BINDING *b = id->prefix->binding;
|
||||
const XML_Char *s = appAtts[i];
|
||||
for (j = 0; j < b->uriLen; j++) {
|
||||
if (!poolAppendChar(&tempPool, b->uri[j]))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
while (*s++ != ':')
|
||||
;
|
||||
do {
|
||||
if (!poolAppendChar(&tempPool, *s))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
} while (*s++);
|
||||
if (ns_triplets) {
|
||||
tempPool.ptr[-1] = namespaceSeparator;
|
||||
s = b->prefix->name;
|
||||
do {
|
||||
if (!poolAppendChar(&tempPool, *s))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
} while (*s++);
|
||||
}
|
||||
|
||||
appAtts[i] = poolStart(&tempPool);
|
||||
poolFinish(&tempPool);
|
||||
}
|
||||
if (!--nPrefixes)
|
||||
break;
|
||||
}
|
||||
else
|
||||
((XML_Char *)(appAtts[i]))[-1] = 0;
|
||||
}
|
||||
}
|
||||
/* clear the flags that say whether attributes were specified */
|
||||
for (; i < attIndex; i += 2)
|
||||
((XML_Char *)(appAtts[i]))[-1] = 0;
|
||||
if (!tagNamePtr)
|
||||
return XML_ERROR_NONE;
|
||||
for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
|
||||
binding->attId->name[-1] = 0;
|
||||
/* expand the element type name */
|
||||
if (elementType->prefix) {
|
||||
binding = elementType->prefix->binding;
|
||||
if (!binding)
|
||||
return XML_ERROR_NONE;
|
||||
localPart = tagNamePtr->str;
|
||||
while (*localPart++ != XML_T(':'))
|
||||
;
|
||||
}
|
||||
else if (dtd.defaultPrefix.binding) {
|
||||
binding = dtd.defaultPrefix.binding;
|
||||
localPart = tagNamePtr->str;
|
||||
}
|
||||
else
|
||||
return XML_ERROR_NONE;
|
||||
tagNamePtr->localPart = localPart;
|
||||
tagNamePtr->uriLen = binding->uriLen;
|
||||
for (i = 0; localPart[i++];)
|
||||
;
|
||||
n = i + binding->uriLen;
|
||||
if (n > binding->uriAlloc) {
|
||||
TAG *p;
|
||||
XML_Char *uri = 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;
|
||||
}
|
||||
memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
|
||||
tagNamePtr->str = binding->uri;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
|
||||
static
|
||||
int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
|
||||
{
|
||||
BINDING *b;
|
||||
int len;
|
||||
for (len = 0; uri[len]; len++)
|
||||
;
|
||||
if (namespaceSeparator)
|
||||
len++;
|
||||
if (freeBindingList) {
|
||||
b = freeBindingList;
|
||||
if (len > b->uriAlloc) {
|
||||
b->uri = REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
|
||||
if (!b->uri)
|
||||
return 0;
|
||||
b->uriAlloc = len + EXPAND_SPARE;
|
||||
}
|
||||
freeBindingList = b->nextTagBinding;
|
||||
}
|
||||
else {
|
||||
b = MALLOC(sizeof(BINDING));
|
||||
if (!b)
|
||||
return 0;
|
||||
b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
|
||||
if (!b->uri) {
|
||||
FREE(b);
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
|
||||
prefix->binding = 0;
|
||||
else
|
||||
prefix->binding = b;
|
||||
b->nextTagBinding = *bindingsPtr;
|
||||
*bindingsPtr = b;
|
||||
if (startNamespaceDeclHandler)
|
||||
startNamespaceDeclHandler(handlerArg, prefix->name,
|
||||
prefix->binding ? uri : 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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 cdataSectionProcessor(XML_Parser parser,
|
||||
const char *start,
|
||||
const char *end,
|
||||
const char **endPtr)
|
||||
{
|
||||
enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
|
||||
if (start) {
|
||||
processor = contentProcessor;
|
||||
return contentProcessor(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 doCdataSection(XML_Parser parser,
|
||||
const ENCODING *enc,
|
||||
const char **startPtr,
|
||||
const char *end,
|
||||
const char **nextPtr)
|
||||
{
|
||||
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 = 0;
|
||||
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;
|
||||
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:
|
||||
if (characterDataHandler) {
|
||||
if (MUST_CONVERT(enc, s)) {
|
||||
for (;;) {
|
||||
ICHAR *dataPtr = (ICHAR *)dataBuf;
|
||||
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
|
||||
*eventEndPP = next;
|
||||
characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
|
||||
if (s == next)
|
||||
break;
|
||||
*eventPP = s;
|
||||
}
|
||||
}
|
||||
else
|
||||
characterDataHandler(handlerArg,
|
||||
(XML_Char *)s,
|
||||
(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 (nextPtr) {
|
||||
*nextPtr = s;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
return XML_ERROR_PARTIAL_CHAR;
|
||||
case XML_TOK_PARTIAL:
|
||||
case XML_TOK_NONE:
|
||||
if (nextPtr) {
|
||||
*nextPtr = s;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
return XML_ERROR_UNCLOSED_CDATA_SECTION;
|
||||
default:
|
||||
*eventPP = next;
|
||||
return XML_ERROR_UNEXPECTED_STATE;
|
||||
}
|
||||
*eventPP = s = next;
|
||||
}
|
||||
/* 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 ignoreSectionProcessor(XML_Parser parser,
|
||||
const char *start,
|
||||
const char *end,
|
||||
const char **endPtr)
|
||||
{
|
||||
enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
|
||||
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)
|
||||
{
|
||||
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 = 0;
|
||||
tok = XmlIgnoreSectionTok(enc, s, end, &next);
|
||||
*eventEndPP = next;
|
||||
switch (tok) {
|
||||
case XML_TOK_IGNORE_SECT:
|
||||
if (defaultHandler)
|
||||
reportDefault(parser, enc, s, next);
|
||||
*startPtr = next;
|
||||
return XML_ERROR_NONE;
|
||||
case XML_TOK_INVALID:
|
||||
*eventPP = next;
|
||||
return XML_ERROR_INVALID_TOKEN;
|
||||
case XML_TOK_PARTIAL_CHAR:
|
||||
if (nextPtr) {
|
||||
*nextPtr = s;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
return XML_ERROR_PARTIAL_CHAR;
|
||||
case XML_TOK_PARTIAL:
|
||||
case XML_TOK_NONE:
|
||||
if (nextPtr) {
|
||||
*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 = 0;
|
||||
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 = 0;
|
||||
const char *storedEncName = 0;
|
||||
const ENCODING *newEncoding = 0;
|
||||
const char *version = 0;
|
||||
const char *versionend;
|
||||
const char *storedversion = 0;
|
||||
int standalone = -1;
|
||||
if (!(ns
|
||||
? XmlParseXmlDeclNS
|
||||
: XmlParseXmlDecl)(isGeneralTextEntity,
|
||||
encoding,
|
||||
s,
|
||||
next,
|
||||
&eventPtr,
|
||||
&version,
|
||||
&versionend,
|
||||
&encodingName,
|
||||
&newEncoding,
|
||||
&standalone))
|
||||
return XML_ERROR_SYNTAX;
|
||||
if (!isGeneralTextEntity && standalone == 1) {
|
||||
dtd.standalone = 1;
|
||||
#ifdef XML_DTD
|
||||
if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
|
||||
paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
|
||||
#endif /* XML_DTD */
|
||||
}
|
||||
if (xmlDeclHandler) {
|
||||
if (encodingName) {
|
||||
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) {
|
||||
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(&tempPool);
|
||||
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 = 0;
|
||||
info.data = 0;
|
||||
info.release = 0;
|
||||
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)
|
||||
info.release(info.data);
|
||||
}
|
||||
return XML_ERROR_UNKNOWN_ENCODING;
|
||||
}
|
||||
|
||||
static enum XML_Error
|
||||
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);
|
||||
}
|
||||
|
||||
static enum XML_Error
|
||||
prologProcessor(XML_Parser parser,
|
||||
const char *s,
|
||||
const char *end,
|
||||
const char **nextPtr)
|
||||
{
|
||||
const char *next;
|
||||
int tok = XmlPrologTok(encoding, s, end, &next);
|
||||
return doProlog(parser, encoding, s, end, tok, next, nextPtr);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
#ifdef XML_DTD
|
||||
static const XML_Char externalSubsetName[] = { '#' , '\0' };
|
||||
#endif /* XML_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;
|
||||
*eventPP = s;
|
||||
*eventEndPP = next;
|
||||
if (tok <= 0) {
|
||||
if (nextPtr != 0 && 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
|
||||
if (enc != encoding)
|
||||
return XML_ERROR_NONE;
|
||||
if (parentParser) {
|
||||
if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
|
||||
== XML_ROLE_ERROR)
|
||||
return XML_ERROR_SYNTAX;
|
||||
hadExternalDoctype = 0;
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_DOCTYPE_NAME:
|
||||
if (startDoctypeDeclHandler) {
|
||||
doctypeName = poolStoreString(&tempPool, enc, s, next);
|
||||
if (! doctypeName)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
poolFinish(&tempPool);
|
||||
doctypeSysid = 0;
|
||||
doctypePubid = 0;
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
|
||||
if (startDoctypeDeclHandler) {
|
||||
startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
|
||||
doctypePubid, 1);
|
||||
doctypeName = 0;
|
||||
poolClear(&tempPool);
|
||||
}
|
||||
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;
|
||||
}
|
||||
break;
|
||||
#endif /* XML_DTD */
|
||||
case XML_ROLE_DOCTYPE_PUBLIC_ID:
|
||||
if (startDoctypeDeclHandler) {
|
||||
doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
|
||||
if (! doctypePubid)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
poolFinish(&tempPool);
|
||||
}
|
||||
#ifdef XML_DTD
|
||||
declEntity = (ENTITY *)lookup(&dtd.paramEntities,
|
||||
externalSubsetName,
|
||||
sizeof(ENTITY));
|
||||
if (!declEntity)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
#endif /* XML_DTD */
|
||||
/* fall through */
|
||||
case XML_ROLE_ENTITY_PUBLIC_ID:
|
||||
if (!XmlIsPublicId(enc, s, next, eventPP))
|
||||
return XML_ERROR_SYNTAX;
|
||||
if (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);
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_DOCTYPE_CLOSE:
|
||||
if (doctypeName) {
|
||||
startDoctypeDeclHandler(handlerArg, doctypeName,
|
||||
doctypeSysid, doctypePubid, 0);
|
||||
poolClear(&tempPool);
|
||||
}
|
||||
if (dtd.complete && hadExternalDoctype) {
|
||||
dtd.complete = 0;
|
||||
#ifdef XML_DTD
|
||||
if (paramEntityParsing && externalEntityRefHandler) {
|
||||
ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
|
||||
externalSubsetName,
|
||||
0);
|
||||
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
|
||||
0,
|
||||
entity->base,
|
||||
entity->systemId,
|
||||
entity->publicId))
|
||||
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
|
||||
}
|
||||
#endif /* XML_DTD */
|
||||
if (!dtd.complete
|
||||
&& !dtd.standalone
|
||||
&& notStandaloneHandler
|
||||
&& !notStandaloneHandler(handlerArg))
|
||||
return XML_ERROR_NOT_STANDALONE;
|
||||
}
|
||||
if (endDoctypeDeclHandler)
|
||||
endDoctypeDeclHandler(handlerArg);
|
||||
break;
|
||||
case XML_ROLE_INSTANCE_START:
|
||||
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;
|
||||
break;
|
||||
case XML_ROLE_ATTRIBUTE_NAME:
|
||||
declAttributeId = getAttributeId(parser, enc, s, next);
|
||||
if (!declAttributeId)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
declAttributeIsCdata = 0;
|
||||
declAttributeType = 0;
|
||||
declAttributeIsId = 0;
|
||||
break;
|
||||
case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
|
||||
declAttributeIsCdata = 1;
|
||||
declAttributeType = "CDATA";
|
||||
break;
|
||||
case XML_ROLE_ATTRIBUTE_TYPE_ID:
|
||||
declAttributeIsId = 1;
|
||||
declAttributeType = "ID";
|
||||
break;
|
||||
case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
|
||||
declAttributeType = "IDREF";
|
||||
break;
|
||||
case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
|
||||
declAttributeType = "IDREFS";
|
||||
break;
|
||||
case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
|
||||
declAttributeType = "ENTITY";
|
||||
break;
|
||||
case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
|
||||
declAttributeType = "ENTITIES";
|
||||
break;
|
||||
case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
|
||||
declAttributeType = "NMTOKEN";
|
||||
break;
|
||||
case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
|
||||
declAttributeType = "NMTOKENS";
|
||||
break;
|
||||
|
||||
case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
|
||||
case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
|
||||
if (attlistDeclHandler)
|
||||
{
|
||||
char *prefix;
|
||||
if (declAttributeType) {
|
||||
prefix = "|";
|
||||
}
|
||||
else {
|
||||
prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
|
||||
? "NOTATION("
|
||||
: "(");
|
||||
}
|
||||
if (! poolAppendString(&tempPool, prefix))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
if (! poolAppend(&tempPool, enc, s, next))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
declAttributeType = tempPool.start;
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
|
||||
case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
|
||||
if (dtd.complete
|
||||
&& !defineAttribute(declElementType, declAttributeId,
|
||||
declAttributeIsCdata, declAttributeIsId, 0,
|
||||
parser))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
if (attlistDeclHandler && declAttributeType) {
|
||||
if (*declAttributeType == '('
|
||||
|| (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
|
||||
/* Enumerated or Notation type */
|
||||
if (! poolAppendChar(&tempPool, ')')
|
||||
|| ! poolAppendChar(&tempPool, '\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);
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
|
||||
case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
|
||||
{
|
||||
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);
|
||||
if (dtd.complete
|
||||
/* ID attributes aren't allowed to have a default */
|
||||
&& !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
if (attlistDeclHandler && declAttributeType) {
|
||||
if (*declAttributeType == '('
|
||||
|| (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
|
||||
/* Enumerated or Notation type */
|
||||
if (! poolAppendChar(&tempPool, ')')
|
||||
|| ! poolAppendChar(&tempPool, '\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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XML_ROLE_ENTITY_VALUE:
|
||||
{
|
||||
enum XML_Error result = storeEntityValue(parser, enc,
|
||||
s + enc->minBytesPerChar,
|
||||
next - enc->minBytesPerChar);
|
||||
if (declEntity) {
|
||||
declEntity->textPtr = poolStart(&dtd.pool);
|
||||
declEntity->textLen = poolLength(&dtd.pool);
|
||||
poolFinish(&dtd.pool);
|
||||
if (entityDeclHandler) {
|
||||
*eventEndPP = s;
|
||||
entityDeclHandler(handlerArg,
|
||||
declEntity->name,
|
||||
declEntity->is_param,
|
||||
declEntity->textPtr,
|
||||
declEntity->textLen,
|
||||
curBase, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
poolDiscard(&dtd.pool);
|
||||
if (result != XML_ERROR_NONE)
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_DOCTYPE_SYSTEM_ID:
|
||||
if (startDoctypeDeclHandler) {
|
||||
doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
|
||||
if (! doctypeSysid)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
poolFinish(&tempPool);
|
||||
}
|
||||
if (!dtd.standalone
|
||||
#ifdef XML_DTD
|
||||
&& !paramEntityParsing
|
||||
#endif /* XML_DTD */
|
||||
&& notStandaloneHandler
|
||||
&& !notStandaloneHandler(handlerArg))
|
||||
return XML_ERROR_NOT_STANDALONE;
|
||||
hadExternalDoctype = 1;
|
||||
#ifndef XML_DTD
|
||||
break;
|
||||
#else /* XML_DTD */
|
||||
if (!declEntity) {
|
||||
declEntity = (ENTITY *)lookup(&dtd.paramEntities,
|
||||
externalSubsetName,
|
||||
sizeof(ENTITY));
|
||||
declEntity->publicId = 0;
|
||||
if (!declEntity)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
/* fall through */
|
||||
#endif /* XML_DTD */
|
||||
case XML_ROLE_ENTITY_SYSTEM_ID:
|
||||
if (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);
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_ENTITY_COMPLETE:
|
||||
if (declEntity && entityDeclHandler) {
|
||||
*eventEndPP = s;
|
||||
entityDeclHandler(handlerArg,
|
||||
declEntity->name,
|
||||
0,0,0,
|
||||
declEntity->base,
|
||||
declEntity->systemId,
|
||||
declEntity->publicId,
|
||||
0);
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_ENTITY_NOTATION_NAME:
|
||||
if (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);
|
||||
}
|
||||
else if (entityDeclHandler) {
|
||||
*eventEndPP = s;
|
||||
entityDeclHandler(handlerArg,
|
||||
declEntity->name,
|
||||
0,0,0,
|
||||
declEntity->base,
|
||||
declEntity->systemId,
|
||||
declEntity->publicId,
|
||||
declEntity->notation);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_GENERAL_ENTITY_NAME:
|
||||
{
|
||||
const XML_Char *name;
|
||||
if (XmlPredefinedEntityName(enc, s, next)) {
|
||||
declEntity = 0;
|
||||
break;
|
||||
}
|
||||
name = poolStoreString(&dtd.pool, enc, s, next);
|
||||
if (!name)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
if (dtd.complete) {
|
||||
declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
|
||||
if (!declEntity)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
if (declEntity->name != name) {
|
||||
poolDiscard(&dtd.pool);
|
||||
declEntity = 0;
|
||||
}
|
||||
else {
|
||||
poolFinish(&dtd.pool);
|
||||
declEntity->publicId = 0;
|
||||
declEntity->is_param = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
poolDiscard(&dtd.pool);
|
||||
declEntity = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_PARAM_ENTITY_NAME:
|
||||
#ifdef XML_DTD
|
||||
if (dtd.complete) {
|
||||
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 = 0;
|
||||
}
|
||||
else {
|
||||
poolFinish(&dtd.pool);
|
||||
declEntity->publicId = 0;
|
||||
declEntity->is_param = 1;
|
||||
}
|
||||
}
|
||||
#else /* not XML_DTD */
|
||||
declEntity = 0;
|
||||
#endif /* not XML_DTD */
|
||||
break;
|
||||
case XML_ROLE_NOTATION_NAME:
|
||||
declNotationPublicId = 0;
|
||||
declNotationName = 0;
|
||||
if (notationDeclHandler) {
|
||||
declNotationName = poolStoreString(&tempPool, enc, s, next);
|
||||
if (!declNotationName)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
poolFinish(&tempPool);
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_NOTATION_PUBLIC_ID:
|
||||
if (!XmlIsPublicId(enc, s, next, eventPP))
|
||||
return XML_ERROR_SYNTAX;
|
||||
if (declNotationName) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
poolClear(&tempPool);
|
||||
break;
|
||||
case XML_ROLE_NOTATION_NO_SYSTEM_ID:
|
||||
if (declNotationPublicId && notationDeclHandler) {
|
||||
*eventEndPP = s;
|
||||
notationDeclHandler(handlerArg,
|
||||
declNotationName,
|
||||
curBase,
|
||||
0,
|
||||
declNotationPublicId);
|
||||
}
|
||||
poolClear(&tempPool);
|
||||
break;
|
||||
case XML_ROLE_ERROR:
|
||||
switch (tok) {
|
||||
case XML_TOK_PARAM_ENTITY_REF:
|
||||
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);
|
||||
result = doIgnoreSection(parser, enc, &next, end, nextPtr);
|
||||
if (!next) {
|
||||
processor = ignoreSectionProcessor;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif /* XML_DTD */
|
||||
case XML_ROLE_GROUP_OPEN:
|
||||
if (prologState.level >= groupSize) {
|
||||
if (groupSize) {
|
||||
groupConnector = REALLOC(groupConnector, groupSize *= 2);
|
||||
if (dtd.scaffIndex)
|
||||
dtd.scaffIndex = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
|
||||
}
|
||||
else
|
||||
groupConnector = 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;
|
||||
}
|
||||
break;
|
||||
case XML_ROLE_GROUP_SEQUENCE:
|
||||
if (groupConnector[prologState.level] == '|')
|
||||
return XML_ERROR_SYNTAX;
|
||||
groupConnector[prologState.level] = ',';
|
||||
break;
|
||||
case XML_ROLE_GROUP_CHOICE:
|
||||
if (groupConnector[prologState.level] == ',')
|
||||
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;
|
||||
}
|
||||
groupConnector[prologState.level] = '|';
|
||||
break;
|
||||
case XML_ROLE_PARAM_ENTITY_REF:
|
||||
#ifdef XML_DTD
|
||||
case XML_ROLE_INNER_PARAM_ENTITY_REF:
|
||||
if (paramEntityParsing
|
||||
&& (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
|
||||
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);
|
||||
if (!entity) {
|
||||
/* FIXME what to do if !dtd.complete? */
|
||||
return XML_ERROR_UNDEFINED_ENTITY;
|
||||
}
|
||||
if (entity->open)
|
||||
return XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
if (entity->textPtr) {
|
||||
enum XML_Error result;
|
||||
result = processInternalParamEntity(parser, entity);
|
||||
if (result != XML_ERROR_NONE)
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
|
||||
return XML_ERROR_PARAM_ENTITY_REF;
|
||||
if (externalEntityRefHandler) {
|
||||
dtd.complete = 0;
|
||||
entity->open = 1;
|
||||
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
|
||||
0,
|
||||
entity->base,
|
||||
entity->systemId,
|
||||
entity->publicId)) {
|
||||
entity->open = 0;
|
||||
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
|
||||
}
|
||||
entity->open = 0;
|
||||
if (dtd.complete)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* XML_DTD */
|
||||
if (!dtd.standalone
|
||||
&& notStandaloneHandler
|
||||
&& !notStandaloneHandler(handlerArg))
|
||||
return XML_ERROR_NOT_STANDALONE;
|
||||
dtd.complete = 0;
|
||||
if (defaultHandler)
|
||||
reportDefault(parser, enc, s, next);
|
||||
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 = 1;
|
||||
}
|
||||
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 = 0;
|
||||
content->numchildren = 0;
|
||||
content->children = 0;
|
||||
content->type = ((role == XML_ROLE_CONTENT_ANY) ?
|
||||
XML_CTYPE_ANY :
|
||||
XML_CTYPE_EMPTY);
|
||||
*eventEndPP = s;
|
||||
elementDeclHandler(handlerArg, declElementType->name, content);
|
||||
}
|
||||
dtd.in_eldecl = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case XML_ROLE_CONTENT_PCDATA:
|
||||
if (dtd.in_eldecl) {
|
||||
dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
|
||||
}
|
||||
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 char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
|
||||
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;
|
||||
dtd.scaffold[myindex].name = el->name;
|
||||
dtd.contentStringLen += nxt - s + 1;
|
||||
}
|
||||
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) {
|
||||
dtd.scaffLevel--;
|
||||
dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
|
||||
if (dtd.scaffLevel == 0) {
|
||||
if (elementDeclHandler) {
|
||||
XML_Content *model = build_model(parser);
|
||||
if (! model)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
*eventEndPP = s;
|
||||
elementDeclHandler(handlerArg, declElementType->name, model);
|
||||
}
|
||||
dtd.in_eldecl = 0;
|
||||
dtd.contentStringLen = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
/* End element declaration stuff */
|
||||
|
||||
case XML_ROLE_NONE:
|
||||
switch (tok) {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (defaultHandler) {
|
||||
switch (tok) {
|
||||
case XML_TOK_PI:
|
||||
case XML_TOK_COMMENT:
|
||||
case XML_TOK_BOM:
|
||||
case XML_TOK_XML_DECL:
|
||||
#ifdef XML_DTD
|
||||
case XML_TOK_IGNORE_SECT:
|
||||
#endif /* XML_DTD */
|
||||
case XML_TOK_PARAM_ENTITY_REF:
|
||||
break;
|
||||
default:
|
||||
#ifdef XML_DTD
|
||||
if (role != XML_ROLE_IGNORE_SECT)
|
||||
#endif /* XML_DTD */
|
||||
reportDefault(parser, enc, s, next);
|
||||
}
|
||||
}
|
||||
s = next;
|
||||
tok = XmlPrologTok(enc, s, end, &next);
|
||||
}
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
static
|
||||
enum XML_Error epilogProcessor(XML_Parser parser,
|
||||
const char *s,
|
||||
const char *end,
|
||||
const char **nextPtr)
|
||||
{
|
||||
processor = epilogProcessor;
|
||||
eventPtr = s;
|
||||
for (;;) {
|
||||
const char *next;
|
||||
int tok = XmlPrologTok(encoding, s, end, &next);
|
||||
eventEndPtr = next;
|
||||
switch (tok) {
|
||||
case -XML_TOK_PROLOG_S:
|
||||
if (defaultHandler) {
|
||||
eventEndPtr = end;
|
||||
reportDefault(parser, encoding, s, end);
|
||||
}
|
||||
/* fall through */
|
||||
case XML_TOK_NONE:
|
||||
if (nextPtr)
|
||||
*nextPtr = end;
|
||||
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 (nextPtr) {
|
||||
*nextPtr = s;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
return XML_ERROR_UNCLOSED_TOKEN;
|
||||
case XML_TOK_PARTIAL_CHAR:
|
||||
if (nextPtr) {
|
||||
*nextPtr = s;
|
||||
return XML_ERROR_NONE;
|
||||
}
|
||||
return XML_ERROR_PARTIAL_CHAR;
|
||||
default:
|
||||
return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
|
||||
}
|
||||
eventPtr = s = next;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XML_DTD
|
||||
|
||||
static enum XML_Error
|
||||
processInternalParamEntity(XML_Parser parser, ENTITY *entity)
|
||||
{
|
||||
const char *s, *end, *next;
|
||||
int tok;
|
||||
enum XML_Error result;
|
||||
OPEN_INTERNAL_ENTITY openEntity;
|
||||
entity->open = 1;
|
||||
openEntity.next = openInternalEntities;
|
||||
openInternalEntities = &openEntity;
|
||||
openEntity.entity = entity;
|
||||
openEntity.internalEventPtr = 0;
|
||||
openEntity.internalEventEndPtr = 0;
|
||||
s = (char *)entity->textPtr;
|
||||
end = (char *)(entity->textPtr + entity->textLen);
|
||||
tok = XmlPrologTok(internalEncoding, s, end, &next);
|
||||
result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
|
||||
entity->open = 0;
|
||||
openInternalEntities = openEntity.next;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* XML_DTD */
|
||||
|
||||
static
|
||||
enum XML_Error errorProcessor(XML_Parser parser,
|
||||
const char *s,
|
||||
const char *end,
|
||||
const char **nextPtr)
|
||||
{
|
||||
cmExpatUnused(s);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(nextPtr);
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
static enum XML_Error
|
||||
storeAttributeValue(XML_Parser parser, const ENCODING *enc, int 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, int isCdata,
|
||||
const char *ptr, const char *end,
|
||||
STRING_POOL *pool)
|
||||
{
|
||||
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;
|
||||
XML_Char ch = 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);
|
||||
if (!entity) {
|
||||
if (dtd.complete) {
|
||||
if (enc == encoding)
|
||||
eventPtr = ptr;
|
||||
return XML_ERROR_UNDEFINED_ENTITY;
|
||||
}
|
||||
}
|
||||
else if (entity->open) {
|
||||
if (enc == encoding)
|
||||
eventPtr = ptr;
|
||||
return XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
}
|
||||
else if (entity->notation) {
|
||||
if (enc == encoding)
|
||||
eventPtr = ptr;
|
||||
return XML_ERROR_BINARY_ENTITY_REF;
|
||||
}
|
||||
else 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 = 1;
|
||||
result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
|
||||
entity->open = 0;
|
||||
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)
|
||||
{
|
||||
STRING_POOL *pool = &(dtd.pool);
|
||||
for (;;) {
|
||||
const char *next;
|
||||
int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
|
||||
switch (tok) {
|
||||
case XML_TOK_PARAM_ENTITY_REF:
|
||||
#ifdef XML_DTD
|
||||
if (parentParser || enc != encoding) {
|
||||
enum XML_Error result;
|
||||
const XML_Char *name;
|
||||
ENTITY *entity;
|
||||
name = poolStoreString(&tempPool, enc,
|
||||
entityTextPtr + enc->minBytesPerChar,
|
||||
next - enc->minBytesPerChar);
|
||||
if (!name)
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
|
||||
poolDiscard(&tempPool);
|
||||
if (!entity) {
|
||||
if (enc == encoding)
|
||||
eventPtr = entityTextPtr;
|
||||
return XML_ERROR_UNDEFINED_ENTITY;
|
||||
}
|
||||
if (entity->open) {
|
||||
if (enc == encoding)
|
||||
eventPtr = entityTextPtr;
|
||||
return XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
}
|
||||
if (entity->systemId) {
|
||||
if (enc == encoding)
|
||||
eventPtr = entityTextPtr;
|
||||
return XML_ERROR_PARAM_ENTITY_REF;
|
||||
}
|
||||
entity->open = 1;
|
||||
result = storeEntityValue(parser,
|
||||
internalEncoding,
|
||||
(char *)entity->textPtr,
|
||||
(char *)(entity->textPtr + entity->textLen));
|
||||
entity->open = 0;
|
||||
if (result)
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
#endif /* XML_DTD */
|
||||
eventPtr = entityTextPtr;
|
||||
return XML_ERROR_SYNTAX;
|
||||
case XML_TOK_NONE:
|
||||
return XML_ERROR_NONE;
|
||||
case XML_TOK_ENTITY_REF:
|
||||
case XML_TOK_DATA_CHARS:
|
||||
if (!poolAppend(pool, enc, entityTextPtr, next))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
break;
|
||||
case XML_TOK_TRAILING_CR:
|
||||
next = entityTextPtr + enc->minBytesPerChar;
|
||||
/* fall through */
|
||||
case XML_TOK_DATA_NEWLINE:
|
||||
if (pool->end == pool->ptr && !poolGrow(pool))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
*(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;
|
||||
return XML_ERROR_BAD_CHAR_REF;
|
||||
}
|
||||
n = XmlEncode(n, (ICHAR *)buf);
|
||||
if (!n) {
|
||||
if (enc == encoding)
|
||||
eventPtr = entityTextPtr;
|
||||
return XML_ERROR_BAD_CHAR_REF;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
if (pool->end == pool->ptr && !poolGrow(pool))
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
*(pool->ptr)++ = buf[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case XML_TOK_PARTIAL:
|
||||
if (enc == encoding)
|
||||
eventPtr = entityTextPtr;
|
||||
return XML_ERROR_INVALID_TOKEN;
|
||||
case XML_TOK_INVALID:
|
||||
if (enc == encoding)
|
||||
eventPtr = next;
|
||||
return XML_ERROR_INVALID_TOKEN;
|
||||
default:
|
||||
if (enc == encoding)
|
||||
eventPtr = entityTextPtr;
|
||||
return XML_ERROR_UNEXPECTED_STATE;
|
||||
}
|
||||
entityTextPtr = next;
|
||||
}
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
static void
|
||||
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, dataPtr - (ICHAR *)dataBuf);
|
||||
*eventPP = s;
|
||||
} while (s != end);
|
||||
}
|
||||
else
|
||||
defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata,
|
||||
int 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 = MALLOC(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
|
||||
}
|
||||
else {
|
||||
type->allocDefaultAtts *= 2;
|
||||
type->defaultAtts = REALLOC(type->defaultAtts,
|
||||
type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
|
||||
}
|
||||
if (!type->defaultAtts)
|
||||
return 0;
|
||||
}
|
||||
att = type->defaultAtts + type->nDefaultAtts;
|
||||
att->id = attId;
|
||||
att->value = value;
|
||||
att->isCdata = isCdata;
|
||||
if (!isCdata)
|
||||
attId->maybeTokenized = 1;
|
||||
type->nDefaultAtts += 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
|
||||
{
|
||||
const XML_Char *name;
|
||||
for (name = elementType->name; *name; name++) {
|
||||
if (*name == XML_T(':')) {
|
||||
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)
|
||||
{
|
||||
ATTRIBUTE_ID *id;
|
||||
const XML_Char *name;
|
||||
if (!poolAppendChar(&dtd.pool, XML_T('\0')))
|
||||
return 0;
|
||||
name = poolStoreString(&dtd.pool, enc, start, end);
|
||||
if (!name)
|
||||
return 0;
|
||||
++name;
|
||||
id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
|
||||
if (!id)
|
||||
return 0;
|
||||
if (id->name != name)
|
||||
poolDiscard(&dtd.pool);
|
||||
else {
|
||||
poolFinish(&dtd.pool);
|
||||
if (!ns)
|
||||
;
|
||||
else if (name[0] == 'x'
|
||||
&& name[1] == 'm'
|
||||
&& name[2] == 'l'
|
||||
&& name[3] == 'n'
|
||||
&& name[4] == 's'
|
||||
&& (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
|
||||
if (name[5] == '\0')
|
||||
id->prefix = &dtd.defaultPrefix;
|
||||
else
|
||||
id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
|
||||
id->xmlns = 1;
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; name[i]; i++) {
|
||||
if (name[i] == XML_T(':')) {
|
||||
int j;
|
||||
for (j = 0; j < i; j++) {
|
||||
if (!poolAppendChar(&dtd.pool, name[j]))
|
||||
return 0;
|
||||
}
|
||||
if (!poolAppendChar(&dtd.pool, XML_T('\0')))
|
||||
return 0;
|
||||
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('\f')
|
||||
|
||||
static
|
||||
const XML_Char *getContext(XML_Parser parser)
|
||||
{
|
||||
HASH_TABLE_ITER iter;
|
||||
int needSep = 0;
|
||||
|
||||
if (dtd.defaultPrefix.binding) {
|
||||
int i;
|
||||
int len;
|
||||
if (!poolAppendChar(&tempPool, XML_T('=')))
|
||||
return 0;
|
||||
len = dtd.defaultPrefix.binding->uriLen;
|
||||
if (namespaceSeparator != XML_T('\0'))
|
||||
len--;
|
||||
for (i = 0; i < len; i++)
|
||||
if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
|
||||
return 0;
|
||||
needSep = 1;
|
||||
}
|
||||
|
||||
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 0;
|
||||
for (s = prefix->name; *s; s++)
|
||||
if (!poolAppendChar(&tempPool, *s))
|
||||
return 0;
|
||||
if (!poolAppendChar(&tempPool, XML_T('=')))
|
||||
return 0;
|
||||
len = prefix->binding->uriLen;
|
||||
if (namespaceSeparator != XML_T('\0'))
|
||||
len--;
|
||||
for (i = 0; i < len; i++)
|
||||
if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
|
||||
return 0;
|
||||
needSep = 1;
|
||||
}
|
||||
|
||||
|
||||
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 0;
|
||||
for (s = e->name; *s; s++)
|
||||
if (!poolAppendChar(&tempPool, *s))
|
||||
return 0;
|
||||
needSep = 1;
|
||||
}
|
||||
|
||||
if (!poolAppendChar(&tempPool, XML_T('\0')))
|
||||
return 0;
|
||||
return tempPool.start;
|
||||
}
|
||||
|
||||
static
|
||||
int setContext(XML_Parser parser, const XML_Char *context)
|
||||
{
|
||||
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 0;
|
||||
e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
|
||||
if (e)
|
||||
e->open = 1;
|
||||
if (*s != XML_T('\0'))
|
||||
s++;
|
||||
context = s;
|
||||
poolDiscard(&tempPool);
|
||||
}
|
||||
else if (*s == '=') {
|
||||
PREFIX *prefix;
|
||||
if (poolLength(&tempPool) == 0)
|
||||
prefix = &dtd.defaultPrefix;
|
||||
else {
|
||||
if (!poolAppendChar(&tempPool, XML_T('\0')))
|
||||
return 0;
|
||||
prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
|
||||
if (!prefix)
|
||||
return 0;
|
||||
if (prefix->name == poolStart(&tempPool)) {
|
||||
prefix->name = poolCopyString(&dtd.pool, prefix->name);
|
||||
if (!prefix->name)
|
||||
return 0;
|
||||
}
|
||||
poolDiscard(&tempPool);
|
||||
}
|
||||
for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
|
||||
if (!poolAppendChar(&tempPool, *context))
|
||||
return 0;
|
||||
if (!poolAppendChar(&tempPool, XML_T('\0')))
|
||||
return 0;
|
||||
if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
|
||||
return 0;
|
||||
poolDiscard(&tempPool);
|
||||
if (*context != XML_T('\0'))
|
||||
++context;
|
||||
s = context;
|
||||
}
|
||||
else {
|
||||
if (!poolAppendChar(&tempPool, *s))
|
||||
return 0;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void 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 int dtdInit(DTD *p, XML_Parser parser)
|
||||
{
|
||||
XML_Memory_Handling_Suite *ms = &((Parser *) parser)->m_mem;
|
||||
poolInit(&(p->pool), ms);
|
||||
hashTableInit(&(p->generalEntities), ms);
|
||||
hashTableInit(&(p->elementTypes), ms);
|
||||
hashTableInit(&(p->attributeIds), ms);
|
||||
hashTableInit(&(p->prefixes), ms);
|
||||
p->complete = 1;
|
||||
p->standalone = 0;
|
||||
#ifdef XML_DTD
|
||||
hashTableInit(&(p->paramEntities), ms);
|
||||
#endif /* XML_DTD */
|
||||
p->defaultPrefix.name = 0;
|
||||
p->defaultPrefix.binding = 0;
|
||||
|
||||
p->in_eldecl = 0;
|
||||
p->scaffIndex = 0;
|
||||
p->scaffLevel = 0;
|
||||
p->scaffold = 0;
|
||||
p->contentStringLen = 0;
|
||||
p->scaffSize = 0;
|
||||
p->scaffCount = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef XML_DTD
|
||||
|
||||
static void dtdSwap(DTD *p1, DTD *p2)
|
||||
{
|
||||
DTD tem;
|
||||
memcpy(&tem, p1, sizeof(DTD));
|
||||
memcpy(p1, p2, sizeof(DTD));
|
||||
memcpy(p2, &tem, sizeof(DTD));
|
||||
}
|
||||
|
||||
#endif /* XML_DTD */
|
||||
|
||||
static void dtdDestroy(DTD *p, XML_Parser parser)
|
||||
{
|
||||
HASH_TABLE_ITER iter;
|
||||
hashTableIterInit(&iter, &(p->elementTypes));
|
||||
for (;;) {
|
||||
ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
|
||||
if (!e)
|
||||
break;
|
||||
if (e->allocDefaultAtts != 0)
|
||||
FREE(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));
|
||||
if (p->scaffIndex)
|
||||
FREE(p->scaffIndex);
|
||||
if (p->scaffold)
|
||||
FREE(p->scaffold);
|
||||
}
|
||||
|
||||
/* 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, XML_Parser parser)
|
||||
{
|
||||
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 *)MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
|
||||
if (!newE->defaultAtts)
|
||||
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 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the entity tables. */
|
||||
if (!copyEntityTable(&(newDtd->generalEntities),
|
||||
&(newDtd->pool),
|
||||
&(oldDtd->generalEntities), parser))
|
||||
return 0;
|
||||
|
||||
#ifdef XML_DTD
|
||||
if (!copyEntityTable(&(newDtd->paramEntities),
|
||||
&(newDtd->pool),
|
||||
&(oldDtd->paramEntities), parser))
|
||||
return 0;
|
||||
#endif /* XML_DTD */
|
||||
|
||||
newDtd->complete = oldDtd->complete;
|
||||
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,
|
||||
XML_Parser parser)
|
||||
{
|
||||
HASH_TABLE_ITER iter;
|
||||
const XML_Char *cachedOldBase = 0;
|
||||
const XML_Char *cachedNewBase = 0;
|
||||
cmExpatUnused(parser);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define INIT_SIZE 64
|
||||
|
||||
static
|
||||
int keyeq(KEY s1, KEY s2)
|
||||
{
|
||||
for (; *s1 == *s2; s1++, s2++)
|
||||
if (*s1 == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
unsigned long hash(KEY s)
|
||||
{
|
||||
unsigned long h = 0;
|
||||
while (*s)
|
||||
h = (h << 5) + h + (unsigned char)*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 0;
|
||||
tsize = INIT_SIZE * sizeof(NAMED *);
|
||||
table->v = table->mem->malloc_fcn(tsize);
|
||||
if (!table->v)
|
||||
return 0;
|
||||
memset(table->v, 0, tsize);
|
||||
table->size = INIT_SIZE;
|
||||
table->usedLim = INIT_SIZE / 2;
|
||||
i = hash(name) & (table->size - 1);
|
||||
}
|
||||
else {
|
||||
unsigned long h = hash(name);
|
||||
for (i = h & (table->size - 1);
|
||||
table->v[i];
|
||||
i == 0 ? i = table->size - 1 : --i) {
|
||||
if (keyeq(name, table->v[i]->name))
|
||||
return table->v[i];
|
||||
}
|
||||
if (!createSize)
|
||||
return 0;
|
||||
if (table->used == table->usedLim) {
|
||||
/* check for overflow */
|
||||
size_t newSize = table->size * 2;
|
||||
size_t tsize = newSize * sizeof(NAMED *);
|
||||
NAMED **newV = table->mem->malloc_fcn(tsize);
|
||||
if (!newV)
|
||||
return 0;
|
||||
memset(newV, 0, tsize);
|
||||
for (i = 0; i < table->size; i++)
|
||||
if (table->v[i]) {
|
||||
size_t j;
|
||||
for (j = hash(table->v[i]->name) & (newSize - 1);
|
||||
newV[j];
|
||||
j == 0 ? j = newSize - 1 : --j)
|
||||
;
|
||||
newV[j] = table->v[i];
|
||||
}
|
||||
table->mem->free_fcn(table->v);
|
||||
table->v = newV;
|
||||
table->size = newSize;
|
||||
table->usedLim = newSize/2;
|
||||
for (i = h & (table->size - 1);
|
||||
table->v[i];
|
||||
i == 0 ? i = table->size - 1 : --i)
|
||||
;
|
||||
}
|
||||
}
|
||||
table->v[i] = table->mem->malloc_fcn(createSize);
|
||||
if (!table->v[i])
|
||||
return 0;
|
||||
memset(table->v[i], 0, createSize);
|
||||
table->v[i]->name = name;
|
||||
(table->used)++;
|
||||
return table->v[i];
|
||||
}
|
||||
|
||||
static
|
||||
void hashTableDestroy(HASH_TABLE *table)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < table->size; i++) {
|
||||
NAMED *p = table->v[i];
|
||||
if (p)
|
||||
table->mem->free_fcn(p);
|
||||
}
|
||||
if (table->v)
|
||||
table->mem->free_fcn(table->v);
|
||||
}
|
||||
|
||||
static
|
||||
void hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
|
||||
{
|
||||
p->size = 0;
|
||||
p->usedLim = 0;
|
||||
p->used = 0;
|
||||
p->v = 0;
|
||||
p->mem = ms;
|
||||
}
|
||||
|
||||
static
|
||||
void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
|
||||
{
|
||||
iter->p = table->v;
|
||||
iter->end = iter->p + table->size;
|
||||
}
|
||||
|
||||
static
|
||||
NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
|
||||
{
|
||||
while (iter->p != iter->end) {
|
||||
NAMED *tem = *(iter->p)++;
|
||||
if (tem)
|
||||
return tem;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
|
||||
{
|
||||
pool->blocks = 0;
|
||||
pool->freeBlocks = 0;
|
||||
pool->start = 0;
|
||||
pool->ptr = 0;
|
||||
pool->end = 0;
|
||||
pool->mem = ms;
|
||||
}
|
||||
|
||||
static
|
||||
void 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 = 0;
|
||||
pool->start = 0;
|
||||
pool->ptr = 0;
|
||||
pool->end = 0;
|
||||
}
|
||||
|
||||
static
|
||||
void poolDestroy(STRING_POOL *pool)
|
||||
{
|
||||
BLOCK *p = pool->blocks;
|
||||
while (p) {
|
||||
BLOCK *tem = p->next;
|
||||
pool->mem->free_fcn(p);
|
||||
p = tem;
|
||||
}
|
||||
pool->blocks = 0;
|
||||
p = pool->freeBlocks;
|
||||
while (p) {
|
||||
BLOCK *tem = p->next;
|
||||
pool->mem->free_fcn(p);
|
||||
p = tem;
|
||||
}
|
||||
pool->freeBlocks = 0;
|
||||
pool->ptr = 0;
|
||||
pool->start = 0;
|
||||
pool->end = 0;
|
||||
}
|
||||
|
||||
static
|
||||
XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
|
||||
const char *ptr, const char *end)
|
||||
{
|
||||
if (!pool->ptr && !poolGrow(pool))
|
||||
return 0;
|
||||
for (;;) {
|
||||
XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
|
||||
if (ptr == end)
|
||||
break;
|
||||
if (!poolGrow(pool))
|
||||
return 0;
|
||||
}
|
||||
return pool->start;
|
||||
}
|
||||
|
||||
static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
|
||||
{
|
||||
do {
|
||||
if (!poolAppendChar(pool, *s))
|
||||
return 0;
|
||||
} 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 0;
|
||||
for (; n > 0; --n, s++) {
|
||||
if (!poolAppendChar(pool, *s))
|
||||
return 0;
|
||||
|
||||
}
|
||||
s = pool->start;
|
||||
poolFinish(pool);
|
||||
return s;
|
||||
}
|
||||
|
||||
static
|
||||
const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s)
|
||||
{
|
||||
while (*s) {
|
||||
if (!poolAppendChar(pool, *s))
|
||||
return 0;
|
||||
s++;
|
||||
}
|
||||
return pool->start;
|
||||
} /* End poolAppendString */
|
||||
|
||||
static
|
||||
XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
|
||||
const char *ptr, const char *end)
|
||||
{
|
||||
if (!poolAppend(pool, enc, ptr, end))
|
||||
return 0;
|
||||
if (pool->ptr == pool->end && !poolGrow(pool))
|
||||
return 0;
|
||||
*(pool->ptr)++ = 0;
|
||||
return pool->start;
|
||||
}
|
||||
|
||||
static
|
||||
int poolGrow(STRING_POOL *pool)
|
||||
{
|
||||
if (pool->freeBlocks) {
|
||||
if (pool->start == 0) {
|
||||
pool->blocks = pool->freeBlocks;
|
||||
pool->freeBlocks = pool->freeBlocks->next;
|
||||
pool->blocks->next = 0;
|
||||
pool->start = pool->blocks->s;
|
||||
pool->end = pool->start + pool->blocks->size;
|
||||
pool->ptr = pool->start;
|
||||
return 1;
|
||||
}
|
||||
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 1;
|
||||
}
|
||||
}
|
||||
if (pool->blocks && pool->start == pool->blocks->s) {
|
||||
int blockSize = (pool->end - pool->start)*2;
|
||||
pool->blocks = pool->mem->realloc_fcn(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
|
||||
if (!pool->blocks)
|
||||
return 0;
|
||||
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 = pool->end - pool->start;
|
||||
if (blockSize < INIT_BLOCK_SIZE)
|
||||
blockSize = INIT_BLOCK_SIZE;
|
||||
else
|
||||
blockSize *= 2;
|
||||
tem = pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
|
||||
if (!tem)
|
||||
return 0;
|
||||
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 1;
|
||||
}
|
||||
|
||||
static int
|
||||
nextScaffoldPart(XML_Parser parser)
|
||||
{
|
||||
CONTENT_SCAFFOLD * me;
|
||||
int next;
|
||||
|
||||
if (! dtd.scaffIndex) {
|
||||
dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
|
||||
if (! dtd.scaffIndex)
|
||||
return -1;
|
||||
dtd.scaffIndex[0] = 0;
|
||||
}
|
||||
|
||||
if (dtd.scaffCount >= dtd.scaffSize) {
|
||||
if (dtd.scaffold) {
|
||||
dtd.scaffSize *= 2;
|
||||
dtd.scaffold = (CONTENT_SCAFFOLD *) REALLOC(dtd.scaffold,
|
||||
dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
|
||||
}
|
||||
else {
|
||||
dtd.scaffSize = 32;
|
||||
dtd.scaffold = (CONTENT_SCAFFOLD *) MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
|
||||
}
|
||||
if (! dtd.scaffold)
|
||||
return -1;
|
||||
}
|
||||
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;
|
||||
} /* End nextScaffoldPart */
|
||||
|
||||
static void
|
||||
build_node (XML_Parser parser,
|
||||
int src_node,
|
||||
XML_Content *dest,
|
||||
XML_Content **contpos,
|
||||
char **strpos)
|
||||
{
|
||||
dest->type = dtd.scaffold[src_node].type;
|
||||
dest->quant = dtd.scaffold[src_node].quant;
|
||||
if (dest->type == XML_CTYPE_NAME) {
|
||||
const char *src;
|
||||
dest->name = *strpos;
|
||||
src = dtd.scaffold[src_node].name;
|
||||
for (;;) {
|
||||
*(*strpos)++ = *src;
|
||||
if (! *src)
|
||||
break;
|
||||
src++;
|
||||
}
|
||||
dest->numchildren = 0;
|
||||
dest->children = 0;
|
||||
}
|
||||
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 = 0;
|
||||
}
|
||||
} /* End build_node */
|
||||
|
||||
static XML_Content *
|
||||
build_model (XML_Parser parser)
|
||||
{
|
||||
XML_Content *ret;
|
||||
XML_Content *cpos;
|
||||
char * str;
|
||||
int allocsize = dtd.scaffCount * sizeof(XML_Content) + dtd.contentStringLen;
|
||||
|
||||
ret = MALLOC(allocsize);
|
||||
if (! ret)
|
||||
return 0;
|
||||
|
||||
str = (char *) (&ret[dtd.scaffCount]);
|
||||
cpos = &ret[1];
|
||||
|
||||
build_node(parser, 0, ret, &cpos, &str);
|
||||
return ret;
|
||||
} /* End build_model */
|
||||
|
||||
static ELEMENT_TYPE *
|
||||
getElementType(XML_Parser parser,
|
||||
const ENCODING *enc,
|
||||
const char *ptr,
|
||||
const char *end)
|
||||
{
|
||||
const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
|
||||
ELEMENT_TYPE *ret;
|
||||
|
||||
if (! name)
|
||||
return 0;
|
||||
ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
|
||||
if (! ret)
|
||||
return 0;
|
||||
if (ret->name != name)
|
||||
poolDiscard(&dtd.pool);
|
||||
else {
|
||||
poolFinish(&dtd.pool);
|
||||
if (!setElementTypePrefix(parser, ret))
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
} /* End getElementType */
|
||||
@@ -1,1401 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
static char RCSId[]
|
||||
= "$Header$";
|
||||
const char* cm_expat_GetXMLRole_RCSId()
|
||||
{
|
||||
/* Avoid warning about unused static without removing RCSId from original. */
|
||||
return RCSId;
|
||||
}
|
||||
|
||||
#include <cmexpat/expatConfig.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' };
|
||||
static const char KW_IGNORE[] = { ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
|
||||
static const char KW_IMPLIED[] = { ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
|
||||
static const char KW_INCLUDE[] = { ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
|
||||
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 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,
|
||||
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 common(PROLOG_STATE *state, int tok);
|
||||
|
||||
static
|
||||
int 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_NONE;
|
||||
case XML_TOK_COMMENT:
|
||||
state->handler = prolog1;
|
||||
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_NONE;
|
||||
case XML_TOK_INSTANCE_START:
|
||||
state->handler = error;
|
||||
return XML_ROLE_INSTANCE_START;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int 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:
|
||||
case XML_TOK_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_NONE;
|
||||
case XML_TOK_INSTANCE_START:
|
||||
state->handler = error;
|
||||
return XML_ROLE_INSTANCE_START;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int prolog2(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_PI:
|
||||
case XML_TOK_COMMENT:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_INSTANCE_START:
|
||||
state->handler = error;
|
||||
return XML_ROLE_INSTANCE_START;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int doctype0(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
case XML_TOK_PREFIXED_NAME:
|
||||
state->handler = doctype1;
|
||||
return XML_ROLE_DOCTYPE_NAME;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int 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_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_NONE;
|
||||
}
|
||||
if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
|
||||
state->handler = doctype2;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int doctype2(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = doctype3;
|
||||
return XML_ROLE_DOCTYPE_PUBLIC_ID;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int doctype3(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = doctype4;
|
||||
return XML_ROLE_DOCTYPE_SYSTEM_ID;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int doctype4(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_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 doctype5(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_DECL_CLOSE:
|
||||
state->handler = prolog2;
|
||||
return XML_ROLE_DOCTYPE_CLOSE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int 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_NONE;
|
||||
}
|
||||
if (XmlNameMatchesAscii(enc,
|
||||
ptr + 2 * MIN_BYTES_PER_CHAR(enc),
|
||||
end,
|
||||
KW_ATTLIST)) {
|
||||
state->handler = attlist0;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
if (XmlNameMatchesAscii(enc,
|
||||
ptr + 2 * MIN_BYTES_PER_CHAR(enc),
|
||||
end,
|
||||
KW_ELEMENT)) {
|
||||
state->handler = element0;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
if (XmlNameMatchesAscii(enc,
|
||||
ptr + 2 * MIN_BYTES_PER_CHAR(enc),
|
||||
end,
|
||||
KW_NOTATION)) {
|
||||
state->handler = notation0;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
break;
|
||||
case XML_TOK_PI:
|
||||
case XML_TOK_COMMENT:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_PARAM_ENTITY_REF:
|
||||
return XML_ROLE_PARAM_ENTITY_REF;
|
||||
case XML_TOK_CLOSE_BRACKET:
|
||||
state->handler = doctype5;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
#ifdef XML_DTD
|
||||
|
||||
static
|
||||
int 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 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 entity0(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_PERCENT:
|
||||
state->handler = entity1;
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
state->handler = entity2;
|
||||
return XML_ROLE_GENERAL_ENTITY_NAME;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int entity1(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
state->handler = entity7;
|
||||
return XML_ROLE_PARAM_ENTITY_NAME;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int 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_NONE;
|
||||
case XML_TOK_NAME:
|
||||
if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
|
||||
state->handler = entity4;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
|
||||
state->handler = entity3;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
break;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_ENTITY_VALUE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int entity3(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = entity4;
|
||||
return XML_ROLE_ENTITY_PUBLIC_ID;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int entity4(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = entity5;
|
||||
return XML_ROLE_ENTITY_SYSTEM_ID;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int 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_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_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int entity6(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_ENTITY_NOTATION_NAME;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int 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_NONE;
|
||||
case XML_TOK_NAME:
|
||||
if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
|
||||
state->handler = entity9;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
|
||||
state->handler = entity8;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
break;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_ENTITY_VALUE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int entity8(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = entity9;
|
||||
return XML_ROLE_ENTITY_PUBLIC_ID;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int entity9(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_ENTITY_SYSTEM_ID;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int notation0(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
state->handler = notation1;
|
||||
return XML_ROLE_NOTATION_NAME;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int 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_NONE;
|
||||
case XML_TOK_NAME:
|
||||
if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
|
||||
state->handler = notation3;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
|
||||
state->handler = notation2;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int notation2(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = notation4;
|
||||
return XML_ROLE_NOTATION_PUBLIC_ID;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int notation3(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_NOTATION_SYSTEM_ID;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int notation4(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = declClose;
|
||||
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 attlist0(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_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 attlist1(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_DECL_CLOSE:
|
||||
setTopLevel(state);
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
case XML_TOK_PREFIXED_NAME:
|
||||
state->handler = attlist2;
|
||||
return XML_ROLE_ATTRIBUTE_NAME;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int attlist2(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
{
|
||||
static const char *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_NONE;
|
||||
}
|
||||
break;
|
||||
case XML_TOK_OPEN_PAREN:
|
||||
state->handler = attlist3;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int attlist3(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_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 attlist4(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_CLOSE_PAREN:
|
||||
state->handler = attlist8;
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_OR:
|
||||
state->handler = attlist3;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int attlist5(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_OPEN_PAREN:
|
||||
state->handler = attlist6;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int attlist6(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
state->handler = attlist7;
|
||||
return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int attlist7(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_CLOSE_PAREN:
|
||||
state->handler = attlist8;
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_OR:
|
||||
state->handler = attlist6;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
/* default value */
|
||||
static
|
||||
int attlist8(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_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_NONE;
|
||||
}
|
||||
break;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = attlist1;
|
||||
return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int attlist9(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_LITERAL:
|
||||
state->handler = attlist1;
|
||||
return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int element0(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
case XML_TOK_PREFIXED_NAME:
|
||||
state->handler = element1;
|
||||
return XML_ROLE_ELEMENT_NAME;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int element1(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_CONTENT_EMPTY;
|
||||
}
|
||||
if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
|
||||
state->handler = declClose;
|
||||
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 element2(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_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 element3(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_CLOSE_PAREN:
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_GROUP_CLOSE;
|
||||
case XML_TOK_CLOSE_PAREN_ASTERISK:
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_GROUP_CLOSE_REP;
|
||||
case XML_TOK_OR:
|
||||
state->handler = element4;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int element4(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_NAME:
|
||||
case XML_TOK_PREFIXED_NAME:
|
||||
state->handler = element5;
|
||||
return XML_ROLE_CONTENT_ELEMENT;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int element5(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_CLOSE_PAREN_ASTERISK:
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_GROUP_CLOSE_REP;
|
||||
case XML_TOK_OR:
|
||||
state->handler = element4;
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
static
|
||||
int element6(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_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 element7(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_CLOSE_PAREN:
|
||||
state->level -= 1;
|
||||
if (state->level == 0)
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_GROUP_CLOSE;
|
||||
case XML_TOK_CLOSE_PAREN_ASTERISK:
|
||||
state->level -= 1;
|
||||
if (state->level == 0)
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_GROUP_CLOSE_REP;
|
||||
case XML_TOK_CLOSE_PAREN_QUESTION:
|
||||
state->level -= 1;
|
||||
if (state->level == 0)
|
||||
state->handler = declClose;
|
||||
return XML_ROLE_GROUP_CLOSE_OPT;
|
||||
case XML_TOK_CLOSE_PAREN_PLUS:
|
||||
state->level -= 1;
|
||||
if (state->level == 0)
|
||||
state->handler = declClose;
|
||||
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 condSect0(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(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 condSect1(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(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 condSect2(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(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 declClose(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_PROLOG_S:
|
||||
return XML_ROLE_NONE;
|
||||
case XML_TOK_DECL_CLOSE:
|
||||
setTopLevel(state);
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static
|
||||
int ignore(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
switch (tok) {
|
||||
case XML_TOK_DECL_CLOSE:
|
||||
state->handler = internalSubset;
|
||||
return 0;
|
||||
default:
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
return common(state, tok);
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
int error(PROLOG_STATE *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc)
|
||||
{
|
||||
cmExpatUnused(state);
|
||||
cmExpatUnused(tok);
|
||||
cmExpatUnused(ptr);
|
||||
cmExpatUnused(end);
|
||||
cmExpatUnused(enc);
|
||||
return XML_ROLE_NONE;
|
||||
}
|
||||
|
||||
static
|
||||
int 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;
|
||||
#endif /* XML_DTD */
|
||||
}
|
||||
|
||||
#ifdef XML_DTD
|
||||
|
||||
void XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
|
||||
{
|
||||
state->handler = externalSubset0;
|
||||
state->documentEntity = 0;
|
||||
state->includeLevel = 0;
|
||||
}
|
||||
|
||||
#endif /* XML_DTD */
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#ifndef XmlRole_INCLUDED
|
||||
#define XmlRole_INCLUDED 1
|
||||
|
||||
#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_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_VALUE,
|
||||
XML_ROLE_ENTITY_SYSTEM_ID,
|
||||
XML_ROLE_ENTITY_PUBLIC_ID,
|
||||
XML_ROLE_ENTITY_COMPLETE,
|
||||
XML_ROLE_ENTITY_NOTATION_NAME,
|
||||
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_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_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,
|
||||
#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 (*handler)(struct prolog_state *state,
|
||||
int tok,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
const ENCODING *enc);
|
||||
unsigned level;
|
||||
#ifdef XML_DTD
|
||||
unsigned includeLevel;
|
||||
int documentEntity;
|
||||
#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 */
|
||||
@@ -1,1584 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#include <cmexpat/expatConfig.h>
|
||||
|
||||
#include "xmltok.h"
|
||||
#include "nametab.h"
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
#pragma warn -8008 // Disable "condition is always true" warning.
|
||||
#pragma warn -8066 // Disable "unreachable code" warning.
|
||||
#endif
|
||||
|
||||
#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))
|
||||
|
||||
#define UTF8_INVALID3(p) \
|
||||
((*p) == 0xED \
|
||||
? (((p)[1] & 0x20) != 0) \
|
||||
: ((*p) == 0xEF \
|
||||
? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
|
||||
: 0))
|
||||
|
||||
#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
|
||||
|
||||
static
|
||||
int isNever(const ENCODING *enc, const char *p)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
cmExpatUnused(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int utf8_isName2(const ENCODING *enc, const char *p)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
|
||||
}
|
||||
|
||||
static
|
||||
int utf8_isName3(const ENCODING *enc, const char *p)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
|
||||
}
|
||||
|
||||
#define utf8_isName4 isNever
|
||||
|
||||
static
|
||||
int utf8_isNmstrt2(const ENCODING *enc, const char *p)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
|
||||
}
|
||||
|
||||
static
|
||||
int utf8_isNmstrt3(const ENCODING *enc, const char *p)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
|
||||
}
|
||||
|
||||
#define utf8_isNmstrt4 isNever
|
||||
|
||||
#define utf8_isInvalid2 isNever
|
||||
|
||||
static
|
||||
int utf8_isInvalid3(const ENCODING *enc, const char *p)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
return UTF8_INVALID3((const unsigned char *)p);
|
||||
}
|
||||
|
||||
static
|
||||
int utf8_isInvalid4(const ENCODING *enc, const char *p)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
return UTF8_INVALID4((const unsigned char *)p);
|
||||
}
|
||||
|
||||
struct normal_encoding {
|
||||
ENCODING enc;
|
||||
unsigned char type[256];
|
||||
#ifdef XML_MIN_SIZE
|
||||
int (*byteType)(const ENCODING *, const char *);
|
||||
int (*isNameMin)(const ENCODING *, const char *);
|
||||
int (*isNmstrtMin)(const ENCODING *, const char *);
|
||||
int (*byteToAscii)(const ENCODING *, const char *);
|
||||
int (*charMatches)(const ENCODING *, const char *, int);
|
||||
#endif /* XML_MIN_SIZE */
|
||||
int (*isName2)(const ENCODING *, const char *);
|
||||
int (*isName3)(const ENCODING *, const char *);
|
||||
int (*isName4)(const ENCODING *, const char *);
|
||||
int (*isNmstrt2)(const ENCODING *, const char *);
|
||||
int (*isNmstrt3)(const ENCODING *, const char *);
|
||||
int (*isNmstrt4)(const ENCODING *, const char *);
|
||||
int (*isInvalid2)(const ENCODING *, const char *);
|
||||
int (*isInvalid3)(const ENCODING *, const char *);
|
||||
int (*isInvalid4)(const ENCODING *, const char *);
|
||||
};
|
||||
|
||||
#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
|
||||
|
||||
#define EMPTY_VTABLE(E) 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
static int 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 sb_byteType(const ENCODING *enc, const char *p)
|
||||
{
|
||||
return SB_BYTE_TYPE(enc, p);
|
||||
}
|
||||
#define BYTE_TYPE(enc, p) \
|
||||
(((const struct 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) \
|
||||
(((const struct normal_encoding *)(enc))->byteToAscii(enc, p))
|
||||
static
|
||||
int 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) \
|
||||
(((const struct normal_encoding *)(enc))->isName ## n(enc, p))
|
||||
#define IS_NMSTRT_CHAR(enc, p, n) \
|
||||
(((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))
|
||||
#define IS_INVALID_CHAR(enc, p, n) \
|
||||
(((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))
|
||||
|
||||
#ifdef XML_MIN_SIZE
|
||||
#define IS_NAME_CHAR_MINBPC(enc, p) \
|
||||
(((const struct normal_encoding *)(enc))->isNameMin(enc, p))
|
||||
#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
|
||||
(((const struct 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) \
|
||||
(((const struct normal_encoding *)(enc))->charMatches(enc, p, c))
|
||||
static
|
||||
int 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
|
||||
#include "xmltok_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 utf8_toUtf8(const ENCODING *enc,
|
||||
const char **fromP, const char *fromLim,
|
||||
char **toP, const char *toLim)
|
||||
{
|
||||
char *to;
|
||||
const char *from;
|
||||
cmExpatUnused(enc);
|
||||
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 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++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f);
|
||||
from += 2;
|
||||
break;
|
||||
case BT_LEAD3:
|
||||
*to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f);
|
||||
from += 3;
|
||||
break;
|
||||
case BT_LEAD4:
|
||||
{
|
||||
unsigned long n;
|
||||
if (to + 1 == toLim)
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
*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 latin1_toUtf8(const ENCODING *enc,
|
||||
const char **fromP, const char *fromLim,
|
||||
char **toP, const char *toLim)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
for (;;) {
|
||||
unsigned char c;
|
||||
if (*fromP == fromLim)
|
||||
break;
|
||||
c = (unsigned char)**fromP;
|
||||
if (c & 0x80) {
|
||||
if (toLim - *toP < 2)
|
||||
break;
|
||||
*(*toP)++ = ((c >> 6) | UTF8_cval2);
|
||||
*(*toP)++ = ((c & 0x3f) | 0x80);
|
||||
(*fromP)++;
|
||||
}
|
||||
else {
|
||||
if (*toP == toLim)
|
||||
break;
|
||||
*(*toP)++ = *(*fromP)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void latin1_toUtf16(const ENCODING *enc,
|
||||
const char **fromP, const char *fromLim,
|
||||
unsigned short **toP, const unsigned short *toLim)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
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_) EMPTY_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_) EMPTY_VTABLE(sb_)
|
||||
};
|
||||
|
||||
static
|
||||
void ascii_toUtf8(const ENCODING *enc,
|
||||
const char **fromP, const char *fromLim,
|
||||
char **toP, const char *toLim)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
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_) EMPTY_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_) EMPTY_VTABLE(sb_)
|
||||
};
|
||||
|
||||
static int 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 E ## toUtf8(const ENCODING *enc, \
|
||||
const char **fromP, const char *fromLim, \
|
||||
char **toP, const char *toLim) \
|
||||
{ \
|
||||
const char *from; \
|
||||
cmExpatUnused(enc);\
|
||||
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 E ## toUtf16(const ENCODING *enc, \
|
||||
const char **fromP, const char *fromLim, \
|
||||
unsigned short **toP, const unsigned short *toLim) \
|
||||
{ \
|
||||
cmExpatUnused(enc);\
|
||||
/* 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 little2_byteType(const ENCODING *enc, const char *p)
|
||||
{
|
||||
return LITTLE2_BYTE_TYPE(enc, p);
|
||||
}
|
||||
|
||||
static
|
||||
int little2_byteToAscii(const ENCODING *enc, const char *p)
|
||||
{
|
||||
return LITTLE2_BYTE_TO_ASCII(enc, p);
|
||||
}
|
||||
|
||||
static
|
||||
int little2_charMatches(const ENCODING *enc, const char *p, int c)
|
||||
{
|
||||
return LITTLE2_CHAR_MATCHES(enc, p, c);
|
||||
}
|
||||
|
||||
static
|
||||
int little2_isNameMin(const ENCODING *enc, const char *p)
|
||||
{
|
||||
return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
|
||||
}
|
||||
|
||||
static
|
||||
int 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)
|
||||
|
||||
#include "xmltok_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 XML_BYTE_ORDER == 12
|
||||
1
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
},
|
||||
{
|
||||
#include "asciitab.h"
|
||||
#include "latin1tab.h"
|
||||
},
|
||||
STANDARD_VTABLE(little2_) EMPTY_VTABLE(little2_)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static const struct normal_encoding little2_encoding = {
|
||||
{ VTABLE, 2, 0,
|
||||
#if XML_BYTE_ORDER == 12
|
||||
1
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
},
|
||||
{
|
||||
#define BT_COLON BT_NMSTRT
|
||||
#include "asciitab.h"
|
||||
#undef BT_COLON
|
||||
#include "latin1tab.h"
|
||||
},
|
||||
STANDARD_VTABLE(little2_) EMPTY_VTABLE(little2_)
|
||||
};
|
||||
|
||||
#if XML_BYTE_ORDER != 21
|
||||
|
||||
#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_) EMPTY_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_) EMPTY_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 big2_byteType(const ENCODING *enc, const char *p)
|
||||
{
|
||||
return BIG2_BYTE_TYPE(enc, p);
|
||||
}
|
||||
|
||||
static
|
||||
int big2_byteToAscii(const ENCODING *enc, const char *p)
|
||||
{
|
||||
return BIG2_BYTE_TO_ASCII(enc, p);
|
||||
}
|
||||
|
||||
static
|
||||
int big2_charMatches(const ENCODING *enc, const char *p, int c)
|
||||
{
|
||||
return BIG2_CHAR_MATCHES(enc, p, c);
|
||||
}
|
||||
|
||||
static
|
||||
int big2_isNameMin(const ENCODING *enc, const char *p)
|
||||
{
|
||||
return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
|
||||
}
|
||||
|
||||
static
|
||||
int 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)
|
||||
|
||||
#include "xmltok_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 XML_BYTE_ORDER == 21
|
||||
1
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
},
|
||||
{
|
||||
#include "asciitab.h"
|
||||
#include "latin1tab.h"
|
||||
},
|
||||
STANDARD_VTABLE(big2_) EMPTY_VTABLE(big2_)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static const struct normal_encoding big2_encoding = {
|
||||
{ VTABLE, 2, 0,
|
||||
#if XML_BYTE_ORDER == 21
|
||||
1
|
||||
#else
|
||||
0
|
||||
#endif
|
||||
},
|
||||
{
|
||||
#define BT_COLON BT_NMSTRT
|
||||
#include "asciitab.h"
|
||||
#undef BT_COLON
|
||||
#include "latin1tab.h"
|
||||
},
|
||||
STANDARD_VTABLE(big2_) EMPTY_VTABLE(big2_)
|
||||
};
|
||||
|
||||
#if XML_BYTE_ORDER != 12
|
||||
|
||||
#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_) EMPTY_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_) EMPTY_VTABLE(big2_)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#undef PREFIX
|
||||
|
||||
static
|
||||
int 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 initUpdatePosition(const ENCODING *enc, const char *ptr,
|
||||
const char *end, POSITION *pos)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
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 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 = 0;
|
||||
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 = 0;
|
||||
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 = 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 = 0;
|
||||
const char *name = 0;
|
||||
const char *nameEnd = 0;
|
||||
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 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 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] = (c | UTF8_cval1);
|
||||
return 1;
|
||||
}
|
||||
if (c < min3) {
|
||||
buf[0] = ((c >> 6) | UTF8_cval2);
|
||||
buf[1] = ((c & 0x3f) | 0x80);
|
||||
return 2;
|
||||
}
|
||||
if (c < min4) {
|
||||
buf[0] = ((c >> 12) | UTF8_cval3);
|
||||
buf[1] = (((c >> 6) & 0x3f) | 0x80);
|
||||
buf[2] = ((c & 0x3f) | 0x80);
|
||||
return 3;
|
||||
}
|
||||
if (c < 0x110000) {
|
||||
buf[0] = ((c >> 18) | UTF8_cval4);
|
||||
buf[1] = (((c >> 12) & 0x3f) | 0x80);
|
||||
buf[2] = (((c >> 6) & 0x3f) | 0x80);
|
||||
buf[3] = ((c & 0x3f) | 0x80);
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int XmlUtf16Encode(int charNum, unsigned short *buf)
|
||||
{
|
||||
if (charNum < 0)
|
||||
return 0;
|
||||
if (charNum < 0x10000) {
|
||||
buf[0] = charNum;
|
||||
return 1;
|
||||
}
|
||||
if (charNum < 0x110000) {
|
||||
charNum -= 0x10000;
|
||||
buf[0] = (charNum >> 10) + 0xD800;
|
||||
buf[1] = (charNum & 0x3FF) + 0xDC00;
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct unknown_encoding {
|
||||
struct normal_encoding normal;
|
||||
int (*convert)(void *userData, const char *p);
|
||||
void *userData;
|
||||
unsigned short utf16[256];
|
||||
char utf8[256][4];
|
||||
};
|
||||
|
||||
int XmlSizeOfUnknownEncoding(void)
|
||||
{
|
||||
return sizeof(struct unknown_encoding);
|
||||
}
|
||||
|
||||
static
|
||||
int unknown_isName(const ENCODING *enc, const char *p)
|
||||
{
|
||||
int c = ((const struct unknown_encoding *)enc)
|
||||
->convert(((const struct unknown_encoding *)enc)->userData, p);
|
||||
if (c & ~0xFFFF)
|
||||
return 0;
|
||||
return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
|
||||
}
|
||||
|
||||
static
|
||||
int unknown_isNmstrt(const ENCODING *enc, const char *p)
|
||||
{
|
||||
int c = ((const struct unknown_encoding *)enc)
|
||||
->convert(((const struct unknown_encoding *)enc)->userData, p);
|
||||
if (c & ~0xFFFF)
|
||||
return 0;
|
||||
return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
|
||||
}
|
||||
|
||||
static
|
||||
int unknown_isInvalid(const ENCODING *enc, const char *p)
|
||||
{
|
||||
int c = ((const struct unknown_encoding *)enc)
|
||||
->convert(((const struct unknown_encoding *)enc)->userData, p);
|
||||
return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
|
||||
}
|
||||
|
||||
static
|
||||
void unknown_toUtf8(const ENCODING *enc,
|
||||
const char **fromP, const char *fromLim,
|
||||
char **toP, const char *toLim)
|
||||
{
|
||||
char buf[XML_UTF8_ENCODE_MAX];
|
||||
for (;;) {
|
||||
const char *utf8;
|
||||
int n;
|
||||
if (*fromP == fromLim)
|
||||
break;
|
||||
utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP];
|
||||
n = *utf8++;
|
||||
if (n == 0) {
|
||||
int c = ((const struct unknown_encoding *)enc)
|
||||
->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
|
||||
n = XmlUtf8Encode(c, buf);
|
||||
if (n > toLim - *toP)
|
||||
break;
|
||||
utf8 = buf;
|
||||
*fromP += ((const struct 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 unknown_toUtf16(const ENCODING *enc,
|
||||
const char **fromP, const char *fromLim,
|
||||
unsigned short **toP, const unsigned short *toLim)
|
||||
{
|
||||
while (*fromP != fromLim && *toP != toLim) {
|
||||
unsigned short c
|
||||
= ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP];
|
||||
if (c == 0) {
|
||||
c = (unsigned short)((const struct unknown_encoding *)enc)
|
||||
->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
|
||||
*fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
|
||||
- (BT_LEAD2 - 2);
|
||||
}
|
||||
else
|
||||
(*fromP)++;
|
||||
*(*toP)++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
ENCODING *
|
||||
XmlInitUnknownEncoding(void *mem,
|
||||
int *table,
|
||||
int (*convert)(void *userData, const char *p),
|
||||
void *userData)
|
||||
{
|
||||
int i;
|
||||
struct unknown_encoding *e = 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] = 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] = 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] = 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 getEncodingIndex(const char *name)
|
||||
{
|
||||
static const char *encodingNames[] = {
|
||||
KW_ISO_8859_1,
|
||||
KW_US_ASCII,
|
||||
KW_UTF_8,
|
||||
KW_UTF_16,
|
||||
KW_UTF_16BE,
|
||||
KW_UTF_16LE,
|
||||
};
|
||||
int i;
|
||||
if (name == 0)
|
||||
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 **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
|
||||
#include "xmltok_ns.c"
|
||||
#undef NS
|
||||
#undef ns
|
||||
|
||||
#ifdef XML_NS
|
||||
|
||||
#define NS(x) x ## NS
|
||||
#define ns(x) x ## _ns
|
||||
|
||||
#include "xmltok_ns.c"
|
||||
|
||||
#undef NS
|
||||
#undef ns
|
||||
|
||||
ENCODING *
|
||||
XmlInitUnknownEncodingNS(void *mem,
|
||||
int *table,
|
||||
int (*convert)(void *userData, const char *p),
|
||||
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 */
|
||||
@@ -1,299 +0,0 @@
|
||||
/*
|
||||
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 */
|
||||
unsigned long lineNumber;
|
||||
unsigned long columnNumber;
|
||||
} POSITION;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const char *valuePtr;
|
||||
const char *valueEnd;
|
||||
char normalized;
|
||||
} ATTRIBUTE;
|
||||
|
||||
struct encoding;
|
||||
typedef struct encoding ENCODING;
|
||||
|
||||
struct encoding {
|
||||
int (*scanners[XML_N_STATES])(const ENCODING *,
|
||||
const char *,
|
||||
const char *,
|
||||
const char **);
|
||||
int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *,
|
||||
const char *,
|
||||
const char *,
|
||||
const char **);
|
||||
int (*sameName)(const ENCODING *,
|
||||
const char *, const char *);
|
||||
int (*nameMatchesAscii)(const ENCODING *,
|
||||
const char *, const char *, const char *);
|
||||
int (*nameLength)(const ENCODING *, const char *);
|
||||
const char *(*skipS)(const ENCODING *, const char *);
|
||||
int (*getAtts)(const ENCODING *enc, const char *ptr,
|
||||
int attsMax, ATTRIBUTE *atts);
|
||||
int (*charRefNumber)(const ENCODING *enc, const char *ptr);
|
||||
int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
|
||||
void (*updatePosition)(const ENCODING *,
|
||||
const char *ptr,
|
||||
const char *end,
|
||||
POSITION *);
|
||||
int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
|
||||
const char **badPtr);
|
||||
void (*utf8Convert)(const ENCODING *enc,
|
||||
const char **fromP,
|
||||
const char *fromLim,
|
||||
char **toP,
|
||||
const char *toLim);
|
||||
void (*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 XmlUtf8Encode(int charNumber, char *buf);
|
||||
int XmlUtf16Encode(int charNumber, unsigned short *buf);
|
||||
|
||||
int XmlSizeOfUnknownEncoding(void);
|
||||
ENCODING *
|
||||
XmlInitUnknownEncoding(void *mem,
|
||||
int *table,
|
||||
int (*conv)(void *userData, const char *p),
|
||||
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,
|
||||
int (*conv)(void *userData, const char *p),
|
||||
void *userData);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* not XmlTok_INCLUDED */
|
||||
@@ -1,1775 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
|
||||
See the file COPYING for copying permission.
|
||||
*/
|
||||
|
||||
#ifndef IS_INVALID_CHAR
|
||||
#define IS_INVALID_CHAR(enc, ptr, n) (0)
|
||||
#endif
|
||||
|
||||
#ifndef INVALID_LEAD_CASE
|
||||
#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;
|
||||
#endif
|
||||
|
||||
#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 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 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 PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr)
|
||||
{
|
||||
int upper = 0;
|
||||
cmExpatUnused(enc);
|
||||
*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 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 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;
|
||||
cmExpatUnused(enc);
|
||||
/* 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 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 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 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 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 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 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 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 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 PREFIX(scanPercent)(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_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 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 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 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)
|
||||
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 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 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 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 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 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 PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
|
||||
{
|
||||
int result = 0;
|
||||
cmExpatUnused(enc);
|
||||
/* 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 PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
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 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 PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
|
||||
const char *end1, const char *ptr2)
|
||||
{
|
||||
cmExpatUnused(enc);
|
||||
for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
|
||||
if (ptr1 == end1)
|
||||
return 0;
|
||||
if (!CHAR_MATCHES(enc, ptr1, *ptr2))
|
||||
return 0;
|
||||
}
|
||||
return ptr1 == end1;
|
||||
}
|
||||
|
||||
static
|
||||
int 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 ptr - start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
const char *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 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 = (unsigned)-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 = (unsigned)-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
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
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>
|
||||
@@ -1,98 +0,0 @@
|
||||
const ENCODING *NS(XmlGetUtf8InternalEncoding)(void)
|
||||
{
|
||||
return &ns(internal_utf8_encoding).enc;
|
||||
}
|
||||
|
||||
const ENCODING *NS(XmlGetUtf16InternalEncoding)(void)
|
||||
{
|
||||
#if XML_BYTE_ORDER == 12
|
||||
return &ns(internal_little2_encoding).enc;
|
||||
#elif XML_BYTE_ORDER == 21
|
||||
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 *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 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 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);
|
||||
}
|
||||
Reference in New Issue
Block a user