2001-02-23 17:55:21 +00:00
/*
* parser . c : an XML 1.0 parser , namespaces and validity support are mostly
* implemented on top of the SAX interfaces
*
* References :
* The XML specification :
* http : //www.w3.org/TR/REC-xml
* Original 1.0 version :
* http : //www.w3.org/TR/1998/REC-xml-19980210
* XML second edition working draft
* http : //www.w3.org/TR/2000/WD-xml-2e-20000814
*
* Okay this is a big file , the parser core is around 7000 lines , then it
* is followed by the progressive parser top routines , then the various
2001-12-31 16:16:02 +00:00
* high level APIs to call the parser and a few miscellaneous functions .
2001-02-23 17:55:21 +00:00
* A number of helper functions and deprecated ones have been moved to
* parserInternals . c to reduce this file size .
* As much as possible the functions are associated with their relative
* production in the XML specification . A few productions defining the
* different ranges of character are actually implanted either in
* parserInternals . h or parserInternals . c
* The DOM tree build is realized from the default SAX callbacks in
* the module SAX . c .
* The routines doing the validation checks are in valid . c and called either
2001-12-31 16:16:02 +00:00
* from the SAX callbacks or as standalone functions using a preparsed
2001-02-23 17:55:21 +00:00
* document .
*
* See Copyright for the status of this software .
*
2001-06-24 12:13:24 +00:00
* daniel @ veillard . com
2001-02-23 17:55:21 +00:00
*/
2002-03-18 19:37:11 +00:00
# define IN_LIBXML
2001-04-21 16:57:29 +00:00
# include "libxml.h"
2002-01-08 10:36:16 +00:00
# if defined(WIN32) && !defined (__CYGWIN__)
2001-02-23 17:55:21 +00:00
# define XML_DIR_SEP '\\'
# else
# define XML_DIR_SEP ' / '
# endif
# include <stdlib.h>
# include <string.h>
# include <libxml/xmlmemory.h>
2001-10-13 09:15:48 +00:00
# include <libxml/threads.h>
# include <libxml/globals.h>
2001-02-23 17:55:21 +00:00
# include <libxml/tree.h>
# include <libxml/parser.h>
# include <libxml/parserInternals.h>
# include <libxml/valid.h>
# include <libxml/entities.h>
# include <libxml/xmlerror.h>
# include <libxml/encoding.h>
# include <libxml/xmlIO.h>
# include <libxml/uri.h>
2001-08-22 14:29:45 +00:00
# ifdef LIBXML_CATALOG_ENABLED
# include <libxml/catalog.h>
# endif
2001-02-23 17:55:21 +00:00
# ifdef HAVE_CTYPE_H
# include <ctype.h>
# endif
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
# ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
# endif
# ifdef HAVE_FCNTL_H
# include <fcntl.h>
# endif
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
# ifdef HAVE_ZLIB_H
# include <zlib.h>
# endif
2003-02-03 08:52:58 +00:00
/**
* MAX_DEPTH :
*
* arbitrary depth limit for the XML documents that we allow to
* process . This is not a limitation of the parser but a safety
* boundary feature .
*/
# define MAX_DEPTH 1024
2001-02-23 17:55:21 +00:00
2001-02-25 19:54:14 +00:00
# define XML_PARSER_BIG_BUFFER_SIZE 300
2001-02-23 17:55:21 +00:00
# define XML_PARSER_BUFFER_SIZE 100
2002-03-18 18:36:20 +00:00
# define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
2001-02-23 17:55:21 +00:00
/*
* List of XML prefixed PI allowed by W3C specs
*/
2001-10-11 22:55:55 +00:00
static const char * xmlW3CPIs [ ] = {
2001-02-23 17:55:21 +00:00
" xml-stylesheet " ,
NULL
} ;
/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
xmlEntityPtr xmlParseStringPEReference ( xmlParserCtxtPtr ctxt ,
const xmlChar * * str ) ;
2001-05-08 10:41:44 +00:00
static int
2001-05-20 13:19:52 +00:00
xmlParseExternalEntityPrivate ( xmlDocPtr doc , xmlParserCtxtPtr oldctxt ,
xmlSAXHandlerPtr sax ,
2001-05-08 10:41:44 +00:00
void * user_data , int depth , const xmlChar * URL ,
2001-05-20 13:19:52 +00:00
const xmlChar * ID , xmlNodePtr * list ) ;
2001-02-23 17:55:21 +00:00
2002-01-13 14:10:10 +00:00
static void
xmlAddEntityReference ( xmlEntityPtr ent , xmlNodePtr firstNode ,
xmlNodePtr lastNode ) ;
2002-11-15 15:24:34 +00:00
static int
xmlParseBalancedChunkMemoryInternal ( xmlParserCtxtPtr oldctxt ,
const xmlChar * string , void * user_data , xmlNodePtr * lst ) ;
2001-02-23 17:55:21 +00:00
/************************************************************************
* *
* Parser stacks related functions and macros *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
xmlEntityPtr xmlParseStringEntityRef ( xmlParserCtxtPtr ctxt ,
const xmlChar * * str ) ;
2001-07-18 19:30:27 +00:00
/**
* inputPush :
* @ ctxt : an XML parser context
2002-01-22 18:15:52 +00:00
* @ value : the parser input
2001-07-18 19:30:27 +00:00
*
* Pushes a new parser input on top of the input stack
2002-01-22 18:15:52 +00:00
*
* Returns 0 in case of error , the index in the stack otherwise
2001-07-18 19:30:27 +00:00
*/
2002-11-30 11:22:59 +00:00
extern int
inputPush ( xmlParserCtxtPtr ctxt , xmlParserInputPtr value )
{
if ( ctxt - > inputNr > = ctxt - > inputMax ) {
ctxt - > inputMax * = 2 ;
ctxt - > inputTab =
( xmlParserInputPtr * ) xmlRealloc ( ctxt - > inputTab ,
ctxt - > inputMax *
sizeof ( ctxt - > inputTab [ 0 ] ) ) ;
if ( ctxt - > inputTab = = NULL ) {
xmlGenericError ( xmlGenericErrorContext , " realloc failed ! \n " ) ;
return ( 0 ) ;
}
}
ctxt - > inputTab [ ctxt - > inputNr ] = value ;
ctxt - > input = value ;
return ( ctxt - > inputNr + + ) ;
}
2001-07-18 19:30:27 +00:00
/**
2002-11-30 11:22:59 +00:00
* inputPop :
2001-07-18 19:30:27 +00:00
* @ ctxt : an XML parser context
*
2002-11-30 11:22:59 +00:00
* Pops the top parser input from the input stack
2001-07-18 19:30:27 +00:00
*
2002-11-30 11:22:59 +00:00
* Returns the input just removed
2001-07-18 19:30:27 +00:00
*/
2002-11-30 11:22:59 +00:00
extern xmlParserInputPtr
inputPop ( xmlParserCtxtPtr ctxt )
{
xmlParserInputPtr ret ;
if ( ctxt - > inputNr < = 0 )
return ( 0 ) ;
ctxt - > inputNr - - ;
if ( ctxt - > inputNr > 0 )
ctxt - > input = ctxt - > inputTab [ ctxt - > inputNr - 1 ] ;
else
ctxt - > input = NULL ;
ret = ctxt - > inputTab [ ctxt - > inputNr ] ;
ctxt - > inputTab [ ctxt - > inputNr ] = 0 ;
return ( ret ) ;
}
2001-07-18 19:30:27 +00:00
/**
2002-11-30 11:22:59 +00:00
* nodePush :
2001-07-18 19:30:27 +00:00
* @ ctxt : an XML parser context
2002-11-30 11:22:59 +00:00
* @ value : the element node
2001-07-18 19:30:27 +00:00
*
2002-11-30 11:22:59 +00:00
* Pushes a new element node on top of the node stack
2002-01-22 18:15:52 +00:00
*
* Returns 0 in case of error , the index in the stack otherwise
2001-07-18 19:30:27 +00:00
*/
2002-11-30 11:22:59 +00:00
extern int
nodePush ( xmlParserCtxtPtr ctxt , xmlNodePtr value )
{
if ( ctxt - > nodeNr > = ctxt - > nodeMax ) {
ctxt - > nodeMax * = 2 ;
ctxt - > nodeTab =
( xmlNodePtr * ) xmlRealloc ( ctxt - > nodeTab ,
ctxt - > nodeMax *
sizeof ( ctxt - > nodeTab [ 0 ] ) ) ;
if ( ctxt - > nodeTab = = NULL ) {
xmlGenericError ( xmlGenericErrorContext , " realloc failed ! \n " ) ;
return ( 0 ) ;
}
}
2003-02-03 08:52:58 +00:00
# ifdef MAX_DEPTH
if ( ctxt - > nodeNr > MAX_DEPTH ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Excessive depth in document: change MAX_DEPTH = %d \n " ,
MAX_DEPTH ) ;
ctxt - > wellFormed = 0 ;
ctxt - > instate = XML_PARSER_EOF ;
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
return ( 0 ) ;
}
# endif
2002-11-30 11:22:59 +00:00
ctxt - > nodeTab [ ctxt - > nodeNr ] = value ;
ctxt - > node = value ;
return ( ctxt - > nodeNr + + ) ;
}
2001-07-18 19:30:27 +00:00
/**
* nodePop :
* @ ctxt : an XML parser context
*
* Pops the top element node from the node stack
*
* Returns the node just removed
*/
2002-11-30 11:22:59 +00:00
extern xmlNodePtr
nodePop ( xmlParserCtxtPtr ctxt )
{
xmlNodePtr ret ;
if ( ctxt - > nodeNr < = 0 )
return ( 0 ) ;
ctxt - > nodeNr - - ;
if ( ctxt - > nodeNr > 0 )
ctxt - > node = ctxt - > nodeTab [ ctxt - > nodeNr - 1 ] ;
else
ctxt - > node = NULL ;
ret = ctxt - > nodeTab [ ctxt - > nodeNr ] ;
ctxt - > nodeTab [ ctxt - > nodeNr ] = 0 ;
return ( ret ) ;
}
2001-07-18 19:30:27 +00:00
/**
2002-11-30 11:22:59 +00:00
* namePush :
2001-07-18 19:30:27 +00:00
* @ ctxt : an XML parser context
2002-11-30 11:22:59 +00:00
* @ value : the element name
2001-07-18 19:30:27 +00:00
*
2002-11-30 11:22:59 +00:00
* Pushes a new element name on top of the name stack
2002-01-22 18:15:52 +00:00
*
* Returns 0 in case of error , the index in the stack otherwise
2001-07-18 19:30:27 +00:00
*/
2002-11-30 11:22:59 +00:00
extern int
namePush ( xmlParserCtxtPtr ctxt , xmlChar * value )
{
if ( ctxt - > nameNr > = ctxt - > nameMax ) {
ctxt - > nameMax * = 2 ;
ctxt - > nameTab =
( xmlChar * * ) xmlRealloc ( ctxt - > nameTab ,
ctxt - > nameMax *
sizeof ( ctxt - > nameTab [ 0 ] ) ) ;
if ( ctxt - > nameTab = = NULL ) {
xmlGenericError ( xmlGenericErrorContext , " realloc failed ! \n " ) ;
return ( 0 ) ;
}
}
ctxt - > nameTab [ ctxt - > nameNr ] = value ;
ctxt - > name = value ;
return ( ctxt - > nameNr + + ) ;
}
/**
* namePop :
* @ ctxt : an XML parser context
*
* Pops the top element name from the name stack
*
* Returns the name just removed
2001-02-23 17:55:21 +00:00
*/
2002-11-30 11:22:59 +00:00
extern xmlChar *
namePop ( xmlParserCtxtPtr ctxt )
{
xmlChar * ret ;
if ( ctxt - > nameNr < = 0 )
return ( 0 ) ;
ctxt - > nameNr - - ;
if ( ctxt - > nameNr > 0 )
ctxt - > name = ctxt - > nameTab [ ctxt - > nameNr - 1 ] ;
else
ctxt - > name = NULL ;
ret = ctxt - > nameTab [ ctxt - > nameNr ] ;
ctxt - > nameTab [ ctxt - > nameNr ] = 0 ;
return ( ret ) ;
}
2001-02-23 17:55:21 +00:00
2001-03-24 17:00:36 +00:00
static int spacePush ( xmlParserCtxtPtr ctxt , int val ) {
2001-02-23 17:55:21 +00:00
if ( ctxt - > spaceNr > = ctxt - > spaceMax ) {
ctxt - > spaceMax * = 2 ;
ctxt - > spaceTab = ( int * ) xmlRealloc ( ctxt - > spaceTab ,
ctxt - > spaceMax * sizeof ( ctxt - > spaceTab [ 0 ] ) ) ;
if ( ctxt - > spaceTab = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc failed ! \n " ) ;
return ( 0 ) ;
}
}
ctxt - > spaceTab [ ctxt - > spaceNr ] = val ;
ctxt - > space = & ctxt - > spaceTab [ ctxt - > spaceNr ] ;
return ( ctxt - > spaceNr + + ) ;
}
2001-03-24 17:00:36 +00:00
static int spacePop ( xmlParserCtxtPtr ctxt ) {
2001-02-23 17:55:21 +00:00
int ret ;
if ( ctxt - > spaceNr < = 0 ) return ( 0 ) ;
ctxt - > spaceNr - - ;
if ( ctxt - > spaceNr > 0 )
ctxt - > space = & ctxt - > spaceTab [ ctxt - > spaceNr - 1 ] ;
else
ctxt - > space = NULL ;
ret = ctxt - > spaceTab [ ctxt - > spaceNr ] ;
ctxt - > spaceTab [ ctxt - > spaceNr ] = - 1 ;
return ( ret ) ;
}
/*
* Macros for accessing the content . Those should be used only by the parser ,
* and not exported .
*
* Dirty macros , i . e . one often need to make assumption on the context to
* use them
*
* CUR_PTR return the current pointer to the xmlChar to be parsed .
* To be used with extreme caution since operations consuming
* characters may move the input buffer to a different location !
* CUR returns the current xmlChar value , i . e . a 8 bit value if compiled
* This should be used internally by the parser
* only to compare to ASCII values otherwise it would break when
* running with UTF - 8 encoding .
* RAW same as CUR but in the input buffer , bypass any token
* extraction that may have been done
* NXT ( n ) returns the n ' th next xmlChar . Same as CUR is should be used only
* to compare on ASCII based substring .
* SKIP ( n ) Skip n xmlChar , and must also be used only to skip ASCII defined
* strings within the parser .
*
* Clean macros , not dependent of an ASCII context , expect UTF - 8 encoding
*
* NEXT Skip to the next character , this does the proper decoding
* in UTF - 8 mode . It also pop - up unfinished entities on the fly .
2001-12-31 16:16:02 +00:00
* NEXTL ( l ) Skip l xmlChar in the input buffer
2001-02-23 17:55:21 +00:00
* CUR_CHAR ( l ) returns the current unicode character ( int ) , set l
* to the number of xmlChars used for the encoding [ 0 - 5 ] .
* CUR_SCHAR same but operate on a string instead of the context
* COPY_BUF copy the current unicode char to the target buffer , increment
* the index
* GROW , SHRINK handling of input buffers
*/
2002-07-01 21:52:03 +00:00
# define RAW (*ctxt->input->cur)
# define CUR (*ctxt->input->cur)
2001-02-23 17:55:21 +00:00
# define NXT(val) ctxt->input->cur[(val)]
# define CUR_PTR ctxt->input->cur
# define SKIP(val) do { \
ctxt - > nbChars + = ( val ) , ctxt - > input - > cur + = ( val ) ; \
if ( * ctxt - > input - > cur = = ' % ' ) xmlParserHandlePEReference ( ctxt ) ; \
2002-03-20 21:55:57 +00:00
if ( ( * ctxt - > input - > cur = = 0 ) & & \
2001-02-23 17:55:21 +00:00
( xmlParserInputGrow ( ctxt - > input , INPUT_CHUNK ) < = 0 ) ) \
xmlPopInput ( ctxt ) ; \
} while ( 0 )
2002-05-29 08:21:33 +00:00
# define SHRINK if (ctxt->input->cur - ctxt->input->base > INPUT_CHUNK) \
xmlSHRINK ( ctxt ) ;
static void xmlSHRINK ( xmlParserCtxtPtr ctxt ) {
xmlParserInputShrink ( ctxt - > input ) ;
if ( ( * ctxt - > input - > cur = = 0 ) & &
( xmlParserInputGrow ( ctxt - > input , INPUT_CHUNK ) < = 0 ) )
xmlPopInput ( ctxt ) ;
2001-02-25 16:11:03 +00:00
}
2001-02-23 17:55:21 +00:00
2002-05-29 08:21:33 +00:00
# define GROW if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) \
xmlGROW ( ctxt ) ;
static void xmlGROW ( xmlParserCtxtPtr ctxt ) {
xmlParserInputGrow ( ctxt - > input , INPUT_CHUNK ) ;
if ( ( * ctxt - > input - > cur = = 0 ) & &
( xmlParserInputGrow ( ctxt - > input , INPUT_CHUNK ) < = 0 ) )
xmlPopInput ( ctxt ) ;
2001-02-25 16:11:03 +00:00
}
2001-02-23 17:55:21 +00:00
# define SKIP_BLANKS xmlSkipBlankChars(ctxt)
# define NEXT xmlNextChar(ctxt)
2001-02-25 19:54:14 +00:00
# define NEXT1 { \
ctxt - > input - > cur + + ; \
ctxt - > nbChars + + ; \
2002-03-20 21:55:57 +00:00
if ( * ctxt - > input - > cur = = 0 ) \
2001-02-25 19:54:14 +00:00
xmlParserInputGrow ( ctxt - > input , INPUT_CHUNK ) ; \
}
2001-02-23 17:55:21 +00:00
# define NEXTL(l) do { \
if ( * ( ctxt - > input - > cur ) = = ' \n ' ) { \
ctxt - > input - > line + + ; ctxt - > input - > col = 1 ; \
} else ctxt - > input - > col + + ; \
2002-07-01 21:52:03 +00:00
ctxt - > input - > cur + = l ; \
2001-02-23 17:55:21 +00:00
if ( * ctxt - > input - > cur = = ' % ' ) xmlParserHandlePEReference ( ctxt ) ; \
} while ( 0 )
# define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
# define CUR_SCHAR(s, l) xmlStringCurrentChar(ctxt, s, &l)
# define COPY_BUF(l,b,i,v) \
if ( l = = 1 ) b [ i + + ] = ( xmlChar ) v ; \
2001-03-24 17:00:36 +00:00
else i + = xmlCopyCharMultiByte ( & b [ i ] , v )
2001-02-23 17:55:21 +00:00
/**
* xmlSkipBlankChars :
* @ ctxt : the XML parser context
*
* skip all blanks character found at that point in the input streams .
* It pops up finished entities in the process if allowable at that point .
*
* Returns the number of space chars skipped
*/
int
xmlSkipBlankChars ( xmlParserCtxtPtr ctxt ) {
2001-04-30 11:46:40 +00:00
int res = 0 ;
2001-02-23 17:55:21 +00:00
/*
* It ' s Okay to use CUR / NEXT here since all the blanks are on
* the ASCII range .
*/
2001-04-30 11:46:40 +00:00
if ( ( ctxt - > inputNr = = 1 ) & & ( ctxt - > instate ! = XML_PARSER_DTD ) ) {
const xmlChar * cur ;
/*
* if we are in the document content , go really fast
*/
cur = ctxt - > input - > cur ;
while ( IS_BLANK ( * cur ) ) {
if ( * cur = = ' \n ' ) {
ctxt - > input - > line + + ; ctxt - > input - > col = 1 ;
}
cur + + ;
2001-02-23 17:55:21 +00:00
res + + ;
2001-04-30 11:46:40 +00:00
if ( * cur = = 0 ) {
ctxt - > input - > cur = cur ;
xmlParserInputGrow ( ctxt - > input , INPUT_CHUNK ) ;
cur = ctxt - > input - > cur ;
}
2001-02-23 17:55:21 +00:00
}
2001-04-30 11:46:40 +00:00
ctxt - > input - > cur = cur ;
} else {
int cur ;
do {
2001-02-23 17:55:21 +00:00
cur = CUR ;
2001-04-30 11:46:40 +00:00
while ( IS_BLANK ( cur ) ) { /* CHECKED tstblanks.xml */
NEXT ;
cur = CUR ;
res + + ;
}
while ( ( cur = = 0 ) & & ( ctxt - > inputNr > 1 ) & &
( ctxt - > instate ! = XML_PARSER_COMMENT ) ) {
xmlPopInput ( ctxt ) ;
cur = CUR ;
}
/*
* Need to handle support of entities branching here
*/
if ( * ctxt - > input - > cur = = ' % ' ) xmlParserHandlePEReference ( ctxt ) ;
} while ( IS_BLANK ( cur ) ) ; /* CHECKED tstblanks.xml */
}
2001-02-23 17:55:21 +00:00
return ( res ) ;
}
/************************************************************************
* *
* Commodity functions to handle entities *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlPopInput :
* @ ctxt : an XML parser context
*
* xmlPopInput : the current input pointed by ctxt - > input came to an end
* pop it and return the next char .
*
* Returns the current xmlChar in the parser context
*/
xmlChar
xmlPopInput ( xmlParserCtxtPtr ctxt ) {
if ( ctxt - > inputNr = = 1 ) return ( 0 ) ; /* End of main Input */
if ( xmlParserDebugEntities )
xmlGenericError ( xmlGenericErrorContext ,
" Popping input %d \n " , ctxt - > inputNr ) ;
xmlFreeInputStream ( inputPop ( ctxt ) ) ;
2002-03-20 21:55:57 +00:00
if ( ( * ctxt - > input - > cur = = 0 ) & &
2001-02-23 17:55:21 +00:00
( xmlParserInputGrow ( ctxt - > input , INPUT_CHUNK ) < = 0 ) )
return ( xmlPopInput ( ctxt ) ) ;
return ( CUR ) ;
}
/**
* xmlPushInput :
* @ ctxt : an XML parser context
* @ input : an XML parser input fragment ( entity , XML fragment . . . ) .
*
* xmlPushInput : switch to a new input stream which is stacked on top
* of the previous one ( s ) .
*/
void
xmlPushInput ( xmlParserCtxtPtr ctxt , xmlParserInputPtr input ) {
if ( input = = NULL ) return ;
if ( xmlParserDebugEntities ) {
if ( ( ctxt - > input ! = NULL ) & & ( ctxt - > input - > filename ) )
xmlGenericError ( xmlGenericErrorContext ,
" %s(%d): " , ctxt - > input - > filename ,
ctxt - > input - > line ) ;
xmlGenericError ( xmlGenericErrorContext ,
" Pushing input %d : %.30s \n " , ctxt - > inputNr + 1 , input - > cur ) ;
}
inputPush ( ctxt , input ) ;
GROW ;
}
/**
* xmlParseCharRef :
* @ ctxt : an XML parser context
*
* parse Reference declarations
*
* [ 66 ] CharRef : : = ' & # ' [ 0 - 9 ] + ' ; ' |
* ' & # x ' [ 0 - 9 a - fA - F ] + ' ; '
*
* [ WFC : Legal Character ]
* Characters referred to using character references must match the
* production for Char .
*
* Returns the value parsed ( as an int ) , 0 in case of error
*/
int
xmlParseCharRef ( xmlParserCtxtPtr ctxt ) {
2001-03-26 22:52:16 +00:00
unsigned int val = 0 ;
2001-02-23 17:55:21 +00:00
int count = 0 ;
/*
* Using RAW / CUR / NEXT is okay since we are working on ASCII range here
*/
2002-03-20 21:55:57 +00:00
if ( ( RAW = = ' & ' ) & & ( NXT ( 1 ) = = ' # ' ) & &
2001-02-23 17:55:21 +00:00
( NXT ( 2 ) = = ' x ' ) ) {
SKIP ( 3 ) ;
GROW ;
while ( RAW ! = ' ; ' ) { /* loop blocked by count */
2002-02-17 21:26:33 +00:00
if ( count + + > 20 ) {
count = 0 ;
GROW ;
}
if ( ( RAW > = ' 0 ' ) & & ( RAW < = ' 9 ' ) )
2001-02-23 17:55:21 +00:00
val = val * 16 + ( CUR - ' 0 ' ) ;
else if ( ( RAW > = ' a ' ) & & ( RAW < = ' f ' ) & & ( count < 20 ) )
val = val * 16 + ( CUR - ' a ' ) + 10 ;
else if ( ( RAW > = ' A ' ) & & ( RAW < = ' F ' ) & & ( count < 20 ) )
val = val * 16 + ( CUR - ' A ' ) + 10 ;
else {
ctxt - > errNo = XML_ERR_INVALID_HEX_CHARREF ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseCharRef: invalid hexadecimal value \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
val = 0 ;
break ;
}
NEXT ;
count + + ;
}
if ( RAW = = ' ; ' ) {
/* on purpose to avoid reentrancy problems with NEXT and SKIP */
ctxt - > nbChars + + ;
ctxt - > input - > cur + + ;
}
2002-03-20 21:55:57 +00:00
} else if ( ( RAW = = ' & ' ) & & ( NXT ( 1 ) = = ' # ' ) ) {
2001-02-23 17:55:21 +00:00
SKIP ( 2 ) ;
GROW ;
while ( RAW ! = ' ; ' ) { /* loop blocked by count */
2002-02-17 21:26:33 +00:00
if ( count + + > 20 ) {
count = 0 ;
GROW ;
}
if ( ( RAW > = ' 0 ' ) & & ( RAW < = ' 9 ' ) )
2001-02-23 17:55:21 +00:00
val = val * 10 + ( CUR - ' 0 ' ) ;
else {
ctxt - > errNo = XML_ERR_INVALID_DEC_CHARREF ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseCharRef: invalid decimal value \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
val = 0 ;
break ;
}
NEXT ;
count + + ;
}
if ( RAW = = ' ; ' ) {
/* on purpose to avoid reentrancy problems with NEXT and SKIP */
ctxt - > nbChars + + ;
ctxt - > input - > cur + + ;
}
} else {
ctxt - > errNo = XML_ERR_INVALID_CHARREF ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseCharRef: invalid value \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* [ WFC : Legal Character ]
* Characters referred to using character references must match the
* production for Char .
*/
if ( IS_CHAR ( val ) ) {
return ( val ) ;
} else {
ctxt - > errNo = XML_ERR_INVALID_CHAR ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
2001-12-31 16:16:02 +00:00
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseCharRef: invalid xmlChar value %d \n " ,
2001-02-23 17:55:21 +00:00
val ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
return ( 0 ) ;
}
/**
* xmlParseStringCharRef :
* @ ctxt : an XML parser context
* @ str : a pointer to an index in the string
*
* parse Reference declarations , variant parsing from a string rather
* than an an input flow .
*
* [ 66 ] CharRef : : = ' & # ' [ 0 - 9 ] + ' ; ' |
* ' & # x ' [ 0 - 9 a - fA - F ] + ' ; '
*
* [ WFC : Legal Character ]
* Characters referred to using character references must match the
* production for Char .
*
* Returns the value parsed ( as an int ) , 0 in case of error , str will be
* updated to the current value of the index
*/
2001-03-24 17:00:36 +00:00
static int
2001-02-23 17:55:21 +00:00
xmlParseStringCharRef ( xmlParserCtxtPtr ctxt , const xmlChar * * str ) {
const xmlChar * ptr ;
xmlChar cur ;
int val = 0 ;
if ( ( str = = NULL ) | | ( * str = = NULL ) ) return ( 0 ) ;
ptr = * str ;
cur = * ptr ;
if ( ( cur = = ' & ' ) & & ( ptr [ 1 ] = = ' # ' ) & & ( ptr [ 2 ] = = ' x ' ) ) {
ptr + = 3 ;
cur = * ptr ;
while ( cur ! = ' ; ' ) { /* Non input consuming loop */
if ( ( cur > = ' 0 ' ) & & ( cur < = ' 9 ' ) )
val = val * 16 + ( cur - ' 0 ' ) ;
else if ( ( cur > = ' a ' ) & & ( cur < = ' f ' ) )
val = val * 16 + ( cur - ' a ' ) + 10 ;
else if ( ( cur > = ' A ' ) & & ( cur < = ' F ' ) )
val = val * 16 + ( cur - ' A ' ) + 10 ;
else {
ctxt - > errNo = XML_ERR_INVALID_HEX_CHARREF ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseStringCharRef: invalid hexadecimal value \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
val = 0 ;
break ;
}
ptr + + ;
cur = * ptr ;
}
if ( cur = = ' ; ' )
ptr + + ;
} else if ( ( cur = = ' & ' ) & & ( ptr [ 1 ] = = ' # ' ) ) {
ptr + = 2 ;
cur = * ptr ;
while ( cur ! = ' ; ' ) { /* Non input consuming loops */
if ( ( cur > = ' 0 ' ) & & ( cur < = ' 9 ' ) )
val = val * 10 + ( cur - ' 0 ' ) ;
else {
ctxt - > errNo = XML_ERR_INVALID_DEC_CHARREF ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseStringCharRef: invalid decimal value \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
val = 0 ;
break ;
}
ptr + + ;
cur = * ptr ;
}
if ( cur = = ' ; ' )
ptr + + ;
} else {
ctxt - > errNo = XML_ERR_INVALID_CHARREF ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-12-31 16:16:02 +00:00
" xmlParseStringCharRef: invalid value \n " ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( 0 ) ;
}
* str = ptr ;
/*
* [ WFC : Legal Character ]
* Characters referred to using character references must match the
* production for Char .
*/
if ( IS_CHAR ( val ) ) {
return ( val ) ;
} else {
ctxt - > errNo = XML_ERR_INVALID_CHAR ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-12-31 16:16:02 +00:00
" xmlParseStringCharRef: invalid xmlChar value %d \n " , val ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
return ( 0 ) ;
}
2002-06-11 10:08:16 +00:00
/**
* xmlNewBlanksWrapperInputStream :
* @ ctxt : an XML parser context
* @ entity : an Entity pointer
*
* Create a new input stream for wrapping
* blanks around a PEReference
*
* Returns the new input stream or NULL
*/
static void deallocblankswrapper ( xmlChar * str ) { xmlFree ( str ) ; }
2002-09-10 11:13:43 +00:00
static xmlParserInputPtr
2002-06-11 10:08:16 +00:00
xmlNewBlanksWrapperInputStream ( xmlParserCtxtPtr ctxt , xmlEntityPtr entity ) {
xmlParserInputPtr input ;
xmlChar * buffer ;
size_t length ;
if ( entity = = NULL ) {
ctxt - > errNo = XML_ERR_INTERNAL_ERROR ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" internal: xmlNewBlanksWrapperInputStream entity = NULL \n " ) ;
ctxt - > errNo = XML_ERR_INTERNAL_ERROR ;
return ( NULL ) ;
}
if ( xmlParserDebugEntities )
xmlGenericError ( xmlGenericErrorContext ,
" new blanks wrapper for entity: %s \n " , entity - > name ) ;
input = xmlNewInputStream ( ctxt ) ;
if ( input = = NULL ) {
return ( NULL ) ;
}
length = xmlStrlen ( entity - > name ) + 5 ;
buffer = xmlMalloc ( length ) ;
if ( buffer = = NULL ) {
return ( NULL ) ;
}
buffer [ 0 ] = ' ' ;
buffer [ 1 ] = ' % ' ;
buffer [ length - 3 ] = ' ; ' ;
buffer [ length - 2 ] = ' ' ;
buffer [ length - 1 ] = 0 ;
memcpy ( buffer + 2 , entity - > name , length - 5 ) ;
input - > free = deallocblankswrapper ;
input - > base = buffer ;
input - > cur = buffer ;
input - > length = length ;
input - > end = & buffer [ length ] ;
return ( input ) ;
}
2001-02-23 17:55:21 +00:00
/**
* xmlParserHandlePEReference :
* @ ctxt : the parser context
*
* [ 69 ] PEReference : : = ' % ' Name ' ; '
*
* [ WFC : No Recursion ]
* A parsed entity must not contain a recursive
* reference to itself , either directly or indirectly .
*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an internal DTD
* subset which contains no parameter entity references , or a document
* with " standalone='yes' " , . . . . . . The declaration of a parameter
* entity must precede any reference to it . . .
*
* [ VC : Entity Declared ]
* In a document with an external subset or external parameter entities
* with " standalone='no' " , . . . . . . The declaration of a parameter entity
* must precede any reference to it . . .
*
* [ WFC : In DTD ]
* Parameter - entity references may only appear in the DTD .
* NOTE : misleading but this is handled .
*
* A PEReference may have been detected in the current input stream
* the handling is done accordingly to
* http : //www.w3.org/TR/REC-xml#entproc
* i . e .
* - Included in literal in entity values
2001-12-31 16:16:02 +00:00
* - Included as Parameter Entity reference within DTDs
2001-02-23 17:55:21 +00:00
*/
void
xmlParserHandlePEReference ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
xmlEntityPtr entity = NULL ;
xmlParserInputPtr input ;
if ( RAW ! = ' % ' ) return ;
switch ( ctxt - > instate ) {
case XML_PARSER_CDATA_SECTION :
return ;
case XML_PARSER_COMMENT :
return ;
case XML_PARSER_START_TAG :
return ;
case XML_PARSER_END_TAG :
return ;
case XML_PARSER_EOF :
ctxt - > errNo = XML_ERR_PEREF_AT_EOF ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " PEReference at EOF \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ;
case XML_PARSER_PROLOG :
case XML_PARSER_START :
case XML_PARSER_MISC :
ctxt - > errNo = XML_ERR_PEREF_IN_PROLOG ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " PEReference in prolog! \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ;
case XML_PARSER_ENTITY_DECL :
case XML_PARSER_CONTENT :
case XML_PARSER_ATTRIBUTE_VALUE :
case XML_PARSER_PI :
case XML_PARSER_SYSTEM_LITERAL :
2002-02-18 19:18:17 +00:00
case XML_PARSER_PUBLIC_LITERAL :
2001-02-23 17:55:21 +00:00
/* we just ignore it there */
return ;
case XML_PARSER_EPILOG :
ctxt - > errNo = XML_ERR_PEREF_IN_EPILOG ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " PEReference in epilog! \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ;
case XML_PARSER_ENTITY_VALUE :
/*
* NOTE : in the case of entity values , we don ' t do the
* substitution here since we need the literal
* entity value to be able to save the internal
* subset of the document .
* This will be handled by xmlStringDecodeEntities
*/
return ;
case XML_PARSER_DTD :
/*
* [ WFC : Well - Formedness Constraint : PEs in Internal Subset ]
* In the internal DTD subset , parameter - entity references
* can occur only where markup declarations can occur , not
* within markup declarations .
* In that case this is handled in xmlParseMarkupDecl
*/
if ( ( ctxt - > external = = 0 ) & & ( ctxt - > inputNr = = 1 ) )
return ;
2002-06-11 10:08:16 +00:00
if ( IS_BLANK ( NXT ( 1 ) ) | | NXT ( 1 ) = = 0 )
return ;
2001-02-23 17:55:21 +00:00
break ;
case XML_PARSER_IGNORE :
return ;
}
NEXT ;
name = xmlParseName ( ctxt ) ;
if ( xmlParserDebugEntities )
xmlGenericError ( xmlGenericErrorContext ,
2001-12-31 16:16:02 +00:00
" PEReference: %s \n " , name ) ;
2001-02-23 17:55:21 +00:00
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_PEREF_NO_NAME ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
2001-12-31 16:16:02 +00:00
ctxt - > sax - > error ( ctxt - > userData , " xmlParserHandlePEReference: no name \n " ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
if ( RAW = = ' ; ' ) {
NEXT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > getParameterEntity ! = NULL ) )
entity = ctxt - > sax - > getParameterEntity ( ctxt - > userData , name ) ;
if ( entity = = NULL ) {
/*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an
* internal DTD subset which contains no parameter entity
* references , or a document with " standalone='yes' " , . . .
* . . . The declaration of a parameter entity must precede
* any reference to it . . .
*/
if ( ( ctxt - > standalone = = 1 ) | |
( ( ctxt - > hasExternalSubset = = 0 ) & &
( ctxt - > hasPErefs = = 0 ) ) ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" PEReference: %%%s; not found \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
/*
* [ VC : Entity Declared ]
* In a document with an external subset or external
* parameter entities with " standalone='no' " , . . .
* . . . The declaration of a parameter entity must precede
* any reference to it . . .
*/
if ( ( ! ctxt - > disableSAX ) & &
( ctxt - > validate ) & & ( ctxt - > vctxt . error ! = NULL ) ) {
ctxt - > vctxt . error ( ctxt - > vctxt . userData ,
" PEReference: %%%s; not found \n " , name ) ;
} else if ( ( ! ctxt - > disableSAX ) & &
( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" PEReference: %%%s; not found \n " , name ) ;
ctxt - > valid = 0 ;
}
2002-06-11 10:08:16 +00:00
} else if ( ctxt - > input - > free ! = deallocblankswrapper ) {
input = xmlNewBlanksWrapperInputStream ( ctxt , entity ) ;
xmlPushInput ( ctxt , input ) ;
2001-02-23 17:55:21 +00:00
} else {
if ( ( entity - > etype = = XML_INTERNAL_PARAMETER_ENTITY ) | |
( entity - > etype = = XML_EXTERNAL_PARAMETER_ENTITY ) ) {
2001-06-20 17:41:10 +00:00
xmlChar start [ 4 ] ;
xmlCharEncoding enc ;
2001-02-23 17:55:21 +00:00
/*
* handle the extra spaces added before and after
* c . f . http : //www.w3.org/TR/REC-xml#as-PE
2001-12-31 16:16:02 +00:00
* this is done independently .
2001-02-23 17:55:21 +00:00
*/
input = xmlNewEntityInputStream ( ctxt , entity ) ;
xmlPushInput ( ctxt , input ) ;
2001-06-20 17:41:10 +00:00
/*
* Get the 4 first bytes and decode the charset
* if enc ! = XML_CHAR_ENCODING_NONE
* plug some encoding conversion routines .
*/
GROW
2002-06-13 15:32:10 +00:00
if ( entity - > length > = 4 ) {
start [ 0 ] = RAW ;
start [ 1 ] = NXT ( 1 ) ;
start [ 2 ] = NXT ( 2 ) ;
start [ 3 ] = NXT ( 3 ) ;
enc = xmlDetectCharEncoding ( start , 4 ) ;
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
xmlSwitchEncoding ( ctxt , enc ) ;
}
2001-06-20 17:41:10 +00:00
}
2001-02-23 17:55:21 +00:00
if ( ( entity - > etype = = XML_EXTERNAL_PARAMETER_ENTITY ) & &
( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) & &
( NXT ( 2 ) = = ' x ' ) & & ( NXT ( 3 ) = = ' m ' ) & &
( NXT ( 4 ) = = ' l ' ) & & ( IS_BLANK ( NXT ( 5 ) ) ) ) {
xmlParseTextDecl ( ctxt ) ;
}
} else {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-12-31 16:16:02 +00:00
" xmlParserHandlePEReference: %s is not a parameter entity \n " ,
2001-02-23 17:55:21 +00:00
name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
}
} else {
ctxt - > errNo = XML_ERR_PEREF_SEMICOL_MISSING ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-12-31 16:16:02 +00:00
" xmlParserHandlePEReference: expecting ';' \n " ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
xmlFree ( name ) ;
}
}
/*
* Macro used to grow the current buffer .
*/
# define growBuffer(buffer) { \
buffer # # _size * = 2 ; \
buffer = ( xmlChar * ) \
xmlRealloc ( buffer , buffer # # _size * sizeof ( xmlChar ) ) ; \
if ( buffer = = NULL ) { \
2002-09-05 11:33:25 +00:00
xmlGenericError ( xmlGenericErrorContext , " realloc failed " ) ; \
2001-02-23 17:55:21 +00:00
return ( NULL ) ; \
} \
}
/**
* xmlStringDecodeEntities :
* @ ctxt : the parser context
* @ str : the input string
* @ what : combination of XML_SUBSTITUTE_REF and XML_SUBSTITUTE_PEREF
* @ end : an end marker xmlChar , 0 if none
* @ end2 : an end marker xmlChar , 0 if none
* @ end3 : an end marker xmlChar , 0 if none
*
2001-12-31 16:16:02 +00:00
* Takes a entity string content and process to do the adequate substitutions .
2001-02-23 17:55:21 +00:00
*
* [ 67 ] Reference : : = EntityRef | CharRef
*
* [ 69 ] PEReference : : = ' % ' Name ' ; '
*
* Returns A newly allocated string with the substitution done . The caller
* must deallocate it !
*/
xmlChar *
xmlStringDecodeEntities ( xmlParserCtxtPtr ctxt , const xmlChar * str , int what ,
xmlChar end , xmlChar end2 , xmlChar end3 ) {
xmlChar * buffer = NULL ;
int buffer_size = 0 ;
xmlChar * current = NULL ;
xmlEntityPtr ent ;
int c , l ;
int nbchars = 0 ;
if ( str = = NULL )
return ( NULL ) ;
if ( ctxt - > depth > 40 ) {
ctxt - > errNo = XML_ERR_ENTITY_LOOP ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Detected entity reference loop \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
/*
* allocate a translation buffer .
*/
buffer_size = XML_PARSER_BIG_BUFFER_SIZE ;
buffer = ( xmlChar * ) xmlMalloc ( buffer_size * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
2002-09-05 11:33:25 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlStringDecodeEntities: malloc failed " ) ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
/*
2001-12-31 16:16:02 +00:00
* OK loop until we reach one of the ending char or a size limit .
2001-02-23 17:55:21 +00:00
* we are operating on already parsed values .
*/
c = CUR_SCHAR ( str , l ) ;
while ( ( c ! = 0 ) & & ( c ! = end ) & & /* non input consuming loop */
( c ! = end2 ) & & ( c ! = end3 ) ) {
if ( c = = 0 ) break ;
if ( ( c = = ' & ' ) & & ( str [ 1 ] = = ' # ' ) ) {
int val = xmlParseStringCharRef ( ctxt , & str ) ;
if ( val ! = 0 ) {
COPY_BUF ( 0 , buffer , nbchars , val ) ;
}
} else if ( ( c = = ' & ' ) & & ( what & XML_SUBSTITUTE_REF ) ) {
if ( xmlParserDebugEntities )
xmlGenericError ( xmlGenericErrorContext ,
" String decoding Entity Reference: %.30s \n " ,
str ) ;
ent = xmlParseStringEntityRef ( ctxt , & str ) ;
if ( ( ent ! = NULL ) & &
( ent - > etype = = XML_INTERNAL_PREDEFINED_ENTITY ) ) {
if ( ent - > content ! = NULL ) {
COPY_BUF ( 0 , buffer , nbchars , ent - > content [ 0 ] ) ;
} else {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" internal error entity has no content \n " ) ;
}
} else if ( ( ent ! = NULL ) & & ( ent - > content ! = NULL ) ) {
xmlChar * rep ;
ctxt - > depth + + ;
rep = xmlStringDecodeEntities ( ctxt , ent - > content , what ,
0 , 0 , 0 ) ;
ctxt - > depth - - ;
if ( rep ! = NULL ) {
current = rep ;
while ( * current ! = 0 ) { /* non input consuming loop */
buffer [ nbchars + + ] = * current + + ;
if ( nbchars >
buffer_size - XML_PARSER_BUFFER_SIZE ) {
growBuffer ( buffer ) ;
}
}
xmlFree ( rep ) ;
}
} else if ( ent ! = NULL ) {
int i = xmlStrlen ( ent - > name ) ;
const xmlChar * cur = ent - > name ;
buffer [ nbchars + + ] = ' & ' ;
if ( nbchars > buffer_size - i - XML_PARSER_BUFFER_SIZE ) {
growBuffer ( buffer ) ;
}
for ( ; i > 0 ; i - - )
buffer [ nbchars + + ] = * cur + + ;
buffer [ nbchars + + ] = ' ; ' ;
}
} else if ( c = = ' % ' & & ( what & XML_SUBSTITUTE_PEREF ) ) {
if ( xmlParserDebugEntities )
xmlGenericError ( xmlGenericErrorContext ,
" String decoding PE Reference: %.30s \n " , str ) ;
ent = xmlParseStringPEReference ( ctxt , & str ) ;
if ( ent ! = NULL ) {
xmlChar * rep ;
ctxt - > depth + + ;
rep = xmlStringDecodeEntities ( ctxt , ent - > content , what ,
0 , 0 , 0 ) ;
ctxt - > depth - - ;
if ( rep ! = NULL ) {
current = rep ;
while ( * current ! = 0 ) { /* non input consuming loop */
buffer [ nbchars + + ] = * current + + ;
if ( nbchars >
buffer_size - XML_PARSER_BUFFER_SIZE ) {
growBuffer ( buffer ) ;
}
}
xmlFree ( rep ) ;
}
}
} else {
COPY_BUF ( l , buffer , nbchars , c ) ;
str + = l ;
if ( nbchars > buffer_size - XML_PARSER_BUFFER_SIZE ) {
growBuffer ( buffer ) ;
}
}
c = CUR_SCHAR ( str , l ) ;
}
buffer [ nbchars + + ] = 0 ;
return ( buffer ) ;
}
/************************************************************************
* *
* Commodity functions to handle xmlChars *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlStrndup :
* @ cur : the input xmlChar *
* @ len : the len of @ cur
*
* a strndup for array of xmlChar ' s
*
* Returns a new xmlChar * or NULL
*/
xmlChar *
xmlStrndup ( const xmlChar * cur , int len ) {
xmlChar * ret ;
if ( ( cur = = NULL ) | | ( len < 0 ) ) return ( NULL ) ;
ret = ( xmlChar * ) xmlMalloc ( ( len + 1 ) * sizeof ( xmlChar ) ) ;
if ( ret = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %ld byte failed \n " ,
( len + 1 ) * ( long ) sizeof ( xmlChar ) ) ;
return ( NULL ) ;
}
memcpy ( ret , cur , len * sizeof ( xmlChar ) ) ;
ret [ len ] = 0 ;
return ( ret ) ;
}
/**
* xmlStrdup :
* @ cur : the input xmlChar *
*
* a strdup for array of xmlChar ' s . Since they are supposed to be
* encoded in UTF - 8 or an encoding with 8 bit based chars , we assume
* a termination mark of ' 0 ' .
*
* Returns a new xmlChar * or NULL
*/
xmlChar *
xmlStrdup ( const xmlChar * cur ) {
const xmlChar * p = cur ;
if ( cur = = NULL ) return ( NULL ) ;
while ( * p ! = 0 ) p + + ; /* non input consuming */
return ( xmlStrndup ( cur , p - cur ) ) ;
}
/**
* xmlCharStrndup :
* @ cur : the input char *
* @ len : the len of @ cur
*
* a strndup for char ' s to xmlChar ' s
*
* Returns a new xmlChar * or NULL
*/
xmlChar *
xmlCharStrndup ( const char * cur , int len ) {
int i ;
xmlChar * ret ;
if ( ( cur = = NULL ) | | ( len < 0 ) ) return ( NULL ) ;
ret = ( xmlChar * ) xmlMalloc ( ( len + 1 ) * sizeof ( xmlChar ) ) ;
if ( ret = = NULL ) {
xmlGenericError ( xmlGenericErrorContext , " malloc of %ld byte failed \n " ,
( len + 1 ) * ( long ) sizeof ( xmlChar ) ) ;
return ( NULL ) ;
}
for ( i = 0 ; i < len ; i + + )
ret [ i ] = ( xmlChar ) cur [ i ] ;
ret [ len ] = 0 ;
return ( ret ) ;
}
/**
* xmlCharStrdup :
* @ cur : the input char *
*
* a strdup for char ' s to xmlChar ' s
*
* Returns a new xmlChar * or NULL
*/
xmlChar *
xmlCharStrdup ( const char * cur ) {
const char * p = cur ;
if ( cur = = NULL ) return ( NULL ) ;
while ( * p ! = ' \0 ' ) p + + ; /* non input consuming */
return ( xmlCharStrndup ( cur , p - cur ) ) ;
}
/**
* xmlStrcmp :
* @ str1 : the first xmlChar *
* @ str2 : the second xmlChar *
*
* a strcmp for xmlChar ' s
*
* Returns the integer result of the comparison
*/
int
xmlStrcmp ( const xmlChar * str1 , const xmlChar * str2 ) {
register int tmp ;
if ( str1 = = str2 ) return ( 0 ) ;
if ( str1 = = NULL ) return ( - 1 ) ;
if ( str2 = = NULL ) return ( 1 ) ;
do {
tmp = * str1 + + - * str2 ;
if ( tmp ! = 0 ) return ( tmp ) ;
} while ( * str2 + + ! = 0 ) ;
return 0 ;
}
/**
* xmlStrEqual :
* @ str1 : the first xmlChar *
* @ str2 : the second xmlChar *
*
* Check if both string are equal of have same content
* Should be a bit more readable and faster than xmlStrEqual ( )
*
* Returns 1 if they are equal , 0 if they are different
*/
int
xmlStrEqual ( const xmlChar * str1 , const xmlChar * str2 ) {
if ( str1 = = str2 ) return ( 1 ) ;
if ( str1 = = NULL ) return ( 0 ) ;
if ( str2 = = NULL ) return ( 0 ) ;
do {
if ( * str1 + + ! = * str2 ) return ( 0 ) ;
} while ( * str2 + + ) ;
return ( 1 ) ;
}
/**
* xmlStrncmp :
* @ str1 : the first xmlChar *
* @ str2 : the second xmlChar *
* @ len : the max comparison length
*
* a strncmp for xmlChar ' s
*
* Returns the integer result of the comparison
*/
int
xmlStrncmp ( const xmlChar * str1 , const xmlChar * str2 , int len ) {
register int tmp ;
if ( len < = 0 ) return ( 0 ) ;
if ( str1 = = str2 ) return ( 0 ) ;
if ( str1 = = NULL ) return ( - 1 ) ;
if ( str2 = = NULL ) return ( 1 ) ;
do {
tmp = * str1 + + - * str2 ;
if ( tmp ! = 0 | | - - len = = 0 ) return ( tmp ) ;
} while ( * str2 + + ! = 0 ) ;
return 0 ;
}
2001-10-11 22:55:55 +00:00
static const xmlChar casemap [ 256 ] = {
2001-02-23 17:55:21 +00:00
0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
0x08 , 0x09 , 0x0A , 0x0B , 0x0C , 0x0D , 0x0E , 0x0F ,
0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 ,
0x18 , 0x19 , 0x1A , 0x1B , 0x1C , 0x1D , 0x1E , 0x1F ,
0x20 , 0x21 , 0x22 , 0x23 , 0x24 , 0x25 , 0x26 , 0x27 ,
0x28 , 0x29 , 0x2A , 0x2B , 0x2C , 0x2D , 0x2E , 0x2F ,
0x30 , 0x31 , 0x32 , 0x33 , 0x34 , 0x35 , 0x36 , 0x37 ,
0x38 , 0x39 , 0x3A , 0x3B , 0x3C , 0x3D , 0x3E , 0x3F ,
0x40 , 0x61 , 0x62 , 0x63 , 0x64 , 0x65 , 0x66 , 0x67 ,
0x68 , 0x69 , 0x6A , 0x6B , 0x6C , 0x6D , 0x6E , 0x6F ,
0x70 , 0x71 , 0x72 , 0x73 , 0x74 , 0x75 , 0x76 , 0x77 ,
0x78 , 0x79 , 0x7A , 0x7B , 0x5C , 0x5D , 0x5E , 0x5F ,
0x60 , 0x61 , 0x62 , 0x63 , 0x64 , 0x65 , 0x66 , 0x67 ,
0x68 , 0x69 , 0x6A , 0x6B , 0x6C , 0x6D , 0x6E , 0x6F ,
0x70 , 0x71 , 0x72 , 0x73 , 0x74 , 0x75 , 0x76 , 0x77 ,
0x78 , 0x79 , 0x7A , 0x7B , 0x7C , 0x7D , 0x7E , 0x7F ,
0x80 , 0x81 , 0x82 , 0x83 , 0x84 , 0x85 , 0x86 , 0x87 ,
0x88 , 0x89 , 0x8A , 0x8B , 0x8C , 0x8D , 0x8E , 0x8F ,
0x90 , 0x91 , 0x92 , 0x93 , 0x94 , 0x95 , 0x96 , 0x97 ,
0x98 , 0x99 , 0x9A , 0x9B , 0x9C , 0x9D , 0x9E , 0x9F ,
0xA0 , 0xA1 , 0xA2 , 0xA3 , 0xA4 , 0xA5 , 0xA6 , 0xA7 ,
0xA8 , 0xA9 , 0xAA , 0xAB , 0xAC , 0xAD , 0xAE , 0xAF ,
0xB0 , 0xB1 , 0xB2 , 0xB3 , 0xB4 , 0xB5 , 0xB6 , 0xB7 ,
0xB8 , 0xB9 , 0xBA , 0xBB , 0xBC , 0xBD , 0xBE , 0xBF ,
0xC0 , 0xC1 , 0xC2 , 0xC3 , 0xC4 , 0xC5 , 0xC6 , 0xC7 ,
0xC8 , 0xC9 , 0xCA , 0xCB , 0xCC , 0xCD , 0xCE , 0xCF ,
0xD0 , 0xD1 , 0xD2 , 0xD3 , 0xD4 , 0xD5 , 0xD6 , 0xD7 ,
0xD8 , 0xD9 , 0xDA , 0xDB , 0xDC , 0xDD , 0xDE , 0xDF ,
0xE0 , 0xE1 , 0xE2 , 0xE3 , 0xE4 , 0xE5 , 0xE6 , 0xE7 ,
0xE8 , 0xE9 , 0xEA , 0xEB , 0xEC , 0xED , 0xEE , 0xEF ,
0xF0 , 0xF1 , 0xF2 , 0xF3 , 0xF4 , 0xF5 , 0xF6 , 0xF7 ,
0xF8 , 0xF9 , 0xFA , 0xFB , 0xFC , 0xFD , 0xFE , 0xFF
} ;
/**
* xmlStrcasecmp :
* @ str1 : the first xmlChar *
* @ str2 : the second xmlChar *
*
* a strcasecmp for xmlChar ' s
*
* Returns the integer result of the comparison
*/
int
xmlStrcasecmp ( const xmlChar * str1 , const xmlChar * str2 ) {
register int tmp ;
if ( str1 = = str2 ) return ( 0 ) ;
if ( str1 = = NULL ) return ( - 1 ) ;
if ( str2 = = NULL ) return ( 1 ) ;
do {
tmp = casemap [ * str1 + + ] - casemap [ * str2 ] ;
if ( tmp ! = 0 ) return ( tmp ) ;
} while ( * str2 + + ! = 0 ) ;
return 0 ;
}
/**
* xmlStrncasecmp :
* @ str1 : the first xmlChar *
* @ str2 : the second xmlChar *
* @ len : the max comparison length
*
* a strncasecmp for xmlChar ' s
*
* Returns the integer result of the comparison
*/
int
xmlStrncasecmp ( const xmlChar * str1 , const xmlChar * str2 , int len ) {
register int tmp ;
if ( len < = 0 ) return ( 0 ) ;
if ( str1 = = str2 ) return ( 0 ) ;
if ( str1 = = NULL ) return ( - 1 ) ;
if ( str2 = = NULL ) return ( 1 ) ;
do {
tmp = casemap [ * str1 + + ] - casemap [ * str2 ] ;
if ( tmp ! = 0 | | - - len = = 0 ) return ( tmp ) ;
} while ( * str2 + + ! = 0 ) ;
return 0 ;
}
/**
* xmlStrchr :
* @ str : the xmlChar * array
* @ val : the xmlChar to search
*
* a strchr for xmlChar ' s
*
2001-12-31 16:16:02 +00:00
* Returns the xmlChar * for the first occurrence or NULL .
2001-02-23 17:55:21 +00:00
*/
const xmlChar *
xmlStrchr ( const xmlChar * str , xmlChar val ) {
if ( str = = NULL ) return ( NULL ) ;
while ( * str ! = 0 ) { /* non input consuming */
if ( * str = = val ) return ( ( xmlChar * ) str ) ;
str + + ;
}
return ( NULL ) ;
}
/**
* xmlStrstr :
* @ str : the xmlChar * array ( haystack )
* @ val : the xmlChar to search ( needle )
*
* a strstr for xmlChar ' s
*
2001-12-31 16:16:02 +00:00
* Returns the xmlChar * for the first occurrence or NULL .
2001-02-23 17:55:21 +00:00
*/
const xmlChar *
2001-06-29 21:31:07 +00:00
xmlStrstr ( const xmlChar * str , const xmlChar * val ) {
2001-02-23 17:55:21 +00:00
int n ;
if ( str = = NULL ) return ( NULL ) ;
if ( val = = NULL ) return ( NULL ) ;
n = xmlStrlen ( val ) ;
if ( n = = 0 ) return ( str ) ;
while ( * str ! = 0 ) { /* non input consuming */
if ( * str = = * val ) {
if ( ! xmlStrncmp ( str , val , n ) ) return ( ( const xmlChar * ) str ) ;
}
str + + ;
}
return ( NULL ) ;
}
/**
* xmlStrcasestr :
* @ str : the xmlChar * array ( haystack )
* @ val : the xmlChar to search ( needle )
*
* a case - ignoring strstr for xmlChar ' s
*
2001-12-31 16:16:02 +00:00
* Returns the xmlChar * for the first occurrence or NULL .
2001-02-23 17:55:21 +00:00
*/
const xmlChar *
xmlStrcasestr ( const xmlChar * str , xmlChar * val ) {
int n ;
if ( str = = NULL ) return ( NULL ) ;
if ( val = = NULL ) return ( NULL ) ;
n = xmlStrlen ( val ) ;
if ( n = = 0 ) return ( str ) ;
while ( * str ! = 0 ) { /* non input consuming */
if ( casemap [ * str ] = = casemap [ * val ] )
if ( ! xmlStrncasecmp ( str , val , n ) ) return ( str ) ;
str + + ;
}
return ( NULL ) ;
}
/**
* xmlStrsub :
* @ str : the xmlChar * array ( haystack )
* @ start : the index of the first char ( zero based )
* @ len : the length of the substring
*
* Extract a substring of a given string
*
2001-12-31 16:16:02 +00:00
* Returns the xmlChar * for the first occurrence or NULL .
2001-02-23 17:55:21 +00:00
*/
xmlChar *
xmlStrsub ( const xmlChar * str , int start , int len ) {
int i ;
if ( str = = NULL ) return ( NULL ) ;
if ( start < 0 ) return ( NULL ) ;
if ( len < 0 ) return ( NULL ) ;
for ( i = 0 ; i < start ; i + + ) {
if ( * str = = 0 ) return ( NULL ) ;
str + + ;
}
if ( * str = = 0 ) return ( NULL ) ;
return ( xmlStrndup ( str , len ) ) ;
}
/**
* xmlStrlen :
* @ str : the xmlChar * array
*
* length of a xmlChar ' s string
*
* Returns the number of xmlChar contained in the ARRAY .
*/
int
xmlStrlen ( const xmlChar * str ) {
int len = 0 ;
if ( str = = NULL ) return ( 0 ) ;
while ( * str ! = 0 ) { /* non input consuming */
str + + ;
len + + ;
}
return ( len ) ;
}
/**
* xmlStrncat :
* @ cur : the original xmlChar * array
* @ add : the xmlChar * array added
* @ len : the length of @ add
*
2001-12-31 16:16:02 +00:00
* a strncat for array of xmlChar ' s , it will extend @ cur with the len
2001-02-23 17:55:21 +00:00
* first bytes of @ add .
*
* Returns a new xmlChar * , the original @ cur is reallocated if needed
* and should not be freed
*/
xmlChar *
xmlStrncat ( xmlChar * cur , const xmlChar * add , int len ) {
int size ;
xmlChar * ret ;
if ( ( add = = NULL ) | | ( len = = 0 ) )
return ( cur ) ;
if ( cur = = NULL )
return ( xmlStrndup ( add , len ) ) ;
size = xmlStrlen ( cur ) ;
ret = ( xmlChar * ) xmlRealloc ( cur , ( size + len + 1 ) * sizeof ( xmlChar ) ) ;
if ( ret = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" xmlStrncat: realloc of %ld byte failed \n " ,
( size + len + 1 ) * ( long ) sizeof ( xmlChar ) ) ;
return ( cur ) ;
}
memcpy ( & ret [ size ] , add , len * sizeof ( xmlChar ) ) ;
ret [ size + len ] = 0 ;
return ( ret ) ;
}
/**
* xmlStrcat :
* @ cur : the original xmlChar * array
* @ add : the xmlChar * array added
*
* a strcat for array of xmlChar ' s . Since they are supposed to be
* encoded in UTF - 8 or an encoding with 8 bit based chars , we assume
* a termination mark of ' 0 ' .
*
* Returns a new xmlChar * containing the concatenated string .
*/
xmlChar *
xmlStrcat ( xmlChar * cur , const xmlChar * add ) {
const xmlChar * p = add ;
if ( add = = NULL ) return ( cur ) ;
if ( cur = = NULL )
return ( xmlStrdup ( add ) ) ;
while ( * p ! = 0 ) p + + ; /* non input consuming */
return ( xmlStrncat ( cur , add , p - add ) ) ;
}
/************************************************************************
* *
* Commodity functions , cleanup needed ? *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* areBlanks :
* @ ctxt : an XML parser context
* @ str : a xmlChar *
* @ len : the size of @ str
*
* Is this a sequence of blank chars that one can ignore ?
*
* Returns 1 if ignorable 0 otherwise .
*/
static int areBlanks ( xmlParserCtxtPtr ctxt , const xmlChar * str , int len ) {
int i , ret ;
xmlNodePtr lastChild ;
2001-09-09 08:38:09 +00:00
/*
* Don ' t spend time trying to differentiate them , the same callback is
* used !
*/
if ( ctxt - > sax - > ignorableWhitespace = = ctxt - > sax - > characters )
2001-03-02 17:36:21 +00:00
return ( 0 ) ;
2001-02-23 17:55:21 +00:00
/*
* Check for xml : space value .
*/
if ( * ( ctxt - > space ) = = 1 )
return ( 0 ) ;
/*
* Check that the string is made of blanks
*/
for ( i = 0 ; i < len ; i + + )
if ( ! ( IS_BLANK ( str [ i ] ) ) ) return ( 0 ) ;
/*
2001-12-31 16:16:02 +00:00
* Look if the element is mixed content in the DTD if available
2001-02-23 17:55:21 +00:00
*/
2001-07-25 22:41:03 +00:00
if ( ctxt - > node = = NULL ) return ( 0 ) ;
2001-02-23 17:55:21 +00:00
if ( ctxt - > myDoc ! = NULL ) {
ret = xmlIsMixedElement ( ctxt - > myDoc , ctxt - > node - > name ) ;
if ( ret = = 0 ) return ( 1 ) ;
if ( ret = = 1 ) return ( 0 ) ;
}
/*
* Otherwise , heuristic : - \
*/
2002-03-20 21:55:57 +00:00
if ( RAW ! = ' < ' ) return ( 0 ) ;
2001-02-23 17:55:21 +00:00
if ( ( ctxt - > node - > children = = NULL ) & &
( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' / ' ) ) return ( 0 ) ;
lastChild = xmlGetLastChild ( ctxt - > node ) ;
if ( lastChild = = NULL ) {
2001-07-12 01:20:08 +00:00
if ( ( ctxt - > node - > type ! = XML_ELEMENT_NODE ) & &
( ctxt - > node - > content ! = NULL ) ) return ( 0 ) ;
2001-02-23 17:55:21 +00:00
} else if ( xmlNodeIsText ( lastChild ) )
return ( 0 ) ;
else if ( ( ctxt - > node - > children ! = NULL ) & &
( xmlNodeIsText ( ctxt - > node - > children ) ) )
return ( 0 ) ;
return ( 1 ) ;
}
/************************************************************************
* *
* Extra stuff for namespace support *
* Relates to http : //www.w3.org/TR/WD-xml-names *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlSplitQName :
* @ ctxt : an XML parser context
* @ name : an XML parser context
* @ prefix : a xmlChar * *
*
* parse an UTF8 encoded XML qualified name string
*
* [ NS 5 ] QName : : = ( Prefix ' : ' ) ? LocalPart
*
* [ NS 6 ] Prefix : : = NCName
*
* [ NS 7 ] LocalPart : : = NCName
*
* Returns the local part , and prefix is updated
* to get the Prefix if any .
*/
xmlChar *
xmlSplitQName ( xmlParserCtxtPtr ctxt , const xmlChar * name , xmlChar * * prefix ) {
xmlChar buf [ XML_MAX_NAMELEN + 5 ] ;
xmlChar * buffer = NULL ;
int len = 0 ;
int max = XML_MAX_NAMELEN ;
xmlChar * ret = NULL ;
const xmlChar * cur = name ;
int c ;
* prefix = NULL ;
# ifndef XML_XML_NAMESPACE
/* xml: prefix is not really a namespace */
if ( ( cur [ 0 ] = = ' x ' ) & & ( cur [ 1 ] = = ' m ' ) & &
( cur [ 2 ] = = ' l ' ) & & ( cur [ 3 ] = = ' : ' ) )
return ( xmlStrdup ( name ) ) ;
# endif
/* nasty but valid */
if ( cur [ 0 ] = = ' : ' )
return ( xmlStrdup ( name ) ) ;
c = * cur + + ;
while ( ( c ! = 0 ) & & ( c ! = ' : ' ) & & ( len < max ) ) { /* tested bigname.xml */
buf [ len + + ] = c ;
c = * cur + + ;
}
if ( len > = max ) {
/*
* Okay someone managed to make a huge name , so he ' s ready to pay
* for the processing speed .
*/
max = len * 2 ;
buffer = ( xmlChar * ) xmlMalloc ( max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlSplitQName: out of memory \n " ) ;
return ( NULL ) ;
}
memcpy ( buffer , buf , len ) ;
while ( ( c ! = 0 ) & & ( c ! = ' : ' ) ) { /* tested bigname.xml */
if ( len + 10 > max ) {
max * = 2 ;
buffer = ( xmlChar * ) xmlRealloc ( buffer ,
max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlSplitQName: out of memory \n " ) ;
return ( NULL ) ;
}
}
buffer [ len + + ] = c ;
c = * cur + + ;
}
buffer [ len ] = 0 ;
}
if ( buffer = = NULL )
ret = xmlStrndup ( buf , len ) ;
else {
ret = buffer ;
buffer = NULL ;
max = XML_MAX_NAMELEN ;
}
if ( c = = ' : ' ) {
2002-10-16 18:02:47 +00:00
c = * cur ;
2001-02-23 17:55:21 +00:00
if ( c = = 0 ) return ( ret ) ;
* prefix = ret ;
len = 0 ;
2002-10-16 18:02:47 +00:00
/*
* Check that the first character is proper to start
* a new name
*/
if ( ! ( ( ( c > = 0x61 ) & & ( c < = 0x7A ) ) | |
( ( c > = 0x41 ) & & ( c < = 0x5A ) ) | |
( c = = ' _ ' ) | | ( c = = ' : ' ) ) ) {
int l ;
int first = CUR_SCHAR ( cur , l ) ;
if ( ! IS_LETTER ( first ) & & ( first ! = ' _ ' ) ) {
2002-12-14 23:00:35 +00:00
if ( ( ctxt ! = NULL ) & & ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > error ! = NULL ) )
2002-10-16 18:02:47 +00:00
ctxt - > sax - > error ( ctxt - > userData ,
" Name %s is not XML Namespace compliant \n " ,
name ) ;
}
}
cur + + ;
2001-02-23 17:55:21 +00:00
while ( ( c ! = 0 ) & & ( len < max ) ) { /* tested bigname2.xml */
buf [ len + + ] = c ;
c = * cur + + ;
}
if ( len > = max ) {
/*
* Okay someone managed to make a huge name , so he ' s ready to pay
* for the processing speed .
*/
max = len * 2 ;
buffer = ( xmlChar * ) xmlMalloc ( max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
2002-12-14 23:00:35 +00:00
if ( ( ctxt ! = NULL ) & & ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > error ! = NULL ) )
2001-02-23 17:55:21 +00:00
ctxt - > sax - > error ( ctxt - > userData ,
" xmlSplitQName: out of memory \n " ) ;
return ( NULL ) ;
}
memcpy ( buffer , buf , len ) ;
while ( c ! = 0 ) { /* tested bigname2.xml */
if ( len + 10 > max ) {
max * = 2 ;
buffer = ( xmlChar * ) xmlRealloc ( buffer ,
max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
2002-12-14 23:00:35 +00:00
if ( ( ctxt ! = NULL ) & & ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > error ! = NULL ) )
2001-02-23 17:55:21 +00:00
ctxt - > sax - > error ( ctxt - > userData ,
" xmlSplitQName: out of memory \n " ) ;
return ( NULL ) ;
}
}
buffer [ len + + ] = c ;
c = * cur + + ;
}
buffer [ len ] = 0 ;
}
if ( buffer = = NULL )
ret = xmlStrndup ( buf , len ) ;
else {
ret = buffer ;
}
}
return ( ret ) ;
}
/************************************************************************
* *
* The parser itself *
* Relates to http : //www.w3.org/TR/REC-xml *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-16 21:05:17 +00:00
static xmlChar * xmlParseNameComplex ( xmlParserCtxtPtr ctxt ) ;
2001-02-23 17:55:21 +00:00
/**
* xmlParseName :
* @ ctxt : an XML parser context
*
* parse an XML name .
*
* [ 4 ] NameChar : : = Letter | Digit | ' . ' | ' - ' | ' _ ' | ' : ' |
* CombiningChar | Extender
*
* [ 5 ] Name : : = ( Letter | ' _ ' | ' : ' ) ( NameChar ) *
*
* [ 6 ] Names : : = Name ( S Name ) *
*
* Returns the Name parsed or NULL
*/
xmlChar *
xmlParseName ( xmlParserCtxtPtr ctxt ) {
2001-02-25 16:11:03 +00:00
const xmlChar * in ;
xmlChar * ret ;
2001-02-23 17:55:21 +00:00
int count = 0 ;
GROW ;
2001-02-25 16:11:03 +00:00
/*
* Accelerator for simple ASCII names
*/
in = ctxt - > input - > cur ;
if ( ( ( * in > = 0x61 ) & & ( * in < = 0x7A ) ) | |
( ( * in > = 0x41 ) & & ( * in < = 0x5A ) ) | |
( * in = = ' _ ' ) | | ( * in = = ' : ' ) ) {
in + + ;
while ( ( ( * in > = 0x61 ) & & ( * in < = 0x7A ) ) | |
( ( * in > = 0x41 ) & & ( * in < = 0x5A ) ) | |
( ( * in > = 0x30 ) & & ( * in < = 0x39 ) ) | |
2001-05-16 21:05:17 +00:00
( * in = = ' _ ' ) | | ( * in = = ' - ' ) | |
( * in = = ' : ' ) | | ( * in = = ' . ' ) )
2001-02-25 16:11:03 +00:00
in + + ;
2001-05-16 21:05:17 +00:00
if ( ( * in > 0 ) & & ( * in < 0x80 ) ) {
2001-02-25 16:11:03 +00:00
count = in - ctxt - > input - > cur ;
ret = xmlStrndup ( ctxt - > input - > cur , count ) ;
ctxt - > input - > cur = in ;
return ( ret ) ;
}
}
2001-03-02 17:36:21 +00:00
return ( xmlParseNameComplex ( ctxt ) ) ;
2001-02-25 19:54:14 +00:00
}
2002-05-29 08:21:33 +00:00
/**
* xmlParseNameAndCompare :
* @ ctxt : an XML parser context
*
* parse an XML name and compares for match
* ( specialized for endtag parsing )
*
*
* Returns NULL for an illegal name , ( xmlChar * ) 1 for success
* and the name for mismatch
*/
2002-09-10 11:13:43 +00:00
static xmlChar *
2002-05-29 08:21:33 +00:00
xmlParseNameAndCompare ( xmlParserCtxtPtr ctxt , xmlChar const * other ) {
const xmlChar * cmp = other ;
const xmlChar * in ;
xmlChar * ret ;
GROW ;
in = ctxt - > input - > cur ;
while ( * in ! = 0 & & * in = = * cmp ) {
+ + in ;
+ + cmp ;
}
if ( * cmp = = 0 & & ( * in = = ' > ' | | IS_BLANK ( * in ) ) ) {
/* success */
ctxt - > input - > cur = in ;
return ( xmlChar * ) 1 ;
}
/* failure (or end of input buffer), check with full function */
ret = xmlParseName ( ctxt ) ;
if ( ret ! = 0 & & xmlStrEqual ( ret , other ) ) {
xmlFree ( ret ) ;
return ( xmlChar * ) 1 ;
}
return ret ;
}
2001-05-16 21:05:17 +00:00
static xmlChar *
2001-02-25 19:54:14 +00:00
xmlParseNameComplex ( xmlParserCtxtPtr ctxt ) {
xmlChar buf [ XML_MAX_NAMELEN + 5 ] ;
int len = 0 , l ;
int c ;
int count = 0 ;
2001-02-25 16:11:03 +00:00
2001-02-25 19:54:14 +00:00
/*
* Handler for more complex cases
*/
GROW ;
2001-02-23 17:55:21 +00:00
c = CUR_CHAR ( l ) ;
if ( ( c = = ' ' ) | | ( c = = ' > ' ) | | ( c = = ' / ' ) | | /* accelerators */
( ! IS_LETTER ( c ) & & ( c ! = ' _ ' ) & &
( c ! = ' : ' ) ) ) {
return ( NULL ) ;
}
while ( ( c ! = ' ' ) & & ( c ! = ' > ' ) & & ( c ! = ' / ' ) & & /* test bigname.xml */
( ( IS_LETTER ( c ) ) | | ( IS_DIGIT ( c ) ) | |
( c = = ' . ' ) | | ( c = = ' - ' ) | |
( c = = ' _ ' ) | | ( c = = ' : ' ) | |
( IS_COMBINING ( c ) ) | |
( IS_EXTENDER ( c ) ) ) ) {
if ( count + + > 100 ) {
count = 0 ;
GROW ;
}
COPY_BUF ( l , buf , len , c ) ;
NEXTL ( l ) ;
c = CUR_CHAR ( l ) ;
if ( len > = XML_MAX_NAMELEN ) {
/*
* Okay someone managed to make a huge name , so he ' s ready to pay
* for the processing speed .
*/
xmlChar * buffer ;
int max = len * 2 ;
buffer = ( xmlChar * ) xmlMalloc ( max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-03-05 09:49:20 +00:00
" xmlParseNameComplex: out of memory \n " ) ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
memcpy ( buffer , buf , len ) ;
while ( ( IS_LETTER ( c ) ) | | ( IS_DIGIT ( c ) ) | | /* test bigname.xml */
( c = = ' . ' ) | | ( c = = ' - ' ) | |
( c = = ' _ ' ) | | ( c = = ' : ' ) | |
( IS_COMBINING ( c ) ) | |
( IS_EXTENDER ( c ) ) ) {
if ( count + + > 100 ) {
count = 0 ;
GROW ;
}
if ( len + 10 > max ) {
max * = 2 ;
buffer = ( xmlChar * ) xmlRealloc ( buffer ,
max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-03-05 09:49:20 +00:00
" xmlParseNameComplex: out of memory \n " ) ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
}
COPY_BUF ( l , buffer , len , c ) ;
NEXTL ( l ) ;
c = CUR_CHAR ( l ) ;
}
buffer [ len ] = 0 ;
return ( buffer ) ;
}
}
return ( xmlStrndup ( buf , len ) ) ;
}
/**
* xmlParseStringName :
* @ ctxt : an XML parser context
* @ str : a pointer to the string pointer ( IN / OUT )
*
* parse an XML name .
*
* [ 4 ] NameChar : : = Letter | Digit | ' . ' | ' - ' | ' _ ' | ' : ' |
* CombiningChar | Extender
*
* [ 5 ] Name : : = ( Letter | ' _ ' | ' : ' ) ( NameChar ) *
*
* [ 6 ] Names : : = Name ( S Name ) *
*
2001-12-31 16:16:02 +00:00
* Returns the Name parsed or NULL . The @ str pointer
2001-02-23 17:55:21 +00:00
* is updated to the current location in the string .
*/
2001-03-24 17:00:36 +00:00
static xmlChar *
2001-02-23 17:55:21 +00:00
xmlParseStringName ( xmlParserCtxtPtr ctxt , const xmlChar * * str ) {
xmlChar buf [ XML_MAX_NAMELEN + 5 ] ;
const xmlChar * cur = * str ;
int len = 0 , l ;
int c ;
c = CUR_SCHAR ( cur , l ) ;
if ( ! IS_LETTER ( c ) & & ( c ! = ' _ ' ) & &
( c ! = ' : ' ) ) {
return ( NULL ) ;
}
while ( ( IS_LETTER ( c ) ) | | ( IS_DIGIT ( c ) ) | | /* test bigentname.xml */
( c = = ' . ' ) | | ( c = = ' - ' ) | |
( c = = ' _ ' ) | | ( c = = ' : ' ) | |
( IS_COMBINING ( c ) ) | |
( IS_EXTENDER ( c ) ) ) {
COPY_BUF ( l , buf , len , c ) ;
cur + = l ;
c = CUR_SCHAR ( cur , l ) ;
if ( len > = XML_MAX_NAMELEN ) { /* test bigentname.xml */
/*
* Okay someone managed to make a huge name , so he ' s ready to pay
* for the processing speed .
*/
xmlChar * buffer ;
int max = len * 2 ;
buffer = ( xmlChar * ) xmlMalloc ( max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseStringName: out of memory \n " ) ;
return ( NULL ) ;
}
memcpy ( buffer , buf , len ) ;
while ( ( IS_LETTER ( c ) ) | | ( IS_DIGIT ( c ) ) | | /* test bigentname.xml */
( c = = ' . ' ) | | ( c = = ' - ' ) | |
( c = = ' _ ' ) | | ( c = = ' : ' ) | |
( IS_COMBINING ( c ) ) | |
( IS_EXTENDER ( c ) ) ) {
if ( len + 10 > max ) {
max * = 2 ;
buffer = ( xmlChar * ) xmlRealloc ( buffer ,
max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseStringName: out of memory \n " ) ;
return ( NULL ) ;
}
}
COPY_BUF ( l , buffer , len , c ) ;
cur + = l ;
c = CUR_SCHAR ( cur , l ) ;
}
buffer [ len ] = 0 ;
* str = cur ;
return ( buffer ) ;
}
}
* str = cur ;
return ( xmlStrndup ( buf , len ) ) ;
}
/**
* xmlParseNmtoken :
* @ ctxt : an XML parser context
*
* parse an XML Nmtoken .
*
* [ 7 ] Nmtoken : : = ( NameChar ) +
*
* [ 8 ] Nmtokens : : = Nmtoken ( S Nmtoken ) *
*
* Returns the Nmtoken parsed or NULL
*/
xmlChar *
xmlParseNmtoken ( xmlParserCtxtPtr ctxt ) {
xmlChar buf [ XML_MAX_NAMELEN + 5 ] ;
int len = 0 , l ;
int c ;
int count = 0 ;
GROW ;
c = CUR_CHAR ( l ) ;
while ( ( IS_LETTER ( c ) ) | | ( IS_DIGIT ( c ) ) | | /* test bigtoken.xml */
( c = = ' . ' ) | | ( c = = ' - ' ) | |
( c = = ' _ ' ) | | ( c = = ' : ' ) | |
( IS_COMBINING ( c ) ) | |
( IS_EXTENDER ( c ) ) ) {
if ( count + + > 100 ) {
count = 0 ;
GROW ;
}
COPY_BUF ( l , buf , len , c ) ;
NEXTL ( l ) ;
c = CUR_CHAR ( l ) ;
if ( len > = XML_MAX_NAMELEN ) {
/*
* Okay someone managed to make a huge token , so he ' s ready to pay
* for the processing speed .
*/
xmlChar * buffer ;
int max = len * 2 ;
buffer = ( xmlChar * ) xmlMalloc ( max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseNmtoken: out of memory \n " ) ;
return ( NULL ) ;
}
memcpy ( buffer , buf , len ) ;
while ( ( IS_LETTER ( c ) ) | | ( IS_DIGIT ( c ) ) | | /* test bigtoken.xml */
( c = = ' . ' ) | | ( c = = ' - ' ) | |
( c = = ' _ ' ) | | ( c = = ' : ' ) | |
( IS_COMBINING ( c ) ) | |
( IS_EXTENDER ( c ) ) ) {
if ( count + + > 100 ) {
count = 0 ;
GROW ;
}
if ( len + 10 > max ) {
max * = 2 ;
buffer = ( xmlChar * ) xmlRealloc ( buffer ,
max * sizeof ( xmlChar ) ) ;
if ( buffer = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-12-31 16:16:02 +00:00
" xmlParseNmtoken: out of memory \n " ) ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
}
COPY_BUF ( l , buffer , len , c ) ;
NEXTL ( l ) ;
c = CUR_CHAR ( l ) ;
}
buffer [ len ] = 0 ;
return ( buffer ) ;
}
}
if ( len = = 0 )
return ( NULL ) ;
return ( xmlStrndup ( buf , len ) ) ;
}
/**
* xmlParseEntityValue :
* @ ctxt : an XML parser context
* @ orig : if non - NULL store a copy of the original entity value
*
* parse a value for ENTITY declarations
*
* [ 9 ] EntityValue : : = ' " ' ( [ ^ % & " ] | PEReference | Reference)* ' " ' |
* " ' " ( [ ^ % & ' ] | PEReference | Reference ) * " ' "
*
2001-12-31 16:16:02 +00:00
* Returns the EntityValue parsed with reference substituted or NULL
2001-02-23 17:55:21 +00:00
*/
xmlChar *
xmlParseEntityValue ( xmlParserCtxtPtr ctxt , xmlChar * * orig ) {
xmlChar * buf = NULL ;
int len = 0 ;
int size = XML_PARSER_BUFFER_SIZE ;
int c , l ;
xmlChar stop ;
xmlChar * ret = NULL ;
const xmlChar * cur = NULL ;
xmlParserInputPtr input ;
if ( RAW = = ' " ' ) stop = ' " ' ;
else if ( RAW = = ' \' ' ) stop = ' \' ' ;
else {
ctxt - > errNo = XML_ERR_ENTITY_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " EntityValue: \" or ' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
buf = ( xmlChar * ) xmlMalloc ( size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %d byte failed \n " , size ) ;
return ( NULL ) ;
}
/*
* The content of the entity definition is copied in a buffer .
*/
ctxt - > instate = XML_PARSER_ENTITY_VALUE ;
input = ctxt - > input ;
GROW ;
NEXT ;
c = CUR_CHAR ( l ) ;
/*
* NOTE : 4.4 .5 Included in Literal
* When a parameter entity reference appears in a literal entity
* value , . . . a single or double quote character in the replacement
* text is always treated as a normal data character and will not
* terminate the literal .
* In practice it means we stop the loop only when back at parsing
* the initial entity and the quote is found
*/
while ( ( IS_CHAR ( c ) ) & & ( ( c ! = stop ) | | /* checked */
( ctxt - > input ! = input ) ) ) {
if ( len + 5 > = size ) {
size * = 2 ;
buf = ( xmlChar * ) xmlRealloc ( buf , size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc of %d byte failed \n " , size ) ;
return ( NULL ) ;
}
}
COPY_BUF ( l , buf , len , c ) ;
NEXTL ( l ) ;
/*
* Pop - up of finished entities .
*/
while ( ( RAW = = 0 ) & & ( ctxt - > inputNr > 1 ) ) /* non input consuming */
xmlPopInput ( ctxt ) ;
GROW ;
c = CUR_CHAR ( l ) ;
if ( c = = 0 ) {
GROW ;
c = CUR_CHAR ( l ) ;
}
}
buf [ len ] = 0 ;
/*
* Raise problem w . r . t . ' & ' and ' % ' being used in non - entities
* reference constructs . Note Charref will be handled in
* xmlStringDecodeEntities ( )
*/
cur = buf ;
while ( * cur ! = 0 ) { /* non input consuming */
if ( ( * cur = = ' % ' ) | | ( ( * cur = = ' & ' ) & & ( cur [ 1 ] ! = ' # ' ) ) ) {
xmlChar * name ;
xmlChar tmp = * cur ;
cur + + ;
name = xmlParseStringName ( ctxt , & cur ) ;
if ( ( name = = NULL ) | | ( * cur ! = ' ; ' ) ) {
ctxt - > errNo = XML_ERR_ENTITY_CHAR_ERROR ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" EntityValue: '%c' forbidden except for entities references \n " ,
tmp ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
2001-10-23 13:10:19 +00:00
if ( ( tmp = = ' % ' ) & & ( ctxt - > inSubset = = 1 ) & &
( ctxt - > inputNr = = 1 ) ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_ENTITY_PE_INTERNAL ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" EntityValue: PEReferences forbidden in internal subset \n " ,
tmp ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( name ! = NULL )
xmlFree ( name ) ;
}
cur + + ;
}
/*
* Then PEReference entities are substituted .
*/
if ( c ! = stop ) {
ctxt - > errNo = XML_ERR_ENTITY_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " EntityValue: \" expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
xmlFree ( buf ) ;
} else {
NEXT ;
/*
* NOTE : 4.4 .7 Bypassed
* When a general entity reference appears in the EntityValue in
* an entity declaration , it is bypassed and left as is .
* so XML_SUBSTITUTE_REF is not set here .
*/
ret = xmlStringDecodeEntities ( ctxt , buf , XML_SUBSTITUTE_PEREF ,
0 , 0 , 0 ) ;
if ( orig ! = NULL )
* orig = buf ;
else
xmlFree ( buf ) ;
}
return ( ret ) ;
}
/**
* xmlParseAttValue :
* @ ctxt : an XML parser context
*
* parse a value for an attribute
* Note : the parser won ' t do substitution of entities here , this
* will be handled later in xmlStringGetNodeList
*
* [ 10 ] AttValue : : = ' " ' ( [ ^ < & " ] | Reference)* ' " ' |
* " ' " ( [ ^ < & ' ] | Reference ) * " ' "
*
* 3.3 .3 Attribute - Value Normalization :
* Before the value of an attribute is passed to the application or
* checked for validity , the XML processor must normalize it as follows :
* - a character reference is processed by appending the referenced
* character to the attribute value
* - an entity reference is processed by recursively processing the
* replacement text of the entity
* - a whitespace character ( # x20 , # xD , # xA , # x9 ) is processed by
* appending # x20 to the normalized value , except that only a single
* # x20 is appended for a " #xD#xA " sequence that is part of an external
* parsed entity or the literal entity value of an internal parsed entity
* - other characters are processed by appending them to the normalized value
* If the declared value is not CDATA , then the XML processor must further
* process the normalized attribute value by discarding any leading and
* trailing space ( # x20 ) characters , and by replacing sequences of space
* ( # x20 ) characters by a single space ( # x20 ) character .
* All attributes for which no declaration has been read should be treated
* by a non - validating parser as if declared CDATA .
*
* Returns the AttValue parsed or NULL . The value has to be freed by the caller .
*/
2002-05-31 09:47:30 +00:00
xmlChar *
xmlParseAttValueComplex ( xmlParserCtxtPtr ctxt ) ;
2001-02-23 17:55:21 +00:00
xmlChar *
xmlParseAttValue ( xmlParserCtxtPtr ctxt ) {
2002-05-31 09:47:30 +00:00
xmlChar limit = 0 ;
2002-09-10 11:13:43 +00:00
const xmlChar * in = NULL ;
2002-05-31 09:47:30 +00:00
xmlChar * ret = NULL ;
SHRINK ;
GROW ;
2002-10-22 17:35:37 +00:00
in = ( xmlChar * ) CUR_PTR ;
2002-05-31 09:47:30 +00:00
if ( * in ! = ' " ' & & * in ! = ' \' ' ) {
ctxt - > errNo = XML_ERR_ATTRIBUTE_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " AttValue: \" or ' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-05-31 09:47:30 +00:00
return ( NULL ) ;
}
ctxt - > instate = XML_PARSER_ATTRIBUTE_VALUE ;
limit = * in ;
+ + in ;
while ( * in ! = limit & & * in > = 0x20 & & * in < = 0x7f & &
* in ! = ' & ' & & * in ! = ' < '
) {
+ + in ;
}
if ( * in ! = limit ) {
return xmlParseAttValueComplex ( ctxt ) ;
}
+ + in ;
ret = xmlStrndup ( CUR_PTR + 1 , in - CUR_PTR - 2 ) ;
CUR_PTR = in ;
return ret ;
}
2002-12-10 15:19:08 +00:00
/**
* xmlParseAttValueComplex :
* @ ctxt : an XML parser context
*
* parse a value for an attribute , this is the fallback function
* of xmlParseAttValue ( ) when the attribute parsing requires handling
* of non - ASCII characters .
*
* Returns the AttValue parsed or NULL . The value has to be freed by the caller .
*/
2002-05-31 09:47:30 +00:00
xmlChar *
xmlParseAttValueComplex ( xmlParserCtxtPtr ctxt ) {
2001-02-23 17:55:21 +00:00
xmlChar limit = 0 ;
xmlChar * buf = NULL ;
int len = 0 ;
int buf_size = 0 ;
int c , l ;
xmlChar * current = NULL ;
xmlEntityPtr ent ;
SHRINK ;
if ( NXT ( 0 ) = = ' " ' ) {
ctxt - > instate = XML_PARSER_ATTRIBUTE_VALUE ;
limit = ' " ' ;
NEXT ;
} else if ( NXT ( 0 ) = = ' \' ' ) {
limit = ' \' ' ;
ctxt - > instate = XML_PARSER_ATTRIBUTE_VALUE ;
NEXT ;
} else {
ctxt - > errNo = XML_ERR_ATTRIBUTE_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " AttValue: \" or ' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
/*
* allocate a translation buffer .
*/
buf_size = XML_PARSER_BUFFER_SIZE ;
buf = ( xmlChar * ) xmlMalloc ( buf_size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
2002-09-05 11:33:25 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" xmlParseAttValue: malloc failed " ) ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
/*
2001-12-31 16:16:02 +00:00
* OK loop until we reach one of the ending char or a size limit .
2001-02-23 17:55:21 +00:00
*/
c = CUR_CHAR ( l ) ;
2002-07-01 21:52:03 +00:00
while ( ( NXT ( 0 ) ! = limit ) & & /* checked */
( c ! = ' < ' ) ) {
2001-02-23 17:55:21 +00:00
if ( c = = 0 ) break ;
2002-07-01 21:52:03 +00:00
if ( c = = ' & ' ) {
2001-02-23 17:55:21 +00:00
if ( NXT ( 1 ) = = ' # ' ) {
int val = xmlParseCharRef ( ctxt ) ;
if ( val = = ' & ' ) {
2001-09-11 09:27:09 +00:00
if ( ctxt - > replaceEntities ) {
if ( len > buf_size - 10 ) {
growBuffer ( buf ) ;
}
buf [ len + + ] = ' & ' ;
} else {
/*
* The reparsing will be done in xmlStringGetNodeList ( )
* called by the attribute ( ) function in SAX . c
*/
static xmlChar buffer [ 6 ] = " & " ;
if ( len > buf_size - 10 ) {
growBuffer ( buf ) ;
}
current = & buffer [ 0 ] ;
while ( * current ! = 0 ) { /* non input consuming */
buf [ len + + ] = * current + + ;
}
2001-02-23 17:55:21 +00:00
}
} else {
2001-03-20 11:27:34 +00:00
if ( len > buf_size - 10 ) {
growBuffer ( buf ) ;
}
2001-02-23 17:55:21 +00:00
len + = xmlCopyChar ( 0 , & buf [ len ] , val ) ;
}
} else {
ent = xmlParseEntityRef ( ctxt ) ;
if ( ( ent ! = NULL ) & &
( ctxt - > replaceEntities ! = 0 ) ) {
xmlChar * rep ;
if ( ent - > etype ! = XML_INTERNAL_PREDEFINED_ENTITY ) {
rep = xmlStringDecodeEntities ( ctxt , ent - > content ,
XML_SUBSTITUTE_REF , 0 , 0 , 0 ) ;
if ( rep ! = NULL ) {
current = rep ;
while ( * current ! = 0 ) { /* non input consuming */
buf [ len + + ] = * current + + ;
if ( len > buf_size - 10 ) {
growBuffer ( buf ) ;
}
}
xmlFree ( rep ) ;
}
} else {
2001-03-20 11:27:34 +00:00
if ( len > buf_size - 10 ) {
growBuffer ( buf ) ;
}
2001-02-23 17:55:21 +00:00
if ( ent - > content ! = NULL )
buf [ len + + ] = ent - > content [ 0 ] ;
}
} else if ( ent ! = NULL ) {
int i = xmlStrlen ( ent - > name ) ;
const xmlChar * cur = ent - > name ;
/*
* This may look absurd but is needed to detect
* entities problems
*/
if ( ( ent - > etype ! = XML_INTERNAL_PREDEFINED_ENTITY ) & &
( ent - > content ! = NULL ) ) {
xmlChar * rep ;
rep = xmlStringDecodeEntities ( ctxt , ent - > content ,
XML_SUBSTITUTE_REF , 0 , 0 , 0 ) ;
if ( rep ! = NULL )
xmlFree ( rep ) ;
}
/*
* Just output the reference
*/
buf [ len + + ] = ' & ' ;
if ( len > buf_size - i - 10 ) {
growBuffer ( buf ) ;
}
for ( ; i > 0 ; i - - )
buf [ len + + ] = * cur + + ;
buf [ len + + ] = ' ; ' ;
}
}
} else {
if ( ( c = = 0x20 ) | | ( c = = 0xD ) | | ( c = = 0xA ) | | ( c = = 0x9 ) ) {
COPY_BUF ( l , buf , len , 0x20 ) ;
if ( len > buf_size - 10 ) {
growBuffer ( buf ) ;
}
} else {
COPY_BUF ( l , buf , len , c ) ;
if ( len > buf_size - 10 ) {
growBuffer ( buf ) ;
}
}
NEXTL ( l ) ;
}
GROW ;
c = CUR_CHAR ( l ) ;
}
buf [ len + + ] = 0 ;
if ( RAW = = ' < ' ) {
ctxt - > errNo = XML_ERR_LT_IN_ATTRIBUTE ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Unescaped '<' not allowed in attributes values \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else if ( RAW ! = limit ) {
ctxt - > errNo = XML_ERR_ATTRIBUTE_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " AttValue: ' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else
NEXT ;
return ( buf ) ;
}
/**
* xmlParseSystemLiteral :
* @ ctxt : an XML parser context
*
* parse an XML Literal
*
* [ 11 ] SystemLiteral : : = ( ' " ' [ ^ " ]* ' " ' ) | ( " ' " [ ^ ' ] * " ' " )
*
* Returns the SystemLiteral parsed or NULL
*/
xmlChar *
xmlParseSystemLiteral ( xmlParserCtxtPtr ctxt ) {
xmlChar * buf = NULL ;
int len = 0 ;
int size = XML_PARSER_BUFFER_SIZE ;
int cur , l ;
xmlChar stop ;
int state = ctxt - > instate ;
int count = 0 ;
SHRINK ;
if ( RAW = = ' " ' ) {
NEXT ;
stop = ' " ' ;
} else if ( RAW = = ' \' ' ) {
NEXT ;
stop = ' \' ' ;
} else {
ctxt - > errNo = XML_ERR_LITERAL_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" SystemLiteral \" or ' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
buf = ( xmlChar * ) xmlMalloc ( size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %d byte failed \n " , size ) ;
return ( NULL ) ;
}
ctxt - > instate = XML_PARSER_SYSTEM_LITERAL ;
cur = CUR_CHAR ( l ) ;
while ( ( IS_CHAR ( cur ) ) & & ( cur ! = stop ) ) { /* checked */
if ( len + 5 > = size ) {
size * = 2 ;
buf = ( xmlChar * ) xmlRealloc ( buf , size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc of %d byte failed \n " , size ) ;
ctxt - > instate = ( xmlParserInputState ) state ;
return ( NULL ) ;
}
}
count + + ;
if ( count > 50 ) {
GROW ;
count = 0 ;
}
COPY_BUF ( l , buf , len , cur ) ;
NEXTL ( l ) ;
cur = CUR_CHAR ( l ) ;
if ( cur = = 0 ) {
GROW ;
SHRINK ;
cur = CUR_CHAR ( l ) ;
}
}
buf [ len ] = 0 ;
ctxt - > instate = ( xmlParserInputState ) state ;
if ( ! IS_CHAR ( cur ) ) {
ctxt - > errNo = XML_ERR_LITERAL_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Unfinished SystemLiteral \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
NEXT ;
}
return ( buf ) ;
}
/**
* xmlParsePubidLiteral :
* @ ctxt : an XML parser context
*
* parse an XML public literal
*
* [ 12 ] PubidLiteral : : = ' " ' PubidChar * ' " ' | " ' " ( PubidChar - " ' " ) * " ' "
*
* Returns the PubidLiteral parsed or NULL .
*/
xmlChar *
xmlParsePubidLiteral ( xmlParserCtxtPtr ctxt ) {
xmlChar * buf = NULL ;
int len = 0 ;
int size = XML_PARSER_BUFFER_SIZE ;
xmlChar cur ;
xmlChar stop ;
int count = 0 ;
2002-02-18 19:18:17 +00:00
xmlParserInputState oldstate = ctxt - > instate ;
2001-02-23 17:55:21 +00:00
SHRINK ;
if ( RAW = = ' " ' ) {
NEXT ;
stop = ' " ' ;
} else if ( RAW = = ' \' ' ) {
NEXT ;
stop = ' \' ' ;
} else {
ctxt - > errNo = XML_ERR_LITERAL_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" SystemLiteral \" or ' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
buf = ( xmlChar * ) xmlMalloc ( size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %d byte failed \n " , size ) ;
return ( NULL ) ;
}
2002-02-18 19:18:17 +00:00
ctxt - > instate = XML_PARSER_PUBLIC_LITERAL ;
2001-02-23 17:55:21 +00:00
cur = CUR ;
while ( ( IS_PUBIDCHAR ( cur ) ) & & ( cur ! = stop ) ) { /* checked */
if ( len + 1 > = size ) {
size * = 2 ;
buf = ( xmlChar * ) xmlRealloc ( buf , size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc of %d byte failed \n " , size ) ;
return ( NULL ) ;
}
}
buf [ len + + ] = cur ;
count + + ;
if ( count > 50 ) {
GROW ;
count = 0 ;
}
NEXT ;
cur = CUR ;
if ( cur = = 0 ) {
GROW ;
SHRINK ;
cur = CUR ;
}
}
buf [ len ] = 0 ;
if ( cur ! = stop ) {
ctxt - > errNo = XML_ERR_LITERAL_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Unfinished PubidLiteral \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
NEXT ;
}
2002-02-18 19:18:17 +00:00
ctxt - > instate = oldstate ;
2001-02-23 17:55:21 +00:00
return ( buf ) ;
}
2001-02-25 16:11:03 +00:00
void xmlParseCharDataComplex ( xmlParserCtxtPtr ctxt , int cdata ) ;
2001-02-23 17:55:21 +00:00
/**
* xmlParseCharData :
* @ ctxt : an XML parser context
* @ cdata : int indicating whether we are within a CDATA section
*
* parse a CharData section .
* if we are within a CDATA section ' ] ] > ' marks an end of section .
*
* The right angle bracket ( > ) may be represented using the string " > ; " ,
* and must , for compatibility , be escaped using " > " or a character
* reference when it appears in the string " ]]> " in content , when that
* string is not marking the end of a CDATA section .
*
* [ 14 ] CharData : : = [ ^ < & ] * - ( [ ^ < & ] * ' ] ] > ' [ ^ < & ] * )
*/
void
xmlParseCharData ( xmlParserCtxtPtr ctxt , int cdata ) {
2002-03-20 21:55:57 +00:00
const xmlChar * in ;
2001-02-25 16:11:03 +00:00
int nbchar = 0 ;
2001-03-26 22:52:16 +00:00
int line = ctxt - > input - > line ;
int col = ctxt - > input - > col ;
2001-02-25 16:11:03 +00:00
SHRINK ;
GROW ;
/*
* Accelerated common case where input don ' t need to be
* modified before passing it to the handler .
*/
2002-07-01 21:52:03 +00:00
if ( ! cdata ) {
2001-02-25 16:11:03 +00:00
in = ctxt - > input - > cur ;
do {
2001-04-29 19:56:59 +00:00
get_more :
2002-03-20 21:55:57 +00:00
while ( ( ( * in > = 0x20 ) & & ( * in ! = ' < ' ) & & ( * in ! = ' ] ' ) & &
( * in ! = ' & ' ) & & ( * in < = 0x7F ) ) | | ( * in = = 0x09 ) )
2001-02-25 16:11:03 +00:00
in + + ;
2002-03-20 21:55:57 +00:00
if ( * in = = 0xA ) {
2001-02-25 16:11:03 +00:00
ctxt - > input - > line + + ;
2001-04-29 19:56:59 +00:00
in + + ;
2002-03-20 21:55:57 +00:00
while ( * in = = 0xA ) {
2001-04-29 19:56:59 +00:00
ctxt - > input - > line + + ;
in + + ;
}
goto get_more ;
2002-03-20 21:55:57 +00:00
}
if ( * in = = ' ] ' ) {
2002-02-17 21:26:33 +00:00
if ( ( in [ 1 ] = = ' ] ' ) & & ( in [ 2 ] = = ' > ' ) ) {
ctxt - > errNo = XML_ERR_MISPLACED_CDATA_END ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Sequence ']]>' not allowed in content \n " ) ;
ctxt - > input - > cur = in ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-02-17 21:26:33 +00:00
return ;
}
in + + ;
goto get_more ;
}
2001-02-25 16:11:03 +00:00
nbchar = in - ctxt - > input - > cur ;
2001-03-07 19:45:40 +00:00
if ( nbchar > 0 ) {
2001-05-10 14:17:55 +00:00
if ( IS_BLANK ( * ctxt - > input - > cur ) ) {
const xmlChar * tmp = ctxt - > input - > cur ;
ctxt - > input - > cur = in ;
if ( areBlanks ( ctxt , tmp , nbchar ) ) {
if ( ctxt - > sax - > ignorableWhitespace ! = NULL )
ctxt - > sax - > ignorableWhitespace ( ctxt - > userData ,
tmp , nbchar ) ;
} else {
if ( ctxt - > sax - > characters ! = NULL )
ctxt - > sax - > characters ( ctxt - > userData ,
tmp , nbchar ) ;
}
2001-06-17 17:58:17 +00:00
line = ctxt - > input - > line ;
col = ctxt - > input - > col ;
2001-03-07 19:45:40 +00:00
} else {
if ( ctxt - > sax - > characters ! = NULL )
ctxt - > sax - > characters ( ctxt - > userData ,
ctxt - > input - > cur , nbchar ) ;
2001-06-17 17:58:17 +00:00
line = ctxt - > input - > line ;
col = ctxt - > input - > col ;
2001-03-07 19:45:40 +00:00
}
2001-02-25 16:11:03 +00:00
}
ctxt - > input - > cur = in ;
2002-03-20 21:55:57 +00:00
if ( * in = = 0xD ) {
in + + ;
if ( * in = = 0xA ) {
ctxt - > input - > cur = in ;
2001-02-25 16:11:03 +00:00
in + + ;
2002-03-20 21:55:57 +00:00
ctxt - > input - > line + + ;
continue ; /* while */
2001-02-25 16:11:03 +00:00
}
2002-03-20 21:55:57 +00:00
in - - ;
}
if ( * in = = ' < ' ) {
return ;
}
if ( * in = = ' & ' ) {
return ;
2001-02-25 16:11:03 +00:00
}
SHRINK ;
GROW ;
in = ctxt - > input - > cur ;
2002-03-20 21:55:57 +00:00
} while ( ( * in > = 0x20 ) & & ( * in < = 0x7F ) ) ;
2001-02-25 16:11:03 +00:00
nbchar = 0 ;
}
2001-03-26 22:52:16 +00:00
ctxt - > input - > line = line ;
ctxt - > input - > col = col ;
2001-02-25 16:11:03 +00:00
xmlParseCharDataComplex ( ctxt , cdata ) ;
}
2002-12-10 15:19:08 +00:00
/**
* xmlParseCharDataComplex :
* @ ctxt : an XML parser context
* @ cdata : int indicating whether we are within a CDATA section
*
* parse a CharData section . this is the fallback function
* of xmlParseCharData ( ) when the parsing requires handling
* of non - ASCII characters .
*/
2001-02-25 16:11:03 +00:00
void
xmlParseCharDataComplex ( xmlParserCtxtPtr ctxt , int cdata ) {
2001-02-23 17:55:21 +00:00
xmlChar buf [ XML_PARSER_BIG_BUFFER_SIZE + 5 ] ;
int nbchar = 0 ;
int cur , l ;
int count = 0 ;
SHRINK ;
GROW ;
cur = CUR_CHAR ( l ) ;
2002-07-01 21:52:03 +00:00
while ( ( cur ! = ' < ' ) & & /* checked */
( cur ! = ' & ' ) & &
( IS_CHAR ( cur ) ) ) /* test also done in xmlCurrentChar() */ {
2001-02-23 17:55:21 +00:00
if ( ( cur = = ' ] ' ) & & ( NXT ( 1 ) = = ' ] ' ) & &
( NXT ( 2 ) = = ' > ' ) ) {
if ( cdata ) break ;
else {
ctxt - > errNo = XML_ERR_MISPLACED_CDATA_END ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Sequence ']]>' not allowed in content \n " ) ;
/* Should this be relaxed ??? I see a "must here */
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
}
COPY_BUF ( l , buf , nbchar , cur ) ;
if ( nbchar > = XML_PARSER_BIG_BUFFER_SIZE ) {
/*
2001-12-31 16:16:02 +00:00
* OK the segment is to be consumed as chars .
2001-02-23 17:55:21 +00:00
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) ) {
if ( areBlanks ( ctxt , buf , nbchar ) ) {
if ( ctxt - > sax - > ignorableWhitespace ! = NULL )
ctxt - > sax - > ignorableWhitespace ( ctxt - > userData ,
buf , nbchar ) ;
} else {
if ( ctxt - > sax - > characters ! = NULL )
ctxt - > sax - > characters ( ctxt - > userData , buf , nbchar ) ;
}
}
nbchar = 0 ;
}
count + + ;
if ( count > 50 ) {
GROW ;
count = 0 ;
}
NEXTL ( l ) ;
cur = CUR_CHAR ( l ) ;
}
if ( nbchar ! = 0 ) {
/*
2001-12-31 16:16:02 +00:00
* OK the segment is to be consumed as chars .
2001-02-23 17:55:21 +00:00
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) ) {
if ( areBlanks ( ctxt , buf , nbchar ) ) {
if ( ctxt - > sax - > ignorableWhitespace ! = NULL )
ctxt - > sax - > ignorableWhitespace ( ctxt - > userData , buf , nbchar ) ;
} else {
if ( ctxt - > sax - > characters ! = NULL )
ctxt - > sax - > characters ( ctxt - > userData , buf , nbchar ) ;
}
}
}
}
/**
* xmlParseExternalID :
* @ ctxt : an XML parser context
* @ publicID : a xmlChar * * receiving PubidLiteral
* @ strict : indicate whether we should restrict parsing to only
* production [ 75 ] , see NOTE below
*
* Parse an External ID or a Public ID
*
2001-12-31 16:16:02 +00:00
* NOTE : Productions [ 75 ] and [ 83 ] interact badly since [ 75 ] can generate
2001-02-23 17:55:21 +00:00
* ' PUBLIC ' S PubidLiteral S SystemLiteral
*
* [ 75 ] ExternalID : : = ' SYSTEM ' S SystemLiteral
* | ' PUBLIC ' S PubidLiteral S SystemLiteral
*
* [ 83 ] PublicID : : = ' PUBLIC ' S PubidLiteral
*
* Returns the function returns SystemLiteral and in the second
* case publicID receives PubidLiteral , is strict is off
* it is possible to return NULL and have publicID set .
*/
xmlChar *
xmlParseExternalID ( xmlParserCtxtPtr ctxt , xmlChar * * publicID , int strict ) {
xmlChar * URI = NULL ;
SHRINK ;
2001-03-22 15:22:27 +00:00
* publicID = NULL ;
2001-02-23 17:55:21 +00:00
if ( ( RAW = = ' S ' ) & & ( NXT ( 1 ) = = ' Y ' ) & &
( NXT ( 2 ) = = ' S ' ) & & ( NXT ( 3 ) = = ' T ' ) & &
( NXT ( 4 ) = = ' E ' ) & & ( NXT ( 5 ) = = ' M ' ) ) {
SKIP ( 6 ) ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after 'SYSTEM' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
URI = xmlParseSystemLiteral ( ctxt ) ;
if ( URI = = NULL ) {
ctxt - > errNo = XML_ERR_URI_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseExternalID: SYSTEM, no URI \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
} else if ( ( RAW = = ' P ' ) & & ( NXT ( 1 ) = = ' U ' ) & &
( NXT ( 2 ) = = ' B ' ) & & ( NXT ( 3 ) = = ' L ' ) & &
( NXT ( 4 ) = = ' I ' ) & & ( NXT ( 5 ) = = ' C ' ) ) {
SKIP ( 6 ) ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after 'PUBLIC' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
* publicID = xmlParsePubidLiteral ( ctxt ) ;
if ( * publicID = = NULL ) {
ctxt - > errNo = XML_ERR_PUBID_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseExternalID: PUBLIC, no Public Identifier \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( strict ) {
/*
* We don ' t handle [ 83 ] so " S SystemLiteral " is required .
*/
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after the Public Identifier \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
} else {
/*
* We handle [ 83 ] so we return immediately , if
* " S SystemLiteral " is not detected . From a purely parsing
* point of view that ' s a nice mess .
*/
const xmlChar * ptr ;
GROW ;
ptr = CUR_PTR ;
if ( ! IS_BLANK ( * ptr ) ) return ( NULL ) ;
while ( IS_BLANK ( * ptr ) ) ptr + + ; /* TODO: dangerous, fix ! */
if ( ( * ptr ! = ' \' ' ) & & ( * ptr ! = ' " ' ) ) return ( NULL ) ;
}
SKIP_BLANKS ;
URI = xmlParseSystemLiteral ( ctxt ) ;
if ( URI = = NULL ) {
ctxt - > errNo = XML_ERR_URI_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseExternalID: PUBLIC, no URI \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
}
return ( URI ) ;
}
/**
* xmlParseComment :
* @ ctxt : an XML parser context
*
* Skip an XML ( SGML ) comment < ! - - . . . . - - >
* The spec says that " For compatibility, the string " - - " (double-hyphen)
* must not occur within comments . "
*
* [ 15 ] Comment : : = ' < ! - - ' ( ( Char - ' - ' ) | ( ' - ' ( Char - ' - ' ) ) ) * ' - - > '
*/
void
xmlParseComment ( xmlParserCtxtPtr ctxt ) {
xmlChar * buf = NULL ;
int len ;
int size = XML_PARSER_BUFFER_SIZE ;
int q , ql ;
int r , rl ;
int cur , l ;
xmlParserInputState state ;
xmlParserInputPtr input = ctxt - > input ;
int count = 0 ;
/*
* Check that there is a comment right here .
*/
if ( ( RAW ! = ' < ' ) | | ( NXT ( 1 ) ! = ' ! ' ) | |
( NXT ( 2 ) ! = ' - ' ) | | ( NXT ( 3 ) ! = ' - ' ) ) return ;
state = ctxt - > instate ;
ctxt - > instate = XML_PARSER_COMMENT ;
SHRINK ;
SKIP ( 4 ) ;
buf = ( xmlChar * ) xmlMalloc ( size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %d byte failed \n " , size ) ;
ctxt - > instate = state ;
return ;
}
q = CUR_CHAR ( ql ) ;
NEXTL ( ql ) ;
r = CUR_CHAR ( rl ) ;
NEXTL ( rl ) ;
cur = CUR_CHAR ( l ) ;
len = 0 ;
while ( IS_CHAR ( cur ) & & /* checked */
( ( cur ! = ' > ' ) | |
( r ! = ' - ' ) | | ( q ! = ' - ' ) ) ) {
2002-02-17 21:26:33 +00:00
if ( ( r = = ' - ' ) & & ( q = = ' - ' ) ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_HYPHEN_IN_COMMENT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Comment must not contain '--' (double-hyphen)` \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( len + 5 > = size ) {
size * = 2 ;
buf = ( xmlChar * ) xmlRealloc ( buf , size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc of %d byte failed \n " , size ) ;
ctxt - > instate = state ;
return ;
}
}
COPY_BUF ( ql , buf , len , q ) ;
q = r ;
ql = rl ;
r = cur ;
rl = l ;
count + + ;
if ( count > 50 ) {
GROW ;
count = 0 ;
}
NEXTL ( l ) ;
cur = CUR_CHAR ( l ) ;
if ( cur = = 0 ) {
SHRINK ;
GROW ;
cur = CUR_CHAR ( l ) ;
}
}
buf [ len ] = 0 ;
if ( ! IS_CHAR ( cur ) ) {
ctxt - > errNo = XML_ERR_COMMENT_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Comment not terminated \n <!--%.50s \n " , buf ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
xmlFree ( buf ) ;
} else {
if ( input ! = ctxt - > input ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Comment doesn't start and stop in the same entity \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
NEXT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > comment ! = NULL ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > comment ( ctxt - > userData , buf ) ;
xmlFree ( buf ) ;
}
ctxt - > instate = state ;
}
/**
* xmlParsePITarget :
* @ ctxt : an XML parser context
*
* parse the name of a PI
*
* [ 17 ] PITarget : : = Name - ( ( ' X ' | ' x ' ) ( ' M ' | ' m ' ) ( ' L ' | ' l ' ) )
*
* Returns the PITarget name or NULL
*/
xmlChar *
xmlParsePITarget ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
name = xmlParseName ( ctxt ) ;
if ( ( name ! = NULL ) & &
( ( name [ 0 ] = = ' x ' ) | | ( name [ 0 ] = = ' X ' ) ) & &
( ( name [ 1 ] = = ' m ' ) | | ( name [ 1 ] = = ' M ' ) ) & &
( ( name [ 2 ] = = ' l ' ) | | ( name [ 2 ] = = ' L ' ) ) ) {
int i ;
if ( ( name [ 0 ] = = ' x ' ) & & ( name [ 1 ] = = ' m ' ) & &
( name [ 2 ] = = ' l ' ) & & ( name [ 3 ] = = 0 ) ) {
ctxt - > errNo = XML_ERR_RESERVED_XML_NAME ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" XML declaration allowed only at the start of the document \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( name ) ;
} else if ( name [ 3 ] = = 0 ) {
ctxt - > errNo = XML_ERR_RESERVED_XML_NAME ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Invalid PI name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( name ) ;
}
for ( i = 0 ; ; i + + ) {
if ( xmlW3CPIs [ i ] = = NULL ) break ;
if ( xmlStrEqual ( name , ( const xmlChar * ) xmlW3CPIs [ i ] ) )
return ( name ) ;
}
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) ) {
ctxt - > errNo = XML_ERR_RESERVED_XML_NAME ;
ctxt - > sax - > warning ( ctxt - > userData ,
2001-12-31 16:16:02 +00:00
" xmlParsePITarget: invalid name prefix 'xml' \n " ) ;
2001-02-23 17:55:21 +00:00
}
}
return ( name ) ;
}
2001-08-22 14:29:45 +00:00
# ifdef LIBXML_CATALOG_ENABLED
/**
* xmlParseCatalogPI :
* @ ctxt : an XML parser context
* @ catalog : the PI value string
*
* parse an XML Catalog Processing Instruction .
*
* < ? oasis - xml - catalog catalog = " http://example.com/catalog.xml " ? >
*
* Occurs only if allowed by the user and if happening in the Misc
* part of the document before any doctype informations
* This will add the given catalog to the parsing context in order
* to be used if there is a resolution need further down in the document
*/
static void
xmlParseCatalogPI ( xmlParserCtxtPtr ctxt , const xmlChar * catalog ) {
xmlChar * URL = NULL ;
const xmlChar * tmp , * base ;
xmlChar marker ;
tmp = catalog ;
while ( IS_BLANK ( * tmp ) ) tmp + + ;
if ( xmlStrncmp ( tmp , BAD_CAST " catalog " , 7 ) )
goto error ;
tmp + = 7 ;
while ( IS_BLANK ( * tmp ) ) tmp + + ;
if ( * tmp ! = ' = ' ) {
return ;
}
tmp + + ;
while ( IS_BLANK ( * tmp ) ) tmp + + ;
marker = * tmp ;
if ( ( marker ! = ' \' ' ) & & ( marker ! = ' " ' ) )
goto error ;
tmp + + ;
base = tmp ;
while ( ( * tmp ! = 0 ) & & ( * tmp ! = marker ) ) tmp + + ;
if ( * tmp = = 0 )
goto error ;
URL = xmlStrndup ( base , tmp - base ) ;
tmp + + ;
while ( IS_BLANK ( * tmp ) ) tmp + + ;
if ( * tmp ! = 0 )
goto error ;
if ( URL ! = NULL ) {
ctxt - > catalogs = xmlCatalogAddLocal ( ctxt - > catalogs , URL ) ;
xmlFree ( URL ) ;
}
return ;
error :
ctxt - > errNo = XML_WAR_CATALOG_PI ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" Catalog PI syntax error: %s \n " , catalog ) ;
if ( URL ! = NULL )
xmlFree ( URL ) ;
}
# endif
2001-02-23 17:55:21 +00:00
/**
* xmlParsePI :
* @ ctxt : an XML parser context
*
* parse an XML Processing Instruction .
*
* [ 16 ] PI : : = ' < ? ' PITarget ( S ( Char * - ( Char * ' ? > ' Char * ) ) ) ? ' ? > '
*
* The processing is transfered to SAX once parsed .
*/
void
xmlParsePI ( xmlParserCtxtPtr ctxt ) {
xmlChar * buf = NULL ;
int len = 0 ;
int size = XML_PARSER_BUFFER_SIZE ;
int cur , l ;
xmlChar * target ;
xmlParserInputState state ;
int count = 0 ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) ) {
xmlParserInputPtr input = ctxt - > input ;
state = ctxt - > instate ;
ctxt - > instate = XML_PARSER_PI ;
/*
* this is a Processing Instruction .
*/
SKIP ( 2 ) ;
SHRINK ;
/*
* Parse the target name and check for special support like
* namespace .
*/
target = xmlParsePITarget ( ctxt ) ;
if ( target ! = NULL ) {
if ( ( RAW = = ' ? ' ) & & ( NXT ( 1 ) = = ' > ' ) ) {
if ( input ! = ctxt - > input ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" PI declaration doesn't start and stop in the same entity \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP ( 2 ) ;
/*
* SAX : PI detected .
*/
if ( ( ctxt - > sax ) & & ( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > processingInstruction ! = NULL ) )
ctxt - > sax - > processingInstruction ( ctxt - > userData ,
target , NULL ) ;
ctxt - > instate = state ;
xmlFree ( target ) ;
return ;
}
buf = ( xmlChar * ) xmlMalloc ( size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %d byte failed \n " , size ) ;
ctxt - > instate = state ;
return ;
}
cur = CUR ;
if ( ! IS_BLANK ( cur ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParsePI: PI %s space expected \n " , target ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
cur = CUR_CHAR ( l ) ;
while ( IS_CHAR ( cur ) & & /* checked */
( ( cur ! = ' ? ' ) | | ( NXT ( 1 ) ! = ' > ' ) ) ) {
if ( len + 5 > = size ) {
size * = 2 ;
buf = ( xmlChar * ) xmlRealloc ( buf , size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc of %d byte failed \n " , size ) ;
ctxt - > instate = state ;
return ;
}
}
count + + ;
if ( count > 50 ) {
GROW ;
count = 0 ;
}
COPY_BUF ( l , buf , len , cur ) ;
NEXTL ( l ) ;
cur = CUR_CHAR ( l ) ;
if ( cur = = 0 ) {
SHRINK ;
GROW ;
cur = CUR_CHAR ( l ) ;
}
}
buf [ len ] = 0 ;
if ( cur ! = ' ? ' ) {
ctxt - > errNo = XML_ERR_PI_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParsePI: PI %s never end ... \n " , target ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
if ( input ! = ctxt - > input ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" PI declaration doesn't start and stop in the same entity \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP ( 2 ) ;
2001-08-22 14:29:45 +00:00
# ifdef LIBXML_CATALOG_ENABLED
if ( ( ( state = = XML_PARSER_MISC ) | |
( state = = XML_PARSER_START ) ) & &
( xmlStrEqual ( target , XML_CATALOG_PI ) ) ) {
xmlCatalogAllow allow = xmlCatalogGetDefaults ( ) ;
if ( ( allow = = XML_CATA_ALLOW_DOCUMENT ) | |
( allow = = XML_CATA_ALLOW_ALL ) )
xmlParseCatalogPI ( ctxt , buf ) ;
}
# endif
2001-02-23 17:55:21 +00:00
/*
* SAX : PI detected .
*/
if ( ( ctxt - > sax ) & & ( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > processingInstruction ! = NULL ) )
ctxt - > sax - > processingInstruction ( ctxt - > userData ,
target , buf ) ;
}
xmlFree ( buf ) ;
xmlFree ( target ) ;
} else {
ctxt - > errNo = XML_ERR_PI_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParsePI : no target name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
ctxt - > instate = state ;
}
}
/**
* xmlParseNotationDecl :
* @ ctxt : an XML parser context
*
* parse a notation declaration
*
* [ 82 ] NotationDecl : : = ' < ! NOTATION ' S Name S ( ExternalID | PublicID ) S ? ' > '
*
* Hence there is actually 3 choices :
* ' PUBLIC ' S PubidLiteral
* ' PUBLIC ' S PubidLiteral S SystemLiteral
* and ' SYSTEM ' S SystemLiteral
*
* See the NOTE on xmlParseExternalID ( ) .
*/
void
xmlParseNotationDecl ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
xmlChar * Pubid ;
xmlChar * Systemid ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & &
( NXT ( 2 ) = = ' N ' ) & & ( NXT ( 3 ) = = ' O ' ) & &
( NXT ( 4 ) = = ' T ' ) & & ( NXT ( 5 ) = = ' A ' ) & &
( NXT ( 6 ) = = ' T ' ) & & ( NXT ( 7 ) = = ' I ' ) & &
( NXT ( 8 ) = = ' O ' ) & & ( NXT ( 9 ) = = ' N ' ) ) {
xmlParserInputPtr input = ctxt - > input ;
SHRINK ;
SKIP ( 10 ) ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after '<!NOTATION' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ;
}
SKIP_BLANKS ;
2001-05-16 21:05:17 +00:00
name = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NOTATION_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" NOTATION: Name expected here \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ;
}
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after the NOTATION name' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ;
}
SKIP_BLANKS ;
/*
* Parse the IDs .
*/
Systemid = xmlParseExternalID ( ctxt , & Pubid , 0 ) ;
SKIP_BLANKS ;
if ( RAW = = ' > ' ) {
if ( input ! = ctxt - > input ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Notation declaration doesn't start and stop in the same entity \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
NEXT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > notationDecl ! = NULL ) )
ctxt - > sax - > notationDecl ( ctxt - > userData , name , Pubid , Systemid ) ;
} else {
ctxt - > errNo = XML_ERR_NOTATION_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" '>' required to close NOTATION declaration \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
xmlFree ( name ) ;
if ( Systemid ! = NULL ) xmlFree ( Systemid ) ;
if ( Pubid ! = NULL ) xmlFree ( Pubid ) ;
}
}
/**
* xmlParseEntityDecl :
* @ ctxt : an XML parser context
*
* parse < ! ENTITY declarations
*
* [ 70 ] EntityDecl : : = GEDecl | PEDecl
*
* [ 71 ] GEDecl : : = ' < ! ENTITY ' S Name S EntityDef S ? ' > '
*
* [ 72 ] PEDecl : : = ' < ! ENTITY ' S ' % ' S Name S PEDef S ? ' > '
*
* [ 73 ] EntityDef : : = EntityValue | ( ExternalID NDataDecl ? )
*
* [ 74 ] PEDef : : = EntityValue | ExternalID
*
* [ 76 ] NDataDecl : : = S ' NDATA ' S Name
*
* [ VC : Notation Declared ]
* The Name must match the declared name of a notation .
*/
void
xmlParseEntityDecl ( xmlParserCtxtPtr ctxt ) {
xmlChar * name = NULL ;
xmlChar * value = NULL ;
xmlChar * URI = NULL , * literal = NULL ;
xmlChar * ndata = NULL ;
int isParameter = 0 ;
xmlChar * orig = NULL ;
2002-06-11 10:08:16 +00:00
int skipped ;
2001-02-23 17:55:21 +00:00
GROW ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & &
( NXT ( 2 ) = = ' E ' ) & & ( NXT ( 3 ) = = ' N ' ) & &
( NXT ( 4 ) = = ' T ' ) & & ( NXT ( 5 ) = = ' I ' ) & &
( NXT ( 6 ) = = ' T ' ) & & ( NXT ( 7 ) = = ' Y ' ) ) {
xmlParserInputPtr input = ctxt - > input ;
SHRINK ;
SKIP ( 8 ) ;
2002-06-11 10:08:16 +00:00
skipped = SKIP_BLANKS ;
if ( skipped = = 0 ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after '<!ENTITY' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( RAW = = ' % ' ) {
NEXT ;
2002-06-11 10:08:16 +00:00
skipped = SKIP_BLANKS ;
if ( skipped = = 0 ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after '%' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
isParameter = 1 ;
}
2001-05-16 21:05:17 +00:00
name = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " xmlParseEntityDecl: no name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ;
}
2002-06-11 10:08:16 +00:00
skipped = SKIP_BLANKS ;
if ( skipped = = 0 ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after the entity name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
2002-06-11 10:08:16 +00:00
ctxt - > instate = XML_PARSER_ENTITY_DECL ;
2001-02-23 17:55:21 +00:00
/*
* handle the various case of definitions . . .
*/
if ( isParameter ) {
if ( ( RAW = = ' " ' ) | | ( RAW = = ' \' ' ) ) {
value = xmlParseEntityValue ( ctxt , & orig ) ;
if ( value ) {
if ( ( ctxt - > sax ! = NULL ) & &
( ! ctxt - > disableSAX ) & & ( ctxt - > sax - > entityDecl ! = NULL ) )
ctxt - > sax - > entityDecl ( ctxt - > userData , name ,
XML_INTERNAL_PARAMETER_ENTITY ,
NULL , NULL , value ) ;
}
} else {
URI = xmlParseExternalID ( ctxt , & literal , 1 ) ;
if ( ( URI = = NULL ) & & ( literal = = NULL ) ) {
ctxt - > errNo = XML_ERR_VALUE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Entity value required \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( URI ) {
xmlURIPtr uri ;
uri = xmlParseURI ( ( const char * ) URI ) ;
if ( uri = = NULL ) {
ctxt - > errNo = XML_ERR_INVALID_URI ;
if ( ( ctxt - > sax ! = NULL ) & &
( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Invalid URI: %s \n " , URI ) ;
2002-02-18 19:18:17 +00:00
/*
* This really ought to be a well formedness error
* but the XML Core WG decided otherwise c . f . issue
* E26 of the XML erratas .
*/
2001-02-23 17:55:21 +00:00
} else {
if ( uri - > fragment ! = NULL ) {
ctxt - > errNo = XML_ERR_URI_FRAGMENT ;
if ( ( ctxt - > sax ! = NULL ) & &
( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Fragment not allowed: %s \n " , URI ) ;
2002-02-18 19:18:17 +00:00
/*
* Okay this is foolish to block those but not
* invalid URIs .
*/
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
} else {
if ( ( ctxt - > sax ! = NULL ) & &
( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > entityDecl ! = NULL ) )
ctxt - > sax - > entityDecl ( ctxt - > userData , name ,
XML_EXTERNAL_PARAMETER_ENTITY ,
literal , URI , NULL ) ;
}
xmlFreeURI ( uri ) ;
}
}
}
} else {
if ( ( RAW = = ' " ' ) | | ( RAW = = ' \' ' ) ) {
value = xmlParseEntityValue ( ctxt , & orig ) ;
if ( ( ctxt - > sax ! = NULL ) & &
( ! ctxt - > disableSAX ) & & ( ctxt - > sax - > entityDecl ! = NULL ) )
ctxt - > sax - > entityDecl ( ctxt - > userData , name ,
XML_INTERNAL_GENERAL_ENTITY ,
NULL , NULL , value ) ;
2002-03-18 18:36:20 +00:00
/*
* For expat compatibility in SAX mode .
*/
if ( ( ctxt - > myDoc = = NULL ) | |
( xmlStrEqual ( ctxt - > myDoc - > version , SAX_COMPAT_MODE ) ) ) {
if ( ctxt - > myDoc = = NULL ) {
ctxt - > myDoc = xmlNewDoc ( SAX_COMPAT_MODE ) ;
}
if ( ctxt - > myDoc - > intSubset = = NULL )
ctxt - > myDoc - > intSubset = xmlNewDtd ( ctxt - > myDoc ,
BAD_CAST " fake " , NULL , NULL ) ;
entityDecl ( ctxt , name , XML_INTERNAL_GENERAL_ENTITY ,
NULL , NULL , value ) ;
}
2001-02-23 17:55:21 +00:00
} else {
URI = xmlParseExternalID ( ctxt , & literal , 1 ) ;
if ( ( URI = = NULL ) & & ( literal = = NULL ) ) {
ctxt - > errNo = XML_ERR_VALUE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Entity value required \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( URI ) {
xmlURIPtr uri ;
uri = xmlParseURI ( ( const char * ) URI ) ;
if ( uri = = NULL ) {
ctxt - > errNo = XML_ERR_INVALID_URI ;
if ( ( ctxt - > sax ! = NULL ) & &
( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Invalid URI: %s \n " , URI ) ;
2002-02-18 19:18:17 +00:00
/*
* This really ought to be a well formedness error
* but the XML Core WG decided otherwise c . f . issue
* E26 of the XML erratas .
*/
2001-02-23 17:55:21 +00:00
} else {
if ( uri - > fragment ! = NULL ) {
ctxt - > errNo = XML_ERR_URI_FRAGMENT ;
if ( ( ctxt - > sax ! = NULL ) & &
( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Fragment not allowed: %s \n " , URI ) ;
2002-02-18 19:18:17 +00:00
/*
* Okay this is foolish to block those but not
* invalid URIs .
*/
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
}
xmlFreeURI ( uri ) ;
}
}
if ( ( RAW ! = ' > ' ) & & ( ! IS_BLANK ( CUR ) ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required before 'NDATA' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
if ( ( RAW = = ' N ' ) & & ( NXT ( 1 ) = = ' D ' ) & &
( NXT ( 2 ) = = ' A ' ) & & ( NXT ( 3 ) = = ' T ' ) & &
( NXT ( 4 ) = = ' A ' ) ) {
SKIP ( 5 ) ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after 'NDATA' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
2001-05-16 21:05:17 +00:00
ndata = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > unparsedEntityDecl ! = NULL ) )
ctxt - > sax - > unparsedEntityDecl ( ctxt - > userData , name ,
literal , URI , ndata ) ;
} else {
if ( ( ctxt - > sax ! = NULL ) & &
( ! ctxt - > disableSAX ) & & ( ctxt - > sax - > entityDecl ! = NULL ) )
ctxt - > sax - > entityDecl ( ctxt - > userData , name ,
XML_EXTERNAL_GENERAL_PARSED_ENTITY ,
literal , URI , NULL ) ;
2002-03-18 18:36:20 +00:00
/*
* For expat compatibility in SAX mode .
* assuming the entity repalcement was asked for
*/
if ( ( ctxt - > replaceEntities ! = 0 ) & &
( ( ctxt - > myDoc = = NULL ) | |
( xmlStrEqual ( ctxt - > myDoc - > version , SAX_COMPAT_MODE ) ) ) ) {
if ( ctxt - > myDoc = = NULL ) {
ctxt - > myDoc = xmlNewDoc ( SAX_COMPAT_MODE ) ;
}
if ( ctxt - > myDoc - > intSubset = = NULL )
ctxt - > myDoc - > intSubset = xmlNewDtd ( ctxt - > myDoc ,
BAD_CAST " fake " , NULL , NULL ) ;
entityDecl ( ctxt , name ,
XML_EXTERNAL_GENERAL_PARSED_ENTITY ,
literal , URI , NULL ) ;
}
2001-02-23 17:55:21 +00:00
}
}
}
SKIP_BLANKS ;
if ( RAW ! = ' > ' ) {
ctxt - > errNo = XML_ERR_ENTITY_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseEntityDecl: entity %s not terminated \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
if ( input ! = ctxt - > input ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Entity declaration doesn't start and stop in the same entity \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
NEXT ;
}
if ( orig ! = NULL ) {
/*
* Ugly mechanism to save the raw entity value .
*/
xmlEntityPtr cur = NULL ;
if ( isParameter ) {
if ( ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > getParameterEntity ! = NULL ) )
cur = ctxt - > sax - > getParameterEntity ( ctxt - > userData , name ) ;
} else {
if ( ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > getEntity ! = NULL ) )
cur = ctxt - > sax - > getEntity ( ctxt - > userData , name ) ;
2002-03-18 18:36:20 +00:00
if ( ( cur = = NULL ) & & ( ctxt - > userData = = ctxt ) ) {
cur = getEntity ( ctxt , name ) ;
}
2001-02-23 17:55:21 +00:00
}
if ( cur ! = NULL ) {
if ( cur - > orig ! = NULL )
xmlFree ( orig ) ;
else
cur - > orig = orig ;
} else
xmlFree ( orig ) ;
}
if ( name ! = NULL ) xmlFree ( name ) ;
if ( value ! = NULL ) xmlFree ( value ) ;
if ( URI ! = NULL ) xmlFree ( URI ) ;
if ( literal ! = NULL ) xmlFree ( literal ) ;
if ( ndata ! = NULL ) xmlFree ( ndata ) ;
}
}
/**
* xmlParseDefaultDecl :
* @ ctxt : an XML parser context
* @ value : Receive a possible fixed default value for the attribute
*
* Parse an attribute default declaration
*
* [ 60 ] DefaultDecl : : = ' # REQUIRED ' | ' # IMPLIED ' | ( ( ' # FIXED ' S ) ? AttValue )
*
* [ VC : Required Attribute ]
* if the default declaration is the keyword # REQUIRED , then the
* attribute must be specified for all elements of the type in the
* attribute - list declaration .
*
* [ VC : Attribute Default Legal ]
* The declared default value must meet the lexical constraints of
* the declared attribute type c . f . xmlValidateAttributeDecl ( )
*
* [ VC : Fixed Attribute Default ]
* if an attribute has a default value declared with the # FIXED
* keyword , instances of that attribute must match the default value .
*
* [ WFC : No < in Attribute Values ]
* handled in xmlParseAttValue ( )
*
* returns : XML_ATTRIBUTE_NONE , XML_ATTRIBUTE_REQUIRED , XML_ATTRIBUTE_IMPLIED
* or XML_ATTRIBUTE_FIXED .
*/
int
xmlParseDefaultDecl ( xmlParserCtxtPtr ctxt , xmlChar * * value ) {
int val ;
xmlChar * ret ;
* value = NULL ;
if ( ( RAW = = ' # ' ) & & ( NXT ( 1 ) = = ' R ' ) & &
( NXT ( 2 ) = = ' E ' ) & & ( NXT ( 3 ) = = ' Q ' ) & &
( NXT ( 4 ) = = ' U ' ) & & ( NXT ( 5 ) = = ' I ' ) & &
( NXT ( 6 ) = = ' R ' ) & & ( NXT ( 7 ) = = ' E ' ) & &
( NXT ( 8 ) = = ' D ' ) ) {
SKIP ( 9 ) ;
return ( XML_ATTRIBUTE_REQUIRED ) ;
}
if ( ( RAW = = ' # ' ) & & ( NXT ( 1 ) = = ' I ' ) & &
( NXT ( 2 ) = = ' M ' ) & & ( NXT ( 3 ) = = ' P ' ) & &
( NXT ( 4 ) = = ' L ' ) & & ( NXT ( 5 ) = = ' I ' ) & &
( NXT ( 6 ) = = ' E ' ) & & ( NXT ( 7 ) = = ' D ' ) ) {
SKIP ( 8 ) ;
return ( XML_ATTRIBUTE_IMPLIED ) ;
}
val = XML_ATTRIBUTE_NONE ;
if ( ( RAW = = ' # ' ) & & ( NXT ( 1 ) = = ' F ' ) & &
( NXT ( 2 ) = = ' I ' ) & & ( NXT ( 3 ) = = ' X ' ) & &
( NXT ( 4 ) = = ' E ' ) & & ( NXT ( 5 ) = = ' D ' ) ) {
SKIP ( 6 ) ;
val = XML_ATTRIBUTE_FIXED ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after '#FIXED' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
}
ret = xmlParseAttValue ( ctxt ) ;
ctxt - > instate = XML_PARSER_DTD ;
if ( ret = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Attribute default value declaration error \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else
* value = ret ;
return ( val ) ;
}
/**
* xmlParseNotationType :
* @ ctxt : an XML parser context
*
* parse an Notation attribute type .
*
* Note : the leading ' NOTATION ' S part has already being parsed . . .
*
* [ 58 ] NotationType : : = ' NOTATION ' S ' ( ' S ? Name ( S ? ' | ' S ? Name ) * S ? ' ) '
*
* [ VC : Notation Attributes ]
* Values of this type must match one of the notation names included
* in the declaration ; all notation names in the declaration must be declared .
*
* Returns : the notation attribute tree built while parsing
*/
xmlEnumerationPtr
xmlParseNotationType ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
xmlEnumerationPtr ret = NULL , last = NULL , cur ;
if ( RAW ! = ' ( ' ) {
ctxt - > errNo = XML_ERR_NOTATION_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" '(' required to start 'NOTATION' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
SHRINK ;
do {
NEXT ;
SKIP_BLANKS ;
2001-05-16 21:05:17 +00:00
name = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Name expected in NOTATION declaration \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( ret ) ;
}
cur = xmlCreateEnumeration ( name ) ;
xmlFree ( name ) ;
if ( cur = = NULL ) return ( ret ) ;
if ( last = = NULL ) ret = last = cur ;
else {
last - > next = cur ;
last = cur ;
}
SKIP_BLANKS ;
} while ( RAW = = ' | ' ) ;
if ( RAW ! = ' ) ' ) {
ctxt - > errNo = XML_ERR_NOTATION_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" ')' required to finish NOTATION declaration \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
if ( ( last ! = NULL ) & & ( last ! = ret ) )
xmlFreeEnumeration ( last ) ;
return ( ret ) ;
}
NEXT ;
return ( ret ) ;
}
/**
* xmlParseEnumerationType :
* @ ctxt : an XML parser context
*
* parse an Enumeration attribute type .
*
* [ 59 ] Enumeration : : = ' ( ' S ? Nmtoken ( S ? ' | ' S ? Nmtoken ) * S ? ' ) '
*
* [ VC : Enumeration ]
* Values of this type must match one of the Nmtoken tokens in
* the declaration
*
* Returns : the enumeration attribute tree built while parsing
*/
xmlEnumerationPtr
xmlParseEnumerationType ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
xmlEnumerationPtr ret = NULL , last = NULL , cur ;
if ( RAW ! = ' ( ' ) {
ctxt - > errNo = XML_ERR_ATTLIST_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" '(' required to start ATTLIST enumeration \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
SHRINK ;
do {
NEXT ;
SKIP_BLANKS ;
name = xmlParseNmtoken ( ctxt ) ;
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NMTOKEN_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" NmToken expected in ATTLIST enumeration \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( ret ) ;
}
cur = xmlCreateEnumeration ( name ) ;
xmlFree ( name ) ;
if ( cur = = NULL ) return ( ret ) ;
if ( last = = NULL ) ret = last = cur ;
else {
last - > next = cur ;
last = cur ;
}
SKIP_BLANKS ;
} while ( RAW = = ' | ' ) ;
if ( RAW ! = ' ) ' ) {
ctxt - > errNo = XML_ERR_ATTLIST_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" ')' required to finish ATTLIST enumeration \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( ret ) ;
}
NEXT ;
return ( ret ) ;
}
/**
* xmlParseEnumeratedType :
* @ ctxt : an XML parser context
* @ tree : the enumeration tree built while parsing
*
* parse an Enumerated attribute type .
*
* [ 57 ] EnumeratedType : : = NotationType | Enumeration
*
* [ 58 ] NotationType : : = ' NOTATION ' S ' ( ' S ? Name ( S ? ' | ' S ? Name ) * S ? ' ) '
*
*
* Returns : XML_ATTRIBUTE_ENUMERATION or XML_ATTRIBUTE_NOTATION
*/
int
xmlParseEnumeratedType ( xmlParserCtxtPtr ctxt , xmlEnumerationPtr * tree ) {
if ( ( RAW = = ' N ' ) & & ( NXT ( 1 ) = = ' O ' ) & &
( NXT ( 2 ) = = ' T ' ) & & ( NXT ( 3 ) = = ' A ' ) & &
( NXT ( 4 ) = = ' T ' ) & & ( NXT ( 5 ) = = ' I ' ) & &
( NXT ( 6 ) = = ' O ' ) & & ( NXT ( 7 ) = = ' N ' ) ) {
SKIP ( 8 ) ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after 'NOTATION' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( 0 ) ;
}
SKIP_BLANKS ;
* tree = xmlParseNotationType ( ctxt ) ;
if ( * tree = = NULL ) return ( 0 ) ;
return ( XML_ATTRIBUTE_NOTATION ) ;
}
* tree = xmlParseEnumerationType ( ctxt ) ;
if ( * tree = = NULL ) return ( 0 ) ;
return ( XML_ATTRIBUTE_ENUMERATION ) ;
}
/**
* xmlParseAttributeType :
* @ ctxt : an XML parser context
* @ tree : the enumeration tree built while parsing
*
* parse the Attribute list def for an element
*
* [ 54 ] AttType : : = StringType | TokenizedType | EnumeratedType
*
* [ 55 ] StringType : : = ' CDATA '
*
* [ 56 ] TokenizedType : : = ' ID ' | ' IDREF ' | ' IDREFS ' | ' ENTITY ' |
* ' ENTITIES ' | ' NMTOKEN ' | ' NMTOKENS '
*
* Validity constraints for attribute values syntax are checked in
* xmlValidateAttributeValue ( )
*
* [ VC : ID ]
* Values of type ID must match the Name production . A name must not
* appear more than once in an XML document as a value of this type ;
* i . e . , ID values must uniquely identify the elements which bear them .
*
* [ VC : One ID per Element Type ]
* No element type may have more than one ID attribute specified .
*
* [ VC : ID Attribute Default ]
* An ID attribute must have a declared default of # IMPLIED or # REQUIRED .
*
* [ VC : IDREF ]
* Values of type IDREF must match the Name production , and values
* of type IDREFS must match Names ; each IDREF Name must match the value
* of an ID attribute on some element in the XML document ; i . e . IDREF
* values must match the value of some ID attribute .
*
* [ VC : Entity Name ]
* Values of type ENTITY must match the Name production , values
* of type ENTITIES must match Names ; each Entity Name must match the
* name of an unparsed entity declared in the DTD .
*
* [ VC : Name Token ]
* Values of type NMTOKEN must match the Nmtoken production ; values
* of type NMTOKENS must match Nmtokens .
*
* Returns the attribute type
*/
int
xmlParseAttributeType ( xmlParserCtxtPtr ctxt , xmlEnumerationPtr * tree ) {
SHRINK ;
if ( ( RAW = = ' C ' ) & & ( NXT ( 1 ) = = ' D ' ) & &
( NXT ( 2 ) = = ' A ' ) & & ( NXT ( 3 ) = = ' T ' ) & &
( NXT ( 4 ) = = ' A ' ) ) {
SKIP ( 5 ) ;
return ( XML_ATTRIBUTE_CDATA ) ;
} else if ( ( RAW = = ' I ' ) & & ( NXT ( 1 ) = = ' D ' ) & &
( NXT ( 2 ) = = ' R ' ) & & ( NXT ( 3 ) = = ' E ' ) & &
( NXT ( 4 ) = = ' F ' ) & & ( NXT ( 5 ) = = ' S ' ) ) {
SKIP ( 6 ) ;
return ( XML_ATTRIBUTE_IDREFS ) ;
} else if ( ( RAW = = ' I ' ) & & ( NXT ( 1 ) = = ' D ' ) & &
( NXT ( 2 ) = = ' R ' ) & & ( NXT ( 3 ) = = ' E ' ) & &
( NXT ( 4 ) = = ' F ' ) ) {
SKIP ( 5 ) ;
return ( XML_ATTRIBUTE_IDREF ) ;
} else if ( ( RAW = = ' I ' ) & & ( NXT ( 1 ) = = ' D ' ) ) {
SKIP ( 2 ) ;
return ( XML_ATTRIBUTE_ID ) ;
} else if ( ( RAW = = ' E ' ) & & ( NXT ( 1 ) = = ' N ' ) & &
( NXT ( 2 ) = = ' T ' ) & & ( NXT ( 3 ) = = ' I ' ) & &
( NXT ( 4 ) = = ' T ' ) & & ( NXT ( 5 ) = = ' Y ' ) ) {
SKIP ( 6 ) ;
return ( XML_ATTRIBUTE_ENTITY ) ;
} else if ( ( RAW = = ' E ' ) & & ( NXT ( 1 ) = = ' N ' ) & &
( NXT ( 2 ) = = ' T ' ) & & ( NXT ( 3 ) = = ' I ' ) & &
( NXT ( 4 ) = = ' T ' ) & & ( NXT ( 5 ) = = ' I ' ) & &
( NXT ( 6 ) = = ' E ' ) & & ( NXT ( 7 ) = = ' S ' ) ) {
SKIP ( 8 ) ;
return ( XML_ATTRIBUTE_ENTITIES ) ;
} else if ( ( RAW = = ' N ' ) & & ( NXT ( 1 ) = = ' M ' ) & &
( NXT ( 2 ) = = ' T ' ) & & ( NXT ( 3 ) = = ' O ' ) & &
( NXT ( 4 ) = = ' K ' ) & & ( NXT ( 5 ) = = ' E ' ) & &
( NXT ( 6 ) = = ' N ' ) & & ( NXT ( 7 ) = = ' S ' ) ) {
SKIP ( 8 ) ;
return ( XML_ATTRIBUTE_NMTOKENS ) ;
} else if ( ( RAW = = ' N ' ) & & ( NXT ( 1 ) = = ' M ' ) & &
( NXT ( 2 ) = = ' T ' ) & & ( NXT ( 3 ) = = ' O ' ) & &
( NXT ( 4 ) = = ' K ' ) & & ( NXT ( 5 ) = = ' E ' ) & &
( NXT ( 6 ) = = ' N ' ) ) {
SKIP ( 7 ) ;
return ( XML_ATTRIBUTE_NMTOKEN ) ;
}
return ( xmlParseEnumeratedType ( ctxt , tree ) ) ;
}
/**
* xmlParseAttributeListDecl :
* @ ctxt : an XML parser context
*
* : parse the Attribute list def for an element
*
* [ 52 ] AttlistDecl : : = ' < ! ATTLIST ' S Name AttDef * S ? ' > '
*
* [ 53 ] AttDef : : = S Name S AttType S DefaultDecl
*
*/
void
xmlParseAttributeListDecl ( xmlParserCtxtPtr ctxt ) {
xmlChar * elemName ;
xmlChar * attrName ;
xmlEnumerationPtr tree ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & &
( NXT ( 2 ) = = ' A ' ) & & ( NXT ( 3 ) = = ' T ' ) & &
( NXT ( 4 ) = = ' T ' ) & & ( NXT ( 5 ) = = ' L ' ) & &
( NXT ( 6 ) = = ' I ' ) & & ( NXT ( 7 ) = = ' S ' ) & &
( NXT ( 8 ) = = ' T ' ) ) {
xmlParserInputPtr input = ctxt - > input ;
SKIP ( 9 ) ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after '<!ATTLIST' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
2001-05-16 21:05:17 +00:00
elemName = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( elemName = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" ATTLIST: no name for Element \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ;
}
SKIP_BLANKS ;
GROW ;
while ( RAW ! = ' > ' ) {
const xmlChar * check = CUR_PTR ;
int type ;
int def ;
xmlChar * defaultValue = NULL ;
GROW ;
tree = NULL ;
2001-05-16 21:05:17 +00:00
attrName = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( attrName = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" ATTLIST: no name for Attribute \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
break ;
}
GROW ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after the attribute name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
if ( attrName ! = NULL )
xmlFree ( attrName ) ;
if ( defaultValue ! = NULL )
xmlFree ( defaultValue ) ;
break ;
}
SKIP_BLANKS ;
type = xmlParseAttributeType ( ctxt , & tree ) ;
if ( type < = 0 ) {
if ( attrName ! = NULL )
xmlFree ( attrName ) ;
if ( defaultValue ! = NULL )
xmlFree ( defaultValue ) ;
break ;
}
GROW ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after the attribute type \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
if ( attrName ! = NULL )
xmlFree ( attrName ) ;
if ( defaultValue ! = NULL )
xmlFree ( defaultValue ) ;
if ( tree ! = NULL )
xmlFreeEnumeration ( tree ) ;
break ;
}
SKIP_BLANKS ;
def = xmlParseDefaultDecl ( ctxt , & defaultValue ) ;
if ( def < = 0 ) {
if ( attrName ! = NULL )
xmlFree ( attrName ) ;
if ( defaultValue ! = NULL )
xmlFree ( defaultValue ) ;
if ( tree ! = NULL )
xmlFreeEnumeration ( tree ) ;
break ;
}
GROW ;
if ( RAW ! = ' > ' ) {
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after the attribute default value \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
if ( attrName ! = NULL )
xmlFree ( attrName ) ;
if ( defaultValue ! = NULL )
xmlFree ( defaultValue ) ;
if ( tree ! = NULL )
xmlFreeEnumeration ( tree ) ;
break ;
}
SKIP_BLANKS ;
}
if ( check = = CUR_PTR ) {
ctxt - > errNo = XML_ERR_INTERNAL_ERROR ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseAttributeListDecl: detected internal error \n " ) ;
if ( attrName ! = NULL )
xmlFree ( attrName ) ;
if ( defaultValue ! = NULL )
xmlFree ( defaultValue ) ;
if ( tree ! = NULL )
xmlFreeEnumeration ( tree ) ;
break ;
}
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > attributeDecl ! = NULL ) )
ctxt - > sax - > attributeDecl ( ctxt - > userData , elemName , attrName ,
type , def , defaultValue , tree ) ;
if ( attrName ! = NULL )
xmlFree ( attrName ) ;
if ( defaultValue ! = NULL )
xmlFree ( defaultValue ) ;
GROW ;
}
if ( RAW = = ' > ' ) {
if ( input ! = ctxt - > input ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Attribute list declaration doesn't start and stop in the same entity \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
NEXT ;
}
xmlFree ( elemName ) ;
}
}
/**
* xmlParseElementMixedContentDecl :
* @ ctxt : an XML parser context
2002-12-11 14:23:49 +00:00
* @ inputchk : the input used for the current entity , needed for boundary checks
2001-02-23 17:55:21 +00:00
*
* parse the declaration for a Mixed Element content
* The leading ' ( ' and spaces have been skipped in xmlParseElementContentDecl
*
* [ 51 ] Mixed : : = ' ( ' S ? ' # PCDATA ' ( S ? ' | ' S ? Name ) * S ? ' ) * ' |
* ' ( ' S ? ' # PCDATA ' S ? ' ) '
*
* [ VC : Proper Group / PE Nesting ] applies to [ 51 ] too ( see [ 49 ] )
*
* [ VC : No Duplicate Types ]
* The same name must not appear more than once in a single
* mixed - content declaration .
*
* returns : the list of the xmlElementContentPtr describing the element choices
*/
xmlElementContentPtr
2002-02-19 21:08:48 +00:00
xmlParseElementMixedContentDecl ( xmlParserCtxtPtr ctxt , xmlParserInputPtr inputchk ) {
2001-02-23 17:55:21 +00:00
xmlElementContentPtr ret = NULL , cur = NULL , n ;
xmlChar * elem = NULL ;
GROW ;
if ( ( RAW = = ' # ' ) & & ( NXT ( 1 ) = = ' P ' ) & &
( NXT ( 2 ) = = ' C ' ) & & ( NXT ( 3 ) = = ' D ' ) & &
( NXT ( 4 ) = = ' A ' ) & & ( NXT ( 5 ) = = ' T ' ) & &
( NXT ( 6 ) = = ' A ' ) ) {
SKIP ( 7 ) ;
SKIP_BLANKS ;
SHRINK ;
if ( RAW = = ' ) ' ) {
2002-02-19 21:08:48 +00:00
if ( ( ctxt - > validate ) & & ( ctxt - > input ! = inputchk ) ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ctxt - > vctxt . error ! = NULL )
ctxt - > vctxt . error ( ctxt - > vctxt . userData ,
" Element content declaration doesn't start and stop in the same entity \n " ) ;
ctxt - > valid = 0 ;
}
2001-02-23 17:55:21 +00:00
NEXT ;
ret = xmlNewElementContent ( NULL , XML_ELEMENT_CONTENT_PCDATA ) ;
if ( RAW = = ' * ' ) {
ret - > ocur = XML_ELEMENT_CONTENT_MULT ;
NEXT ;
}
return ( ret ) ;
}
if ( ( RAW = = ' ( ' ) | | ( RAW = = ' | ' ) ) {
ret = cur = xmlNewElementContent ( NULL , XML_ELEMENT_CONTENT_PCDATA ) ;
if ( ret = = NULL ) return ( NULL ) ;
}
while ( RAW = = ' | ' ) {
NEXT ;
if ( elem = = NULL ) {
ret = xmlNewElementContent ( NULL , XML_ELEMENT_CONTENT_OR ) ;
if ( ret = = NULL ) return ( NULL ) ;
ret - > c1 = cur ;
2001-04-20 13:03:48 +00:00
if ( cur ! = NULL )
cur - > parent = ret ;
2001-02-23 17:55:21 +00:00
cur = ret ;
} else {
n = xmlNewElementContent ( NULL , XML_ELEMENT_CONTENT_OR ) ;
if ( n = = NULL ) return ( NULL ) ;
n - > c1 = xmlNewElementContent ( elem , XML_ELEMENT_CONTENT_ELEMENT ) ;
2001-04-20 13:03:48 +00:00
if ( n - > c1 ! = NULL )
n - > c1 - > parent = n ;
2001-02-23 17:55:21 +00:00
cur - > c2 = n ;
2001-04-20 13:03:48 +00:00
if ( n ! = NULL )
n - > parent = cur ;
2001-02-23 17:55:21 +00:00
cur = n ;
xmlFree ( elem ) ;
}
SKIP_BLANKS ;
2001-05-16 21:05:17 +00:00
elem = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( elem = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementMixedContentDecl : Name expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
xmlFreeElementContent ( cur ) ;
return ( NULL ) ;
}
SKIP_BLANKS ;
GROW ;
}
if ( ( RAW = = ' ) ' ) & & ( NXT ( 1 ) = = ' * ' ) ) {
if ( elem ! = NULL ) {
cur - > c2 = xmlNewElementContent ( elem ,
XML_ELEMENT_CONTENT_ELEMENT ) ;
2001-04-20 13:03:48 +00:00
if ( cur - > c2 ! = NULL )
cur - > c2 - > parent = cur ;
2001-02-23 17:55:21 +00:00
xmlFree ( elem ) ;
}
ret - > ocur = XML_ELEMENT_CONTENT_MULT ;
2002-02-19 21:08:48 +00:00
if ( ( ctxt - > validate ) & & ( ctxt - > input ! = inputchk ) ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ctxt - > vctxt . error ! = NULL )
ctxt - > vctxt . error ( ctxt - > vctxt . userData ,
" Element content declaration doesn't start and stop in the same entity \n " ) ;
ctxt - > valid = 0 ;
}
2001-02-23 17:55:21 +00:00
SKIP ( 2 ) ;
} else {
if ( elem ! = NULL ) xmlFree ( elem ) ;
xmlFreeElementContent ( ret ) ;
ctxt - > errNo = XML_ERR_MIXED_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementMixedContentDecl : '|' or ')*' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
} else {
ctxt - > errNo = XML_ERR_PCDATA_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementMixedContentDecl : '#PCDATA' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
return ( ret ) ;
}
/**
* xmlParseElementChildrenContentDecl :
* @ ctxt : an XML parser context
2002-12-11 14:23:49 +00:00
* @ inputchk : the input used for the current entity , needed for boundary checks
2001-02-23 17:55:21 +00:00
*
* parse the declaration for a Mixed Element content
* The leading ' ( ' and spaces have been skipped in xmlParseElementContentDecl
*
*
* [ 47 ] children : : = ( choice | seq ) ( ' ? ' | ' * ' | ' + ' ) ?
*
* [ 48 ] cp : : = ( Name | choice | seq ) ( ' ? ' | ' * ' | ' + ' ) ?
*
* [ 49 ] choice : : = ' ( ' S ? cp ( S ? ' | ' S ? cp ) * S ? ' ) '
*
* [ 50 ] seq : : = ' ( ' S ? cp ( S ? ' , ' S ? cp ) * S ? ' ) '
*
* [ VC : Proper Group / PE Nesting ] applies to [ 49 ] and [ 50 ]
* TODO Parameter - entity replacement text must be properly nested
2001-12-31 16:16:02 +00:00
* with parenthesized groups . That is to say , if either of the
2001-02-23 17:55:21 +00:00
* opening or closing parentheses in a choice , seq , or Mixed
* construct is contained in the replacement text for a parameter
* entity , both must be contained in the same replacement text . For
* interoperability , if a parameter - entity reference appears in a
* choice , seq , or Mixed construct , its replacement text should not
* be empty , and neither the first nor last non - blank character of
* the replacement text should be a connector ( | or , ) .
*
2001-07-18 19:30:27 +00:00
* Returns the tree of xmlElementContentPtr describing the element
2001-02-23 17:55:21 +00:00
* hierarchy .
*/
xmlElementContentPtr
xmlParseElementChildrenContentDecl
2002-02-19 21:08:48 +00:00
( xmlParserCtxtPtr ctxt , xmlParserInputPtr inputchk ) {
2001-02-23 17:55:21 +00:00
xmlElementContentPtr ret = NULL , cur = NULL , last = NULL , op = NULL ;
xmlChar * elem ;
xmlChar type = 0 ;
SKIP_BLANKS ;
GROW ;
if ( RAW = = ' ( ' ) {
2002-02-19 21:08:48 +00:00
xmlParserInputPtr input = ctxt - > input ;
2001-02-23 17:55:21 +00:00
/* Recurse on first child */
NEXT ;
SKIP_BLANKS ;
2002-02-19 21:08:48 +00:00
cur = ret = xmlParseElementChildrenContentDecl ( ctxt , input ) ;
2001-02-23 17:55:21 +00:00
SKIP_BLANKS ;
GROW ;
} else {
2001-05-16 21:05:17 +00:00
elem = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( elem = = NULL ) {
ctxt - > errNo = XML_ERR_ELEMCONTENT_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementChildrenContentDecl : Name or '(' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
cur = ret = xmlNewElementContent ( elem , XML_ELEMENT_CONTENT_ELEMENT ) ;
GROW ;
if ( RAW = = ' ? ' ) {
cur - > ocur = XML_ELEMENT_CONTENT_OPT ;
NEXT ;
} else if ( RAW = = ' * ' ) {
cur - > ocur = XML_ELEMENT_CONTENT_MULT ;
NEXT ;
} else if ( RAW = = ' + ' ) {
cur - > ocur = XML_ELEMENT_CONTENT_PLUS ;
NEXT ;
} else {
cur - > ocur = XML_ELEMENT_CONTENT_ONCE ;
}
xmlFree ( elem ) ;
GROW ;
}
SKIP_BLANKS ;
SHRINK ;
while ( RAW ! = ' ) ' ) {
/*
* Each loop we parse one separator and one element .
*/
if ( RAW = = ' , ' ) {
if ( type = = 0 ) type = CUR ;
/*
* Detect " Name | Name , Name " error
*/
else if ( type ! = CUR ) {
ctxt - > errNo = XML_ERR_SEPARATOR_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementChildrenContentDecl : '%c' expected \n " ,
type ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-02-20 16:48:52 +00:00
if ( ( last ! = NULL ) & & ( last ! = ret ) )
2001-02-23 17:55:21 +00:00
xmlFreeElementContent ( last ) ;
if ( ret ! = NULL )
xmlFreeElementContent ( ret ) ;
return ( NULL ) ;
}
NEXT ;
op = xmlNewElementContent ( NULL , XML_ELEMENT_CONTENT_SEQ ) ;
if ( op = = NULL ) {
2002-02-20 16:48:52 +00:00
if ( ( last ! = NULL ) & & ( last ! = ret ) )
xmlFreeElementContent ( last ) ;
2001-02-23 17:55:21 +00:00
xmlFreeElementContent ( ret ) ;
return ( NULL ) ;
}
if ( last = = NULL ) {
op - > c1 = ret ;
2001-04-20 13:03:48 +00:00
if ( ret ! = NULL )
ret - > parent = op ;
2001-02-23 17:55:21 +00:00
ret = cur = op ;
} else {
cur - > c2 = op ;
2001-04-20 13:03:48 +00:00
if ( op ! = NULL )
op - > parent = cur ;
2001-02-23 17:55:21 +00:00
op - > c1 = last ;
2001-04-20 13:03:48 +00:00
if ( last ! = NULL )
last - > parent = op ;
2001-02-23 17:55:21 +00:00
cur = op ;
last = NULL ;
}
} else if ( RAW = = ' | ' ) {
if ( type = = 0 ) type = CUR ;
/*
* Detect " Name , Name | Name " error
*/
else if ( type ! = CUR ) {
ctxt - > errNo = XML_ERR_SEPARATOR_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementChildrenContentDecl : '%c' expected \n " ,
type ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-02-20 16:48:52 +00:00
if ( ( last ! = NULL ) & & ( last ! = ret ) )
2001-02-23 17:55:21 +00:00
xmlFreeElementContent ( last ) ;
if ( ret ! = NULL )
xmlFreeElementContent ( ret ) ;
return ( NULL ) ;
}
NEXT ;
op = xmlNewElementContent ( NULL , XML_ELEMENT_CONTENT_OR ) ;
if ( op = = NULL ) {
2002-02-20 16:48:52 +00:00
if ( ( last ! = NULL ) & & ( last ! = ret ) )
2001-02-23 17:55:21 +00:00
xmlFreeElementContent ( last ) ;
if ( ret ! = NULL )
xmlFreeElementContent ( ret ) ;
return ( NULL ) ;
}
if ( last = = NULL ) {
op - > c1 = ret ;
2001-04-20 13:03:48 +00:00
if ( ret ! = NULL )
ret - > parent = op ;
2001-02-23 17:55:21 +00:00
ret = cur = op ;
} else {
cur - > c2 = op ;
2001-04-20 13:03:48 +00:00
if ( op ! = NULL )
op - > parent = cur ;
2001-02-23 17:55:21 +00:00
op - > c1 = last ;
2001-04-20 13:03:48 +00:00
if ( last ! = NULL )
last - > parent = op ;
2001-02-23 17:55:21 +00:00
cur = op ;
last = NULL ;
}
} else {
ctxt - > errNo = XML_ERR_ELEMCONTENT_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementChildrenContentDecl : ',' '|' or ')' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
if ( ret ! = NULL )
xmlFreeElementContent ( ret ) ;
return ( NULL ) ;
}
GROW ;
SKIP_BLANKS ;
GROW ;
if ( RAW = = ' ( ' ) {
2002-02-19 21:08:48 +00:00
xmlParserInputPtr input = ctxt - > input ;
2001-02-23 17:55:21 +00:00
/* Recurse on second child */
NEXT ;
SKIP_BLANKS ;
2002-02-19 21:08:48 +00:00
last = xmlParseElementChildrenContentDecl ( ctxt , input ) ;
2001-02-23 17:55:21 +00:00
SKIP_BLANKS ;
} else {
2001-05-16 21:05:17 +00:00
elem = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( elem = = NULL ) {
ctxt - > errNo = XML_ERR_ELEMCONTENT_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementChildrenContentDecl : Name or '(' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
if ( ret ! = NULL )
xmlFreeElementContent ( ret ) ;
return ( NULL ) ;
}
last = xmlNewElementContent ( elem , XML_ELEMENT_CONTENT_ELEMENT ) ;
xmlFree ( elem ) ;
if ( RAW = = ' ? ' ) {
last - > ocur = XML_ELEMENT_CONTENT_OPT ;
NEXT ;
} else if ( RAW = = ' * ' ) {
last - > ocur = XML_ELEMENT_CONTENT_MULT ;
NEXT ;
} else if ( RAW = = ' + ' ) {
last - > ocur = XML_ELEMENT_CONTENT_PLUS ;
NEXT ;
} else {
last - > ocur = XML_ELEMENT_CONTENT_ONCE ;
}
}
SKIP_BLANKS ;
GROW ;
}
if ( ( cur ! = NULL ) & & ( last ! = NULL ) ) {
cur - > c2 = last ;
2001-04-20 13:03:48 +00:00
if ( last ! = NULL )
last - > parent = cur ;
2001-02-23 17:55:21 +00:00
}
2002-02-19 21:08:48 +00:00
if ( ( ctxt - > validate ) & & ( ctxt - > input ! = inputchk ) ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ctxt - > vctxt . error ! = NULL )
ctxt - > vctxt . error ( ctxt - > vctxt . userData ,
" Element content declaration doesn't start and stop in the same entity \n " ) ;
ctxt - > valid = 0 ;
}
2001-02-23 17:55:21 +00:00
NEXT ;
if ( RAW = = ' ? ' ) {
2001-04-18 21:41:07 +00:00
if ( ret ! = NULL )
ret - > ocur = XML_ELEMENT_CONTENT_OPT ;
2001-02-23 17:55:21 +00:00
NEXT ;
} else if ( RAW = = ' * ' ) {
2001-10-18 14:57:24 +00:00
if ( ret ! = NULL ) {
2001-04-18 21:41:07 +00:00
ret - > ocur = XML_ELEMENT_CONTENT_MULT ;
2001-10-18 14:57:24 +00:00
cur = ret ;
/*
* Some normalization :
* ( a | b * | c ? ) * = = ( a | b | c ) *
*/
while ( cur - > type = = XML_ELEMENT_CONTENT_OR ) {
if ( ( cur - > c1 ! = NULL ) & &
( ( cur - > c1 - > ocur = = XML_ELEMENT_CONTENT_OPT ) | |
( cur - > c1 - > ocur = = XML_ELEMENT_CONTENT_MULT ) ) )
cur - > c1 - > ocur = XML_ELEMENT_CONTENT_ONCE ;
if ( ( cur - > c2 ! = NULL ) & &
( ( cur - > c2 - > ocur = = XML_ELEMENT_CONTENT_OPT ) | |
( cur - > c2 - > ocur = = XML_ELEMENT_CONTENT_MULT ) ) )
cur - > c2 - > ocur = XML_ELEMENT_CONTENT_ONCE ;
cur = cur - > c2 ;
}
}
2001-02-23 17:55:21 +00:00
NEXT ;
} else if ( RAW = = ' + ' ) {
2001-10-18 14:57:24 +00:00
if ( ret ! = NULL ) {
int found = 0 ;
2001-04-18 21:41:07 +00:00
ret - > ocur = XML_ELEMENT_CONTENT_PLUS ;
2001-10-18 14:57:24 +00:00
/*
* Some normalization :
* ( a | b * ) + = = ( a | b ) *
* ( a | b ? ) + = = ( a | b ) *
*/
while ( cur - > type = = XML_ELEMENT_CONTENT_OR ) {
if ( ( cur - > c1 ! = NULL ) & &
( ( cur - > c1 - > ocur = = XML_ELEMENT_CONTENT_OPT ) | |
( cur - > c1 - > ocur = = XML_ELEMENT_CONTENT_MULT ) ) ) {
cur - > c1 - > ocur = XML_ELEMENT_CONTENT_ONCE ;
found = 1 ;
}
if ( ( cur - > c2 ! = NULL ) & &
( ( cur - > c2 - > ocur = = XML_ELEMENT_CONTENT_OPT ) | |
( cur - > c2 - > ocur = = XML_ELEMENT_CONTENT_MULT ) ) ) {
cur - > c2 - > ocur = XML_ELEMENT_CONTENT_ONCE ;
found = 1 ;
}
cur = cur - > c2 ;
}
if ( found )
ret - > ocur = XML_ELEMENT_CONTENT_MULT ;
}
2001-02-23 17:55:21 +00:00
NEXT ;
}
return ( ret ) ;
}
/**
* xmlParseElementContentDecl :
* @ ctxt : an XML parser context
* @ name : the name of the element being defined .
* @ result : the Element Content pointer will be stored here if any
*
* parse the declaration for an Element content either Mixed or Children ,
* the cases EMPTY and ANY are handled directly in xmlParseElementDecl
*
* [ 46 ] contentspec : : = ' EMPTY ' | ' ANY ' | Mixed | children
*
* returns : the type of element content XML_ELEMENT_TYPE_xxx
*/
int
xmlParseElementContentDecl ( xmlParserCtxtPtr ctxt , xmlChar * name ,
xmlElementContentPtr * result ) {
xmlElementContentPtr tree = NULL ;
xmlParserInputPtr input = ctxt - > input ;
int res ;
* result = NULL ;
if ( RAW ! = ' ( ' ) {
ctxt - > errNo = XML_ERR_ELEMCONTENT_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-03-24 17:00:36 +00:00
" xmlParseElementContentDecl : %s '(' expected \n " , name ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( - 1 ) ;
}
NEXT ;
GROW ;
SKIP_BLANKS ;
if ( ( RAW = = ' # ' ) & & ( NXT ( 1 ) = = ' P ' ) & &
( NXT ( 2 ) = = ' C ' ) & & ( NXT ( 3 ) = = ' D ' ) & &
( NXT ( 4 ) = = ' A ' ) & & ( NXT ( 5 ) = = ' T ' ) & &
( NXT ( 6 ) = = ' A ' ) ) {
2002-02-19 21:08:48 +00:00
tree = xmlParseElementMixedContentDecl ( ctxt , input ) ;
2001-02-23 17:55:21 +00:00
res = XML_ELEMENT_TYPE_MIXED ;
} else {
2002-02-19 21:08:48 +00:00
tree = xmlParseElementChildrenContentDecl ( ctxt , input ) ;
2001-02-23 17:55:21 +00:00
res = XML_ELEMENT_TYPE_ELEMENT ;
}
SKIP_BLANKS ;
* result = tree ;
return ( res ) ;
}
/**
* xmlParseElementDecl :
* @ ctxt : an XML parser context
*
* parse an Element declaration .
*
* [ 45 ] elementdecl : : = ' < ! ELEMENT ' S Name S contentspec S ? ' > '
*
* [ VC : Unique Element Type Declaration ]
* No element type may be declared more than once
*
* Returns the type of the element , or - 1 in case of error
*/
int
xmlParseElementDecl ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
int ret = - 1 ;
xmlElementContentPtr content = NULL ;
GROW ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & &
( NXT ( 2 ) = = ' E ' ) & & ( NXT ( 3 ) = = ' L ' ) & &
( NXT ( 4 ) = = ' E ' ) & & ( NXT ( 5 ) = = ' M ' ) & &
( NXT ( 6 ) = = ' E ' ) & & ( NXT ( 7 ) = = ' N ' ) & &
( NXT ( 8 ) = = ' T ' ) ) {
xmlParserInputPtr input = ctxt - > input ;
SKIP ( 9 ) ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after 'ELEMENT' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
2001-05-16 21:05:17 +00:00
name = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementDecl: no name for Element \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( - 1 ) ;
}
while ( ( RAW = = 0 ) & & ( ctxt - > inputNr > 1 ) )
xmlPopInput ( ctxt ) ;
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space required after the element name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
if ( ( RAW = = ' E ' ) & & ( NXT ( 1 ) = = ' M ' ) & &
( NXT ( 2 ) = = ' P ' ) & & ( NXT ( 3 ) = = ' T ' ) & &
( NXT ( 4 ) = = ' Y ' ) ) {
SKIP ( 5 ) ;
/*
* Element must always be empty .
*/
ret = XML_ELEMENT_TYPE_EMPTY ;
} else if ( ( RAW = = ' A ' ) & & ( NXT ( 1 ) = = ' N ' ) & &
( NXT ( 2 ) = = ' Y ' ) ) {
SKIP ( 3 ) ;
/*
* Element is a generic container .
*/
ret = XML_ELEMENT_TYPE_ANY ;
} else if ( RAW = = ' ( ' ) {
ret = xmlParseElementContentDecl ( ctxt , name , & content ) ;
} else {
/*
* [ WFC : PEs in Internal Subset ] error handling .
*/
if ( ( RAW = = ' % ' ) & & ( ctxt - > external = = 0 ) & &
( ctxt - > inputNr = = 1 ) ) {
ctxt - > errNo = XML_ERR_PEREF_IN_INT_SUBSET ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" PEReference: forbidden within markup decl in internal subset \n " ) ;
} else {
ctxt - > errNo = XML_ERR_ELEMCONTENT_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected \n " ) ;
}
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
if ( name ! = NULL ) xmlFree ( name ) ;
return ( - 1 ) ;
}
SKIP_BLANKS ;
/*
* Pop - up of finished entities .
*/
while ( ( RAW = = 0 ) & & ( ctxt - > inputNr > 1 ) )
xmlPopInput ( ctxt ) ;
SKIP_BLANKS ;
if ( RAW ! = ' > ' ) {
ctxt - > errNo = XML_ERR_GT_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseElementDecl: expected '>' at the end \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
if ( input ! = ctxt - > input ) {
ctxt - > errNo = XML_ERR_ENTITY_BOUNDARY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Element declaration doesn't start and stop in the same entity \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
NEXT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > elementDecl ! = NULL ) )
ctxt - > sax - > elementDecl ( ctxt - > userData , name , ret ,
content ) ;
}
if ( content ! = NULL ) {
xmlFreeElementContent ( content ) ;
}
if ( name ! = NULL ) {
xmlFree ( name ) ;
}
}
return ( ret ) ;
}
/**
* xmlParseConditionalSections
* @ ctxt : an XML parser context
*
* [ 61 ] conditionalSect : : = includeSect | ignoreSect
* [ 62 ] includeSect : : = ' < ! [ ' S ? ' INCLUDE ' S ? ' [ ' extSubsetDecl ' ] ] > '
* [ 63 ] ignoreSect : : = ' < ! [ ' S ? ' IGNORE ' S ? ' [ ' ignoreSectContents * ' ] ] > '
* [ 64 ] ignoreSectContents : : = Ignore ( ' < ! [ ' ignoreSectContents ' ] ] > ' Ignore ) *
* [ 65 ] Ignore : : = Char * - ( Char * ( ' < ! [ ' | ' ] ] > ' ) Char * )
*/
2001-03-24 17:00:36 +00:00
static void
2001-02-23 17:55:21 +00:00
xmlParseConditionalSections ( xmlParserCtxtPtr ctxt ) {
SKIP ( 3 ) ;
SKIP_BLANKS ;
if ( ( RAW = = ' I ' ) & & ( NXT ( 1 ) = = ' N ' ) & & ( NXT ( 2 ) = = ' C ' ) & &
( NXT ( 3 ) = = ' L ' ) & & ( NXT ( 4 ) = = ' U ' ) & & ( NXT ( 5 ) = = ' D ' ) & &
( NXT ( 6 ) = = ' E ' ) ) {
SKIP ( 7 ) ;
SKIP_BLANKS ;
if ( RAW ! = ' [ ' ) {
ctxt - > errNo = XML_ERR_CONDSEC_INVALID ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" XML conditional section '[' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
NEXT ;
}
if ( xmlParserDebugEntities ) {
if ( ( ctxt - > input ! = NULL ) & & ( ctxt - > input - > filename ) )
xmlGenericError ( xmlGenericErrorContext ,
" %s(%d): " , ctxt - > input - > filename ,
ctxt - > input - > line ) ;
xmlGenericError ( xmlGenericErrorContext ,
" Entering INCLUDE Conditional Section \n " ) ;
}
while ( ( RAW ! = 0 ) & & ( ( RAW ! = ' ] ' ) | | ( NXT ( 1 ) ! = ' ] ' ) | |
( NXT ( 2 ) ! = ' > ' ) ) ) {
const xmlChar * check = CUR_PTR ;
int cons = ctxt - > input - > consumed ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & & ( NXT ( 2 ) = = ' [ ' ) ) {
xmlParseConditionalSections ( ctxt ) ;
} else if ( IS_BLANK ( CUR ) ) {
NEXT ;
} else if ( RAW = = ' % ' ) {
xmlParsePEReference ( ctxt ) ;
} else
xmlParseMarkupDecl ( ctxt ) ;
/*
* Pop - up of finished entities .
*/
while ( ( RAW = = 0 ) & & ( ctxt - > inputNr > 1 ) )
xmlPopInput ( ctxt ) ;
2002-07-01 21:52:03 +00:00
if ( ( CUR_PTR = = check ) & & ( cons = = ctxt - > input - > consumed ) ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Content error in the external subset \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
break ;
}
}
if ( xmlParserDebugEntities ) {
if ( ( ctxt - > input ! = NULL ) & & ( ctxt - > input - > filename ) )
xmlGenericError ( xmlGenericErrorContext ,
" %s(%d): " , ctxt - > input - > filename ,
ctxt - > input - > line ) ;
xmlGenericError ( xmlGenericErrorContext ,
" Leaving INCLUDE Conditional Section \n " ) ;
}
} else if ( ( RAW = = ' I ' ) & & ( NXT ( 1 ) = = ' G ' ) & & ( NXT ( 2 ) = = ' N ' ) & &
( NXT ( 3 ) = = ' O ' ) & & ( NXT ( 4 ) = = ' R ' ) & & ( NXT ( 5 ) = = ' E ' ) ) {
int state ;
int instate ;
int depth = 0 ;
SKIP ( 6 ) ;
SKIP_BLANKS ;
if ( RAW ! = ' [ ' ) {
ctxt - > errNo = XML_ERR_CONDSEC_INVALID ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" XML conditional section '[' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
NEXT ;
}
if ( xmlParserDebugEntities ) {
if ( ( ctxt - > input ! = NULL ) & & ( ctxt - > input - > filename ) )
xmlGenericError ( xmlGenericErrorContext ,
" %s(%d): " , ctxt - > input - > filename ,
ctxt - > input - > line ) ;
xmlGenericError ( xmlGenericErrorContext ,
" Entering IGNORE Conditional Section \n " ) ;
}
/*
2001-12-31 16:16:02 +00:00
* Parse up to the end of the conditional section
2001-02-23 17:55:21 +00:00
* But disable SAX event generating DTD building in the meantime
*/
state = ctxt - > disableSAX ;
instate = ctxt - > instate ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
ctxt - > instate = XML_PARSER_IGNORE ;
2002-02-17 21:26:33 +00:00
while ( ( depth > = 0 ) & & ( RAW ! = 0 ) ) {
2001-02-23 17:55:21 +00:00
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & & ( NXT ( 2 ) = = ' [ ' ) ) {
depth + + ;
SKIP ( 3 ) ;
continue ;
}
if ( ( RAW = = ' ] ' ) & & ( NXT ( 1 ) = = ' ] ' ) & & ( NXT ( 2 ) = = ' > ' ) ) {
if ( - - depth > = 0 ) SKIP ( 3 ) ;
continue ;
}
NEXT ;
continue ;
}
ctxt - > disableSAX = state ;
ctxt - > instate = instate ;
if ( xmlParserDebugEntities ) {
if ( ( ctxt - > input ! = NULL ) & & ( ctxt - > input - > filename ) )
xmlGenericError ( xmlGenericErrorContext ,
" %s(%d): " , ctxt - > input - > filename ,
ctxt - > input - > line ) ;
xmlGenericError ( xmlGenericErrorContext ,
" Leaving IGNORE Conditional Section \n " ) ;
}
} else {
ctxt - > errNo = XML_ERR_CONDSEC_INVALID ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" XML conditional section INCLUDE or IGNORE keyword expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( RAW = = 0 )
SHRINK ;
if ( RAW = = 0 ) {
ctxt - > errNo = XML_ERR_CONDSEC_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" XML conditional section not closed \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
SKIP ( 3 ) ;
}
}
2001-07-31 15:10:53 +00:00
/**
* xmlParseMarkupDecl :
* @ ctxt : an XML parser context
*
* parse Markup declarations
*
* [ 29 ] markupdecl : : = elementdecl | AttlistDecl | EntityDecl |
* NotationDecl | PI | Comment
*
* [ VC : Proper Declaration / PE Nesting ]
* Parameter - entity replacement text must be properly nested with
* markup declarations . That is to say , if either the first character
* or the last character of a markup declaration ( markupdecl above ) is
* contained in the replacement text for a parameter - entity reference ,
* both must be contained in the same replacement text .
*
* [ WFC : PEs in Internal Subset ]
* In the internal DTD subset , parameter - entity references can occur
* only where markup declarations can occur , not within markup declarations .
* ( This does not apply to references that occur in external parameter
* entities or to the external subset . )
*/
void
xmlParseMarkupDecl ( xmlParserCtxtPtr ctxt ) {
GROW ;
xmlParseElementDecl ( ctxt ) ;
xmlParseAttributeListDecl ( ctxt ) ;
xmlParseEntityDecl ( ctxt ) ;
xmlParseNotationDecl ( ctxt ) ;
xmlParsePI ( ctxt ) ;
xmlParseComment ( ctxt ) ;
/*
* This is only for internal subset . On external entities ,
* the replacement is done before parsing stage
*/
if ( ( ctxt - > external = = 0 ) & & ( ctxt - > inputNr = = 1 ) )
xmlParsePEReference ( ctxt ) ;
/*
* Conditional sections are allowed from entities included
* by PE References in the internal subset .
*/
if ( ( ctxt - > external = = 0 ) & & ( ctxt - > inputNr > 1 ) ) {
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & & ( NXT ( 2 ) = = ' [ ' ) ) {
xmlParseConditionalSections ( ctxt ) ;
}
}
ctxt - > instate = XML_PARSER_DTD ;
}
/**
* xmlParseTextDecl :
* @ ctxt : an XML parser context
*
* parse an XML declaration header for external entities
*
* [ 77 ] TextDecl : : = ' < ? xml ' VersionInfo ? EncodingDecl S ? ' ? > '
*
* Question : Seems that EncodingDecl is mandatory ? Is that a typo ?
*/
void
xmlParseTextDecl ( xmlParserCtxtPtr ctxt ) {
xmlChar * version ;
/*
* We know that ' < ? xml ' is here .
*/
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) & &
( NXT ( 2 ) = = ' x ' ) & & ( NXT ( 3 ) = = ' m ' ) & &
( NXT ( 4 ) = = ' l ' ) & & ( IS_BLANK ( NXT ( 5 ) ) ) ) {
SKIP ( 5 ) ;
} else {
ctxt - > errNo = XML_ERR_XMLDECL_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Text declaration '<?xml' required \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-07-31 15:10:53 +00:00
return ;
}
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Space needed after '<?xml' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-07-31 15:10:53 +00:00
}
SKIP_BLANKS ;
/*
* We may have the VersionInfo here .
*/
version = xmlParseVersionInfo ( ctxt ) ;
if ( version = = NULL )
version = xmlCharStrdup ( XML_DEFAULT_VERSION ) ;
2002-01-07 16:54:10 +00:00
else {
if ( ! IS_BLANK ( CUR ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Space needed here \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-01-07 16:54:10 +00:00
}
}
2001-07-31 15:10:53 +00:00
ctxt - > input - > version = version ;
/*
* We must have the encoding declaration
*/
xmlParseEncodingDecl ( ctxt ) ;
if ( ctxt - > errNo = = XML_ERR_UNSUPPORTED_ENCODING ) {
/*
* The XML REC instructs us to stop parsing right here
*/
return ;
}
SKIP_BLANKS ;
if ( ( RAW = = ' ? ' ) & & ( NXT ( 1 ) = = ' > ' ) ) {
SKIP ( 2 ) ;
} else if ( RAW = = ' > ' ) {
/* Deprecated old WD ... */
ctxt - > errNo = XML_ERR_XMLDECL_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" XML declaration must end-up with '?>' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-07-31 15:10:53 +00:00
NEXT ;
} else {
ctxt - > errNo = XML_ERR_XMLDECL_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" parsing XML declaration: '?>' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-07-31 15:10:53 +00:00
MOVETO_ENDTAG ( CUR_PTR ) ;
NEXT ;
}
}
2001-02-23 17:55:21 +00:00
/**
* xmlParseExternalSubset :
* @ ctxt : an XML parser context
* @ ExternalID : the external identifier
* @ SystemID : the system identifier ( or URL )
*
* parse Markup declarations from an external subset
*
* [ 30 ] extSubset : : = textDecl ? extSubsetDecl
*
* [ 31 ] extSubsetDecl : : = ( markupdecl | conditionalSect | PEReference | S ) *
*/
void
xmlParseExternalSubset ( xmlParserCtxtPtr ctxt , const xmlChar * ExternalID ,
const xmlChar * SystemID ) {
GROW ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) & &
( NXT ( 2 ) = = ' x ' ) & & ( NXT ( 3 ) = = ' m ' ) & &
( NXT ( 4 ) = = ' l ' ) ) {
xmlParseTextDecl ( ctxt ) ;
if ( ctxt - > errNo = = XML_ERR_UNSUPPORTED_ENCODING ) {
/*
* The XML REC instructs us to stop parsing right here
*/
ctxt - > instate = XML_PARSER_EOF ;
return ;
}
}
if ( ctxt - > myDoc = = NULL ) {
ctxt - > myDoc = xmlNewDoc ( BAD_CAST " 1.0 " ) ;
}
if ( ( ctxt - > myDoc ! = NULL ) & & ( ctxt - > myDoc - > intSubset = = NULL ) )
xmlCreateIntSubset ( ctxt - > myDoc , NULL , ExternalID , SystemID ) ;
ctxt - > instate = XML_PARSER_DTD ;
ctxt - > external = 1 ;
while ( ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) ) | |
( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) ) | |
2001-07-25 21:39:46 +00:00
( RAW = = ' % ' ) | | IS_BLANK ( CUR ) ) {
2001-02-23 17:55:21 +00:00
const xmlChar * check = CUR_PTR ;
int cons = ctxt - > input - > consumed ;
GROW ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & & ( NXT ( 2 ) = = ' [ ' ) ) {
xmlParseConditionalSections ( ctxt ) ;
} else if ( IS_BLANK ( CUR ) ) {
NEXT ;
} else if ( RAW = = ' % ' ) {
xmlParsePEReference ( ctxt ) ;
} else
xmlParseMarkupDecl ( ctxt ) ;
/*
* Pop - up of finished entities .
*/
while ( ( RAW = = 0 ) & & ( ctxt - > inputNr > 1 ) )
xmlPopInput ( ctxt ) ;
2002-07-01 21:52:03 +00:00
if ( ( CUR_PTR = = check ) & & ( cons = = ctxt - > input - > consumed ) ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Content error in the external subset \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
break ;
}
}
if ( RAW ! = 0 ) {
ctxt - > errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Extra content at the end of the document \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
}
/**
* xmlParseReference :
* @ ctxt : an XML parser context
*
* parse and handle entity references in content , depending on the SAX
* interface , this may end - up in a call to character ( ) if this is a
* CharRef , a predefined entity , if there is no reference ( ) callback .
* or if the parser was asked to switch to that mode .
*
* [ 67 ] Reference : : = EntityRef | CharRef
*/
void
xmlParseReference ( xmlParserCtxtPtr ctxt ) {
xmlEntityPtr ent ;
xmlChar * val ;
if ( RAW ! = ' & ' ) return ;
if ( NXT ( 1 ) = = ' # ' ) {
int i = 0 ;
xmlChar out [ 10 ] ;
int hex = NXT ( 2 ) ;
2001-03-24 17:00:36 +00:00
int value = xmlParseCharRef ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( ctxt - > charset ! = XML_CHAR_ENCODING_UTF8 ) {
/*
* So we are using non - UTF - 8 buffers
* Check that the char fit on 8 bits , if not
* generate a CharRef .
*/
2001-03-24 17:00:36 +00:00
if ( value < = 0xFF ) {
out [ 0 ] = value ;
2001-02-23 17:55:21 +00:00
out [ 1 ] = 0 ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > characters ! = NULL ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > characters ( ctxt - > userData , out , 1 ) ;
} else {
if ( ( hex = = ' x ' ) | | ( hex = = ' X ' ) )
2002-06-14 17:07:10 +00:00
snprintf ( ( char * ) out , sizeof ( out ) , " #x%X " , value ) ;
2001-02-23 17:55:21 +00:00
else
2002-06-14 17:07:10 +00:00
snprintf ( ( char * ) out , sizeof ( out ) , " #%d " , value ) ;
2001-02-23 17:55:21 +00:00
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > reference ! = NULL ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > reference ( ctxt - > userData , out ) ;
}
} else {
/*
* Just encode the value in UTF - 8
*/
2001-03-24 17:00:36 +00:00
COPY_BUF ( 0 , out , i , value ) ;
2001-02-23 17:55:21 +00:00
out [ i ] = 0 ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > characters ! = NULL ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > characters ( ctxt - > userData , out , i ) ;
}
} else {
ent = xmlParseEntityRef ( ctxt ) ;
if ( ent = = NULL ) return ;
2002-02-17 21:26:33 +00:00
if ( ! ctxt - > wellFormed )
return ;
2001-02-23 17:55:21 +00:00
if ( ( ent - > name ! = NULL ) & &
( ent - > etype ! = XML_INTERNAL_PREDEFINED_ENTITY ) ) {
xmlNodePtr list = NULL ;
int ret ;
/*
* The first reference to the entity trigger a parsing phase
* where the ent - > children is filled with the result from
* the parsing .
*/
if ( ent - > children = = NULL ) {
xmlChar * value ;
value = ent - > content ;
/*
* Check that this entity is well formed
*/
if ( ( value ! = NULL ) & &
( value [ 1 ] = = 0 ) & & ( value [ 0 ] = = ' < ' ) & &
( xmlStrEqual ( ent - > name , BAD_CAST " lt " ) ) ) {
/*
* DONE : get definite answer on this ! ! !
* Lots of entity decls are used to declare a single
* char
* < ! ENTITY lt " < " >
* Which seems to be valid since
* 2.4 : The ampersand character ( & ) and the left angle
* bracket ( < ) may appear in their literal form only
* when used . . . They are also legal within the literal
* entity value of an internal entity declaration ; i
* see " 4.3.2 Well-Formed Parsed Entities " .
* IMHO 2.4 and 4.3 .2 are directly in contradiction .
* Looking at the OASIS test suite and James Clark
* tests , this is broken . However the XML REC uses
* it . Is the XML REC not well - formed ? ? ? ?
* This is a hack to avoid this problem
*
* ANSWER : since lt gt amp . . are already defined ,
* this is a redefinition and hence the fact that the
2001-12-31 16:16:02 +00:00
* content is not well balanced is not a Wf error , this
2001-02-23 17:55:21 +00:00
* is lousy but acceptable .
*/
list = xmlNewDocText ( ctxt - > myDoc , value ) ;
if ( list ! = NULL ) {
if ( ( ent - > etype = = XML_INTERNAL_GENERAL_ENTITY ) & &
( ent - > children = = NULL ) ) {
ent - > children = list ;
ent - > last = list ;
2002-12-30 00:01:08 +00:00
ent - > owner = 1 ;
2001-02-23 17:55:21 +00:00
list - > parent = ( xmlNodePtr ) ent ;
} else {
xmlFreeNodeList ( list ) ;
}
} else if ( list ! = NULL ) {
xmlFreeNodeList ( list ) ;
}
} else {
/*
* 4.3 .2 : An internal general parsed entity is well - formed
* if its replacement text matches the production labeled
* content .
*/
2002-03-18 11:45:56 +00:00
void * user_data ;
/*
* This is a bit hackish but this seems the best
* way to make sure both SAX and DOM entity support
* behaves okay .
*/
if ( ctxt - > userData = = ctxt )
user_data = NULL ;
else
user_data = ctxt - > userData ;
2001-02-23 17:55:21 +00:00
if ( ent - > etype = = XML_INTERNAL_GENERAL_ENTITY ) {
ctxt - > depth + + ;
2002-11-15 15:24:34 +00:00
ret = xmlParseBalancedChunkMemoryInternal ( ctxt ,
value , user_data , & list ) ;
2001-02-23 17:55:21 +00:00
ctxt - > depth - - ;
} else if ( ent - > etype = =
XML_EXTERNAL_GENERAL_PARSED_ENTITY ) {
ctxt - > depth + + ;
2001-05-20 13:19:52 +00:00
ret = xmlParseExternalEntityPrivate ( ctxt - > myDoc , ctxt ,
2002-03-18 11:45:56 +00:00
ctxt - > sax , user_data , ctxt - > depth ,
2001-05-20 13:19:52 +00:00
ent - > URI , ent - > ExternalID , & list ) ;
2001-02-23 17:55:21 +00:00
ctxt - > depth - - ;
} else {
ret = - 1 ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Internal: invalid entity type \n " ) ;
}
if ( ret = = XML_ERR_ENTITY_LOOP ) {
ctxt - > errNo = XML_ERR_ENTITY_LOOP ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Detected entity reference loop \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-02-17 21:26:33 +00:00
return ;
2001-02-23 17:55:21 +00:00
} else if ( ( ret = = 0 ) & & ( list ! = NULL ) ) {
2001-05-16 21:05:17 +00:00
if ( ( ( ent - > etype = = XML_INTERNAL_GENERAL_ENTITY ) | |
( ent - > etype = = XML_EXTERNAL_GENERAL_PARSED_ENTITY ) ) & &
2001-02-23 17:55:21 +00:00
( ent - > children = = NULL ) ) {
ent - > children = list ;
2001-07-04 19:49:14 +00:00
if ( ctxt - > replaceEntities ) {
/*
* Prune it directly in the generated document
* except for single text nodes .
*/
if ( ( list - > type = = XML_TEXT_NODE ) & &
( list - > next = = NULL ) ) {
list - > parent = ( xmlNodePtr ) ent ;
list = NULL ;
2002-12-30 00:01:08 +00:00
ent - > owner = 1 ;
2001-07-04 19:49:14 +00:00
} else {
2002-12-30 00:01:08 +00:00
ent - > owner = 0 ;
2001-07-04 19:49:14 +00:00
while ( list ! = NULL ) {
list - > parent = ( xmlNodePtr ) ctxt - > node ;
2002-11-16 15:35:11 +00:00
list - > doc = ctxt - > myDoc ;
2001-07-04 19:49:14 +00:00
if ( list - > next = = NULL )
ent - > last = list ;
list = list - > next ;
2002-01-13 14:10:10 +00:00
}
2001-07-04 19:49:14 +00:00
list = ent - > children ;
2002-01-13 14:10:10 +00:00
if ( ent - > etype = = XML_EXTERNAL_GENERAL_PARSED_ENTITY )
xmlAddEntityReference ( ent , list , NULL ) ;
2001-07-04 19:49:14 +00:00
}
} else {
2002-12-30 00:01:08 +00:00
ent - > owner = 1 ;
2001-07-04 19:49:14 +00:00
while ( list ! = NULL ) {
list - > parent = ( xmlNodePtr ) ent ;
if ( list - > next = = NULL )
ent - > last = list ;
list = list - > next ;
}
2001-02-23 17:55:21 +00:00
}
} else {
xmlFreeNodeList ( list ) ;
2001-07-04 19:49:14 +00:00
list = NULL ;
2001-02-23 17:55:21 +00:00
}
} else if ( ret > 0 ) {
ctxt - > errNo = ret ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Entity value required \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else if ( list ! = NULL ) {
xmlFreeNodeList ( list ) ;
2001-07-04 19:49:14 +00:00
list = NULL ;
2001-02-23 17:55:21 +00:00
}
}
}
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > reference ! = NULL ) & &
( ctxt - > replaceEntities = = 0 ) & & ( ! ctxt - > disableSAX ) ) {
/*
* Create a node .
*/
ctxt - > sax - > reference ( ctxt - > userData , ent - > name ) ;
return ;
} else if ( ctxt - > replaceEntities ) {
if ( ( ctxt - > node ! = NULL ) & & ( ent - > children ! = NULL ) ) {
/*
* Seems we are generating the DOM content , do
2001-07-04 19:49:14 +00:00
* a simple tree copy for all references except the first
2001-12-31 16:16:02 +00:00
* In the first occurrence list contains the replacement
2001-02-23 17:55:21 +00:00
*/
2001-07-04 19:49:14 +00:00
if ( list = = NULL ) {
2002-01-13 14:10:10 +00:00
xmlNodePtr new = NULL , cur , firstChild = NULL ;
2001-07-04 19:49:14 +00:00
cur = ent - > children ;
while ( cur ! = NULL ) {
new = xmlCopyNode ( cur , 1 ) ;
2003-01-09 23:19:02 +00:00
if ( new ! = NULL ) {
new - > _private = cur - > _private ;
if ( firstChild = = NULL ) {
firstChild = new ;
}
xmlAddChild ( ctxt - > node , new ) ;
2002-01-13 14:10:10 +00:00
}
2001-07-04 19:49:14 +00:00
if ( cur = = ent - > last )
break ;
cur = cur - > next ;
}
2002-01-13 14:10:10 +00:00
if ( ent - > etype = = XML_EXTERNAL_GENERAL_PARSED_ENTITY )
xmlAddEntityReference ( ent , firstChild , new ) ;
2001-07-04 19:49:14 +00:00
} else {
/*
* the name change is to avoid coalescing of the
2001-12-31 16:16:02 +00:00
* node with a possible previous text one which
* would make ent - > children a dangling pointer
2001-07-04 19:49:14 +00:00
*/
if ( ent - > children - > type = = XML_TEXT_NODE )
ent - > children - > name = xmlStrdup ( BAD_CAST " nbktext " ) ;
if ( ( ent - > last ! = ent - > children ) & &
( ent - > last - > type = = XML_TEXT_NODE ) )
ent - > last - > name = xmlStrdup ( BAD_CAST " nbktext " ) ;
xmlAddChildList ( ctxt - > node , ent - > children ) ;
}
2001-02-23 17:55:21 +00:00
/*
* This is to avoid a nasty side effect , see
* characters ( ) in SAX . c
*/
ctxt - > nodemem = 0 ;
ctxt - > nodelen = 0 ;
return ;
} else {
/*
* Probably running in SAX mode
*/
xmlParserInputPtr input ;
input = xmlNewEntityInputStream ( ctxt , ent ) ;
xmlPushInput ( ctxt , input ) ;
if ( ( ent - > etype = = XML_EXTERNAL_GENERAL_PARSED_ENTITY ) & &
( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) & &
( NXT ( 2 ) = = ' x ' ) & & ( NXT ( 3 ) = = ' m ' ) & &
( NXT ( 4 ) = = ' l ' ) & & ( IS_BLANK ( NXT ( 5 ) ) ) ) {
xmlParseTextDecl ( ctxt ) ;
if ( ctxt - > errNo = = XML_ERR_UNSUPPORTED_ENCODING ) {
/*
* The XML REC instructs us to stop parsing right here
*/
ctxt - > instate = XML_PARSER_EOF ;
return ;
}
if ( input - > standalone = = 1 ) {
ctxt - > errNo = XML_ERR_EXT_ENTITY_STANDALONE ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" external parsed entities cannot be standalone \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
}
return ;
}
}
} else {
val = ent - > content ;
if ( val = = NULL ) return ;
/*
* inline the entity .
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > characters ! = NULL ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > characters ( ctxt - > userData , val , xmlStrlen ( val ) ) ;
}
}
}
/**
* xmlParseEntityRef :
* @ ctxt : an XML parser context
*
* parse ENTITY references declarations
*
* [ 68 ] EntityRef : : = ' & ' Name ' ; '
*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an internal DTD
* subset which contains no parameter entity references , or a document
* with " standalone='yes' " , the Name given in the entity reference
* must match that in an entity declaration , except that well - formed
* documents need not declare any of the following entities : amp , lt ,
* gt , apos , quot . The declaration of a parameter entity must precede
* any reference to it . Similarly , the declaration of a general entity
* must precede any reference to it which appears in a default value in an
* attribute - list declaration . Note that if entities are declared in the
* external subset or in external parameter entities , a non - validating
* processor is not obligated to read and process their declarations ;
* for such documents , the rule that an entity must be declared is a
* well - formedness constraint only if standalone = ' yes ' .
*
* [ WFC : Parsed Entity ]
* An entity reference must not contain the name of an unparsed entity
*
* Returns the xmlEntityPtr if found , or NULL otherwise .
*/
xmlEntityPtr
xmlParseEntityRef ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
xmlEntityPtr ent = NULL ;
GROW ;
if ( RAW = = ' & ' ) {
NEXT ;
name = xmlParseName ( ctxt ) ;
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseEntityRef: no name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
if ( RAW = = ' ; ' ) {
NEXT ;
/*
* Ask first SAX for entity resolution , otherwise try the
* predefined set .
*/
if ( ctxt - > sax ! = NULL ) {
if ( ctxt - > sax - > getEntity ! = NULL )
ent = ctxt - > sax - > getEntity ( ctxt - > userData , name ) ;
if ( ent = = NULL )
ent = xmlGetPredefinedEntity ( name ) ;
2002-03-18 18:36:20 +00:00
if ( ( ent = = NULL ) & & ( ctxt - > userData = = ctxt ) ) {
ent = getEntity ( ctxt , name ) ;
}
2001-02-23 17:55:21 +00:00
}
/*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an
* internal DTD subset which contains no parameter entity
* references , or a document with " standalone='yes' " , the
* Name given in the entity reference must match that in an
* entity declaration , except that well - formed documents
* need not declare any of the following entities : amp , lt ,
* gt , apos , quot .
* The declaration of a parameter entity must precede any
* reference to it .
* Similarly , the declaration of a general entity must
* precede any reference to it which appears in a default
* value in an attribute - list declaration . Note that if
* entities are declared in the external subset or in
* external parameter entities , a non - validating processor
* is not obligated to read and process their declarations ;
* for such documents , the rule that an entity must be
* declared is a well - formedness constraint only if
* standalone = ' yes ' .
*/
if ( ent = = NULL ) {
if ( ( ctxt - > standalone = = 1 ) | |
( ( ctxt - > hasExternalSubset = = 0 ) & &
( ctxt - > hasPErefs = = 0 ) ) ) {
ctxt - > errNo = XML_ERR_UNDECLARED_ENTITY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Entity '%s' not defined \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-02-18 22:27:47 +00:00
ctxt - > valid = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
ctxt - > errNo = XML_WAR_UNDECLARED_ENTITY ;
2001-08-22 14:29:45 +00:00
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
2001-06-26 16:08:24 +00:00
ctxt - > sax - > error ( ctxt - > userData ,
2001-02-23 17:55:21 +00:00
" Entity '%s' not defined \n " , name ) ;
2002-02-18 22:27:47 +00:00
ctxt - > valid = 0 ;
2001-02-23 17:55:21 +00:00
}
}
/*
* [ WFC : Parsed Entity ]
* An entity reference must not contain the name of an
* unparsed entity
*/
else if ( ent - > etype = = XML_EXTERNAL_GENERAL_UNPARSED_ENTITY ) {
ctxt - > errNo = XML_ERR_UNPARSED_ENTITY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Entity reference to unparsed entity %s \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* [ WFC : No External Entity References ]
* Attribute values cannot contain direct or indirect
* entity references to external entities .
*/
else if ( ( ctxt - > instate = = XML_PARSER_ATTRIBUTE_VALUE ) & &
( ent - > etype = = XML_EXTERNAL_GENERAL_PARSED_ENTITY ) ) {
ctxt - > errNo = XML_ERR_ENTITY_IS_EXTERNAL ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Attribute references external entity '%s' \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* [ WFC : No < in Attribute Values ]
* The replacement text of any entity referred to directly or
* indirectly in an attribute value ( other than " < " ) must
* not contain a < .
*/
else if ( ( ctxt - > instate = = XML_PARSER_ATTRIBUTE_VALUE ) & &
( ent ! = NULL ) & &
( ! xmlStrEqual ( ent - > name , BAD_CAST " lt " ) ) & &
( ent - > content ! = NULL ) & &
( xmlStrchr ( ent - > content , ' < ' ) ) ) {
ctxt - > errNo = XML_ERR_LT_IN_ATTRIBUTE ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" '<' in entity '%s' is not allowed in attributes values \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* Internal check , no parameter entities here . . .
*/
else {
switch ( ent - > etype ) {
case XML_INTERNAL_PARAMETER_ENTITY :
case XML_EXTERNAL_PARAMETER_ENTITY :
ctxt - > errNo = XML_ERR_ENTITY_IS_PARAMETER ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Attempt to reference the parameter entity '%s' \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
break ;
default :
break ;
}
}
/*
* [ WFC : No Recursion ]
* A parsed entity must not contain a recursive reference
* to itself , either directly or indirectly .
* Done somewhere else
*/
} else {
ctxt - > errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseEntityRef: expecting ';' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
xmlFree ( name ) ;
}
}
return ( ent ) ;
}
/**
* xmlParseStringEntityRef :
* @ ctxt : an XML parser context
* @ str : a pointer to an index in the string
*
* parse ENTITY references declarations , but this version parses it from
* a string value .
*
* [ 68 ] EntityRef : : = ' & ' Name ' ; '
*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an internal DTD
* subset which contains no parameter entity references , or a document
* with " standalone='yes' " , the Name given in the entity reference
* must match that in an entity declaration , except that well - formed
* documents need not declare any of the following entities : amp , lt ,
* gt , apos , quot . The declaration of a parameter entity must precede
* any reference to it . Similarly , the declaration of a general entity
* must precede any reference to it which appears in a default value in an
* attribute - list declaration . Note that if entities are declared in the
* external subset or in external parameter entities , a non - validating
* processor is not obligated to read and process their declarations ;
* for such documents , the rule that an entity must be declared is a
* well - formedness constraint only if standalone = ' yes ' .
*
* [ WFC : Parsed Entity ]
* An entity reference must not contain the name of an unparsed entity
*
* Returns the xmlEntityPtr if found , or NULL otherwise . The str pointer
* is updated to the current location in the string .
*/
xmlEntityPtr
xmlParseStringEntityRef ( xmlParserCtxtPtr ctxt , const xmlChar * * str ) {
xmlChar * name ;
const xmlChar * ptr ;
xmlChar cur ;
xmlEntityPtr ent = NULL ;
if ( ( str = = NULL ) | | ( * str = = NULL ) )
return ( NULL ) ;
ptr = * str ;
cur = * ptr ;
if ( cur = = ' & ' ) {
ptr + + ;
cur = * ptr ;
name = xmlParseStringName ( ctxt , & ptr ) ;
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-08-13 10:43:15 +00:00
" xmlParseStringEntityRef: no name \n " ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
if ( * ptr = = ' ; ' ) {
ptr + + ;
/*
* Ask first SAX for entity resolution , otherwise try the
* predefined set .
*/
if ( ctxt - > sax ! = NULL ) {
if ( ctxt - > sax - > getEntity ! = NULL )
ent = ctxt - > sax - > getEntity ( ctxt - > userData , name ) ;
if ( ent = = NULL )
ent = xmlGetPredefinedEntity ( name ) ;
2002-03-18 18:36:20 +00:00
if ( ( ent = = NULL ) & & ( ctxt - > userData = = ctxt ) ) {
ent = getEntity ( ctxt , name ) ;
}
2001-02-23 17:55:21 +00:00
}
/*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an
* internal DTD subset which contains no parameter entity
* references , or a document with " standalone='yes' " , the
* Name given in the entity reference must match that in an
* entity declaration , except that well - formed documents
* need not declare any of the following entities : amp , lt ,
* gt , apos , quot .
* The declaration of a parameter entity must precede any
* reference to it .
* Similarly , the declaration of a general entity must
* precede any reference to it which appears in a default
* value in an attribute - list declaration . Note that if
* entities are declared in the external subset or in
* external parameter entities , a non - validating processor
* is not obligated to read and process their declarations ;
* for such documents , the rule that an entity must be
* declared is a well - formedness constraint only if
* standalone = ' yes ' .
*/
if ( ent = = NULL ) {
if ( ( ctxt - > standalone = = 1 ) | |
( ( ctxt - > hasExternalSubset = = 0 ) & &
( ctxt - > hasPErefs = = 0 ) ) ) {
ctxt - > errNo = XML_ERR_UNDECLARED_ENTITY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Entity '%s' not defined \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
ctxt - > errNo = XML_WAR_UNDECLARED_ENTITY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" Entity '%s' not defined \n " , name ) ;
}
}
/*
* [ WFC : Parsed Entity ]
* An entity reference must not contain the name of an
* unparsed entity
*/
else if ( ent - > etype = = XML_EXTERNAL_GENERAL_UNPARSED_ENTITY ) {
ctxt - > errNo = XML_ERR_UNPARSED_ENTITY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Entity reference to unparsed entity %s \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* [ WFC : No External Entity References ]
* Attribute values cannot contain direct or indirect
* entity references to external entities .
*/
else if ( ( ctxt - > instate = = XML_PARSER_ATTRIBUTE_VALUE ) & &
( ent - > etype = = XML_EXTERNAL_GENERAL_PARSED_ENTITY ) ) {
ctxt - > errNo = XML_ERR_ENTITY_IS_EXTERNAL ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Attribute references external entity '%s' \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* [ WFC : No < in Attribute Values ]
* The replacement text of any entity referred to directly or
* indirectly in an attribute value ( other than " < " ) must
* not contain a < .
*/
else if ( ( ctxt - > instate = = XML_PARSER_ATTRIBUTE_VALUE ) & &
( ent ! = NULL ) & &
( ! xmlStrEqual ( ent - > name , BAD_CAST " lt " ) ) & &
( ent - > content ! = NULL ) & &
( xmlStrchr ( ent - > content , ' < ' ) ) ) {
ctxt - > errNo = XML_ERR_LT_IN_ATTRIBUTE ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" '<' in entity '%s' is not allowed in attributes values \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* Internal check , no parameter entities here . . .
*/
else {
switch ( ent - > etype ) {
case XML_INTERNAL_PARAMETER_ENTITY :
case XML_EXTERNAL_PARAMETER_ENTITY :
ctxt - > errNo = XML_ERR_ENTITY_IS_PARAMETER ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Attempt to reference the parameter entity '%s' \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
break ;
default :
break ;
}
}
/*
* [ WFC : No Recursion ]
* A parsed entity must not contain a recursive reference
* to itself , either directly or indirectly .
2001-12-31 16:16:02 +00:00
* Done somewhere else
2001-02-23 17:55:21 +00:00
*/
} else {
ctxt - > errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2001-08-13 10:43:15 +00:00
" xmlParseStringEntityRef: expecting ';' \n " ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
xmlFree ( name ) ;
}
}
* str = ptr ;
return ( ent ) ;
}
/**
* xmlParsePEReference :
* @ ctxt : an XML parser context
*
* parse PEReference declarations
* The entity content is handled directly by pushing it ' s content as
* a new input stream .
*
* [ 69 ] PEReference : : = ' % ' Name ' ; '
*
* [ WFC : No Recursion ]
* A parsed entity must not contain a recursive
* reference to itself , either directly or indirectly .
*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an internal DTD
* subset which contains no parameter entity references , or a document
* with " standalone='yes' " , . . . . . . The declaration of a parameter
* entity must precede any reference to it . . .
*
* [ VC : Entity Declared ]
* In a document with an external subset or external parameter entities
* with " standalone='no' " , . . . . . . The declaration of a parameter entity
* must precede any reference to it . . .
*
* [ WFC : In DTD ]
* Parameter - entity references may only appear in the DTD .
* NOTE : misleading but this is handled .
*/
void
xmlParsePEReference ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
xmlEntityPtr entity = NULL ;
xmlParserInputPtr input ;
if ( RAW = = ' % ' ) {
NEXT ;
2001-05-16 21:05:17 +00:00
name = xmlParseName ( ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParsePEReference: no name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
if ( RAW = = ' ; ' ) {
NEXT ;
if ( ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > getParameterEntity ! = NULL ) )
entity = ctxt - > sax - > getParameterEntity ( ctxt - > userData ,
name ) ;
if ( entity = = NULL ) {
/*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an
* internal DTD subset which contains no parameter entity
* references , or a document with " standalone='yes' " , . . .
* . . . The declaration of a parameter entity must precede
* any reference to it . . .
*/
if ( ( ctxt - > standalone = = 1 ) | |
( ( ctxt - > hasExternalSubset = = 0 ) & &
( ctxt - > hasPErefs = = 0 ) ) ) {
ctxt - > errNo = XML_ERR_UNDECLARED_ENTITY ;
if ( ( ! ctxt - > disableSAX ) & &
( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" PEReference: %%%s; not found \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
/*
* [ VC : Entity Declared ]
* In a document with an external subset or external
* parameter entities with " standalone='no' " , . . .
* . . . The declaration of a parameter entity must precede
* any reference to it . . .
*/
if ( ( ! ctxt - > disableSAX ) & &
( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" PEReference: %%%s; not found \n " , name ) ;
ctxt - > valid = 0 ;
}
} else {
/*
* Internal checking in case the entity quest barfed
*/
if ( ( entity - > etype ! = XML_INTERNAL_PARAMETER_ENTITY ) & &
( entity - > etype ! = XML_EXTERNAL_PARAMETER_ENTITY ) ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" Internal: %%%s; is not a parameter entity \n " , name ) ;
2002-06-11 10:08:16 +00:00
} else if ( ctxt - > input - > free ! = deallocblankswrapper ) {
input = xmlNewBlanksWrapperInputStream ( ctxt , entity ) ;
xmlPushInput ( ctxt , input ) ;
2001-02-23 17:55:21 +00:00
} else {
/*
* TODO ! ! !
* handle the extra spaces added before and after
* c . f . http : //www.w3.org/TR/REC-xml#as-PE
*/
input = xmlNewEntityInputStream ( ctxt , entity ) ;
xmlPushInput ( ctxt , input ) ;
if ( ( entity - > etype = = XML_EXTERNAL_PARAMETER_ENTITY ) & &
( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) & &
( NXT ( 2 ) = = ' x ' ) & & ( NXT ( 3 ) = = ' m ' ) & &
( NXT ( 4 ) = = ' l ' ) & & ( IS_BLANK ( NXT ( 5 ) ) ) ) {
xmlParseTextDecl ( ctxt ) ;
if ( ctxt - > errNo = = XML_ERR_UNSUPPORTED_ENCODING ) {
/*
* The XML REC instructs us to stop parsing
* right here
*/
ctxt - > instate = XML_PARSER_EOF ;
xmlFree ( name ) ;
return ;
}
}
}
}
ctxt - > hasPErefs = 1 ;
} else {
ctxt - > errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParsePEReference: expecting ';' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
xmlFree ( name ) ;
}
}
}
/**
* xmlParseStringPEReference :
* @ ctxt : an XML parser context
* @ str : a pointer to an index in the string
*
* parse PEReference declarations
*
* [ 69 ] PEReference : : = ' % ' Name ' ; '
*
* [ WFC : No Recursion ]
* A parsed entity must not contain a recursive
* reference to itself , either directly or indirectly .
*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an internal DTD
* subset which contains no parameter entity references , or a document
* with " standalone='yes' " , . . . . . . The declaration of a parameter
* entity must precede any reference to it . . .
*
* [ VC : Entity Declared ]
* In a document with an external subset or external parameter entities
* with " standalone='no' " , . . . . . . The declaration of a parameter entity
* must precede any reference to it . . .
*
* [ WFC : In DTD ]
* Parameter - entity references may only appear in the DTD .
* NOTE : misleading but this is handled .
*
* Returns the string of the entity content .
* str is updated to the current value of the index
*/
xmlEntityPtr
xmlParseStringPEReference ( xmlParserCtxtPtr ctxt , const xmlChar * * str ) {
const xmlChar * ptr ;
xmlChar cur ;
xmlChar * name ;
xmlEntityPtr entity = NULL ;
if ( ( str = = NULL ) | | ( * str = = NULL ) ) return ( NULL ) ;
ptr = * str ;
cur = * ptr ;
if ( cur = = ' % ' ) {
ptr + + ;
cur = * ptr ;
name = xmlParseStringName ( ctxt , & ptr ) ;
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseStringPEReference: no name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
cur = * ptr ;
if ( cur = = ' ; ' ) {
ptr + + ;
cur = * ptr ;
if ( ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > getParameterEntity ! = NULL ) )
entity = ctxt - > sax - > getParameterEntity ( ctxt - > userData ,
name ) ;
if ( entity = = NULL ) {
/*
* [ WFC : Entity Declared ]
* In a document without any DTD , a document with only an
* internal DTD subset which contains no parameter entity
* references , or a document with " standalone='yes' " , . . .
* . . . The declaration of a parameter entity must precede
* any reference to it . . .
*/
if ( ( ctxt - > standalone = = 1 ) | |
( ( ctxt - > hasExternalSubset = = 0 ) & &
( ctxt - > hasPErefs = = 0 ) ) ) {
ctxt - > errNo = XML_ERR_UNDECLARED_ENTITY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" PEReference: %%%s; not found \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else {
/*
* [ VC : Entity Declared ]
* In a document with an external subset or external
* parameter entities with " standalone='no' " , . . .
* . . . The declaration of a parameter entity must
* precede any reference to it . . .
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" PEReference: %%%s; not found \n " , name ) ;
ctxt - > valid = 0 ;
}
} else {
/*
* Internal checking in case the entity quest barfed
*/
if ( ( entity - > etype ! = XML_INTERNAL_PARAMETER_ENTITY ) & &
( entity - > etype ! = XML_EXTERNAL_PARAMETER_ENTITY ) ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" Internal: %%%s; is not a parameter entity \n " , name ) ;
}
}
ctxt - > hasPErefs = 1 ;
} else {
ctxt - > errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseStringPEReference: expecting ';' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
xmlFree ( name ) ;
}
}
* str = ptr ;
return ( entity ) ;
}
/**
* xmlParseDocTypeDecl :
* @ ctxt : an XML parser context
*
* parse a DOCTYPE declaration
*
* [ 28 ] doctypedecl : : = ' < ! DOCTYPE ' S Name ( S ExternalID ) ? S ?
* ( ' [ ' ( markupdecl | PEReference | S ) * ' ] ' S ? ) ? ' > '
*
* [ VC : Root Element Type ]
* The Name in the document type declaration must match the element
* type of the root element .
*/
void
xmlParseDocTypeDecl ( xmlParserCtxtPtr ctxt ) {
xmlChar * name = NULL ;
xmlChar * ExternalID = NULL ;
xmlChar * URI = NULL ;
/*
* We know that ' < ! DOCTYPE ' has been detected .
*/
SKIP ( 9 ) ;
SKIP_BLANKS ;
/*
* Parse the DOCTYPE name .
*/
name = xmlParseName ( ctxt ) ;
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseDocTypeDecl : no DOCTYPE name ! \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
ctxt - > intSubName = name ;
SKIP_BLANKS ;
/*
* Check for SystemID and ExternalID
*/
URI = xmlParseExternalID ( ctxt , & ExternalID , 1 ) ;
if ( ( URI ! = NULL ) | | ( ExternalID ! = NULL ) ) {
ctxt - > hasExternalSubset = 1 ;
}
ctxt - > extSubURI = URI ;
ctxt - > extSubSystem = ExternalID ;
SKIP_BLANKS ;
/*
* Create and update the internal subset .
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > internalSubset ! = NULL ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > internalSubset ( ctxt - > userData , name , ExternalID , URI ) ;
/*
* Is there any internal subset declarations ?
* they are handled separately in xmlParseInternalSubset ( )
*/
if ( RAW = = ' [ ' )
return ;
/*
* We should be at the end of the DOCTYPE declaration .
*/
if ( RAW ! = ' > ' ) {
ctxt - > errNo = XML_ERR_DOCTYPE_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
2001-10-02 09:22:47 +00:00
ctxt - > sax - > error ( ctxt - > userData , " DOCTYPE improperly terminated \n " ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
NEXT ;
}
/**
2001-12-31 16:16:02 +00:00
* xmlParseInternalSubset :
2001-02-23 17:55:21 +00:00
* @ ctxt : an XML parser context
*
* parse the internal subset declaration
*
* [ 28 end ] ( ' [ ' ( markupdecl | PEReference | S ) * ' ] ' S ? ) ? ' > '
*/
2001-03-24 17:00:36 +00:00
static void
2001-02-23 17:55:21 +00:00
xmlParseInternalSubset ( xmlParserCtxtPtr ctxt ) {
/*
* Is there any DTD definition ?
*/
if ( RAW = = ' [ ' ) {
ctxt - > instate = XML_PARSER_DTD ;
NEXT ;
/*
* Parse the succession of Markup declarations and
* PEReferences .
* Subsequence ( markupdecl | PEReference | S ) *
*/
while ( RAW ! = ' ] ' ) {
const xmlChar * check = CUR_PTR ;
int cons = ctxt - > input - > consumed ;
SKIP_BLANKS ;
xmlParseMarkupDecl ( ctxt ) ;
xmlParsePEReference ( ctxt ) ;
/*
* Pop - up of finished entities .
*/
while ( ( RAW = = 0 ) & & ( ctxt - > inputNr > 1 ) )
xmlPopInput ( ctxt ) ;
if ( ( CUR_PTR = = check ) & & ( cons = = ctxt - > input - > consumed ) ) {
ctxt - > errNo = XML_ERR_INTERNAL_ERROR ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseInternalSubset: error detected in Markup declaration \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
break ;
}
}
if ( RAW = = ' ] ' ) {
NEXT ;
SKIP_BLANKS ;
}
}
/*
* We should be at the end of the DOCTYPE declaration .
*/
if ( RAW ! = ' > ' ) {
ctxt - > errNo = XML_ERR_DOCTYPE_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
2001-10-02 09:22:47 +00:00
ctxt - > sax - > error ( ctxt - > userData , " DOCTYPE improperly terminated \n " ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
NEXT ;
}
/**
* xmlParseAttribute :
* @ ctxt : an XML parser context
* @ value : a xmlChar * * used to store the value of the attribute
*
* parse an attribute
*
* [ 41 ] Attribute : : = Name Eq AttValue
*
* [ WFC : No External Entity References ]
* Attribute values cannot contain direct or indirect entity references
* to external entities .
*
* [ WFC : No < in Attribute Values ]
* The replacement text of any entity referred to directly or indirectly in
* an attribute value ( other than " < " ) must not contain a < .
*
* [ VC : Attribute Value Type ]
* The attribute must have been declared ; the value must be of the type
* declared for it .
*
* [ 25 ] Eq : : = S ? ' = ' S ?
*
* With namespace :
*
* [ NS 11 ] Attribute : : = QName Eq AttValue
*
* Also the case QName = = xmlns : ? ? ? is handled independently as a namespace
* definition .
*
* Returns the attribute name , and the value in * value .
*/
xmlChar *
xmlParseAttribute ( xmlParserCtxtPtr ctxt , xmlChar * * value ) {
xmlChar * name , * val ;
* value = NULL ;
2002-02-19 13:46:09 +00:00
GROW ;
2001-02-23 17:55:21 +00:00
name = xmlParseName ( ctxt ) ;
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " error parsing attribute name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
/*
* read the value
*/
SKIP_BLANKS ;
if ( RAW = = ' = ' ) {
NEXT ;
SKIP_BLANKS ;
val = xmlParseAttValue ( ctxt ) ;
ctxt - > instate = XML_PARSER_CONTENT ;
} else {
ctxt - > errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Specification mandate value for attribute %s \n " , name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
xmlFree ( name ) ;
return ( NULL ) ;
}
/*
* Check that xml : lang conforms to the specification
* No more registered as an error , just generate a warning now
* since this was deprecated in XML second edition
*/
if ( ( ctxt - > pedantic ) & & ( xmlStrEqual ( name , BAD_CAST " xml:lang " ) ) ) {
if ( ! xmlCheckLanguageID ( val ) ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData ,
" Malformed value for xml:lang : %s \n " , val ) ;
}
}
/*
* Check that xml : space conforms to the specification
*/
if ( xmlStrEqual ( name , BAD_CAST " xml:space " ) ) {
if ( xmlStrEqual ( val , BAD_CAST " default " ) )
* ( ctxt - > space ) = 0 ;
else if ( xmlStrEqual ( val , BAD_CAST " preserve " ) )
* ( ctxt - > space ) = 1 ;
else {
ctxt - > errNo = XML_ERR_ATTRIBUTE_WITHOUT_VALUE ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Invalid value for xml:space : \" %s \" , \" default \" or \" preserve \" expected \n " ,
val ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
}
* value = val ;
return ( name ) ;
}
/**
* xmlParseStartTag :
* @ ctxt : an XML parser context
*
* parse a start of tag either for rule element or
* EmptyElement . In both case we don ' t parse the tag closing chars .
*
* [ 40 ] STag : : = ' < ' Name ( S Attribute ) * S ? ' > '
*
* [ WFC : Unique Att Spec ]
* No attribute name may appear more than once in the same start - tag or
* empty - element tag .
*
* [ 44 ] EmptyElemTag : : = ' < ' Name ( S Attribute ) * S ? ' / > '
*
* [ WFC : Unique Att Spec ]
* No attribute name may appear more than once in the same start - tag or
* empty - element tag .
*
* With namespace :
*
* [ NS 8 ] STag : : = ' < ' QName ( S Attribute ) * S ? ' > '
*
* [ NS 10 ] EmptyElement : : = ' < ' QName ( S Attribute ) * S ? ' / > '
*
* Returns the element name parsed
*/
xmlChar *
xmlParseStartTag ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
xmlChar * attname ;
xmlChar * attvalue ;
const xmlChar * * atts = NULL ;
int nbatts = 0 ;
int maxatts = 0 ;
int i ;
if ( RAW ! = ' < ' ) return ( NULL ) ;
2001-02-25 19:54:14 +00:00
NEXT1 ;
2001-02-23 17:55:21 +00:00
name = xmlParseName ( ctxt ) ;
if ( name = = NULL ) {
ctxt - > errNo = XML_ERR_NAME_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseStartTag: invalid element name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
/*
* Now parse the attributes , it ends up with the ending
*
* ( S Attribute ) * S ?
*/
SKIP_BLANKS ;
GROW ;
2001-02-25 19:54:14 +00:00
while ( ( RAW ! = ' > ' ) & &
( ( RAW ! = ' / ' ) | | ( NXT ( 1 ) ! = ' > ' ) ) & &
( IS_CHAR ( RAW ) ) ) {
2001-02-23 17:55:21 +00:00
const xmlChar * q = CUR_PTR ;
int cons = ctxt - > input - > consumed ;
attname = xmlParseAttribute ( ctxt , & attvalue ) ;
if ( ( attname ! = NULL ) & & ( attvalue ! = NULL ) ) {
/*
* [ WFC : Unique Att Spec ]
* No attribute name may appear more than once in the same
* start - tag or empty - element tag .
*/
for ( i = 0 ; i < nbatts ; i + = 2 ) {
if ( xmlStrEqual ( atts [ i ] , attname ) ) {
ctxt - > errNo = XML_ERR_ATTRIBUTE_REDEFINED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Attribute %s redefined \n " ,
attname ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
xmlFree ( attname ) ;
xmlFree ( attvalue ) ;
goto failed ;
}
}
/*
* Add the pair to atts
*/
if ( atts = = NULL ) {
maxatts = 10 ;
atts = ( const xmlChar * * ) xmlMalloc ( maxatts * sizeof ( xmlChar * ) ) ;
if ( atts = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %ld byte failed \n " ,
maxatts * ( long ) sizeof ( xmlChar * ) ) ;
return ( NULL ) ;
}
} else if ( nbatts + 4 > maxatts ) {
maxatts * = 2 ;
atts = ( const xmlChar * * ) xmlRealloc ( ( void * ) atts ,
maxatts * sizeof ( xmlChar * ) ) ;
if ( atts = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc of %ld byte failed \n " ,
maxatts * ( long ) sizeof ( xmlChar * ) ) ;
return ( NULL ) ;
}
}
atts [ nbatts + + ] = attname ;
atts [ nbatts + + ] = attvalue ;
atts [ nbatts ] = NULL ;
atts [ nbatts + 1 ] = NULL ;
} else {
if ( attname ! = NULL )
xmlFree ( attname ) ;
if ( attvalue ! = NULL )
xmlFree ( attvalue ) ;
}
failed :
2002-12-17 10:31:45 +00:00
GROW
2001-02-23 17:55:21 +00:00
if ( ( RAW = = ' > ' ) | | ( ( ( RAW = = ' / ' ) & & ( NXT ( 1 ) = = ' > ' ) ) ) )
break ;
if ( ! IS_BLANK ( RAW ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" attributes construct error \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
if ( ( cons = = ctxt - > input - > consumed ) & & ( q = = CUR_PTR ) ) {
ctxt - > errNo = XML_ERR_INTERNAL_ERROR ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseStartTag: problem parsing attributes \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
break ;
}
GROW ;
}
/*
* SAX : Start of Element !
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > startElement ! = NULL ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > startElement ( ctxt - > userData , name , atts ) ;
if ( atts ! = NULL ) {
for ( i = 0 ; i < nbatts ; i + + ) xmlFree ( ( xmlChar * ) atts [ i ] ) ;
xmlFree ( ( void * ) atts ) ;
}
return ( name ) ;
}
/**
* xmlParseEndTag :
* @ ctxt : an XML parser context
*
* parse an end of tag
*
* [ 42 ] ETag : : = ' < / ' Name S ? ' > '
*
* With namespace
*
* [ NS 9 ] ETag : : = ' < / ' QName S ? ' > '
*/
void
xmlParseEndTag ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
xmlChar * oldname ;
GROW ;
if ( ( RAW ! = ' < ' ) | | ( NXT ( 1 ) ! = ' / ' ) ) {
ctxt - > errNo = XML_ERR_LTSLASH_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " xmlParseEndTag: '</' not found \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ;
}
SKIP ( 2 ) ;
2002-05-29 08:21:33 +00:00
name = xmlParseNameAndCompare ( ctxt , ctxt - > name ) ;
2001-02-23 17:55:21 +00:00
/*
* We should definitely be at the ending " S? '>' " part
*/
GROW ;
SKIP_BLANKS ;
if ( ( ! IS_CHAR ( RAW ) ) | | ( RAW ! = ' > ' ) ) {
ctxt - > errNo = XML_ERR_GT_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " End tag : expected '>' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else
2001-02-25 19:54:14 +00:00
NEXT1 ;
2001-02-23 17:55:21 +00:00
/*
* [ WFC : Element Type Match ]
* The Name in an element ' s end - tag must match the element type in the
* start - tag .
*
*/
2002-05-29 08:21:33 +00:00
if ( name ! = ( xmlChar * ) 1 ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_TAG_NAME_MISMATCH ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) ) {
2002-05-29 08:21:33 +00:00
if ( name ! = NULL ) {
2001-02-23 17:55:21 +00:00
ctxt - > sax - > error ( ctxt - > userData ,
" Opening and ending tag mismatch: %s and %s \n " ,
ctxt - > name , name ) ;
2002-05-29 08:21:33 +00:00
} else {
2001-02-23 17:55:21 +00:00
ctxt - > sax - > error ( ctxt - > userData ,
2001-12-31 16:16:02 +00:00
" Ending tag error for: %s \n " , ctxt - > name ) ;
2001-02-23 17:55:21 +00:00
}
}
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
#if 0
else {
/*
* Recover in case of one missing close
*/
if ( ( ctxt - > nameNr > 2 ) & &
( xmlStrEqual ( ctxt - > nameTab [ ctxt - > nameNr - 2 ] , name ) ) ) {
namePop ( ctxt ) ;
spacePop ( ctxt ) ;
}
}
# endif
if ( name ! = NULL )
xmlFree ( name ) ;
2001-02-23 17:55:21 +00:00
}
/*
* SAX : End of Tag
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > endElement ! = NULL ) & &
( ! ctxt - > disableSAX ) )
2002-05-29 08:21:33 +00:00
ctxt - > sax - > endElement ( ctxt - > userData , ctxt - > name ) ;
2001-02-23 17:55:21 +00:00
oldname = namePop ( ctxt ) ;
spacePop ( ctxt ) ;
if ( oldname ! = NULL ) {
# ifdef DEBUG_STACK
xmlGenericError ( xmlGenericErrorContext , " Close: popped %s \n " , oldname ) ;
# endif
xmlFree ( oldname ) ;
}
return ;
}
/**
* xmlParseCDSect :
* @ ctxt : an XML parser context
*
* Parse escaped pure raw content .
*
* [ 18 ] CDSect : : = CDStart CData CDEnd
*
* [ 19 ] CDStart : : = ' < ! [ CDATA [ '
*
* [ 20 ] Data : : = ( Char * - ( Char * ' ] ] > ' Char * ) )
*
* [ 21 ] CDEnd : : = ' ] ] > '
*/
void
xmlParseCDSect ( xmlParserCtxtPtr ctxt ) {
xmlChar * buf = NULL ;
int len = 0 ;
int size = XML_PARSER_BUFFER_SIZE ;
int r , rl ;
int s , sl ;
int cur , l ;
int count = 0 ;
if ( ( NXT ( 0 ) = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & &
( NXT ( 2 ) = = ' [ ' ) & & ( NXT ( 3 ) = = ' C ' ) & &
( NXT ( 4 ) = = ' D ' ) & & ( NXT ( 5 ) = = ' A ' ) & &
( NXT ( 6 ) = = ' T ' ) & & ( NXT ( 7 ) = = ' A ' ) & &
( NXT ( 8 ) = = ' [ ' ) ) {
SKIP ( 9 ) ;
} else
return ;
ctxt - > instate = XML_PARSER_CDATA_SECTION ;
r = CUR_CHAR ( rl ) ;
if ( ! IS_CHAR ( r ) ) {
ctxt - > errNo = XML_ERR_CDATA_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" CData section not finished \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
ctxt - > instate = XML_PARSER_CONTENT ;
return ;
}
NEXTL ( rl ) ;
s = CUR_CHAR ( sl ) ;
if ( ! IS_CHAR ( s ) ) {
ctxt - > errNo = XML_ERR_CDATA_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" CData section not finished \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
ctxt - > instate = XML_PARSER_CONTENT ;
return ;
}
NEXTL ( sl ) ;
cur = CUR_CHAR ( l ) ;
buf = ( xmlChar * ) xmlMalloc ( size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %d byte failed \n " , size ) ;
return ;
}
while ( IS_CHAR ( cur ) & &
( ( r ! = ' ] ' ) | | ( s ! = ' ] ' ) | | ( cur ! = ' > ' ) ) ) {
if ( len + 5 > = size ) {
size * = 2 ;
buf = ( xmlChar * ) xmlRealloc ( buf , size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc of %d byte failed \n " , size ) ;
return ;
}
}
COPY_BUF ( rl , buf , len , r ) ;
r = s ;
rl = sl ;
s = cur ;
sl = l ;
count + + ;
if ( count > 50 ) {
GROW ;
count = 0 ;
}
NEXTL ( l ) ;
cur = CUR_CHAR ( l ) ;
}
buf [ len ] = 0 ;
ctxt - > instate = XML_PARSER_CONTENT ;
if ( cur ! = ' > ' ) {
ctxt - > errNo = XML_ERR_CDATA_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" CData section not finished \n %.50s \n " , buf ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
xmlFree ( buf ) ;
return ;
}
NEXTL ( l ) ;
/*
2001-12-31 16:16:02 +00:00
* OK the buffer is to be consumed as cdata .
2001-02-23 17:55:21 +00:00
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) ) {
if ( ctxt - > sax - > cdataBlock ! = NULL )
ctxt - > sax - > cdataBlock ( ctxt - > userData , buf , len ) ;
2001-07-08 13:15:55 +00:00
else if ( ctxt - > sax - > characters ! = NULL )
ctxt - > sax - > characters ( ctxt - > userData , buf , len ) ;
2001-02-23 17:55:21 +00:00
}
xmlFree ( buf ) ;
}
/**
* xmlParseContent :
* @ ctxt : an XML parser context
*
* Parse a content :
*
* [ 43 ] content : : = ( element | CharData | Reference | CDSect | PI | Comment ) *
*/
void
xmlParseContent ( xmlParserCtxtPtr ctxt ) {
GROW ;
2002-07-01 21:52:03 +00:00
while ( ( RAW ! = 0 ) & &
2001-02-23 17:55:21 +00:00
( ( RAW ! = ' < ' ) | | ( NXT ( 1 ) ! = ' / ' ) ) ) {
const xmlChar * test = CUR_PTR ;
int cons = ctxt - > input - > consumed ;
2001-02-25 19:54:14 +00:00
const xmlChar * cur = ctxt - > input - > cur ;
2001-02-23 17:55:21 +00:00
/*
* First case : a Processing Instruction .
*/
2002-07-01 21:52:03 +00:00
if ( ( * cur = = ' < ' ) & & ( cur [ 1 ] = = ' ? ' ) ) {
2001-02-23 17:55:21 +00:00
xmlParsePI ( ctxt ) ;
}
/*
* Second case : a CDSection
*/
2001-02-25 19:54:14 +00:00
else if ( ( * cur = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & &
2001-02-23 17:55:21 +00:00
( NXT ( 2 ) = = ' [ ' ) & & ( NXT ( 3 ) = = ' C ' ) & &
( NXT ( 4 ) = = ' D ' ) & & ( NXT ( 5 ) = = ' A ' ) & &
( NXT ( 6 ) = = ' T ' ) & & ( NXT ( 7 ) = = ' A ' ) & &
( NXT ( 8 ) = = ' [ ' ) ) {
xmlParseCDSect ( ctxt ) ;
}
/*
* Third case : a comment
*/
2001-02-25 19:54:14 +00:00
else if ( ( * cur = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & &
2001-02-23 17:55:21 +00:00
( NXT ( 2 ) = = ' - ' ) & & ( NXT ( 3 ) = = ' - ' ) ) {
xmlParseComment ( ctxt ) ;
ctxt - > instate = XML_PARSER_CONTENT ;
}
/*
* Fourth case : a sub - element .
*/
2001-02-25 19:54:14 +00:00
else if ( * cur = = ' < ' ) {
2001-02-23 17:55:21 +00:00
xmlParseElement ( ctxt ) ;
}
/*
* Fifth case : a reference . If if has not been resolved ,
* parsing returns it ' s Name , create the node
*/
2001-02-25 19:54:14 +00:00
else if ( * cur = = ' & ' ) {
2001-02-23 17:55:21 +00:00
xmlParseReference ( ctxt ) ;
}
/*
* Last case , text . Note that References are handled directly .
*/
else {
xmlParseCharData ( ctxt , 0 ) ;
}
GROW ;
/*
* Pop - up of finished entities .
*/
2002-03-20 21:55:57 +00:00
while ( ( RAW = = 0 ) & & ( ctxt - > inputNr > 1 ) )
2001-02-23 17:55:21 +00:00
xmlPopInput ( ctxt ) ;
SHRINK ;
2002-07-01 21:52:03 +00:00
if ( ( cons = = ctxt - > input - > consumed ) & & ( test = = CUR_PTR ) ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_INTERNAL_ERROR ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" detected an error in element content \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
ctxt - > instate = XML_PARSER_EOF ;
break ;
}
}
}
/**
* xmlParseElement :
* @ ctxt : an XML parser context
*
* parse an XML element , this is highly recursive
*
* [ 39 ] element : : = EmptyElemTag | STag content ETag
*
* [ WFC : Element Type Match ]
* The Name in an element ' s end - tag must match the element type in the
* start - tag .
*
* [ VC : Element Valid ]
* An element is valid if there is a declaration matching elementdecl
* where the Name matches the element type and one of the following holds :
* - The declaration matches EMPTY and the element has no content .
* - The declaration matches children and the sequence of child elements
* belongs to the language generated by the regular expression in the
* content model , with optional white space ( characters matching the
* nonterminal S ) between each pair of child elements .
* - The declaration matches Mixed and the content consists of character
* data and child elements whose types match names in the content model .
* - The declaration matches ANY , and the types of any child elements have
* been declared .
*/
void
xmlParseElement ( xmlParserCtxtPtr ctxt ) {
xmlChar * name ;
xmlChar * oldname ;
xmlParserNodeInfo node_info ;
xmlNodePtr ret ;
/* Capture start position */
if ( ctxt - > record_info ) {
node_info . begin_pos = ctxt - > input - > consumed +
( CUR_PTR - ctxt - > input - > base ) ;
node_info . begin_line = ctxt - > input - > line ;
}
if ( ctxt - > spaceNr = = 0 )
spacePush ( ctxt , - 1 ) ;
else
spacePush ( ctxt , * ctxt - > space ) ;
name = xmlParseStartTag ( ctxt ) ;
if ( name = = NULL ) {
spacePop ( ctxt ) ;
return ;
}
namePush ( ctxt , name ) ;
ret = ctxt - > node ;
/*
* [ VC : Root Element Type ]
* The Name in the document type declaration must match the element
* type of the root element .
*/
if ( ctxt - > validate & & ctxt - > wellFormed & & ctxt - > myDoc & &
ctxt - > node & & ( ctxt - > node = = ctxt - > myDoc - > children ) )
ctxt - > valid & = xmlValidateRoot ( & ctxt - > vctxt , ctxt - > myDoc ) ;
/*
* Check for an Empty Element .
*/
if ( ( RAW = = ' / ' ) & & ( NXT ( 1 ) = = ' > ' ) ) {
SKIP ( 2 ) ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > endElement ! = NULL ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > endElement ( ctxt - > userData , name ) ;
oldname = namePop ( ctxt ) ;
spacePop ( ctxt ) ;
if ( oldname ! = NULL ) {
# ifdef DEBUG_STACK
xmlGenericError ( xmlGenericErrorContext , " Close: popped %s \n " , oldname ) ;
# endif
xmlFree ( oldname ) ;
}
if ( ret ! = NULL & & ctxt - > record_info ) {
node_info . end_pos = ctxt - > input - > consumed +
( CUR_PTR - ctxt - > input - > base ) ;
node_info . end_line = ctxt - > input - > line ;
node_info . node = ret ;
xmlParserAddNodeInfo ( ctxt , & node_info ) ;
}
return ;
}
if ( RAW = = ' > ' ) {
2001-02-25 19:54:14 +00:00
NEXT1 ;
2001-02-23 17:55:21 +00:00
} else {
ctxt - > errNo = XML_ERR_GT_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2002-06-11 07:24:56 +00:00
" Couldn't find end of Start Tag %s \n " ,
name ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
/*
* end of parsing of this node .
*/
nodePop ( ctxt ) ;
oldname = namePop ( ctxt ) ;
spacePop ( ctxt ) ;
if ( oldname ! = NULL ) {
# ifdef DEBUG_STACK
xmlGenericError ( xmlGenericErrorContext , " Close: popped %s \n " , oldname ) ;
# endif
xmlFree ( oldname ) ;
}
/*
* Capture end position and add node
*/
if ( ret ! = NULL & & ctxt - > record_info ) {
node_info . end_pos = ctxt - > input - > consumed +
( CUR_PTR - ctxt - > input - > base ) ;
node_info . end_line = ctxt - > input - > line ;
node_info . node = ret ;
xmlParserAddNodeInfo ( ctxt , & node_info ) ;
}
return ;
}
/*
* Parse the content of the element :
*/
xmlParseContent ( ctxt ) ;
if ( ! IS_CHAR ( RAW ) ) {
2001-12-31 16:37:34 +00:00
ctxt - > errNo = XML_ERR_TAG_NOT_FINISHED ;
2001-02-23 17:55:21 +00:00
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
2002-06-11 07:24:56 +00:00
" Premature end of data in tag %s \n " , name ) ;
2001-02-23 17:55:21 +00:00
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
/*
* end of parsing of this node .
*/
nodePop ( ctxt ) ;
oldname = namePop ( ctxt ) ;
spacePop ( ctxt ) ;
if ( oldname ! = NULL ) {
# ifdef DEBUG_STACK
xmlGenericError ( xmlGenericErrorContext , " Close: popped %s \n " , oldname ) ;
# endif
xmlFree ( oldname ) ;
}
return ;
}
/*
* parse the end of tag : ' < / ' should be here .
*/
xmlParseEndTag ( ctxt ) ;
/*
* Capture end position and add node
*/
if ( ret ! = NULL & & ctxt - > record_info ) {
node_info . end_pos = ctxt - > input - > consumed +
( CUR_PTR - ctxt - > input - > base ) ;
node_info . end_line = ctxt - > input - > line ;
node_info . node = ret ;
xmlParserAddNodeInfo ( ctxt , & node_info ) ;
}
}
/**
* xmlParseVersionNum :
* @ ctxt : an XML parser context
*
* parse the XML version value .
*
* [ 26 ] VersionNum : : = ( [ a - zA - Z0 - 9 _ . : ] | ' - ' ) +
*
* Returns the string giving the XML version number , or NULL
*/
xmlChar *
xmlParseVersionNum ( xmlParserCtxtPtr ctxt ) {
xmlChar * buf = NULL ;
int len = 0 ;
int size = 10 ;
xmlChar cur ;
buf = ( xmlChar * ) xmlMalloc ( size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %d byte failed \n " , size ) ;
return ( NULL ) ;
}
cur = CUR ;
while ( ( ( cur > = ' a ' ) & & ( cur < = ' z ' ) ) | |
( ( cur > = ' A ' ) & & ( cur < = ' Z ' ) ) | |
( ( cur > = ' 0 ' ) & & ( cur < = ' 9 ' ) ) | |
( cur = = ' _ ' ) | | ( cur = = ' . ' ) | |
( cur = = ' : ' ) | | ( cur = = ' - ' ) ) {
if ( len + 1 > = size ) {
size * = 2 ;
buf = ( xmlChar * ) xmlRealloc ( buf , size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc of %d byte failed \n " , size ) ;
return ( NULL ) ;
}
}
buf [ len + + ] = cur ;
NEXT ;
cur = CUR ;
}
buf [ len ] = 0 ;
return ( buf ) ;
}
/**
* xmlParseVersionInfo :
* @ ctxt : an XML parser context
*
* parse the XML version .
*
* [ 24 ] VersionInfo : : = S ' version ' Eq ( ' VersionNum ' | " VersionNum " )
*
* [ 25 ] Eq : : = S ? ' = ' S ?
*
* Returns the version string , e . g . " 1.0 "
*/
xmlChar *
xmlParseVersionInfo ( xmlParserCtxtPtr ctxt ) {
xmlChar * version = NULL ;
const xmlChar * q ;
if ( ( RAW = = ' v ' ) & & ( NXT ( 1 ) = = ' e ' ) & &
( NXT ( 2 ) = = ' r ' ) & & ( NXT ( 3 ) = = ' s ' ) & &
( NXT ( 4 ) = = ' i ' ) & & ( NXT ( 5 ) = = ' o ' ) & &
( NXT ( 6 ) = = ' n ' ) ) {
SKIP ( 7 ) ;
SKIP_BLANKS ;
if ( RAW ! = ' = ' ) {
ctxt - > errNo = XML_ERR_EQUAL_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseVersionInfo : expected '=' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
NEXT ;
SKIP_BLANKS ;
if ( RAW = = ' " ' ) {
NEXT ;
q = CUR_PTR ;
version = xmlParseVersionNum ( ctxt ) ;
if ( RAW ! = ' " ' ) {
ctxt - > errNo = XML_ERR_STRING_NOT_CLOSED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" String not closed \n %.50s \n " , q ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else
NEXT ;
} else if ( RAW = = ' \' ' ) {
NEXT ;
q = CUR_PTR ;
version = xmlParseVersionNum ( ctxt ) ;
if ( RAW ! = ' \' ' ) {
ctxt - > errNo = XML_ERR_STRING_NOT_CLOSED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" String not closed \n %.50s \n " , q ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else
NEXT ;
} else {
ctxt - > errNo = XML_ERR_STRING_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseVersionInfo : expected ' or \" \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
}
return ( version ) ;
}
/**
* xmlParseEncName :
* @ ctxt : an XML parser context
*
* parse the XML encoding name
*
* [ 81 ] EncName : : = [ A - Za - z ] ( [ A - Za - z0 - 9. _ ] | ' - ' ) *
*
* Returns the encoding name value or NULL
*/
xmlChar *
xmlParseEncName ( xmlParserCtxtPtr ctxt ) {
xmlChar * buf = NULL ;
int len = 0 ;
int size = 10 ;
xmlChar cur ;
cur = CUR ;
if ( ( ( cur > = ' a ' ) & & ( cur < = ' z ' ) ) | |
( ( cur > = ' A ' ) & & ( cur < = ' Z ' ) ) ) {
buf = ( xmlChar * ) xmlMalloc ( size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" malloc of %d byte failed \n " , size ) ;
return ( NULL ) ;
}
buf [ len + + ] = cur ;
NEXT ;
cur = CUR ;
while ( ( ( cur > = ' a ' ) & & ( cur < = ' z ' ) ) | |
( ( cur > = ' A ' ) & & ( cur < = ' Z ' ) ) | |
( ( cur > = ' 0 ' ) & & ( cur < = ' 9 ' ) ) | |
( cur = = ' . ' ) | | ( cur = = ' _ ' ) | |
( cur = = ' - ' ) ) {
if ( len + 1 > = size ) {
size * = 2 ;
buf = ( xmlChar * ) xmlRealloc ( buf , size * sizeof ( xmlChar ) ) ;
if ( buf = = NULL ) {
xmlGenericError ( xmlGenericErrorContext ,
" realloc of %d byte failed \n " , size ) ;
return ( NULL ) ;
}
}
buf [ len + + ] = cur ;
NEXT ;
cur = CUR ;
if ( cur = = 0 ) {
SHRINK ;
GROW ;
cur = CUR ;
}
}
buf [ len ] = 0 ;
} else {
ctxt - > errNo = XML_ERR_ENCODING_NAME ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Invalid XML encoding name \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
return ( buf ) ;
}
/**
* xmlParseEncodingDecl :
* @ ctxt : an XML parser context
*
* parse the XML encoding declaration
*
* [ 80 ] EncodingDecl : : = S ' encoding ' Eq ( ' " ' EncName ' " ' | " ' " EncName " ' " )
*
* this setups the conversion filters .
*
* Returns the encoding value or NULL
*/
xmlChar *
xmlParseEncodingDecl ( xmlParserCtxtPtr ctxt ) {
xmlChar * encoding = NULL ;
const xmlChar * q ;
SKIP_BLANKS ;
if ( ( RAW = = ' e ' ) & & ( NXT ( 1 ) = = ' n ' ) & &
( NXT ( 2 ) = = ' c ' ) & & ( NXT ( 3 ) = = ' o ' ) & &
( NXT ( 4 ) = = ' d ' ) & & ( NXT ( 5 ) = = ' i ' ) & &
( NXT ( 6 ) = = ' n ' ) & & ( NXT ( 7 ) = = ' g ' ) ) {
SKIP ( 8 ) ;
SKIP_BLANKS ;
if ( RAW ! = ' = ' ) {
ctxt - > errNo = XML_ERR_EQUAL_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseEncodingDecl : expected '=' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( NULL ) ;
}
NEXT ;
SKIP_BLANKS ;
if ( RAW = = ' " ' ) {
NEXT ;
q = CUR_PTR ;
encoding = xmlParseEncName ( ctxt ) ;
if ( RAW ! = ' " ' ) {
ctxt - > errNo = XML_ERR_STRING_NOT_CLOSED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" String not closed \n %.50s \n " , q ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else
NEXT ;
} else if ( RAW = = ' \' ' ) {
NEXT ;
q = CUR_PTR ;
encoding = xmlParseEncName ( ctxt ) ;
if ( RAW ! = ' \' ' ) {
ctxt - > errNo = XML_ERR_STRING_NOT_CLOSED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" String not closed \n %.50s \n " , q ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else
NEXT ;
2002-02-17 23:18:55 +00:00
} else {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_STRING_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" xmlParseEncodingDecl : expected ' or \" \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( encoding ! = NULL ) {
xmlCharEncoding enc ;
xmlCharEncodingHandlerPtr handler ;
if ( ctxt - > input - > encoding ! = NULL )
xmlFree ( ( xmlChar * ) ctxt - > input - > encoding ) ;
ctxt - > input - > encoding = encoding ;
enc = xmlParseCharEncoding ( ( const char * ) encoding ) ;
/*
* registered set of known encodings
*/
if ( enc ! = XML_CHAR_ENCODING_ERROR ) {
xmlSwitchEncoding ( ctxt , enc ) ;
if ( ctxt - > errNo = = XML_ERR_UNSUPPORTED_ENCODING ) {
2002-04-09 16:10:39 +00:00
ctxt - > input - > encoding = NULL ;
2001-02-23 17:55:21 +00:00
xmlFree ( encoding ) ;
return ( NULL ) ;
}
} else {
/*
* fallback for unknown encodings
*/
handler = xmlFindCharEncodingHandler ( ( const char * ) encoding ) ;
if ( handler ! = NULL ) {
xmlSwitchToEncoding ( ctxt , handler ) ;
} else {
ctxt - > errNo = XML_ERR_UNSUPPORTED_ENCODING ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Unsupported encoding %s \n " , encoding ) ;
return ( NULL ) ;
}
}
}
}
return ( encoding ) ;
}
/**
* xmlParseSDDecl :
* @ ctxt : an XML parser context
*
* parse the XML standalone declaration
*
* [ 32 ] SDDecl : : = S ' standalone ' Eq
* ( ( " ' " ( ' yes ' | ' no ' ) " ' " ) | ( ' " ' ( ' yes ' | ' no ' ) ' " '))
*
* [ VC : Standalone Document Declaration ]
* TODO The standalone document declaration must have the value " no "
* if any external markup declarations contain declarations of :
* - attributes with default values , if elements to which these
* attributes apply appear in the document without specifications
* of values for these attributes , or
* - entities ( other than amp , lt , gt , apos , quot ) , if references
* to those entities appear in the document , or
* - attributes with values subject to normalization , where the
* attribute appears in the document with a value which will change
* as a result of normalization , or
* - element types with element content , if white space occurs directly
* within any instance of those types .
*
* Returns 1 if standalone , 0 otherwise
*/
int
xmlParseSDDecl ( xmlParserCtxtPtr ctxt ) {
int standalone = - 1 ;
SKIP_BLANKS ;
if ( ( RAW = = ' s ' ) & & ( NXT ( 1 ) = = ' t ' ) & &
( NXT ( 2 ) = = ' a ' ) & & ( NXT ( 3 ) = = ' n ' ) & &
( NXT ( 4 ) = = ' d ' ) & & ( NXT ( 5 ) = = ' a ' ) & &
( NXT ( 6 ) = = ' l ' ) & & ( NXT ( 7 ) = = ' o ' ) & &
( NXT ( 8 ) = = ' n ' ) & & ( NXT ( 9 ) = = ' e ' ) ) {
SKIP ( 10 ) ;
SKIP_BLANKS ;
if ( RAW ! = ' = ' ) {
ctxt - > errNo = XML_ERR_EQUAL_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" XML standalone declaration : expected '=' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
return ( standalone ) ;
}
NEXT ;
SKIP_BLANKS ;
if ( RAW = = ' \' ' ) {
NEXT ;
if ( ( RAW = = ' n ' ) & & ( NXT ( 1 ) = = ' o ' ) ) {
standalone = 0 ;
SKIP ( 2 ) ;
} else if ( ( RAW = = ' y ' ) & & ( NXT ( 1 ) = = ' e ' ) & &
( NXT ( 2 ) = = ' s ' ) ) {
standalone = 1 ;
SKIP ( 3 ) ;
} else {
ctxt - > errNo = XML_ERR_STANDALONE_VALUE ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" standalone accepts only 'yes' or 'no' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( RAW ! = ' \' ' ) {
ctxt - > errNo = XML_ERR_STRING_NOT_CLOSED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " String not closed \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else
NEXT ;
} else if ( RAW = = ' " ' ) {
NEXT ;
if ( ( RAW = = ' n ' ) & & ( NXT ( 1 ) = = ' o ' ) ) {
standalone = 0 ;
SKIP ( 2 ) ;
} else if ( ( RAW = = ' y ' ) & & ( NXT ( 1 ) = = ' e ' ) & &
( NXT ( 2 ) = = ' s ' ) ) {
standalone = 1 ;
SKIP ( 3 ) ;
} else {
ctxt - > errNo = XML_ERR_STANDALONE_VALUE ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" standalone accepts only 'yes' or 'no' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( RAW ! = ' " ' ) {
ctxt - > errNo = XML_ERR_STRING_NOT_CLOSED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " String not closed \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else
NEXT ;
} else {
ctxt - > errNo = XML_ERR_STRING_NOT_STARTED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Standalone value not found \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
}
return ( standalone ) ;
}
/**
* xmlParseXMLDecl :
* @ ctxt : an XML parser context
*
* parse an XML declaration header
*
* [ 23 ] XMLDecl : : = ' < ? xml ' VersionInfo EncodingDecl ? SDDecl ? S ? ' ? > '
*/
void
xmlParseXMLDecl ( xmlParserCtxtPtr ctxt ) {
xmlChar * version ;
/*
* We know that ' < ? xml ' is here .
*/
SKIP ( 5 ) ;
if ( ! IS_BLANK ( RAW ) ) {
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Blank needed after '<?xml' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
/*
2001-11-29 16:11:38 +00:00
* We must have the VersionInfo here .
2001-02-23 17:55:21 +00:00
*/
version = xmlParseVersionInfo ( ctxt ) ;
2001-11-29 16:11:38 +00:00
if ( version = = NULL ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Malformed declaration expecting version \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-11-29 16:11:38 +00:00
} else {
if ( ! xmlStrEqual ( version , ( const xmlChar * ) XML_DEFAULT_VERSION ) ) {
/*
* TODO : Blueberry should be detected here
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > warning ! = NULL ) )
ctxt - > sax - > warning ( ctxt - > userData , " Unsupported version '%s' \n " ,
version ) ;
}
if ( ctxt - > version ! = NULL )
2001-12-05 12:03:33 +00:00
xmlFree ( ( void * ) ctxt - > version ) ;
2001-11-29 16:11:38 +00:00
ctxt - > version = version ;
2001-09-05 15:51:05 +00:00
}
2001-02-23 17:55:21 +00:00
/*
* We may have the encoding declaration
*/
if ( ! IS_BLANK ( RAW ) ) {
if ( ( RAW = = ' ? ' ) & & ( NXT ( 1 ) = = ' > ' ) ) {
SKIP ( 2 ) ;
return ;
}
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Blank needed here \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
xmlParseEncodingDecl ( ctxt ) ;
if ( ctxt - > errNo = = XML_ERR_UNSUPPORTED_ENCODING ) {
/*
* The XML REC instructs us to stop parsing right here
*/
return ;
}
/*
* We may have the standalone status .
*/
if ( ( ctxt - > input - > encoding ! = NULL ) & & ( ! IS_BLANK ( RAW ) ) ) {
if ( ( RAW = = ' ? ' ) & & ( NXT ( 1 ) = = ' > ' ) ) {
SKIP ( 2 ) ;
return ;
}
ctxt - > errNo = XML_ERR_SPACE_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Blank needed here \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
SKIP_BLANKS ;
ctxt - > input - > standalone = xmlParseSDDecl ( ctxt ) ;
SKIP_BLANKS ;
if ( ( RAW = = ' ? ' ) & & ( NXT ( 1 ) = = ' > ' ) ) {
SKIP ( 2 ) ;
} else if ( RAW = = ' > ' ) {
/* Deprecated old WD ... */
ctxt - > errNo = XML_ERR_XMLDECL_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" XML declaration must end-up with '?>' \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
NEXT ;
} else {
ctxt - > errNo = XML_ERR_XMLDECL_NOT_FINISHED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" parsing XML declaration: '?>' expected \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
MOVETO_ENDTAG ( CUR_PTR ) ;
NEXT ;
}
}
/**
* xmlParseMisc :
* @ ctxt : an XML parser context
*
2001-12-31 16:16:02 +00:00
* parse an XML Misc * optional field .
2001-02-23 17:55:21 +00:00
*
* [ 27 ] Misc : : = Comment | PI | S
*/
void
xmlParseMisc ( xmlParserCtxtPtr ctxt ) {
2002-03-20 21:55:57 +00:00
while ( ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) ) | |
( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & &
( NXT ( 2 ) = = ' - ' ) & & ( NXT ( 3 ) = = ' - ' ) ) | |
IS_BLANK ( CUR ) ) {
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) ) {
2001-02-23 17:55:21 +00:00
xmlParsePI ( ctxt ) ;
2002-03-20 21:55:57 +00:00
} else if ( IS_BLANK ( CUR ) ) {
2001-02-23 17:55:21 +00:00
NEXT ;
} else
xmlParseComment ( ctxt ) ;
}
}
/**
* xmlParseDocument :
* @ ctxt : an XML parser context
*
* parse an XML document ( and build a tree if using the standard SAX
* interface ) .
*
* [ 1 ] document : : = prolog element Misc *
*
* [ 22 ] prolog : : = XMLDecl ? Misc * ( doctypedecl Misc * ) ?
*
* Returns 0 , - 1 in case of error . the parser context is augmented
* as a result of the parsing .
*/
int
xmlParseDocument ( xmlParserCtxtPtr ctxt ) {
xmlChar start [ 4 ] ;
xmlCharEncoding enc ;
xmlInitParser ( ) ;
GROW ;
/*
* SAX : beginning of the document processing .
*/
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > setDocumentLocator ) )
ctxt - > sax - > setDocumentLocator ( ctxt - > userData , & xmlDefaultSAXLocator ) ;
2001-08-03 12:06:36 +00:00
if ( ctxt - > encoding = = ( const xmlChar * ) XML_CHAR_ENCODING_NONE ) {
2001-07-28 17:21:12 +00:00
/*
* Get the 4 first bytes and decode the charset
* if enc ! = XML_CHAR_ENCODING_NONE
* plug some encoding conversion routines .
*/
start [ 0 ] = RAW ;
start [ 1 ] = NXT ( 1 ) ;
start [ 2 ] = NXT ( 2 ) ;
start [ 3 ] = NXT ( 3 ) ;
enc = xmlDetectCharEncoding ( start , 4 ) ;
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
xmlSwitchEncoding ( ctxt , enc ) ;
}
2001-02-23 17:55:21 +00:00
}
if ( CUR = = 0 ) {
ctxt - > errNo = XML_ERR_DOCUMENT_EMPTY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Document is empty \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* Check for the XMLDecl in the Prolog .
*/
GROW ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) & &
( NXT ( 2 ) = = ' x ' ) & & ( NXT ( 3 ) = = ' m ' ) & &
( NXT ( 4 ) = = ' l ' ) & & ( IS_BLANK ( NXT ( 5 ) ) ) ) {
/*
* Note that we will switch encoding on the fly .
*/
xmlParseXMLDecl ( ctxt ) ;
if ( ctxt - > errNo = = XML_ERR_UNSUPPORTED_ENCODING ) {
/*
* The XML REC instructs us to stop parsing right here
*/
return ( - 1 ) ;
}
ctxt - > standalone = ctxt - > input - > standalone ;
SKIP_BLANKS ;
} else {
ctxt - > version = xmlCharStrdup ( XML_DEFAULT_VERSION ) ;
}
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > startDocument ) & & ( ! ctxt - > disableSAX ) )
ctxt - > sax - > startDocument ( ctxt - > userData ) ;
/*
* The Misc part of the Prolog
*/
GROW ;
xmlParseMisc ( ctxt ) ;
/*
* Then possibly doc type declaration ( s ) and more Misc
* ( doctypedecl Misc * ) ?
*/
GROW ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ! ' ) & &
( NXT ( 2 ) = = ' D ' ) & & ( NXT ( 3 ) = = ' O ' ) & &
( NXT ( 4 ) = = ' C ' ) & & ( NXT ( 5 ) = = ' T ' ) & &
( NXT ( 6 ) = = ' Y ' ) & & ( NXT ( 7 ) = = ' P ' ) & &
( NXT ( 8 ) = = ' E ' ) ) {
ctxt - > inSubset = 1 ;
xmlParseDocTypeDecl ( ctxt ) ;
if ( RAW = = ' [ ' ) {
ctxt - > instate = XML_PARSER_DTD ;
xmlParseInternalSubset ( ctxt ) ;
}
/*
* Create and update the external subset .
*/
ctxt - > inSubset = 2 ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > externalSubset ! = NULL ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > externalSubset ( ctxt - > userData , ctxt - > intSubName ,
ctxt - > extSubSystem , ctxt - > extSubURI ) ;
ctxt - > inSubset = 0 ;
ctxt - > instate = XML_PARSER_PROLOG ;
xmlParseMisc ( ctxt ) ;
}
/*
* Time to start parsing the tree itself
*/
GROW ;
if ( RAW ! = ' < ' ) {
ctxt - > errNo = XML_ERR_DOCUMENT_EMPTY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Start tag expected, '<' not found \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
ctxt - > instate = XML_PARSER_EOF ;
} else {
ctxt - > instate = XML_PARSER_CONTENT ;
xmlParseElement ( ctxt ) ;
ctxt - > instate = XML_PARSER_EPILOG ;
/*
* The Misc part at the end
*/
xmlParseMisc ( ctxt ) ;
2002-03-20 21:55:57 +00:00
if ( RAW ! = 0 ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_DOCUMENT_END ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Extra content at the end of the document \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
ctxt - > instate = XML_PARSER_EOF ;
}
/*
* SAX : end of the document processing .
*/
2002-03-05 15:41:29 +00:00
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > endDocument ! = NULL ) )
2001-02-23 17:55:21 +00:00
ctxt - > sax - > endDocument ( ctxt - > userData ) ;
2002-03-18 18:36:20 +00:00
/*
* Remove locally kept entity definitions if the tree was not built
*/
if ( ( ctxt - > myDoc ! = NULL ) & &
( xmlStrEqual ( ctxt - > myDoc - > version , SAX_COMPAT_MODE ) ) ) {
xmlFreeDoc ( ctxt - > myDoc ) ;
ctxt - > myDoc = NULL ;
}
2002-02-17 22:47:37 +00:00
if ( ! ctxt - > wellFormed ) {
ctxt - > valid = 0 ;
return ( - 1 ) ;
}
2001-02-23 17:55:21 +00:00
return ( 0 ) ;
}
/**
* xmlParseExtParsedEnt :
* @ ctxt : an XML parser context
*
2001-12-31 16:16:02 +00:00
* parse a general parsed entity
2001-02-23 17:55:21 +00:00
* An external general parsed entity is well - formed if it matches the
* production labeled extParsedEnt .
*
* [ 78 ] extParsedEnt : : = TextDecl ? content
*
* Returns 0 , - 1 in case of error . the parser context is augmented
* as a result of the parsing .
*/
int
xmlParseExtParsedEnt ( xmlParserCtxtPtr ctxt ) {
xmlChar start [ 4 ] ;
xmlCharEncoding enc ;
xmlDefaultSAXHandlerInit ( ) ;
GROW ;
/*
* SAX : beginning of the document processing .
*/
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > setDocumentLocator ) )
ctxt - > sax - > setDocumentLocator ( ctxt - > userData , & xmlDefaultSAXLocator ) ;
/*
* Get the 4 first bytes and decode the charset
* if enc ! = XML_CHAR_ENCODING_NONE
* plug some encoding conversion routines .
*/
start [ 0 ] = RAW ;
start [ 1 ] = NXT ( 1 ) ;
start [ 2 ] = NXT ( 2 ) ;
start [ 3 ] = NXT ( 3 ) ;
enc = xmlDetectCharEncoding ( start , 4 ) ;
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
xmlSwitchEncoding ( ctxt , enc ) ;
}
if ( CUR = = 0 ) {
ctxt - > errNo = XML_ERR_DOCUMENT_EMPTY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Document is empty \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* Check for the XMLDecl in the Prolog .
*/
GROW ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) & &
( NXT ( 2 ) = = ' x ' ) & & ( NXT ( 3 ) = = ' m ' ) & &
( NXT ( 4 ) = = ' l ' ) & & ( IS_BLANK ( NXT ( 5 ) ) ) ) {
/*
* Note that we will switch encoding on the fly .
*/
xmlParseXMLDecl ( ctxt ) ;
if ( ctxt - > errNo = = XML_ERR_UNSUPPORTED_ENCODING ) {
/*
* The XML REC instructs us to stop parsing right here
*/
return ( - 1 ) ;
}
SKIP_BLANKS ;
} else {
ctxt - > version = xmlCharStrdup ( XML_DEFAULT_VERSION ) ;
}
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > startDocument ) & & ( ! ctxt - > disableSAX ) )
ctxt - > sax - > startDocument ( ctxt - > userData ) ;
/*
* Doing validity checking on chunk doesn ' t make sense
*/
ctxt - > instate = XML_PARSER_CONTENT ;
ctxt - > validate = 0 ;
ctxt - > loadsubset = 0 ;
ctxt - > depth = 0 ;
xmlParseContent ( ctxt ) ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' / ' ) ) {
ctxt - > errNo = XML_ERR_NOT_WELL_BALANCED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" chunk is not well balanced \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else if ( RAW ! = 0 ) {
ctxt - > errNo = XML_ERR_EXTRA_CONTENT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" extra content at the end of well balanced chunk \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
/*
* SAX : end of the document processing .
*/
2002-03-05 15:41:29 +00:00
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > endDocument ! = NULL ) )
2001-02-23 17:55:21 +00:00
ctxt - > sax - > endDocument ( ctxt - > userData ) ;
if ( ! ctxt - > wellFormed ) return ( - 1 ) ;
return ( 0 ) ;
}
/************************************************************************
* *
* Progressive parsing interfaces *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlParseLookupSequence :
* @ ctxt : an XML parser context
* @ first : the first char to lookup
* @ next : the next char to lookup or zero
* @ third : the next char to lookup or zero
*
* Try to find if a sequence ( first , next , third ) or just ( first next ) or
* ( first ) is available in the input stream .
* This function has a side effect of ( possibly ) incrementing ctxt - > checkIndex
* to avoid rescanning sequences of bytes , it DOES change the state of the
* parser , do not use liberally .
*
* Returns the index to the current parsing point if the full sequence
* is available , - 1 otherwise .
*/
2001-03-24 17:00:36 +00:00
static int
2001-02-23 17:55:21 +00:00
xmlParseLookupSequence ( xmlParserCtxtPtr ctxt , xmlChar first ,
xmlChar next , xmlChar third ) {
int base , len ;
xmlParserInputPtr in ;
const xmlChar * buf ;
in = ctxt - > input ;
if ( in = = NULL ) return ( - 1 ) ;
base = in - > cur - in - > base ;
if ( base < 0 ) return ( - 1 ) ;
if ( ctxt - > checkIndex > base )
base = ctxt - > checkIndex ;
if ( in - > buf = = NULL ) {
buf = in - > base ;
len = in - > length ;
} else {
buf = in - > buf - > buffer - > content ;
len = in - > buf - > buffer - > use ;
}
/* take into account the sequence length */
if ( third ) len - = 2 ;
else if ( next ) len - - ;
for ( ; base < len ; base + + ) {
if ( buf [ base ] = = first ) {
if ( third ! = 0 ) {
if ( ( buf [ base + 1 ] ! = next ) | |
( buf [ base + 2 ] ! = third ) ) continue ;
} else if ( next ! = 0 ) {
if ( buf [ base + 1 ] ! = next ) continue ;
}
ctxt - > checkIndex = 0 ;
# ifdef DEBUG_PUSH
if ( next = = 0 )
xmlGenericError ( xmlGenericErrorContext ,
" PP: lookup '%c' found at %d \n " ,
first , base ) ;
else if ( third = = 0 )
xmlGenericError ( xmlGenericErrorContext ,
" PP: lookup '%c%c' found at %d \n " ,
first , next , base ) ;
else
xmlGenericError ( xmlGenericErrorContext ,
" PP: lookup '%c%c%c' found at %d \n " ,
first , next , third , base ) ;
# endif
return ( base - ( in - > cur - in - > base ) ) ;
}
}
ctxt - > checkIndex = base ;
# ifdef DEBUG_PUSH
if ( next = = 0 )
xmlGenericError ( xmlGenericErrorContext ,
" PP: lookup '%c' failed \n " , first ) ;
else if ( third = = 0 )
xmlGenericError ( xmlGenericErrorContext ,
" PP: lookup '%c%c' failed \n " , first , next ) ;
else
xmlGenericError ( xmlGenericErrorContext ,
" PP: lookup '%c%c%c' failed \n " , first , next , third ) ;
# endif
return ( - 1 ) ;
}
/**
* xmlParseTryOrFinish :
* @ ctxt : an XML parser context
* @ terminate : last chunk indicator
*
* Try to progress on parsing
*
* Returns zero if no parsing was possible
*/
2001-03-24 17:00:36 +00:00
static int
2001-02-23 17:55:21 +00:00
xmlParseTryOrFinish ( xmlParserCtxtPtr ctxt , int terminate ) {
int ret = 0 ;
int avail ;
xmlChar cur , next ;
# ifdef DEBUG_PUSH
switch ( ctxt - > instate ) {
case XML_PARSER_EOF :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try EOF \n " ) ; break ;
case XML_PARSER_START :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try START \n " ) ; break ;
case XML_PARSER_MISC :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try MISC \n " ) ; break ;
case XML_PARSER_COMMENT :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try COMMENT \n " ) ; break ;
case XML_PARSER_PROLOG :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try PROLOG \n " ) ; break ;
case XML_PARSER_START_TAG :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try START_TAG \n " ) ; break ;
case XML_PARSER_CONTENT :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try CONTENT \n " ) ; break ;
case XML_PARSER_CDATA_SECTION :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try CDATA_SECTION \n " ) ; break ;
case XML_PARSER_END_TAG :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try END_TAG \n " ) ; break ;
case XML_PARSER_ENTITY_DECL :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try ENTITY_DECL \n " ) ; break ;
case XML_PARSER_ENTITY_VALUE :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try ENTITY_VALUE \n " ) ; break ;
case XML_PARSER_ATTRIBUTE_VALUE :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try ATTRIBUTE_VALUE \n " ) ; break ;
case XML_PARSER_DTD :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try DTD \n " ) ; break ;
case XML_PARSER_EPILOG :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try EPILOG \n " ) ; break ;
case XML_PARSER_PI :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try PI \n " ) ; break ;
case XML_PARSER_IGNORE :
xmlGenericError ( xmlGenericErrorContext ,
" PP: try IGNORE \n " ) ; break ;
}
# endif
while ( 1 ) {
2002-05-09 18:20:01 +00:00
SHRINK ;
2001-02-23 17:55:21 +00:00
/*
* Pop - up of finished entities .
*/
while ( ( RAW = = 0 ) & & ( ctxt - > inputNr > 1 ) )
xmlPopInput ( ctxt ) ;
if ( ctxt - > input = = NULL ) break ;
if ( ctxt - > input - > buf = = NULL )
avail = ctxt - > input - > length - ( ctxt - > input - > cur - ctxt - > input - > base ) ;
2002-02-20 22:17:58 +00:00
else {
/*
* If we are operating on converted input , try to flush
* remainng chars to avoid them stalling in the non - converted
* buffer .
*/
if ( ( ctxt - > input - > buf - > raw ! = NULL ) & &
( ctxt - > input - > buf - > raw - > use > 0 ) ) {
int base = ctxt - > input - > base -
ctxt - > input - > buf - > buffer - > content ;
int current = ctxt - > input - > cur - ctxt - > input - > base ;
xmlParserInputBufferPush ( ctxt - > input - > buf , 0 , " " ) ;
ctxt - > input - > base = ctxt - > input - > buf - > buffer - > content + base ;
ctxt - > input - > cur = ctxt - > input - > base + current ;
ctxt - > input - > end =
& ctxt - > input - > buf - > buffer - > content [
ctxt - > input - > buf - > buffer - > use ] ;
}
avail = ctxt - > input - > buf - > buffer - > use -
( ctxt - > input - > cur - ctxt - > input - > base ) ;
}
2001-02-23 17:55:21 +00:00
if ( avail < 1 )
goto done ;
switch ( ctxt - > instate ) {
case XML_PARSER_EOF :
/*
* Document parsing is done !
*/
goto done ;
case XML_PARSER_START :
2001-06-28 12:13:56 +00:00
if ( ctxt - > charset = = XML_CHAR_ENCODING_NONE ) {
xmlChar start [ 4 ] ;
xmlCharEncoding enc ;
/*
* Very first chars read from the document flow .
*/
if ( avail < 4 )
goto done ;
/*
* Get the 4 first bytes and decode the charset
* if enc ! = XML_CHAR_ENCODING_NONE
* plug some encoding conversion routines .
*/
start [ 0 ] = RAW ;
start [ 1 ] = NXT ( 1 ) ;
start [ 2 ] = NXT ( 2 ) ;
start [ 3 ] = NXT ( 3 ) ;
enc = xmlDetectCharEncoding ( start , 4 ) ;
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
xmlSwitchEncoding ( ctxt , enc ) ;
}
break ;
}
2001-02-23 17:55:21 +00:00
cur = ctxt - > input - > cur [ 0 ] ;
next = ctxt - > input - > cur [ 1 ] ;
if ( cur = = 0 ) {
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > setDocumentLocator ) )
ctxt - > sax - > setDocumentLocator ( ctxt - > userData ,
& xmlDefaultSAXLocator ) ;
ctxt - > errNo = XML_ERR_DOCUMENT_EMPTY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData , " Document is empty \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
ctxt - > instate = XML_PARSER_EOF ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering EOF \n " ) ;
# endif
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > endDocument ! = NULL ) )
ctxt - > sax - > endDocument ( ctxt - > userData ) ;
goto done ;
}
if ( ( cur = = ' < ' ) & & ( next = = ' ? ' ) ) {
/* PI or XML decl */
if ( avail < 5 ) return ( ret ) ;
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' ? ' , ' > ' , 0 ) < 0 ) )
return ( ret ) ;
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > setDocumentLocator ) )
ctxt - > sax - > setDocumentLocator ( ctxt - > userData ,
& xmlDefaultSAXLocator ) ;
if ( ( ctxt - > input - > cur [ 2 ] = = ' x ' ) & &
( ctxt - > input - > cur [ 3 ] = = ' m ' ) & &
( ctxt - > input - > cur [ 4 ] = = ' l ' ) & &
( IS_BLANK ( ctxt - > input - > cur [ 5 ] ) ) ) {
ret + = 5 ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing XML Decl \n " ) ;
# endif
xmlParseXMLDecl ( ctxt ) ;
if ( ctxt - > errNo = = XML_ERR_UNSUPPORTED_ENCODING ) {
/*
* The XML REC instructs us to stop parsing right
* here
*/
ctxt - > instate = XML_PARSER_EOF ;
return ( 0 ) ;
}
ctxt - > standalone = ctxt - > input - > standalone ;
if ( ( ctxt - > encoding = = NULL ) & &
( ctxt - > input - > encoding ! = NULL ) )
ctxt - > encoding = xmlStrdup ( ctxt - > input - > encoding ) ;
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > startDocument ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > startDocument ( ctxt - > userData ) ;
ctxt - > instate = XML_PARSER_MISC ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering MISC \n " ) ;
# endif
} else {
ctxt - > version = xmlCharStrdup ( XML_DEFAULT_VERSION ) ;
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > startDocument ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > startDocument ( ctxt - > userData ) ;
ctxt - > instate = XML_PARSER_MISC ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering MISC \n " ) ;
# endif
}
} else {
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > setDocumentLocator ) )
ctxt - > sax - > setDocumentLocator ( ctxt - > userData ,
& xmlDefaultSAXLocator ) ;
ctxt - > version = xmlCharStrdup ( XML_DEFAULT_VERSION ) ;
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > startDocument ) & &
( ! ctxt - > disableSAX ) )
ctxt - > sax - > startDocument ( ctxt - > userData ) ;
ctxt - > instate = XML_PARSER_MISC ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering MISC \n " ) ;
# endif
}
break ;
case XML_PARSER_MISC :
SKIP_BLANKS ;
if ( ctxt - > input - > buf = = NULL )
avail = ctxt - > input - > length - ( ctxt - > input - > cur - ctxt - > input - > base ) ;
else
avail = ctxt - > input - > buf - > buffer - > use - ( ctxt - > input - > cur - ctxt - > input - > base ) ;
if ( avail < 2 )
goto done ;
cur = ctxt - > input - > cur [ 0 ] ;
next = ctxt - > input - > cur [ 1 ] ;
if ( ( cur = = ' < ' ) & & ( next = = ' ? ' ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' ? ' , ' > ' , 0 ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing PI \n " ) ;
# endif
xmlParsePI ( ctxt ) ;
} else if ( ( cur = = ' < ' ) & & ( next = = ' ! ' ) & &
( ctxt - > input - > cur [ 2 ] = = ' - ' ) & & ( ctxt - > input - > cur [ 3 ] = = ' - ' ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' - ' , ' - ' , ' > ' ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing Comment \n " ) ;
# endif
xmlParseComment ( ctxt ) ;
ctxt - > instate = XML_PARSER_MISC ;
} else if ( ( cur = = ' < ' ) & & ( next = = ' ! ' ) & &
( ctxt - > input - > cur [ 2 ] = = ' D ' ) & & ( ctxt - > input - > cur [ 3 ] = = ' O ' ) & &
( ctxt - > input - > cur [ 4 ] = = ' C ' ) & & ( ctxt - > input - > cur [ 5 ] = = ' T ' ) & &
( ctxt - > input - > cur [ 6 ] = = ' Y ' ) & & ( ctxt - > input - > cur [ 7 ] = = ' P ' ) & &
( ctxt - > input - > cur [ 8 ] = = ' E ' ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' > ' , 0 , 0 ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing internal subset \n " ) ;
# endif
ctxt - > inSubset = 1 ;
xmlParseDocTypeDecl ( ctxt ) ;
if ( RAW = = ' [ ' ) {
ctxt - > instate = XML_PARSER_DTD ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering DTD \n " ) ;
# endif
} else {
/*
* Create and update the external subset .
*/
ctxt - > inSubset = 2 ;
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > externalSubset ! = NULL ) )
ctxt - > sax - > externalSubset ( ctxt - > userData ,
ctxt - > intSubName , ctxt - > extSubSystem ,
ctxt - > extSubURI ) ;
ctxt - > inSubset = 0 ;
ctxt - > instate = XML_PARSER_PROLOG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering PROLOG \n " ) ;
# endif
}
} else if ( ( cur = = ' < ' ) & & ( next = = ' ! ' ) & &
( avail < 9 ) ) {
goto done ;
} else {
ctxt - > instate = XML_PARSER_START_TAG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering START_TAG \n " ) ;
# endif
}
break ;
case XML_PARSER_IGNORE :
xmlGenericError ( xmlGenericErrorContext ,
" PP: internal error, state == IGNORE " ) ;
ctxt - > instate = XML_PARSER_DTD ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering DTD \n " ) ;
# endif
break ;
case XML_PARSER_PROLOG :
SKIP_BLANKS ;
if ( ctxt - > input - > buf = = NULL )
avail = ctxt - > input - > length - ( ctxt - > input - > cur - ctxt - > input - > base ) ;
else
avail = ctxt - > input - > buf - > buffer - > use - ( ctxt - > input - > cur - ctxt - > input - > base ) ;
if ( avail < 2 )
goto done ;
cur = ctxt - > input - > cur [ 0 ] ;
next = ctxt - > input - > cur [ 1 ] ;
if ( ( cur = = ' < ' ) & & ( next = = ' ? ' ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' ? ' , ' > ' , 0 ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing PI \n " ) ;
# endif
xmlParsePI ( ctxt ) ;
} else if ( ( cur = = ' < ' ) & & ( next = = ' ! ' ) & &
( ctxt - > input - > cur [ 2 ] = = ' - ' ) & & ( ctxt - > input - > cur [ 3 ] = = ' - ' ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' - ' , ' - ' , ' > ' ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing Comment \n " ) ;
# endif
xmlParseComment ( ctxt ) ;
ctxt - > instate = XML_PARSER_PROLOG ;
} else if ( ( cur = = ' < ' ) & & ( next = = ' ! ' ) & &
( avail < 4 ) ) {
goto done ;
} else {
ctxt - > instate = XML_PARSER_START_TAG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering START_TAG \n " ) ;
# endif
}
break ;
case XML_PARSER_EPILOG :
SKIP_BLANKS ;
if ( ctxt - > input - > buf = = NULL )
avail = ctxt - > input - > length - ( ctxt - > input - > cur - ctxt - > input - > base ) ;
else
avail = ctxt - > input - > buf - > buffer - > use - ( ctxt - > input - > cur - ctxt - > input - > base ) ;
if ( avail < 2 )
goto done ;
cur = ctxt - > input - > cur [ 0 ] ;
next = ctxt - > input - > cur [ 1 ] ;
if ( ( cur = = ' < ' ) & & ( next = = ' ? ' ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' ? ' , ' > ' , 0 ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing PI \n " ) ;
# endif
xmlParsePI ( ctxt ) ;
ctxt - > instate = XML_PARSER_EPILOG ;
} else if ( ( cur = = ' < ' ) & & ( next = = ' ! ' ) & &
( ctxt - > input - > cur [ 2 ] = = ' - ' ) & & ( ctxt - > input - > cur [ 3 ] = = ' - ' ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' - ' , ' - ' , ' > ' ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing Comment \n " ) ;
# endif
xmlParseComment ( ctxt ) ;
ctxt - > instate = XML_PARSER_EPILOG ;
} else if ( ( cur = = ' < ' ) & & ( next = = ' ! ' ) & &
( avail < 4 ) ) {
goto done ;
} else {
ctxt - > errNo = XML_ERR_DOCUMENT_END ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Extra content at the end of the document \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
ctxt - > instate = XML_PARSER_EOF ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering EOF \n " ) ;
# endif
2002-03-05 15:41:29 +00:00
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > endDocument ! = NULL ) )
2001-02-23 17:55:21 +00:00
ctxt - > sax - > endDocument ( ctxt - > userData ) ;
goto done ;
}
break ;
case XML_PARSER_START_TAG : {
xmlChar * name , * oldname ;
if ( ( avail < 2 ) & & ( ctxt - > inputNr = = 1 ) )
goto done ;
cur = ctxt - > input - > cur [ 0 ] ;
if ( cur ! = ' < ' ) {
ctxt - > errNo = XML_ERR_DOCUMENT_EMPTY ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Start tag expect, '<' not found \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
ctxt - > instate = XML_PARSER_EOF ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering EOF \n " ) ;
# endif
2002-03-05 15:41:29 +00:00
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > endDocument ! = NULL ) )
2001-02-23 17:55:21 +00:00
ctxt - > sax - > endDocument ( ctxt - > userData ) ;
goto done ;
}
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' > ' , 0 , 0 ) < 0 ) )
goto done ;
if ( ctxt - > spaceNr = = 0 )
spacePush ( ctxt , - 1 ) ;
else
spacePush ( ctxt , * ctxt - > space ) ;
name = xmlParseStartTag ( ctxt ) ;
if ( name = = NULL ) {
spacePop ( ctxt ) ;
ctxt - > instate = XML_PARSER_EOF ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering EOF \n " ) ;
# endif
2002-03-05 15:41:29 +00:00
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > endDocument ! = NULL ) )
2001-02-23 17:55:21 +00:00
ctxt - > sax - > endDocument ( ctxt - > userData ) ;
goto done ;
}
namePush ( ctxt , xmlStrdup ( name ) ) ;
/*
* [ VC : Root Element Type ]
* The Name in the document type declaration must match
* the element type of the root element .
*/
if ( ctxt - > validate & & ctxt - > wellFormed & & ctxt - > myDoc & &
ctxt - > node & & ( ctxt - > node = = ctxt - > myDoc - > children ) )
ctxt - > valid & = xmlValidateRoot ( & ctxt - > vctxt , ctxt - > myDoc ) ;
/*
* Check for an Empty Element .
*/
if ( ( RAW = = ' / ' ) & & ( NXT ( 1 ) = = ' > ' ) ) {
SKIP ( 2 ) ;
if ( ( ctxt - > sax ! = NULL ) & &
( ctxt - > sax - > endElement ! = NULL ) & & ( ! ctxt - > disableSAX ) )
ctxt - > sax - > endElement ( ctxt - > userData , name ) ;
xmlFree ( name ) ;
oldname = namePop ( ctxt ) ;
spacePop ( ctxt ) ;
if ( oldname ! = NULL ) {
# ifdef DEBUG_STACK
xmlGenericError ( xmlGenericErrorContext , " Close: popped %s \n " , oldname ) ;
# endif
xmlFree ( oldname ) ;
}
if ( ctxt - > name = = NULL ) {
ctxt - > instate = XML_PARSER_EPILOG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering EPILOG \n " ) ;
# endif
} else {
ctxt - > instate = XML_PARSER_CONTENT ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering CONTENT \n " ) ;
# endif
}
break ;
}
if ( RAW = = ' > ' ) {
NEXT ;
} else {
ctxt - > errNo = XML_ERR_GT_REQUIRED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Couldn't find end of Start Tag %s \n " ,
name ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
/*
* end of parsing of this node .
*/
nodePop ( ctxt ) ;
oldname = namePop ( ctxt ) ;
spacePop ( ctxt ) ;
if ( oldname ! = NULL ) {
# ifdef DEBUG_STACK
xmlGenericError ( xmlGenericErrorContext , " Close: popped %s \n " , oldname ) ;
# endif
xmlFree ( oldname ) ;
}
}
xmlFree ( name ) ;
ctxt - > instate = XML_PARSER_CONTENT ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering CONTENT \n " ) ;
# endif
break ;
}
case XML_PARSER_CONTENT : {
const xmlChar * test ;
int cons ;
if ( ( avail < 2 ) & & ( ctxt - > inputNr = = 1 ) )
goto done ;
cur = ctxt - > input - > cur [ 0 ] ;
next = ctxt - > input - > cur [ 1 ] ;
test = CUR_PTR ;
cons = ctxt - > input - > consumed ;
if ( ( cur = = ' < ' ) & & ( next = = ' ? ' ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' ? ' , ' > ' , 0 ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing PI \n " ) ;
# endif
xmlParsePI ( ctxt ) ;
} else if ( ( cur = = ' < ' ) & & ( next = = ' ! ' ) & &
( ctxt - > input - > cur [ 2 ] = = ' - ' ) & & ( ctxt - > input - > cur [ 3 ] = = ' - ' ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' - ' , ' - ' , ' > ' ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing Comment \n " ) ;
# endif
xmlParseComment ( ctxt ) ;
ctxt - > instate = XML_PARSER_CONTENT ;
} else if ( ( cur = = ' < ' ) & & ( ctxt - > input - > cur [ 1 ] = = ' ! ' ) & &
( ctxt - > input - > cur [ 2 ] = = ' [ ' ) & & ( NXT ( 3 ) = = ' C ' ) & &
( ctxt - > input - > cur [ 4 ] = = ' D ' ) & & ( NXT ( 5 ) = = ' A ' ) & &
( ctxt - > input - > cur [ 6 ] = = ' T ' ) & & ( NXT ( 7 ) = = ' A ' ) & &
( ctxt - > input - > cur [ 8 ] = = ' [ ' ) ) {
SKIP ( 9 ) ;
ctxt - > instate = XML_PARSER_CDATA_SECTION ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering CDATA_SECTION \n " ) ;
# endif
break ;
} else if ( ( cur = = ' < ' ) & & ( next = = ' ! ' ) & &
( avail < 9 ) ) {
goto done ;
} else if ( ( cur = = ' < ' ) & & ( next = = ' / ' ) ) {
ctxt - > instate = XML_PARSER_END_TAG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering END_TAG \n " ) ;
# endif
break ;
} else if ( cur = = ' < ' ) {
ctxt - > instate = XML_PARSER_START_TAG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering START_TAG \n " ) ;
# endif
break ;
} else if ( cur = = ' & ' ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' ; ' , 0 , 0 ) < 0 ) )
goto done ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing Reference \n " ) ;
# endif
xmlParseReference ( ctxt ) ;
} else {
/* TODO Avoid the extra copy, handle directly !!! */
/*
* Goal of the following test is :
* - minimize calls to the SAX ' character ' callback
* when they are mergeable
* - handle an problem for isBlank when we only parse
* a sequence of blank chars and the next one is
* not available to check against ' < ' presence .
* - tries to homogenize the differences in SAX
2001-12-31 16:16:02 +00:00
* callbacks between the push and pull versions
2001-02-23 17:55:21 +00:00
* of the parser .
*/
if ( ( ctxt - > inputNr = = 1 ) & &
( avail < XML_PARSER_BIG_BUFFER_SIZE ) ) {
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' < ' , 0 , 0 ) < 0 ) )
goto done ;
}
ctxt - > checkIndex = 0 ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: Parsing char data \n " ) ;
# endif
xmlParseCharData ( ctxt , 0 ) ;
}
/*
* Pop - up of finished entities .
*/
while ( ( RAW = = 0 ) & & ( ctxt - > inputNr > 1 ) )
xmlPopInput ( ctxt ) ;
2002-07-01 21:52:03 +00:00
if ( ( cons = = ctxt - > input - > consumed ) & & ( test = = CUR_PTR ) ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_INTERNAL_ERROR ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" detected an error in element content \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
ctxt - > instate = XML_PARSER_EOF ;
break ;
}
break ;
}
case XML_PARSER_CDATA_SECTION : {
/*
* The Push mode need to have the SAX callback for
* cdataBlock merge back contiguous callbacks .
*/
int base ;
base = xmlParseLookupSequence ( ctxt , ' ] ' , ' ] ' , ' > ' ) ;
if ( base < 0 ) {
if ( avail > = XML_PARSER_BIG_BUFFER_SIZE + 2 ) {
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) ) {
if ( ctxt - > sax - > cdataBlock ! = NULL )
ctxt - > sax - > cdataBlock ( ctxt - > userData , ctxt - > input - > cur ,
XML_PARSER_BIG_BUFFER_SIZE ) ;
}
SKIP ( XML_PARSER_BIG_BUFFER_SIZE ) ;
ctxt - > checkIndex = 0 ;
}
goto done ;
} else {
if ( ( ctxt - > sax ! = NULL ) & & ( base > 0 ) & &
( ! ctxt - > disableSAX ) ) {
if ( ctxt - > sax - > cdataBlock ! = NULL )
ctxt - > sax - > cdataBlock ( ctxt - > userData ,
ctxt - > input - > cur , base ) ;
}
SKIP ( base + 3 ) ;
ctxt - > checkIndex = 0 ;
ctxt - > instate = XML_PARSER_CONTENT ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering CONTENT \n " ) ;
# endif
}
break ;
}
case XML_PARSER_END_TAG :
if ( avail < 2 )
goto done ;
if ( ( ! terminate ) & &
( xmlParseLookupSequence ( ctxt , ' > ' , 0 , 0 ) < 0 ) )
goto done ;
xmlParseEndTag ( ctxt ) ;
if ( ctxt - > name = = NULL ) {
ctxt - > instate = XML_PARSER_EPILOG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering EPILOG \n " ) ;
# endif
} else {
ctxt - > instate = XML_PARSER_CONTENT ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering CONTENT \n " ) ;
# endif
}
break ;
case XML_PARSER_DTD : {
/*
* Sorry but progressive parsing of the internal subset
* is not expected to be supported . We first check that
* the full content of the internal subset is available and
* the parsing is launched only at that point .
* Internal subset ends up with " ']' S? '>' " in an unescaped
* section and not in a ' ] ] > ' sequence which are conditional
* sections ( whoever argued to keep that crap in XML deserve
* a place in hell ! ) .
*/
int base , i ;
xmlChar * buf ;
xmlChar quote = 0 ;
base = ctxt - > input - > cur - ctxt - > input - > base ;
if ( base < 0 ) return ( 0 ) ;
if ( ctxt - > checkIndex > base )
base = ctxt - > checkIndex ;
buf = ctxt - > input - > buf - > buffer - > content ;
for ( ; ( unsigned int ) base < ctxt - > input - > buf - > buffer - > use ;
base + + ) {
if ( quote ! = 0 ) {
if ( buf [ base ] = = quote )
quote = 0 ;
continue ;
}
if ( buf [ base ] = = ' " ' ) {
quote = ' " ' ;
continue ;
}
if ( buf [ base ] = = ' \' ' ) {
quote = ' \' ' ;
continue ;
}
if ( buf [ base ] = = ' ] ' ) {
if ( ( unsigned int ) base + 1 > =
ctxt - > input - > buf - > buffer - > use )
break ;
if ( buf [ base + 1 ] = = ' ] ' ) {
/* conditional crap, skip both ']' ! */
base + + ;
continue ;
}
for ( i = 0 ;
( unsigned int ) base + i < ctxt - > input - > buf - > buffer - > use ;
i + + ) {
if ( buf [ base + i ] = = ' > ' )
goto found_end_int_subset ;
}
break ;
}
}
/*
* We didn ' t found the end of the Internal subset
*/
if ( quote = = 0 )
ctxt - > checkIndex = base ;
# ifdef DEBUG_PUSH
if ( next = = 0 )
xmlGenericError ( xmlGenericErrorContext ,
" PP: lookup of int subset end filed \n " ) ;
# endif
goto done ;
found_end_int_subset :
xmlParseInternalSubset ( ctxt ) ;
ctxt - > inSubset = 2 ;
if ( ( ctxt - > sax ! = NULL ) & & ( ! ctxt - > disableSAX ) & &
( ctxt - > sax - > externalSubset ! = NULL ) )
ctxt - > sax - > externalSubset ( ctxt - > userData , ctxt - > intSubName ,
ctxt - > extSubSystem , ctxt - > extSubURI ) ;
ctxt - > inSubset = 0 ;
ctxt - > instate = XML_PARSER_PROLOG ;
ctxt - > checkIndex = 0 ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering PROLOG \n " ) ;
# endif
break ;
}
case XML_PARSER_COMMENT :
xmlGenericError ( xmlGenericErrorContext ,
" PP: internal error, state == COMMENT \n " ) ;
ctxt - > instate = XML_PARSER_CONTENT ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering CONTENT \n " ) ;
# endif
break ;
case XML_PARSER_PI :
xmlGenericError ( xmlGenericErrorContext ,
" PP: internal error, state == PI \n " ) ;
ctxt - > instate = XML_PARSER_CONTENT ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering CONTENT \n " ) ;
# endif
break ;
case XML_PARSER_ENTITY_DECL :
xmlGenericError ( xmlGenericErrorContext ,
" PP: internal error, state == ENTITY_DECL \n " ) ;
ctxt - > instate = XML_PARSER_DTD ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering DTD \n " ) ;
# endif
break ;
case XML_PARSER_ENTITY_VALUE :
xmlGenericError ( xmlGenericErrorContext ,
" PP: internal error, state == ENTITY_VALUE \n " ) ;
ctxt - > instate = XML_PARSER_CONTENT ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering DTD \n " ) ;
# endif
break ;
case XML_PARSER_ATTRIBUTE_VALUE :
xmlGenericError ( xmlGenericErrorContext ,
" PP: internal error, state == ATTRIBUTE_VALUE \n " ) ;
ctxt - > instate = XML_PARSER_START_TAG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering START_TAG \n " ) ;
# endif
break ;
case XML_PARSER_SYSTEM_LITERAL :
xmlGenericError ( xmlGenericErrorContext ,
" PP: internal error, state == SYSTEM_LITERAL \n " ) ;
ctxt - > instate = XML_PARSER_START_TAG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering START_TAG \n " ) ;
2002-02-18 19:18:17 +00:00
# endif
break ;
case XML_PARSER_PUBLIC_LITERAL :
xmlGenericError ( xmlGenericErrorContext ,
" PP: internal error, state == PUBLIC_LITERAL \n " ) ;
ctxt - > instate = XML_PARSER_START_TAG ;
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext ,
" PP: entering START_TAG \n " ) ;
2001-02-23 17:55:21 +00:00
# endif
break ;
}
}
done :
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext , " PP: done %d \n " , ret ) ;
# endif
return ( ret ) ;
}
/**
* xmlParseChunk :
* @ ctxt : an XML parser context
* @ chunk : an char array
* @ size : the size in byte of the chunk
* @ terminate : last chunk indicator
*
* Parse a Chunk of memory
*
* Returns zero if no error , the xmlParserErrors otherwise .
*/
int
xmlParseChunk ( xmlParserCtxtPtr ctxt , const char * chunk , int size ,
int terminate ) {
if ( ( size > 0 ) & & ( chunk ! = NULL ) & & ( ctxt - > input ! = NULL ) & &
( ctxt - > input - > buf ! = NULL ) & & ( ctxt - > instate ! = XML_PARSER_EOF ) ) {
int base = ctxt - > input - > base - ctxt - > input - > buf - > buffer - > content ;
int cur = ctxt - > input - > cur - ctxt - > input - > base ;
xmlParserInputBufferPush ( ctxt - > input - > buf , size , chunk ) ;
ctxt - > input - > base = ctxt - > input - > buf - > buffer - > content + base ;
ctxt - > input - > cur = ctxt - > input - > base + cur ;
2001-02-25 16:11:03 +00:00
ctxt - > input - > end =
& ctxt - > input - > buf - > buffer - > content [ ctxt - > input - > buf - > buffer - > use ] ;
2001-02-23 17:55:21 +00:00
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext , " PP: pushed %d \n " , size ) ;
# endif
if ( ( terminate ) | | ( ctxt - > input - > buf - > buffer - > use > 80 ) )
xmlParseTryOrFinish ( ctxt , terminate ) ;
} else if ( ctxt - > instate ! = XML_PARSER_EOF ) {
if ( ( ctxt - > input ! = NULL ) & & ctxt - > input - > buf ! = NULL ) {
xmlParserInputBufferPtr in = ctxt - > input - > buf ;
if ( ( in - > encoder ! = NULL ) & & ( in - > buffer ! = NULL ) & &
( in - > raw ! = NULL ) ) {
int nbchars ;
nbchars = xmlCharEncInFunc ( in - > encoder , in - > buffer , in - > raw ) ;
if ( nbchars < 0 ) {
xmlGenericError ( xmlGenericErrorContext ,
" xmlParseChunk: encoder error \n " ) ;
return ( XML_ERR_INVALID_ENCODING ) ;
}
}
}
}
xmlParseTryOrFinish ( ctxt , terminate ) ;
if ( terminate ) {
/*
* Check for termination
*/
2002-10-14 11:15:18 +00:00
int avail = 0 ;
if ( ctxt - > input - > buf = = NULL )
avail = ctxt - > input - > length -
( ctxt - > input - > cur - ctxt - > input - > base ) ;
else
avail = ctxt - > input - > buf - > buffer - > use -
( ctxt - > input - > cur - ctxt - > input - > base ) ;
2001-02-23 17:55:21 +00:00
if ( ( ctxt - > instate ! = XML_PARSER_EOF ) & &
( ctxt - > instate ! = XML_PARSER_EPILOG ) ) {
ctxt - > errNo = XML_ERR_DOCUMENT_END ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Extra content at the end of the document \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
2002-10-14 11:15:18 +00:00
if ( ( ctxt - > instate = = XML_PARSER_EPILOG ) & & ( avail > 0 ) ) {
ctxt - > errNo = XML_ERR_DOCUMENT_END ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" Extra content at the end of the document \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-10-14 11:15:18 +00:00
}
2001-02-23 17:55:21 +00:00
if ( ctxt - > instate ! = XML_PARSER_EOF ) {
2002-03-05 15:41:29 +00:00
if ( ( ctxt - > sax ) & & ( ctxt - > sax - > endDocument ! = NULL ) )
2001-02-23 17:55:21 +00:00
ctxt - > sax - > endDocument ( ctxt - > userData ) ;
}
ctxt - > instate = XML_PARSER_EOF ;
}
return ( ( xmlParserErrors ) ctxt - > errNo ) ;
}
/************************************************************************
* *
* I / O front end functions to the parser *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlStopParser :
* @ ctxt : an XML parser context
*
* Blocks further parser processing
*/
void
xmlStopParser ( xmlParserCtxtPtr ctxt ) {
ctxt - > instate = XML_PARSER_EOF ;
if ( ctxt - > input ! = NULL )
ctxt - > input - > cur = BAD_CAST " " ;
}
/**
* xmlCreatePushParserCtxt :
* @ sax : a SAX handler
* @ user_data : The user data returned on SAX callbacks
* @ chunk : a pointer to an array of chars
* @ size : number of chars in the array
* @ filename : an optional file name or URI
*
2002-07-06 19:22:28 +00:00
* Create a parser context for using the XML parser in push mode .
* If @ buffer and @ size are non - NULL , the data is used to detect
* the encoding . The remaining characters will be parsed so they
* don ' t need to be fed in again through xmlParseChunk .
2001-02-23 17:55:21 +00:00
* To allow content encoding detection , @ size should be > = 4
* The value of @ filename is used for fetching external entities
* and error / warning reports .
*
* Returns the new parser context or NULL
*/
2002-07-06 19:22:28 +00:00
2001-02-23 17:55:21 +00:00
xmlParserCtxtPtr
xmlCreatePushParserCtxt ( xmlSAXHandlerPtr sax , void * user_data ,
const char * chunk , int size , const char * filename ) {
xmlParserCtxtPtr ctxt ;
xmlParserInputPtr inputStream ;
xmlParserInputBufferPtr buf ;
xmlCharEncoding enc = XML_CHAR_ENCODING_NONE ;
/*
* plug some encoding conversion routines
*/
if ( ( chunk ! = NULL ) & & ( size > = 4 ) )
enc = xmlDetectCharEncoding ( ( const xmlChar * ) chunk , size ) ;
buf = xmlAllocParserInputBuffer ( enc ) ;
if ( buf = = NULL ) return ( NULL ) ;
ctxt = xmlNewParserCtxt ( ) ;
if ( ctxt = = NULL ) {
xmlFree ( buf ) ;
return ( NULL ) ;
}
if ( sax ! = NULL ) {
if ( ctxt - > sax ! = & xmlDefaultSAXHandler )
xmlFree ( ctxt - > sax ) ;
ctxt - > sax = ( xmlSAXHandlerPtr ) xmlMalloc ( sizeof ( xmlSAXHandler ) ) ;
if ( ctxt - > sax = = NULL ) {
xmlFree ( buf ) ;
xmlFree ( ctxt ) ;
return ( NULL ) ;
}
memcpy ( ctxt - > sax , sax , sizeof ( xmlSAXHandler ) ) ;
if ( user_data ! = NULL )
ctxt - > userData = user_data ;
}
if ( filename = = NULL ) {
ctxt - > directory = NULL ;
} else {
ctxt - > directory = xmlParserGetDirectory ( filename ) ;
}
inputStream = xmlNewInputStream ( ctxt ) ;
if ( inputStream = = NULL ) {
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
if ( filename = = NULL )
inputStream - > filename = NULL ;
else
2002-09-10 11:13:43 +00:00
inputStream - > filename = ( char * )
2003-02-19 14:51:00 +00:00
xmlCanonicPath ( ( const xmlChar * ) filename ) ;
2001-02-23 17:55:21 +00:00
inputStream - > buf = buf ;
inputStream - > base = inputStream - > buf - > buffer - > content ;
inputStream - > cur = inputStream - > buf - > buffer - > content ;
2001-02-25 16:11:03 +00:00
inputStream - > end =
& inputStream - > buf - > buffer - > content [ inputStream - > buf - > buffer - > use ] ;
2001-02-23 17:55:21 +00:00
inputPush ( ctxt , inputStream ) ;
if ( ( size > 0 ) & & ( chunk ! = NULL ) & & ( ctxt - > input ! = NULL ) & &
( ctxt - > input - > buf ! = NULL ) ) {
2002-01-06 12:47:22 +00:00
int base = ctxt - > input - > base - ctxt - > input - > buf - > buffer - > content ;
int cur = ctxt - > input - > cur - ctxt - > input - > base ;
2001-02-23 17:55:21 +00:00
xmlParserInputBufferPush ( ctxt - > input - > buf , size , chunk ) ;
2002-01-06 12:47:22 +00:00
ctxt - > input - > base = ctxt - > input - > buf - > buffer - > content + base ;
ctxt - > input - > cur = ctxt - > input - > base + cur ;
ctxt - > input - > end =
& ctxt - > input - > buf - > buffer - > content [ ctxt - > input - > buf - > buffer - > use ] ;
2001-02-23 17:55:21 +00:00
# ifdef DEBUG_PUSH
xmlGenericError ( xmlGenericErrorContext , " PP: pushed %d \n " , size ) ;
# endif
}
2001-06-28 12:13:56 +00:00
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
xmlSwitchEncoding ( ctxt , enc ) ;
}
2001-02-23 17:55:21 +00:00
return ( ctxt ) ;
}
/**
* xmlCreateIOParserCtxt :
* @ sax : a SAX handler
* @ user_data : The user data returned on SAX callbacks
* @ ioread : an I / O read function
* @ ioclose : an I / O close function
* @ ioctx : an I / O handler
* @ enc : the charset encoding if known
*
* Create a parser context for using the XML parser with an existing
* I / O stream
*
* Returns the new parser context or NULL
*/
xmlParserCtxtPtr
xmlCreateIOParserCtxt ( xmlSAXHandlerPtr sax , void * user_data ,
xmlInputReadCallback ioread , xmlInputCloseCallback ioclose ,
void * ioctx , xmlCharEncoding enc ) {
xmlParserCtxtPtr ctxt ;
xmlParserInputPtr inputStream ;
xmlParserInputBufferPtr buf ;
buf = xmlParserInputBufferCreateIO ( ioread , ioclose , ioctx , enc ) ;
if ( buf = = NULL ) return ( NULL ) ;
ctxt = xmlNewParserCtxt ( ) ;
if ( ctxt = = NULL ) {
xmlFree ( buf ) ;
return ( NULL ) ;
}
if ( sax ! = NULL ) {
if ( ctxt - > sax ! = & xmlDefaultSAXHandler )
xmlFree ( ctxt - > sax ) ;
ctxt - > sax = ( xmlSAXHandlerPtr ) xmlMalloc ( sizeof ( xmlSAXHandler ) ) ;
if ( ctxt - > sax = = NULL ) {
xmlFree ( buf ) ;
xmlFree ( ctxt ) ;
return ( NULL ) ;
}
memcpy ( ctxt - > sax , sax , sizeof ( xmlSAXHandler ) ) ;
if ( user_data ! = NULL )
ctxt - > userData = user_data ;
}
inputStream = xmlNewIOInputStream ( ctxt , buf , enc ) ;
if ( inputStream = = NULL ) {
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
inputPush ( ctxt , inputStream ) ;
return ( ctxt ) ;
}
/************************************************************************
* *
2001-12-31 16:16:02 +00:00
* Front ends when parsing a DTD *
2001-02-23 17:55:21 +00:00
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlIOParseDTD :
* @ sax : the SAX handler block or NULL
* @ input : an Input Buffer
* @ enc : the charset encoding if known
*
* Load and parse a DTD
*
* Returns the resulting xmlDtdPtr or NULL in case of error .
* @ input will be freed at parsing end .
*/
xmlDtdPtr
xmlIOParseDTD ( xmlSAXHandlerPtr sax , xmlParserInputBufferPtr input ,
xmlCharEncoding enc ) {
xmlDtdPtr ret = NULL ;
xmlParserCtxtPtr ctxt ;
xmlParserInputPtr pinput = NULL ;
2001-06-20 17:41:10 +00:00
xmlChar start [ 4 ] ;
2001-02-23 17:55:21 +00:00
if ( input = = NULL )
return ( NULL ) ;
ctxt = xmlNewParserCtxt ( ) ;
if ( ctxt = = NULL ) {
return ( NULL ) ;
}
/*
* Set - up the SAX context
*/
if ( sax ! = NULL ) {
if ( ctxt - > sax ! = NULL )
xmlFree ( ctxt - > sax ) ;
ctxt - > sax = sax ;
ctxt - > userData = NULL ;
}
/*
* generate a parser input from the I / O handler
*/
pinput = xmlNewIOInputStream ( ctxt , input , enc ) ;
if ( pinput = = NULL ) {
if ( sax ! = NULL ) ctxt - > sax = NULL ;
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
/*
* plug some encoding conversion routines here .
*/
xmlPushInput ( ctxt , pinput ) ;
pinput - > filename = NULL ;
pinput - > line = 1 ;
pinput - > col = 1 ;
pinput - > base = ctxt - > input - > cur ;
pinput - > cur = ctxt - > input - > cur ;
pinput - > free = NULL ;
/*
* let ' s parse that entity knowing it ' s an external subset .
*/
ctxt - > inSubset = 2 ;
ctxt - > myDoc = xmlNewDoc ( BAD_CAST " 1.0 " ) ;
ctxt - > myDoc - > extSubset = xmlNewDtd ( ctxt - > myDoc , BAD_CAST " none " ,
BAD_CAST " none " , BAD_CAST " none " ) ;
2001-06-20 17:41:10 +00:00
if ( enc = = XML_CHAR_ENCODING_NONE ) {
/*
* Get the 4 first bytes and decode the charset
* if enc ! = XML_CHAR_ENCODING_NONE
* plug some encoding conversion routines .
*/
start [ 0 ] = RAW ;
start [ 1 ] = NXT ( 1 ) ;
start [ 2 ] = NXT ( 2 ) ;
start [ 3 ] = NXT ( 3 ) ;
enc = xmlDetectCharEncoding ( start , 4 ) ;
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
xmlSwitchEncoding ( ctxt , enc ) ;
}
}
2001-02-23 17:55:21 +00:00
xmlParseExternalSubset ( ctxt , BAD_CAST " none " , BAD_CAST " none " ) ;
if ( ctxt - > myDoc ! = NULL ) {
if ( ctxt - > wellFormed ) {
ret = ctxt - > myDoc - > extSubset ;
ctxt - > myDoc - > extSubset = NULL ;
} else {
ret = NULL ;
}
xmlFreeDoc ( ctxt - > myDoc ) ;
ctxt - > myDoc = NULL ;
}
if ( sax ! = NULL ) ctxt - > sax = NULL ;
xmlFreeParserCtxt ( ctxt ) ;
return ( ret ) ;
}
/**
* xmlSAXParseDTD :
* @ sax : the SAX handler block
* @ ExternalID : a NAME * containing the External ID of the DTD
* @ SystemID : a NAME * containing the URL to the DTD
*
* Load and parse an external subset .
*
* Returns the resulting xmlDtdPtr or NULL in case of error .
*/
xmlDtdPtr
xmlSAXParseDTD ( xmlSAXHandlerPtr sax , const xmlChar * ExternalID ,
const xmlChar * SystemID ) {
xmlDtdPtr ret = NULL ;
xmlParserCtxtPtr ctxt ;
xmlParserInputPtr input = NULL ;
xmlCharEncoding enc ;
if ( ( ExternalID = = NULL ) & & ( SystemID = = NULL ) ) return ( NULL ) ;
ctxt = xmlNewParserCtxt ( ) ;
if ( ctxt = = NULL ) {
return ( NULL ) ;
}
/*
* Set - up the SAX context
*/
if ( sax ! = NULL ) {
if ( ctxt - > sax ! = NULL )
xmlFree ( ctxt - > sax ) ;
ctxt - > sax = sax ;
ctxt - > userData = NULL ;
}
/*
* Ask the Entity resolver to load the damn thing
*/
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > resolveEntity ! = NULL ) )
input = ctxt - > sax - > resolveEntity ( ctxt - > userData , ExternalID , SystemID ) ;
if ( input = = NULL ) {
if ( sax ! = NULL ) ctxt - > sax = NULL ;
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
/*
* plug some encoding conversion routines here .
*/
xmlPushInput ( ctxt , input ) ;
enc = xmlDetectCharEncoding ( ctxt - > input - > cur , 4 ) ;
xmlSwitchEncoding ( ctxt , enc ) ;
if ( input - > filename = = NULL )
input - > filename = ( char * ) xmlStrdup ( SystemID ) ;
input - > line = 1 ;
input - > col = 1 ;
input - > base = ctxt - > input - > cur ;
input - > cur = ctxt - > input - > cur ;
input - > free = NULL ;
/*
* let ' s parse that entity knowing it ' s an external subset .
*/
ctxt - > inSubset = 2 ;
ctxt - > myDoc = xmlNewDoc ( BAD_CAST " 1.0 " ) ;
ctxt - > myDoc - > extSubset = xmlNewDtd ( ctxt - > myDoc , BAD_CAST " none " ,
ExternalID , SystemID ) ;
xmlParseExternalSubset ( ctxt , ExternalID , SystemID ) ;
if ( ctxt - > myDoc ! = NULL ) {
if ( ctxt - > wellFormed ) {
ret = ctxt - > myDoc - > extSubset ;
ctxt - > myDoc - > extSubset = NULL ;
} else {
ret = NULL ;
}
xmlFreeDoc ( ctxt - > myDoc ) ;
ctxt - > myDoc = NULL ;
}
if ( sax ! = NULL ) ctxt - > sax = NULL ;
xmlFreeParserCtxt ( ctxt ) ;
return ( ret ) ;
}
/**
* xmlParseDTD :
* @ ExternalID : a NAME * containing the External ID of the DTD
* @ SystemID : a NAME * containing the URL to the DTD
*
* Load and parse an external subset .
*
* Returns the resulting xmlDtdPtr or NULL in case of error .
*/
xmlDtdPtr
xmlParseDTD ( const xmlChar * ExternalID , const xmlChar * SystemID ) {
return ( xmlSAXParseDTD ( NULL , ExternalID , SystemID ) ) ;
}
/************************************************************************
* *
* Front ends when parsing an Entity *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlParseCtxtExternalEntity :
* @ ctx : the existing parsing context
* @ URL : the URL for the entity to load
* @ ID : the System ID for the entity to load
2001-08-21 10:56:31 +00:00
* @ lst : the return value for the set of parsed nodes
2001-02-23 17:55:21 +00:00
*
* Parse an external general entity within an existing parsing context
* An external general parsed entity is well - formed if it matches the
* production labeled extParsedEnt .
*
* [ 78 ] extParsedEnt : : = TextDecl ? content
*
* Returns 0 if the entity is well formed , - 1 in case of args problem and
* the parser error code otherwise
*/
int
xmlParseCtxtExternalEntity ( xmlParserCtxtPtr ctx , const xmlChar * URL ,
2001-08-21 10:56:31 +00:00
const xmlChar * ID , xmlNodePtr * lst ) {
2001-02-23 17:55:21 +00:00
xmlParserCtxtPtr ctxt ;
xmlDocPtr newDoc ;
xmlSAXHandlerPtr oldsax = NULL ;
int ret = 0 ;
2001-06-20 17:41:10 +00:00
xmlChar start [ 4 ] ;
xmlCharEncoding enc ;
2001-02-23 17:55:21 +00:00
if ( ctx - > depth > 40 ) {
return ( XML_ERR_ENTITY_LOOP ) ;
}
2001-08-21 10:56:31 +00:00
if ( lst ! = NULL )
* lst = NULL ;
2001-02-23 17:55:21 +00:00
if ( ( URL = = NULL ) & & ( ID = = NULL ) )
return ( - 1 ) ;
if ( ctx - > myDoc = = NULL ) /* @@ relax but check for dereferences */
return ( - 1 ) ;
ctxt = xmlCreateEntityParserCtxt ( URL , ID , NULL ) ;
if ( ctxt = = NULL ) return ( - 1 ) ;
ctxt - > userData = ctxt ;
2003-01-08 17:47:49 +00:00
ctxt - > _private = ctx - > _private ;
2001-02-23 17:55:21 +00:00
oldsax = ctxt - > sax ;
ctxt - > sax = ctx - > sax ;
newDoc = xmlNewDoc ( BAD_CAST " 1.0 " ) ;
if ( newDoc = = NULL ) {
xmlFreeParserCtxt ( ctxt ) ;
return ( - 1 ) ;
}
if ( ctx - > myDoc ! = NULL ) {
newDoc - > intSubset = ctx - > myDoc - > intSubset ;
newDoc - > extSubset = ctx - > myDoc - > extSubset ;
}
if ( ctx - > myDoc - > URL ! = NULL ) {
newDoc - > URL = xmlStrdup ( ctx - > myDoc - > URL ) ;
}
newDoc - > children = xmlNewDocNode ( newDoc , NULL , BAD_CAST " pseudoroot " , NULL ) ;
if ( newDoc - > children = = NULL ) {
ctxt - > sax = oldsax ;
xmlFreeParserCtxt ( ctxt ) ;
newDoc - > intSubset = NULL ;
newDoc - > extSubset = NULL ;
xmlFreeDoc ( newDoc ) ;
return ( - 1 ) ;
}
nodePush ( ctxt , newDoc - > children ) ;
if ( ctx - > myDoc = = NULL ) {
ctxt - > myDoc = newDoc ;
} else {
ctxt - > myDoc = ctx - > myDoc ;
newDoc - > children - > doc = ctx - > myDoc ;
}
2001-06-20 17:41:10 +00:00
/*
* Get the 4 first bytes and decode the charset
* if enc ! = XML_CHAR_ENCODING_NONE
* plug some encoding conversion routines .
*/
GROW
start [ 0 ] = RAW ;
start [ 1 ] = NXT ( 1 ) ;
start [ 2 ] = NXT ( 2 ) ;
start [ 3 ] = NXT ( 3 ) ;
enc = xmlDetectCharEncoding ( start , 4 ) ;
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
xmlSwitchEncoding ( ctxt , enc ) ;
}
2001-02-23 17:55:21 +00:00
/*
* Parse a possible text declaration first
*/
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) & &
( NXT ( 2 ) = = ' x ' ) & & ( NXT ( 3 ) = = ' m ' ) & &
( NXT ( 4 ) = = ' l ' ) & & ( IS_BLANK ( NXT ( 5 ) ) ) ) {
xmlParseTextDecl ( ctxt ) ;
}
/*
* Doing validity checking on chunk doesn ' t make sense
*/
ctxt - > instate = XML_PARSER_CONTENT ;
ctxt - > validate = ctx - > validate ;
ctxt - > loadsubset = ctx - > loadsubset ;
ctxt - > depth = ctx - > depth + 1 ;
ctxt - > replaceEntities = ctx - > replaceEntities ;
if ( ctxt - > validate ) {
ctxt - > vctxt . error = ctx - > vctxt . error ;
ctxt - > vctxt . warning = ctx - > vctxt . warning ;
} else {
ctxt - > vctxt . error = NULL ;
ctxt - > vctxt . warning = NULL ;
}
2001-06-19 11:07:54 +00:00
ctxt - > vctxt . nodeTab = NULL ;
ctxt - > vctxt . nodeNr = 0 ;
ctxt - > vctxt . nodeMax = 0 ;
ctxt - > vctxt . node = NULL ;
2001-02-23 17:55:21 +00:00
xmlParseContent ( ctxt ) ;
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' / ' ) ) {
ctxt - > errNo = XML_ERR_NOT_WELL_BALANCED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" chunk is not well balanced \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else if ( RAW ! = 0 ) {
ctxt - > errNo = XML_ERR_EXTRA_CONTENT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" extra content at the end of well balanced chunk \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( ctxt - > node ! = newDoc - > children ) {
ctxt - > errNo = XML_ERR_NOT_WELL_BALANCED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" chunk is not well balanced \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( ! ctxt - > wellFormed ) {
if ( ctxt - > errNo = = 0 )
ret = 1 ;
else
ret = ctxt - > errNo ;
} else {
2001-08-21 10:56:31 +00:00
if ( lst ! = NULL ) {
2001-02-23 17:55:21 +00:00
xmlNodePtr cur ;
/*
* Return the newly created nodeset after unlinking it from
* they pseudo parent .
*/
cur = newDoc - > children - > children ;
2001-08-21 10:56:31 +00:00
* lst = cur ;
2001-02-23 17:55:21 +00:00
while ( cur ! = NULL ) {
cur - > parent = NULL ;
cur = cur - > next ;
}
newDoc - > children - > children = NULL ;
}
ret = 0 ;
}
ctxt - > sax = oldsax ;
xmlFreeParserCtxt ( ctxt ) ;
newDoc - > intSubset = NULL ;
newDoc - > extSubset = NULL ;
xmlFreeDoc ( newDoc ) ;
return ( ret ) ;
}
/**
2001-05-08 10:41:44 +00:00
* xmlParseExternalEntityPrivate :
2001-02-23 17:55:21 +00:00
* @ doc : the document the chunk pertains to
2001-05-20 13:19:52 +00:00
* @ oldctxt : the previous parser context if available
2001-02-23 17:55:21 +00:00
* @ sax : the SAX handler bloc ( possibly NULL )
* @ user_data : The user data returned on SAX callbacks ( possibly NULL )
* @ depth : Used for loop detection , use 0
* @ URL : the URL for the entity to load
* @ ID : the System ID for the entity to load
* @ list : the return value for the set of parsed nodes
*
2001-05-08 10:41:44 +00:00
* Private version of xmlParseExternalEntity ( )
2001-02-23 17:55:21 +00:00
*
* Returns 0 if the entity is well formed , - 1 in case of args problem and
* the parser error code otherwise
*/
2001-05-08 10:41:44 +00:00
static int
2001-05-20 13:19:52 +00:00
xmlParseExternalEntityPrivate ( xmlDocPtr doc , xmlParserCtxtPtr oldctxt ,
xmlSAXHandlerPtr sax ,
2001-05-08 10:41:44 +00:00
void * user_data , int depth , const xmlChar * URL ,
2001-05-20 13:19:52 +00:00
const xmlChar * ID , xmlNodePtr * list ) {
2001-02-23 17:55:21 +00:00
xmlParserCtxtPtr ctxt ;
xmlDocPtr newDoc ;
xmlSAXHandlerPtr oldsax = NULL ;
int ret = 0 ;
2001-06-20 17:41:10 +00:00
xmlChar start [ 4 ] ;
xmlCharEncoding enc ;
2001-02-23 17:55:21 +00:00
if ( depth > 40 ) {
return ( XML_ERR_ENTITY_LOOP ) ;
}
if ( list ! = NULL )
* list = NULL ;
if ( ( URL = = NULL ) & & ( ID = = NULL ) )
return ( - 1 ) ;
if ( doc = = NULL ) /* @@ relax but check for dereferences */
return ( - 1 ) ;
ctxt = xmlCreateEntityParserCtxt ( URL , ID , NULL ) ;
if ( ctxt = = NULL ) return ( - 1 ) ;
ctxt - > userData = ctxt ;
2001-05-20 13:19:52 +00:00
if ( oldctxt ! = NULL ) {
ctxt - > _private = oldctxt - > _private ;
ctxt - > loadsubset = oldctxt - > loadsubset ;
ctxt - > validate = oldctxt - > validate ;
ctxt - > external = oldctxt - > external ;
} else {
/*
* Doing validity checking on chunk without context
* doesn ' t make sense
*/
ctxt - > _private = NULL ;
ctxt - > validate = 0 ;
ctxt - > external = 2 ;
ctxt - > loadsubset = 0 ;
}
2001-02-23 17:55:21 +00:00
if ( sax ! = NULL ) {
oldsax = ctxt - > sax ;
ctxt - > sax = sax ;
if ( user_data ! = NULL )
ctxt - > userData = user_data ;
}
newDoc = xmlNewDoc ( BAD_CAST " 1.0 " ) ;
if ( newDoc = = NULL ) {
xmlFreeParserCtxt ( ctxt ) ;
return ( - 1 ) ;
}
if ( doc ! = NULL ) {
newDoc - > intSubset = doc - > intSubset ;
newDoc - > extSubset = doc - > extSubset ;
}
if ( doc - > URL ! = NULL ) {
newDoc - > URL = xmlStrdup ( doc - > URL ) ;
}
newDoc - > children = xmlNewDocNode ( newDoc , NULL , BAD_CAST " pseudoroot " , NULL ) ;
if ( newDoc - > children = = NULL ) {
if ( sax ! = NULL )
ctxt - > sax = oldsax ;
xmlFreeParserCtxt ( ctxt ) ;
newDoc - > intSubset = NULL ;
newDoc - > extSubset = NULL ;
xmlFreeDoc ( newDoc ) ;
return ( - 1 ) ;
}
nodePush ( ctxt , newDoc - > children ) ;
if ( doc = = NULL ) {
ctxt - > myDoc = newDoc ;
} else {
ctxt - > myDoc = doc ;
newDoc - > children - > doc = doc ;
}
2001-06-20 17:41:10 +00:00
/*
* Get the 4 first bytes and decode the charset
* if enc ! = XML_CHAR_ENCODING_NONE
* plug some encoding conversion routines .
*/
GROW ;
start [ 0 ] = RAW ;
start [ 1 ] = NXT ( 1 ) ;
start [ 2 ] = NXT ( 2 ) ;
start [ 3 ] = NXT ( 3 ) ;
enc = xmlDetectCharEncoding ( start , 4 ) ;
if ( enc ! = XML_CHAR_ENCODING_NONE ) {
xmlSwitchEncoding ( ctxt , enc ) ;
}
2001-02-23 17:55:21 +00:00
/*
* Parse a possible text declaration first
*/
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' ? ' ) & &
( NXT ( 2 ) = = ' x ' ) & & ( NXT ( 3 ) = = ' m ' ) & &
( NXT ( 4 ) = = ' l ' ) & & ( IS_BLANK ( NXT ( 5 ) ) ) ) {
xmlParseTextDecl ( ctxt ) ;
}
ctxt - > instate = XML_PARSER_CONTENT ;
ctxt - > depth = depth ;
xmlParseContent ( ctxt ) ;
2002-03-20 21:55:57 +00:00
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' / ' ) ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_NOT_WELL_BALANCED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" chunk is not well balanced \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-03-20 21:55:57 +00:00
} else if ( RAW ! = 0 ) {
2001-02-23 17:55:21 +00:00
ctxt - > errNo = XML_ERR_EXTRA_CONTENT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" extra content at the end of well balanced chunk \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( ctxt - > node ! = newDoc - > children ) {
ctxt - > errNo = XML_ERR_NOT_WELL_BALANCED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" chunk is not well balanced \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( ! ctxt - > wellFormed ) {
if ( ctxt - > errNo = = 0 )
ret = 1 ;
else
ret = ctxt - > errNo ;
} else {
if ( list ! = NULL ) {
xmlNodePtr cur ;
/*
* Return the newly created nodeset after unlinking it from
* they pseudo parent .
*/
cur = newDoc - > children - > children ;
* list = cur ;
while ( cur ! = NULL ) {
cur - > parent = NULL ;
cur = cur - > next ;
}
newDoc - > children - > children = NULL ;
}
ret = 0 ;
}
if ( sax ! = NULL )
ctxt - > sax = oldsax ;
xmlFreeParserCtxt ( ctxt ) ;
newDoc - > intSubset = NULL ;
newDoc - > extSubset = NULL ;
xmlFreeDoc ( newDoc ) ;
return ( ret ) ;
}
2001-05-08 10:41:44 +00:00
/**
* xmlParseExternalEntity :
* @ doc : the document the chunk pertains to
* @ sax : the SAX handler bloc ( possibly NULL )
* @ user_data : The user data returned on SAX callbacks ( possibly NULL )
* @ depth : Used for loop detection , use 0
* @ URL : the URL for the entity to load
* @ ID : the System ID for the entity to load
2001-08-21 10:56:31 +00:00
* @ lst : the return value for the set of parsed nodes
2001-05-08 10:41:44 +00:00
*
* Parse an external general entity
* An external general parsed entity is well - formed if it matches the
* production labeled extParsedEnt .
*
* [ 78 ] extParsedEnt : : = TextDecl ? content
*
* Returns 0 if the entity is well formed , - 1 in case of args problem and
* the parser error code otherwise
*/
int
xmlParseExternalEntity ( xmlDocPtr doc , xmlSAXHandlerPtr sax , void * user_data ,
2001-08-21 10:56:31 +00:00
int depth , const xmlChar * URL , const xmlChar * ID , xmlNodePtr * lst ) {
2001-05-20 13:19:52 +00:00
return ( xmlParseExternalEntityPrivate ( doc , NULL , sax , user_data , depth , URL ,
2001-08-21 10:56:31 +00:00
ID , lst ) ) ;
2001-05-08 10:41:44 +00:00
}
2001-02-23 17:55:21 +00:00
/**
2001-03-21 18:06:15 +00:00
* xmlParseBalancedChunkMemory :
2001-02-23 17:55:21 +00:00
* @ doc : the document the chunk pertains to
* @ sax : the SAX handler bloc ( possibly NULL )
* @ user_data : The user data returned on SAX callbacks ( possibly NULL )
* @ depth : Used for loop detection , use 0
* @ string : the input string in UTF8 or ISO - Latin ( zero terminated )
2001-08-21 10:56:31 +00:00
* @ lst : the return value for the set of parsed nodes
2001-02-23 17:55:21 +00:00
*
* Parse a well - balanced chunk of an XML document
* called by the parser
* The allowed sequence for the Well Balanced Chunk is the one defined by
* the content production in the XML grammar :
*
* [ 43 ] content : : = ( element | CharData | Reference | CDSect | PI | Comment ) *
*
* Returns 0 if the chunk is well balanced , - 1 in case of args problem and
* the parser error code otherwise
*/
int
xmlParseBalancedChunkMemory ( xmlDocPtr doc , xmlSAXHandlerPtr sax ,
2001-08-21 10:56:31 +00:00
void * user_data , int depth , const xmlChar * string , xmlNodePtr * lst ) {
2002-08-02 22:19:49 +00:00
return xmlParseBalancedChunkMemoryRecover ( doc , sax , user_data ,
depth , string , lst , 0 ) ;
}
2002-11-15 15:24:34 +00:00
/**
* xmlParseBalancedChunkMemoryInternal :
* @ oldctxt : the existing parsing context
* @ string : the input string in UTF8 or ISO - Latin ( zero terminated )
* @ user_data : the user data field for the parser context
* @ lst : the return value for the set of parsed nodes
*
*
* Parse a well - balanced chunk of an XML document
* called by the parser
* The allowed sequence for the Well Balanced Chunk is the one defined by
* the content production in the XML grammar :
*
* [ 43 ] content : : = ( element | CharData | Reference | CDSect | PI | Comment ) *
*
* Returns 0 if the chunk is well balanced , - 1 in case of args problem and
* the parser error code otherwise
*
* In case recover is set to 1 , the nodelist will not be empty even if
* the parsed chunk is not well balanced .
*/
static int
xmlParseBalancedChunkMemoryInternal ( xmlParserCtxtPtr oldctxt ,
const xmlChar * string , void * user_data , xmlNodePtr * lst ) {
xmlParserCtxtPtr ctxt ;
2002-11-16 15:35:11 +00:00
xmlDocPtr newDoc = NULL ;
2002-11-15 15:24:34 +00:00
xmlSAXHandlerPtr oldsax = NULL ;
2002-11-16 15:35:11 +00:00
xmlNodePtr content = NULL ;
2002-11-15 15:24:34 +00:00
int size ;
int ret = 0 ;
if ( oldctxt - > depth > 40 ) {
return ( XML_ERR_ENTITY_LOOP ) ;
}
if ( lst ! = NULL )
* lst = NULL ;
if ( string = = NULL )
return ( - 1 ) ;
size = xmlStrlen ( string ) ;
ctxt = xmlCreateMemoryParserCtxt ( ( char * ) string , size ) ;
if ( ctxt = = NULL ) return ( - 1 ) ;
if ( user_data ! = NULL )
ctxt - > userData = user_data ;
else
ctxt - > userData = ctxt ;
oldsax = ctxt - > sax ;
ctxt - > sax = oldctxt - > sax ;
2002-12-09 14:13:43 +00:00
ctxt - > _private = oldctxt - > _private ;
2002-11-16 15:35:11 +00:00
if ( oldctxt - > myDoc = = NULL ) {
newDoc = xmlNewDoc ( BAD_CAST " 1.0 " ) ;
if ( newDoc = = NULL ) {
ctxt - > sax = oldsax ;
xmlFreeParserCtxt ( ctxt ) ;
return ( - 1 ) ;
}
ctxt - > myDoc = newDoc ;
} else {
ctxt - > myDoc = oldctxt - > myDoc ;
content = ctxt - > myDoc - > children ;
2002-11-15 15:24:34 +00:00
}
2002-11-25 13:20:04 +00:00
ctxt - > myDoc - > children = xmlNewDocNode ( ctxt - > myDoc , NULL ,
2002-11-16 15:35:11 +00:00
BAD_CAST " pseudoroot " , NULL ) ;
if ( ctxt - > myDoc - > children = = NULL ) {
2002-11-15 15:24:34 +00:00
ctxt - > sax = oldsax ;
xmlFreeParserCtxt ( ctxt ) ;
2002-11-16 15:35:11 +00:00
if ( newDoc ! = NULL )
xmlFreeDoc ( newDoc ) ;
2002-11-15 15:24:34 +00:00
return ( - 1 ) ;
}
2002-11-16 15:35:11 +00:00
nodePush ( ctxt , ctxt - > myDoc - > children ) ;
2002-11-15 15:24:34 +00:00
ctxt - > instate = XML_PARSER_CONTENT ;
ctxt - > depth = oldctxt - > depth + 1 ;
ctxt - > validate = 0 ;
ctxt - > loadsubset = oldctxt - > loadsubset ;
2002-11-16 15:35:11 +00:00
xmlParseContent ( ctxt ) ;
2002-11-15 15:24:34 +00:00
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' / ' ) ) {
ctxt - > errNo = XML_ERR_NOT_WELL_BALANCED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" chunk is not well balanced \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-11-15 15:24:34 +00:00
} else if ( RAW ! = 0 ) {
ctxt - > errNo = XML_ERR_EXTRA_CONTENT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" extra content at the end of well balanced chunk \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-11-15 15:24:34 +00:00
}
2002-11-16 15:35:11 +00:00
if ( ctxt - > node ! = ctxt - > myDoc - > children ) {
2002-11-15 15:24:34 +00:00
ctxt - > errNo = XML_ERR_NOT_WELL_BALANCED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" chunk is not well balanced \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2002-11-15 15:24:34 +00:00
}
if ( ! ctxt - > wellFormed ) {
if ( ctxt - > errNo = = 0 )
ret = 1 ;
else
ret = ctxt - > errNo ;
} else {
ret = 0 ;
}
if ( ( lst ! = NULL ) & & ( ret = = 0 ) ) {
xmlNodePtr cur ;
/*
* Return the newly created nodeset after unlinking it from
* they pseudo parent .
*/
2002-11-16 15:35:11 +00:00
cur = ctxt - > myDoc - > children - > children ;
2002-11-15 15:24:34 +00:00
* lst = cur ;
while ( cur ! = NULL ) {
2003-02-04 15:07:21 +00:00
if ( oldctxt - > validate & & oldctxt - > wellFormed & &
oldctxt - > myDoc & & oldctxt - > myDoc - > intSubset ) {
oldctxt - > valid & = xmlValidateElement ( & oldctxt - > vctxt ,
oldctxt - > myDoc , cur ) ;
}
2002-11-15 15:24:34 +00:00
cur - > parent = NULL ;
cur = cur - > next ;
}
2002-11-16 15:35:11 +00:00
ctxt - > myDoc - > children - > children = NULL ;
}
if ( ctxt - > myDoc ! = NULL ) {
xmlFreeNode ( ctxt - > myDoc - > children ) ;
ctxt - > myDoc - > children = content ;
2002-11-15 15:24:34 +00:00
}
ctxt - > sax = oldsax ;
xmlFreeParserCtxt ( ctxt ) ;
2002-11-16 15:35:11 +00:00
if ( newDoc ! = NULL )
xmlFreeDoc ( newDoc ) ;
2002-11-15 15:24:34 +00:00
return ( ret ) ;
}
2002-08-02 22:19:49 +00:00
/**
* xmlParseBalancedChunkMemoryRecover :
* @ doc : the document the chunk pertains to
* @ sax : the SAX handler bloc ( possibly NULL )
* @ user_data : The user data returned on SAX callbacks ( possibly NULL )
* @ depth : Used for loop detection , use 0
* @ string : the input string in UTF8 or ISO - Latin ( zero terminated )
* @ lst : the return value for the set of parsed nodes
* @ recover : return nodes even if the data is broken ( use 0 )
*
*
* Parse a well - balanced chunk of an XML document
* called by the parser
* The allowed sequence for the Well Balanced Chunk is the one defined by
* the content production in the XML grammar :
*
* [ 43 ] content : : = ( element | CharData | Reference | CDSect | PI | Comment ) *
*
* Returns 0 if the chunk is well balanced , - 1 in case of args problem and
* the parser error code otherwise
*
* In case recover is set to 1 , the nodelist will not be empty even if
* the parsed chunk is not well balanced .
*/
int
xmlParseBalancedChunkMemoryRecover ( xmlDocPtr doc , xmlSAXHandlerPtr sax ,
void * user_data , int depth , const xmlChar * string , xmlNodePtr * lst ,
int recover ) {
2001-02-23 17:55:21 +00:00
xmlParserCtxtPtr ctxt ;
xmlDocPtr newDoc ;
xmlSAXHandlerPtr oldsax = NULL ;
2002-10-22 14:22:46 +00:00
xmlNodePtr content ;
2001-02-23 17:55:21 +00:00
int size ;
int ret = 0 ;
if ( depth > 40 ) {
return ( XML_ERR_ENTITY_LOOP ) ;
}
2001-08-21 10:56:31 +00:00
if ( lst ! = NULL )
* lst = NULL ;
2001-02-23 17:55:21 +00:00
if ( string = = NULL )
return ( - 1 ) ;
size = xmlStrlen ( string ) ;
ctxt = xmlCreateMemoryParserCtxt ( ( char * ) string , size ) ;
if ( ctxt = = NULL ) return ( - 1 ) ;
ctxt - > userData = ctxt ;
if ( sax ! = NULL ) {
oldsax = ctxt - > sax ;
ctxt - > sax = sax ;
if ( user_data ! = NULL )
ctxt - > userData = user_data ;
}
newDoc = xmlNewDoc ( BAD_CAST " 1.0 " ) ;
if ( newDoc = = NULL ) {
xmlFreeParserCtxt ( ctxt ) ;
return ( - 1 ) ;
}
if ( doc ! = NULL ) {
newDoc - > intSubset = doc - > intSubset ;
newDoc - > extSubset = doc - > extSubset ;
}
newDoc - > children = xmlNewDocNode ( newDoc , NULL , BAD_CAST " pseudoroot " , NULL ) ;
if ( newDoc - > children = = NULL ) {
if ( sax ! = NULL )
ctxt - > sax = oldsax ;
xmlFreeParserCtxt ( ctxt ) ;
newDoc - > intSubset = NULL ;
newDoc - > extSubset = NULL ;
xmlFreeDoc ( newDoc ) ;
return ( - 1 ) ;
}
nodePush ( ctxt , newDoc - > children ) ;
if ( doc = = NULL ) {
ctxt - > myDoc = newDoc ;
} else {
2002-08-22 20:52:17 +00:00
ctxt - > myDoc = newDoc ;
2001-02-23 17:55:21 +00:00
newDoc - > children - > doc = doc ;
}
ctxt - > instate = XML_PARSER_CONTENT ;
ctxt - > depth = depth ;
/*
* Doing validity checking on chunk doesn ' t make sense
*/
ctxt - > validate = 0 ;
ctxt - > loadsubset = 0 ;
2002-10-26 19:29:51 +00:00
if ( doc ! = NULL ) {
content = doc - > children ;
doc - > children = NULL ;
xmlParseContent ( ctxt ) ;
doc - > children = content ;
}
else {
xmlParseContent ( ctxt ) ;
}
2001-02-23 17:55:21 +00:00
if ( ( RAW = = ' < ' ) & & ( NXT ( 1 ) = = ' / ' ) ) {
ctxt - > errNo = XML_ERR_NOT_WELL_BALANCED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" chunk is not well balanced \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
} else if ( RAW ! = 0 ) {
ctxt - > errNo = XML_ERR_EXTRA_CONTENT ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" extra content at the end of well balanced chunk \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( ctxt - > node ! = newDoc - > children ) {
ctxt - > errNo = XML_ERR_NOT_WELL_BALANCED ;
if ( ( ctxt - > sax ! = NULL ) & & ( ctxt - > sax - > error ! = NULL ) )
ctxt - > sax - > error ( ctxt - > userData ,
" chunk is not well balanced \n " ) ;
ctxt - > wellFormed = 0 ;
2002-11-17 16:47:27 +00:00
if ( ctxt - > recovery = = 0 ) ctxt - > disableSAX = 1 ;
2001-02-23 17:55:21 +00:00
}
if ( ! ctxt - > wellFormed ) {
if ( ctxt - > errNo = = 0 )
ret = 1 ;
else
ret = ctxt - > errNo ;
} else {
2002-08-02 22:19:49 +00:00
ret = 0 ;
}
if ( lst ! = NULL & & ( ret = = 0 | | recover = = 1 ) ) {
xmlNodePtr cur ;
2001-02-23 17:55:21 +00:00
/*
* Return the newly created nodeset after unlinking it from
* they pseudo parent .
*/
cur = newDoc - > children - > children ;
2001-08-21 10:56:31 +00:00
* lst = cur ;
2001-02-23 17:55:21 +00:00
while ( cur ! = NULL ) {
cur - > parent = NULL ;
cur = cur - > next ;
}
newDoc - > children - > children = NULL ;
}
2002-08-02 22:19:49 +00:00
2001-02-23 17:55:21 +00:00
if ( sax ! = NULL )
ctxt - > sax = oldsax ;
xmlFreeParserCtxt ( ctxt ) ;
newDoc - > intSubset = NULL ;
newDoc - > extSubset = NULL ;
xmlFreeDoc ( newDoc ) ;
return ( ret ) ;
}
/**
* xmlSAXParseEntity :
* @ sax : the SAX handler block
* @ filename : the filename
*
* parse an XML external entity out of context and build a tree .
* It use the given SAX function block to handle the parsing callback .
* If sax is NULL , fallback to the default DOM tree building routines .
*
* [ 78 ] extParsedEnt : : = TextDecl ? content
*
* This correspond to a " Well Balanced " chunk
*
* Returns the resulting document tree
*/
xmlDocPtr
xmlSAXParseEntity ( xmlSAXHandlerPtr sax , const char * filename ) {
xmlDocPtr ret ;
xmlParserCtxtPtr ctxt ;
char * directory = NULL ;
ctxt = xmlCreateFileParserCtxt ( filename ) ;
if ( ctxt = = NULL ) {
return ( NULL ) ;
}
if ( sax ! = NULL ) {
if ( ctxt - > sax ! = NULL )
xmlFree ( ctxt - > sax ) ;
ctxt - > sax = sax ;
ctxt - > userData = NULL ;
}
if ( ( ctxt - > directory = = NULL ) & & ( directory = = NULL ) )
directory = xmlParserGetDirectory ( filename ) ;
xmlParseExtParsedEnt ( ctxt ) ;
if ( ctxt - > wellFormed )
ret = ctxt - > myDoc ;
else {
ret = NULL ;
xmlFreeDoc ( ctxt - > myDoc ) ;
ctxt - > myDoc = NULL ;
}
if ( sax ! = NULL )
ctxt - > sax = NULL ;
xmlFreeParserCtxt ( ctxt ) ;
return ( ret ) ;
}
/**
* xmlParseEntity :
* @ filename : the filename
*
* parse an XML external entity out of context and build a tree .
*
* [ 78 ] extParsedEnt : : = TextDecl ? content
*
* This correspond to a " Well Balanced " chunk
*
* Returns the resulting document tree
*/
xmlDocPtr
xmlParseEntity ( const char * filename ) {
return ( xmlSAXParseEntity ( NULL , filename ) ) ;
}
/**
* xmlCreateEntityParserCtxt :
* @ URL : the entity URL
* @ ID : the entity PUBLIC ID
2001-12-31 16:16:02 +00:00
* @ base : a possible base for the target URI
2001-02-23 17:55:21 +00:00
*
* Create a parser context for an external entity
* Automatic support for ZLIB / Compress compressed document is provided
* by default if found at compile - time .
*
* Returns the new parser context or NULL
*/
xmlParserCtxtPtr
xmlCreateEntityParserCtxt ( const xmlChar * URL , const xmlChar * ID ,
const xmlChar * base ) {
xmlParserCtxtPtr ctxt ;
xmlParserInputPtr inputStream ;
char * directory = NULL ;
xmlChar * uri ;
ctxt = xmlNewParserCtxt ( ) ;
if ( ctxt = = NULL ) {
return ( NULL ) ;
}
uri = xmlBuildURI ( URL , base ) ;
if ( uri = = NULL ) {
inputStream = xmlLoadExternalEntity ( ( char * ) URL , ( char * ) ID , ctxt ) ;
if ( inputStream = = NULL ) {
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
inputPush ( ctxt , inputStream ) ;
if ( ( ctxt - > directory = = NULL ) & & ( directory = = NULL ) )
directory = xmlParserGetDirectory ( ( char * ) URL ) ;
if ( ( ctxt - > directory = = NULL ) & & ( directory ! = NULL ) )
ctxt - > directory = directory ;
} else {
inputStream = xmlLoadExternalEntity ( ( char * ) uri , ( char * ) ID , ctxt ) ;
if ( inputStream = = NULL ) {
xmlFree ( uri ) ;
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
inputPush ( ctxt , inputStream ) ;
if ( ( ctxt - > directory = = NULL ) & & ( directory = = NULL ) )
directory = xmlParserGetDirectory ( ( char * ) uri ) ;
if ( ( ctxt - > directory = = NULL ) & & ( directory ! = NULL ) )
ctxt - > directory = directory ;
xmlFree ( uri ) ;
}
return ( ctxt ) ;
}
/************************************************************************
* *
* Front ends when parsing from a file *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlCreateFileParserCtxt :
* @ filename : the filename
*
* Create a parser context for a file content .
* Automatic support for ZLIB / Compress compressed document is provided
* by default if found at compile - time .
*
* Returns the new parser context or NULL
*/
xmlParserCtxtPtr
xmlCreateFileParserCtxt ( const char * filename )
{
xmlParserCtxtPtr ctxt ;
xmlParserInputPtr inputStream ;
char * directory = NULL ;
ctxt = xmlNewParserCtxt ( ) ;
if ( ctxt = = NULL ) {
if ( xmlDefaultSAXHandler . error ! = NULL ) {
xmlDefaultSAXHandler . error ( NULL , " out of memory \n " ) ;
}
return ( NULL ) ;
}
2003-02-19 14:51:00 +00:00
inputStream = xmlLoadExternalEntity ( filename , NULL , ctxt ) ;
2001-02-23 17:55:21 +00:00
if ( inputStream = = NULL ) {
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
inputPush ( ctxt , inputStream ) ;
if ( ( ctxt - > directory = = NULL ) & & ( directory = = NULL ) )
2003-02-19 14:51:00 +00:00
directory = xmlParserGetDirectory ( filename ) ;
2001-02-23 17:55:21 +00:00
if ( ( ctxt - > directory = = NULL ) & & ( directory ! = NULL ) )
ctxt - > directory = directory ;
return ( ctxt ) ;
}
/**
2001-10-02 13:54:14 +00:00
* xmlSAXParseFileWithData :
2001-02-23 17:55:21 +00:00
* @ sax : the SAX handler block
* @ filename : the filename
* @ recovery : work in recovery mode , i . e . tries to read no Well Formed
* documents
2001-10-02 13:54:14 +00:00
* @ data : the userdata
2001-02-23 17:55:21 +00:00
*
* parse an XML file and build a tree . Automatic support for ZLIB / Compress
* compressed document is provided by default if found at compile - time .
* It use the given SAX function block to handle the parsing callback .
* If sax is NULL , fallback to the default DOM tree building routines .
*
2002-04-22 16:01:24 +00:00
* User data ( void * ) is stored within the parser context in the
* context ' s _private member , so it is available nearly everywhere in libxml
2001-10-02 13:54:14 +00:00
*
2001-02-23 17:55:21 +00:00
* Returns the resulting document tree
*/
xmlDocPtr
2001-10-02 13:54:14 +00:00
xmlSAXParseFileWithData ( xmlSAXHandlerPtr sax , const char * filename ,
int recovery , void * data ) {
2001-02-23 17:55:21 +00:00
xmlDocPtr ret ;
xmlParserCtxtPtr ctxt ;
char * directory = NULL ;
2001-10-29 11:48:19 +00:00
xmlInitParser ( ) ;
2001-02-23 17:55:21 +00:00
ctxt = xmlCreateFileParserCtxt ( filename ) ;
if ( ctxt = = NULL ) {
return ( NULL ) ;
}
if ( sax ! = NULL ) {
if ( ctxt - > sax ! = NULL )
xmlFree ( ctxt - > sax ) ;
ctxt - > sax = sax ;
}
2001-10-02 13:54:14 +00:00
if ( data ! = NULL ) {
ctxt - > _private = data ;
}
2001-02-23 17:55:21 +00:00
if ( ( ctxt - > directory = = NULL ) & & ( directory = = NULL ) )
directory = xmlParserGetDirectory ( filename ) ;
if ( ( ctxt - > directory = = NULL ) & & ( directory ! = NULL ) )
ctxt - > directory = ( char * ) xmlStrdup ( ( xmlChar * ) directory ) ;
2002-11-17 16:47:27 +00:00
ctxt - > recovery = recovery ;
2001-02-23 17:55:21 +00:00
xmlParseDocument ( ctxt ) ;
if ( ( ctxt - > wellFormed ) | | recovery ) ret = ctxt - > myDoc ;
else {
ret = NULL ;
xmlFreeDoc ( ctxt - > myDoc ) ;
ctxt - > myDoc = NULL ;
}
if ( sax ! = NULL )
ctxt - > sax = NULL ;
xmlFreeParserCtxt ( ctxt ) ;
return ( ret ) ;
}
2001-10-02 13:54:14 +00:00
/**
* xmlSAXParseFile :
* @ sax : the SAX handler block
* @ filename : the filename
* @ recovery : work in recovery mode , i . e . tries to read no Well Formed
* documents
*
* parse an XML file and build a tree . Automatic support for ZLIB / Compress
* compressed document is provided by default if found at compile - time .
* It use the given SAX function block to handle the parsing callback .
* If sax is NULL , fallback to the default DOM tree building routines .
*
* Returns the resulting document tree
*/
xmlDocPtr
xmlSAXParseFile ( xmlSAXHandlerPtr sax , const char * filename ,
int recovery ) {
return ( xmlSAXParseFileWithData ( sax , filename , recovery , NULL ) ) ;
}
2001-02-23 17:55:21 +00:00
/**
* xmlRecoverDoc :
* @ cur : a pointer to an array of xmlChar
*
* parse an XML in - memory document and build a tree .
* In the case the document is not Well Formed , a tree is built anyway
*
* Returns the resulting document tree
*/
xmlDocPtr
xmlRecoverDoc ( xmlChar * cur ) {
return ( xmlSAXParseDoc ( NULL , cur , 1 ) ) ;
}
/**
* xmlParseFile :
* @ filename : the filename
*
* parse an XML file and build a tree . Automatic support for ZLIB / Compress
* compressed document is provided by default if found at compile - time .
*
2001-08-31 14:55:30 +00:00
* Returns the resulting document tree if the file was wellformed ,
* NULL otherwise .
2001-02-23 17:55:21 +00:00
*/
xmlDocPtr
xmlParseFile ( const char * filename ) {
return ( xmlSAXParseFile ( NULL , filename , 0 ) ) ;
}
/**
* xmlRecoverFile :
* @ filename : the filename
*
* parse an XML file and build a tree . Automatic support for ZLIB / Compress
* compressed document is provided by default if found at compile - time .
* In the case the document is not Well Formed , a tree is built anyway
*
* Returns the resulting document tree
*/
xmlDocPtr
xmlRecoverFile ( const char * filename ) {
return ( xmlSAXParseFile ( NULL , filename , 1 ) ) ;
}
/**
* xmlSetupParserForBuffer :
* @ ctxt : an XML parser context
* @ buffer : a xmlChar * buffer
* @ filename : a file name
*
* Setup the parser context to parse a new buffer ; Clears any prior
* contents from the parser context . The buffer parameter must not be
* NULL , but the filename parameter can be
*/
void
xmlSetupParserForBuffer ( xmlParserCtxtPtr ctxt , const xmlChar * buffer ,
const char * filename )
{
xmlParserInputPtr input ;
input = xmlNewInputStream ( ctxt ) ;
if ( input = = NULL ) {
2002-09-05 11:33:25 +00:00
xmlGenericError ( xmlGenericErrorContext ,
" malloc " ) ;
2001-02-23 17:55:21 +00:00
xmlFree ( ctxt ) ;
return ;
}
xmlClearParserCtxt ( ctxt ) ;
if ( filename ! = NULL )
input - > filename = xmlMemStrdup ( filename ) ;
input - > base = buffer ;
input - > cur = buffer ;
2001-02-25 16:11:03 +00:00
input - > end = & buffer [ xmlStrlen ( buffer ) ] ;
2001-02-23 17:55:21 +00:00
inputPush ( ctxt , input ) ;
}
/**
* xmlSAXUserParseFile :
* @ sax : a SAX handler
* @ user_data : The user data returned on SAX callbacks
* @ filename : a file name
*
* parse an XML file and call the given SAX handler routines .
* Automatic support for ZLIB / Compress compressed document is provided
*
* Returns 0 in case of success or a error number otherwise
*/
int
xmlSAXUserParseFile ( xmlSAXHandlerPtr sax , void * user_data ,
const char * filename ) {
int ret = 0 ;
xmlParserCtxtPtr ctxt ;
ctxt = xmlCreateFileParserCtxt ( filename ) ;
if ( ctxt = = NULL ) return - 1 ;
if ( ctxt - > sax ! = & xmlDefaultSAXHandler )
xmlFree ( ctxt - > sax ) ;
ctxt - > sax = sax ;
if ( user_data ! = NULL )
ctxt - > userData = user_data ;
xmlParseDocument ( ctxt ) ;
if ( ctxt - > wellFormed )
ret = 0 ;
else {
if ( ctxt - > errNo ! = 0 )
ret = ctxt - > errNo ;
else
ret = - 1 ;
}
if ( sax ! = NULL )
ctxt - > sax = NULL ;
xmlFreeParserCtxt ( ctxt ) ;
return ret ;
}
/************************************************************************
* *
* Front ends when parsing from memory *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/**
* xmlCreateMemoryParserCtxt :
* @ buffer : a pointer to a char array
* @ size : the size of the array
*
* Create a parser context for an XML in - memory document .
*
* Returns the new parser context or NULL
*/
xmlParserCtxtPtr
2001-05-16 10:57:35 +00:00
xmlCreateMemoryParserCtxt ( const char * buffer , int size ) {
2001-02-23 17:55:21 +00:00
xmlParserCtxtPtr ctxt ;
xmlParserInputPtr input ;
xmlParserInputBufferPtr buf ;
if ( buffer = = NULL )
return ( NULL ) ;
if ( size < = 0 )
return ( NULL ) ;
ctxt = xmlNewParserCtxt ( ) ;
if ( ctxt = = NULL )
return ( NULL ) ;
buf = xmlParserInputBufferCreateMem ( buffer , size , XML_CHAR_ENCODING_NONE ) ;
2002-11-19 08:11:14 +00:00
if ( buf = = NULL ) {
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
2001-02-23 17:55:21 +00:00
input = xmlNewInputStream ( ctxt ) ;
if ( input = = NULL ) {
2002-11-19 08:11:14 +00:00
xmlFreeParserInputBuffer ( buf ) ;
2001-02-23 17:55:21 +00:00
xmlFreeParserCtxt ( ctxt ) ;
return ( NULL ) ;
}
input - > filename = NULL ;
input - > buf = buf ;
input - > base = input - > buf - > buffer - > content ;
input - > cur = input - > buf - > buffer - > content ;
2001-02-25 16:11:03 +00:00
input - > end = & input - > buf - > buffer - > content [ input - > buf - > buffer - > use ] ;
2001-02-23 17:55:21 +00:00
inputPush ( ctxt , input ) ;
return ( ctxt ) ;
}
/**
2002-11-12 12:36:52 +00:00
* xmlSAXParseMemoryWithData :
2001-02-23 17:55:21 +00:00
* @ sax : the SAX handler block
* @ buffer : an pointer to a char array
* @ size : the size of the array
2002-11-12 12:36:52 +00:00
* @ recovery : work in recovery mode , i . e . tries to read no Well Formed
2001-02-23 17:55:21 +00:00
* documents
2002-11-12 12:36:52 +00:00
* @ data : the userdata
2001-02-23 17:55:21 +00:00
*
* parse an XML in - memory block and use the given SAX function block
* to handle the parsing callback . If sax is NULL , fallback to the default
* DOM tree building routines .
2002-11-12 12:36:52 +00:00
*
* User data ( void * ) is stored within the parser context in the
* context ' s _private member , so it is available nearly everywhere in libxml
*
2001-02-23 17:55:21 +00:00
* Returns the resulting document tree
*/
2002-11-12 12:36:52 +00:00
2001-02-23 17:55:21 +00:00
xmlDocPtr
2002-11-12 12:36:52 +00:00
xmlSAXParseMemoryWithData ( xmlSAXHandlerPtr sax , const char * buffer ,
int size , int recovery , void * data ) {
2001-02-23 17:55:21 +00:00
xmlDocPtr ret ;
xmlParserCtxtPtr ctxt ;
ctxt = xmlCreateMemoryParserCtxt ( buffer , size ) ;
if ( ctxt = = NULL ) return ( NULL ) ;
if ( sax ! = NULL ) {
2002-11-12 12:36:52 +00:00
if ( ctxt - > sax ! = NULL )
xmlFree ( ctxt - > sax ) ;
2001-02-23 17:55:21 +00:00
ctxt - > sax = sax ;
}
2002-11-12 12:36:52 +00:00
if ( data ! = NULL ) {
ctxt - > _private = data ;
}
2001-02-23 17:55:21 +00:00
xmlParseDocument ( ctxt ) ;
if ( ( ctxt - > wellFormed ) | | recovery ) ret = ctxt - > myDoc ;
else {
ret = NULL ;
xmlFreeDoc ( ctxt - > myDoc ) ;
ctxt - > myDoc = NULL ;
}
if ( sax ! = NULL )
ctxt - > sax = NULL ;
xmlFreeParserCtxt ( ctxt ) ;
return ( ret ) ;
}
2002-11-12 12:36:52 +00:00
/**
* xmlSAXParseMemory :
* @ sax : the SAX handler block
* @ buffer : an pointer to a char array
* @ size : the size of the array
* @ recovery : work in recovery mode , i . e . tries to read not Well Formed
* documents
*
* parse an XML in - memory block and use the given SAX function block
* to handle the parsing callback . If sax is NULL , fallback to the default
* DOM tree building routines .
*
* Returns the resulting document tree
*/
xmlDocPtr
xmlSAXParseMemory ( xmlSAXHandlerPtr sax , const char * buffer ,
int size , int recovery ) {
return xmlSAXParseMemoryWithData ( sax , buffer , size , recovery , NULL ) ;
}
2001-02-23 17:55:21 +00:00
/**
* xmlParseMemory :
* @ buffer : an pointer to a char array
* @ size : the size of the array
*
* parse an XML in - memory block and build a tree .
*
* Returns the resulting document tree
*/
2001-07-26 20:05:51 +00:00
xmlDocPtr xmlParseMemory ( const char * buffer , int size ) {
2001-02-23 17:55:21 +00:00
return ( xmlSAXParseMemory ( NULL , buffer , size , 0 ) ) ;
}
/**
* xmlRecoverMemory :
* @ buffer : an pointer to a char array
* @ size : the size of the array
*
* parse an XML in - memory block and build a tree .
* In the case the document is not Well Formed , a tree is built anyway
*
* Returns the resulting document tree
*/
2001-07-26 20:05:51 +00:00
xmlDocPtr xmlRecoverMemory ( const char * buffer , int size ) {
2001-02-23 17:55:21 +00:00
return ( xmlSAXParseMemory ( NULL , buffer , size , 1 ) ) ;
}
/**
* xmlSAXUserParseMemory :
* @ sax : a SAX handler
* @ user_data : The user data returned on SAX callbacks
* @ buffer : an in - memory XML document input
* @ size : the length of the XML document in bytes
*
* A better SAX parsing routine .
* parse an XML in - memory buffer and call the given SAX handler routines .
*
* Returns 0 in case of success or a error number otherwise
*/
int xmlSAXUserParseMemory ( xmlSAXHandlerPtr sax , void * user_data ,
2001-05-16 10:57:35 +00:00
const char * buffer , int size ) {
2001-02-23 17:55:21 +00:00
int ret = 0 ;
xmlParserCtxtPtr ctxt ;
xmlSAXHandlerPtr oldsax = NULL ;
2002-08-14 08:48:52 +00:00
if ( sax = = NULL ) return - 1 ;
2001-02-23 17:55:21 +00:00
ctxt = xmlCreateMemoryParserCtxt ( buffer , size ) ;
if ( ctxt = = NULL ) return - 1 ;
2002-08-14 08:48:52 +00:00
oldsax = ctxt - > sax ;
ctxt - > sax = sax ;
2001-04-26 09:33:18 +00:00
if ( user_data ! = NULL )
ctxt - > userData = user_data ;
2001-02-23 17:55:21 +00:00
xmlParseDocument ( ctxt ) ;
if ( ctxt - > wellFormed )
ret = 0 ;
else {
if ( ctxt - > errNo ! = 0 )
ret = ctxt - > errNo ;
else
ret = - 1 ;
}
2002-08-14 08:48:52 +00:00
ctxt - > sax = oldsax ;
2001-02-23 17:55:21 +00:00
xmlFreeParserCtxt ( ctxt ) ;
return ret ;
}
/**
* xmlCreateDocParserCtxt :
* @ cur : a pointer to an array of xmlChar
*
* Creates a parser context for an XML in - memory document .
*
* Returns the new parser context or NULL
*/
xmlParserCtxtPtr
xmlCreateDocParserCtxt ( xmlChar * cur ) {
int len ;
if ( cur = = NULL )
return ( NULL ) ;
len = xmlStrlen ( cur ) ;
return ( xmlCreateMemoryParserCtxt ( ( char * ) cur , len ) ) ;
}
/**
* xmlSAXParseDoc :
* @ sax : the SAX handler block
* @ cur : a pointer to an array of xmlChar
* @ recovery : work in recovery mode , i . e . tries to read no Well Formed
* documents
*
* parse an XML in - memory document and build a tree .
* It use the given SAX function block to handle the parsing callback .
* If sax is NULL , fallback to the default DOM tree building routines .
*
* Returns the resulting document tree
*/
xmlDocPtr
xmlSAXParseDoc ( xmlSAXHandlerPtr sax , xmlChar * cur , int recovery ) {
xmlDocPtr ret ;
xmlParserCtxtPtr ctxt ;
if ( cur = = NULL ) return ( NULL ) ;
ctxt = xmlCreateDocParserCtxt ( cur ) ;
if ( ctxt = = NULL ) return ( NULL ) ;
if ( sax ! = NULL ) {
ctxt - > sax = sax ;
ctxt - > userData = NULL ;
}
xmlParseDocument ( ctxt ) ;
if ( ( ctxt - > wellFormed ) | | recovery ) ret = ctxt - > myDoc ;
else {
ret = NULL ;
xmlFreeDoc ( ctxt - > myDoc ) ;
ctxt - > myDoc = NULL ;
}
if ( sax ! = NULL )
ctxt - > sax = NULL ;
xmlFreeParserCtxt ( ctxt ) ;
return ( ret ) ;
}
/**
* xmlParseDoc :
* @ cur : a pointer to an array of xmlChar
*
* parse an XML in - memory document and build a tree .
*
* Returns the resulting document tree
*/
xmlDocPtr
xmlParseDoc ( xmlChar * cur ) {
return ( xmlSAXParseDoc ( NULL , cur , 0 ) ) ;
}
2002-01-13 14:10:10 +00:00
/************************************************************************
* *
* Specific function to keep track of entities references *
* and used by the XSLT debugger *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static xmlEntityReferenceFunc xmlEntityRefFunc = NULL ;
/**
* xmlAddEntityReference :
* @ ent : A valid entity
* @ firstNode : A valid first node for children of entity
* @ lastNode : A valid last node of children entity
*
* Notify of a reference to an entity of type XML_EXTERNAL_GENERAL_PARSED_ENTITY
*/
static void
xmlAddEntityReference ( xmlEntityPtr ent , xmlNodePtr firstNode ,
xmlNodePtr lastNode )
{
if ( xmlEntityRefFunc ! = NULL ) {
( * xmlEntityRefFunc ) ( ent , firstNode , lastNode ) ;
}
}
/**
* xmlSetEntityReferenceFunc :
2002-12-10 15:19:08 +00:00
* @ func : A valid function
2002-01-13 14:10:10 +00:00
*
* Set the function to call call back when a xml reference has been made
*/
void
xmlSetEntityReferenceFunc ( xmlEntityReferenceFunc func )
{
xmlEntityRefFunc = func ;
}
2001-02-23 17:55:21 +00:00
/************************************************************************
* *
* Miscellaneous *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef LIBXML_XPATH_ENABLED
# include <libxml/xpath.h>
# endif
2002-01-18 11:49:26 +00:00
extern void xmlGenericErrorDefaultFunc ( void * ctx , const char * msg , . . . ) ;
2001-02-23 17:55:21 +00:00
static int xmlParserInitialized = 0 ;
/**
* xmlInitParser :
*
* Initialization function for the XML parser .
* This is not reentrant . Call once before processing in case of
* use in multithreaded programs .
*/
void
xmlInitParser ( void ) {
2001-10-17 15:58:35 +00:00
if ( xmlParserInitialized ! = 0 )
return ;
2001-02-23 17:55:21 +00:00
2002-01-18 11:49:26 +00:00
if ( ( xmlGenericError = = xmlGenericErrorDefaultFunc ) | |
( xmlGenericError = = NULL ) )
initGenericErrorDefaultFunc ( NULL ) ;
2001-10-13 09:15:48 +00:00
xmlInitThreads ( ) ;
2001-10-14 09:56:15 +00:00
xmlInitMemory ( ) ;
2001-02-23 17:55:21 +00:00
xmlInitCharEncodingHandlers ( ) ;
xmlInitializePredefinedEntities ( ) ;
xmlDefaultSAXHandlerInit ( ) ;
xmlRegisterDefaultInputCallbacks ( ) ;
xmlRegisterDefaultOutputCallbacks ( ) ;
# ifdef LIBXML_HTML_ENABLED
htmlInitAutoClose ( ) ;
htmlDefaultSAXHandlerInit ( ) ;
# endif
# ifdef LIBXML_XPATH_ENABLED
xmlXPathInit ( ) ;
# endif
xmlParserInitialized = 1 ;
}
/**
* xmlCleanupParser :
*
* Cleanup function for the XML parser . It tries to reclaim all
* parsing related global memory allocated for the parser processing .
* It doesn ' t deallocate any document related memory . Calling this
* function should not prevent reusing the parser .
2003-01-24 14:14:52 +00:00
* One should call xmlCleanupParser ( ) only when the process has
* finished using the library or XML document built with it .
2001-02-23 17:55:21 +00:00
*/
void
xmlCleanupParser ( void ) {
xmlCleanupCharEncodingHandlers ( ) ;
xmlCleanupPredefinedEntities ( ) ;
2001-08-22 00:06:49 +00:00
# ifdef LIBXML_CATALOG_ENABLED
xmlCatalogCleanup ( ) ;
# endif
2001-10-13 09:15:48 +00:00
xmlCleanupThreads ( ) ;
xmlParserInitialized = 0 ;
2001-02-23 17:55:21 +00:00
}