version 1.139, 1999/12/22 11:19:50
|
version 1.140, 1999/12/28 15:31:14
|
Line 43
|
Line 43
|
#include "xmlIO.h" |
#include "xmlIO.h" |
#include "xml-error.h" |
#include "xml-error.h" |
|
|
|
#define XML_PARSER_BIG_BUFFER_SIZE 1000 |
|
#define XML_PARSER_BUFFER_SIZE 100 |
|
|
const char *xmlParserVersion = LIBXML_VERSION; |
const char *xmlParserVersion = LIBXML_VERSION; |
|
|
/* |
/* |
Line 61 const char *xmlW3CPIs[] = {
|
Line 64 const char *xmlW3CPIs[] = {
|
************************************************************************/ |
************************************************************************/ |
|
|
/* #define DEBUG_INPUT */ |
/* #define DEBUG_INPUT */ |
|
/* #define DEBUG_STACK */ |
|
/* #define DEBUG_PUSH */ |
|
|
|
|
#define INPUT_CHUNK 250 |
#define INPUT_CHUNK 250 |
/* we need to keep enough input to show errors in context */ |
/* we need to keep enough input to show errors in context */ |
Line 170 xmlParserInputGrow(xmlParserInputPtr in,
|
Line 176 xmlParserInputGrow(xmlParserInputPtr in,
|
|
|
return(0); |
return(0); |
} |
} |
ret = xmlParserInputBufferGrow(in->buf, len); |
if ((in->buf->netIO != NULL) || (in->buf->file != NULL) || |
|
#ifdef HAVE_ZLIB_H |
|
(in->buf->gzfile != NULL) || |
|
#endif |
|
(in->buf->fd >= 0)) |
|
ret = xmlParserInputBufferGrow(in->buf, len); |
|
else |
|
return(0); |
|
|
/* |
/* |
* NOTE : in->base may be a "dandling" i.e. freed pointer in this |
* NOTE : in->base may be a "dandling" i.e. freed pointer in this |
Line 256 xmlEntityPtr xmlParseStringEntityRef(xml
|
Line 269 xmlEntityPtr xmlParseStringEntityRef(xml
|
* Generic function for accessing stacks in the Parser Context |
* Generic function for accessing stacks in the Parser Context |
*/ |
*/ |
|
|
#define PUSH_AND_POP(type, name) \ |
#define PUSH_AND_POP(scope, type, name) \ |
extern int name##Push(xmlParserCtxtPtr ctxt, type value) { \ |
scope int name##Push(xmlParserCtxtPtr ctxt, type value) { \ |
if (ctxt->name##Nr >= ctxt->name##Max) { \ |
if (ctxt->name##Nr >= ctxt->name##Max) { \ |
ctxt->name##Max *= 2; \ |
ctxt->name##Max *= 2; \ |
ctxt->name##Tab = (void *) xmlRealloc(ctxt->name##Tab, \ |
ctxt->name##Tab = (void *) xmlRealloc(ctxt->name##Tab, \ |
Line 271 extern int name##Push(xmlParserCtxtPtr c
|
Line 284 extern int name##Push(xmlParserCtxtPtr c
|
ctxt->name = value; \ |
ctxt->name = value; \ |
return(ctxt->name##Nr++); \ |
return(ctxt->name##Nr++); \ |
} \ |
} \ |
extern type name##Pop(xmlParserCtxtPtr ctxt) { \ |
scope type name##Pop(xmlParserCtxtPtr ctxt) { \ |
type ret; \ |
type ret; \ |
if (ctxt->name##Nr <= 0) return(0); \ |
if (ctxt->name##Nr <= 0) return(0); \ |
ctxt->name##Nr--; \ |
ctxt->name##Nr--; \ |
Line 284 extern type name##Pop(xmlParserCtxtPtr c
|
Line 297 extern type name##Pop(xmlParserCtxtPtr c
|
return(ret); \ |
return(ret); \ |
} \ |
} \ |
|
|
PUSH_AND_POP(xmlParserInputPtr, input) |
PUSH_AND_POP(extern, xmlParserInputPtr, input) |
PUSH_AND_POP(xmlNodePtr, node) |
PUSH_AND_POP(extern, xmlNodePtr, node) |
|
PUSH_AND_POP(extern, xmlChar*, name) |
|
|
/* |
/* |
* Macros for accessing the content. Those should be used only by the parser, |
* Macros for accessing the content. Those should be used only by the parser, |
Line 444 xmlNewInputStream(xmlParserCtxtPtr ctxt)
|
Line 458 xmlNewInputStream(xmlParserCtxtPtr ctxt)
|
input->buf = NULL; |
input->buf = NULL; |
input->free = NULL; |
input->free = NULL; |
input->consumed = 0; |
input->consumed = 0; |
|
input->length = 0; |
return(input); |
return(input); |
} |
} |
|
|
Line 507 xmlNewEntityInputStream(xmlParserCtxtPtr
|
Line 522 xmlNewEntityInputStream(xmlParserCtxtPtr
|
input->filename = (char *) entity->SystemID; /* TODO !!! char <- xmlChar */ |
input->filename = (char *) entity->SystemID; /* TODO !!! char <- xmlChar */ |
input->base = entity->content; |
input->base = entity->content; |
input->cur = entity->content; |
input->cur = entity->content; |
|
input->length = entity->length; |
return(input); |
return(input); |
} |
} |
|
|
Line 535 xmlNewStringInputStream(xmlParserCtxtPtr
|
Line 551 xmlNewStringInputStream(xmlParserCtxtPtr
|
} |
} |
input->base = buffer; |
input->base = buffer; |
input->cur = buffer; |
input->cur = buffer; |
|
input->length = xmlStrlen(buffer); |
return(input); |
return(input); |
} |
} |
|
|
Line 556 xmlNewInputFromFile(xmlParserCtxtPtr ctx
|
Line 573 xmlNewInputFromFile(xmlParserCtxtPtr ctx
|
if (ctxt == NULL) return(NULL); |
if (ctxt == NULL) return(NULL); |
buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE); |
buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE); |
if (buf == NULL) { |
if (buf == NULL) { |
char name[1024]; |
char name[XML_PARSER_BIG_BUFFER_SIZE]; |
|
|
if ((ctxt->input != NULL) && (ctxt->input->directory != NULL)) { |
if ((ctxt->input != NULL) && (ctxt->input->directory != NULL)) { |
#ifdef WIN32 |
#ifdef WIN32 |
Line 638 xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
|
Line 655 xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
|
ctxt->hasPErefs = 0; |
ctxt->hasPErefs = 0; |
ctxt->html = 0; |
ctxt->html = 0; |
ctxt->external = 0; |
ctxt->external = 0; |
ctxt->instate = XML_PARSER_PROLOG; |
ctxt->instate = XML_PARSER_START; |
ctxt->token = 0; |
ctxt->token = 0; |
ctxt->directory = NULL; |
ctxt->directory = NULL; |
|
|
Line 648 xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
|
Line 665 xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
|
ctxt->nodeMax = 10; |
ctxt->nodeMax = 10; |
ctxt->node = NULL; |
ctxt->node = NULL; |
|
|
|
/* Allocate the Name stack */ |
|
ctxt->nameTab = (xmlChar **) xmlMalloc(10 * sizeof(xmlChar *)); |
|
ctxt->nameNr = 0; |
|
ctxt->nameMax = 10; |
|
ctxt->name = NULL; |
|
|
if (sax == NULL) ctxt->sax = &xmlDefaultSAXHandler; |
if (sax == NULL) ctxt->sax = &xmlDefaultSAXHandler; |
else { |
else { |
ctxt->sax = sax; |
ctxt->sax = sax; |
Line 664 xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
|
Line 687 xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
|
ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue; |
ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue; |
ctxt->record_info = 0; |
ctxt->record_info = 0; |
ctxt->nbChars = 0; |
ctxt->nbChars = 0; |
|
ctxt->checkIndex = 0; |
|
ctxt->errNo = XML_ERR_OK; |
xmlInitNodeInfoSeq(&ctxt->node_seq); |
xmlInitNodeInfoSeq(&ctxt->node_seq); |
} |
} |
|
|
Line 679 void
|
Line 704 void
|
xmlFreeParserCtxt(xmlParserCtxtPtr ctxt) |
xmlFreeParserCtxt(xmlParserCtxtPtr ctxt) |
{ |
{ |
xmlParserInputPtr input; |
xmlParserInputPtr input; |
|
xmlChar *oldname; |
|
|
if (ctxt == NULL) return; |
if (ctxt == NULL) return; |
|
|
while ((input = inputPop(ctxt)) != NULL) { |
while ((input = inputPop(ctxt)) != NULL) { |
xmlFreeInputStream(input); |
xmlFreeInputStream(input); |
} |
} |
|
while ((oldname = namePop(ctxt)) != NULL) { |
|
xmlFree(oldname); |
|
} |
|
if (ctxt->nameTab != NULL) xmlFree(ctxt->nameTab); |
if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab); |
if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab); |
if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab); |
if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab); |
if (ctxt->version != NULL) xmlFree((char *) ctxt->version); |
if (ctxt->version != NULL) xmlFree((char *) ctxt->version); |
Line 970 fprintf(stderr, "xmlParserHandleReferenc
|
Line 999 fprintf(stderr, "xmlParserHandleReferenc
|
GROW; |
GROW; |
if ((CUR == '&') && (NXT(1) == '#')) { |
if ((CUR == '&') && (NXT(1) == '#')) { |
switch(ctxt->instate) { |
switch(ctxt->instate) { |
|
case XML_PARSER_ENTITY_DECL: |
|
case XML_PARSER_PI: |
case XML_PARSER_CDATA_SECTION: |
case XML_PARSER_CDATA_SECTION: |
return; |
|
case XML_PARSER_COMMENT: |
case XML_PARSER_COMMENT: |
|
/* we just ignore it there */ |
|
return; |
|
case XML_PARSER_START_TAG: |
|
return; |
|
case XML_PARSER_END_TAG: |
return; |
return; |
case XML_PARSER_EOF: |
case XML_PARSER_EOF: |
ctxt->errNo = XML_ERR_CHARREF_AT_EOF; |
ctxt->errNo = XML_ERR_CHARREF_AT_EOF; |
Line 981 fprintf(stderr, "xmlParserHandleReferenc
|
Line 1016 fprintf(stderr, "xmlParserHandleReferenc
|
ctxt->wellFormed = 0; |
ctxt->wellFormed = 0; |
return; |
return; |
case XML_PARSER_PROLOG: |
case XML_PARSER_PROLOG: |
|
case XML_PARSER_START: |
|
case XML_PARSER_MISC: |
ctxt->errNo = XML_ERR_CHARREF_IN_PROLOG; |
ctxt->errNo = XML_ERR_CHARREF_IN_PROLOG; |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
ctxt->sax->error(ctxt->userData, "CharRef in prolog!\n"); |
ctxt->sax->error(ctxt->userData, "CharRef in prolog!\n"); |
Line 999 fprintf(stderr, "xmlParserHandleReferenc
|
Line 1036 fprintf(stderr, "xmlParserHandleReferenc
|
"CharRef are forbiden in DTDs!\n"); |
"CharRef are forbiden in DTDs!\n"); |
ctxt->wellFormed = 0; |
ctxt->wellFormed = 0; |
return; |
return; |
case XML_PARSER_ENTITY_DECL: |
|
/* we just ignore it there */ |
|
return; |
|
case XML_PARSER_ENTITY_VALUE: |
case XML_PARSER_ENTITY_VALUE: |
/* |
/* |
* NOTE: in the case of entity values, we don't do the |
* NOTE: in the case of entity values, we don't do the |
Line 1023 fprintf(stderr, "xmlParserHandleReferenc
|
Line 1057 fprintf(stderr, "xmlParserHandleReferenc
|
switch(ctxt->instate) { |
switch(ctxt->instate) { |
case XML_PARSER_CDATA_SECTION: |
case XML_PARSER_CDATA_SECTION: |
return; |
return; |
|
case XML_PARSER_PI: |
case XML_PARSER_COMMENT: |
case XML_PARSER_COMMENT: |
return; |
return; |
|
case XML_PARSER_START_TAG: |
|
return; |
|
case XML_PARSER_END_TAG: |
|
return; |
case XML_PARSER_EOF: |
case XML_PARSER_EOF: |
ctxt->errNo = XML_ERR_ENTITYREF_AT_EOF; |
ctxt->errNo = XML_ERR_ENTITYREF_AT_EOF; |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
Line 1032 fprintf(stderr, "xmlParserHandleReferenc
|
Line 1071 fprintf(stderr, "xmlParserHandleReferenc
|
ctxt->wellFormed = 0; |
ctxt->wellFormed = 0; |
return; |
return; |
case XML_PARSER_PROLOG: |
case XML_PARSER_PROLOG: |
|
case XML_PARSER_START: |
|
case XML_PARSER_MISC: |
ctxt->errNo = XML_ERR_ENTITYREF_IN_PROLOG; |
ctxt->errNo = XML_ERR_ENTITYREF_IN_PROLOG; |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
ctxt->sax->error(ctxt->userData, "Reference in prolog!\n"); |
ctxt->sax->error(ctxt->userData, "Reference in prolog!\n"); |
Line 1195 fprintf(stderr, "xmlParserHandlePERefere
|
Line 1236 fprintf(stderr, "xmlParserHandlePERefere
|
return; |
return; |
case XML_PARSER_COMMENT: |
case XML_PARSER_COMMENT: |
return; |
return; |
|
case XML_PARSER_START_TAG: |
|
return; |
|
case XML_PARSER_END_TAG: |
|
return; |
case XML_PARSER_EOF: |
case XML_PARSER_EOF: |
ctxt->errNo = XML_ERR_PEREF_AT_EOF; |
ctxt->errNo = XML_ERR_PEREF_AT_EOF; |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
Line 1202 fprintf(stderr, "xmlParserHandlePERefere
|
Line 1247 fprintf(stderr, "xmlParserHandlePERefere
|
ctxt->wellFormed = 0; |
ctxt->wellFormed = 0; |
return; |
return; |
case XML_PARSER_PROLOG: |
case XML_PARSER_PROLOG: |
|
case XML_PARSER_START: |
|
case XML_PARSER_MISC: |
ctxt->errNo = XML_ERR_PEREF_IN_PROLOG; |
ctxt->errNo = XML_ERR_PEREF_IN_PROLOG; |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
ctxt->sax->error(ctxt->userData, "PEReference in prolog!\n"); |
ctxt->sax->error(ctxt->userData, "PEReference in prolog!\n"); |
Line 1210 fprintf(stderr, "xmlParserHandlePERefere
|
Line 1257 fprintf(stderr, "xmlParserHandlePERefere
|
case XML_PARSER_ENTITY_DECL: |
case XML_PARSER_ENTITY_DECL: |
case XML_PARSER_CONTENT: |
case XML_PARSER_CONTENT: |
case XML_PARSER_ATTRIBUTE_VALUE: |
case XML_PARSER_ATTRIBUTE_VALUE: |
|
case XML_PARSER_PI: |
/* we just ignore it there */ |
/* we just ignore it there */ |
return; |
return; |
case XML_PARSER_EPILOG: |
case XML_PARSER_EPILOG: |
Line 1355 xmlDecodeEntities(xmlParserCtxtPtr ctxt,
|
Line 1403 xmlDecodeEntities(xmlParserCtxtPtr ctxt,
|
/* |
/* |
* allocate a translation buffer. |
* allocate a translation buffer. |
*/ |
*/ |
buffer_size = 1000; |
buffer_size = XML_PARSER_BIG_BUFFER_SIZE; |
buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); |
buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); |
if (buffer == NULL) { |
if (buffer == NULL) { |
perror("xmlDecodeEntities: malloc failed"); |
perror("xmlDecodeEntities: malloc failed"); |
Line 1382 xmlDecodeEntities(xmlParserCtxtPtr ctxt,
|
Line 1430 xmlDecodeEntities(xmlParserCtxtPtr ctxt,
|
current = ent->content; |
current = ent->content; |
while (*current != 0) { |
while (*current != 0) { |
*out++ = *current++; |
*out++ = *current++; |
if (out - buffer > buffer_size - 100) { |
if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) { |
int index = out - buffer; |
int index = out - buffer; |
|
|
growBuffer(buffer); |
growBuffer(buffer); |
Line 1396 xmlDecodeEntities(xmlParserCtxtPtr ctxt,
|
Line 1444 xmlDecodeEntities(xmlParserCtxtPtr ctxt,
|
|
|
nbchars += i + 2; |
nbchars += i + 2; |
*out++ = '&'; |
*out++ = '&'; |
if (out - buffer > buffer_size - i - 100) { |
if (out - buffer > buffer_size - i - XML_PARSER_BUFFER_SIZE) { |
int index = out - buffer; |
int index = out - buffer; |
|
|
growBuffer(buffer); |
growBuffer(buffer); |
Line 1427 xmlDecodeEntities(xmlParserCtxtPtr ctxt,
|
Line 1475 xmlDecodeEntities(xmlParserCtxtPtr ctxt,
|
/* invalid for UTF-8 , use COPY(out); !!!!!! */ |
/* invalid for UTF-8 , use COPY(out); !!!!!! */ |
*out++ = cur; |
*out++ = cur; |
nbchars++; |
nbchars++; |
if (out - buffer > buffer_size - 100) { |
if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) { |
int index = out - buffer; |
int index = out - buffer; |
|
|
growBuffer(buffer); |
growBuffer(buffer); |
Line 1471 xmlStringDecodeEntities(xmlParserCtxtPtr
|
Line 1519 xmlStringDecodeEntities(xmlParserCtxtPtr
|
/* |
/* |
* allocate a translation buffer. |
* allocate a translation buffer. |
*/ |
*/ |
buffer_size = 500; |
buffer_size = XML_PARSER_BIG_BUFFER_SIZE; |
buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); |
buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); |
if (buffer == NULL) { |
if (buffer == NULL) { |
perror("xmlDecodeEntities: malloc failed"); |
perror("xmlDecodeEntities: malloc failed"); |
Line 1498 xmlStringDecodeEntities(xmlParserCtxtPtr
|
Line 1546 xmlStringDecodeEntities(xmlParserCtxtPtr
|
current = ent->content; |
current = ent->content; |
while (*current != 0) { |
while (*current != 0) { |
*out++ = *current++; |
*out++ = *current++; |
if (out - buffer > buffer_size - 100) { |
if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) { |
int index = out - buffer; |
int index = out - buffer; |
|
|
growBuffer(buffer); |
growBuffer(buffer); |
Line 1510 xmlStringDecodeEntities(xmlParserCtxtPtr
|
Line 1558 xmlStringDecodeEntities(xmlParserCtxtPtr
|
const xmlChar *cur = ent->name; |
const xmlChar *cur = ent->name; |
|
|
*out++ = '&'; |
*out++ = '&'; |
if (out - buffer > buffer_size - i - 100) { |
if (out - buffer > buffer_size - i - XML_PARSER_BUFFER_SIZE) { |
int index = out - buffer; |
int index = out - buffer; |
|
|
growBuffer(buffer); |
growBuffer(buffer); |
Line 1526 xmlStringDecodeEntities(xmlParserCtxtPtr
|
Line 1574 xmlStringDecodeEntities(xmlParserCtxtPtr
|
current = ent->content; |
current = ent->content; |
while (*current != 0) { |
while (*current != 0) { |
*out++ = *current++; |
*out++ = *current++; |
if (out - buffer > buffer_size - 100) { |
if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) { |
int index = out - buffer; |
int index = out - buffer; |
|
|
growBuffer(buffer); |
growBuffer(buffer); |
Line 1537 xmlStringDecodeEntities(xmlParserCtxtPtr
|
Line 1585 xmlStringDecodeEntities(xmlParserCtxtPtr
|
} else { |
} else { |
/* invalid for UTF-8 , use COPY(out); !!!!!! */ |
/* invalid for UTF-8 , use COPY(out); !!!!!! */ |
*out++ = cur; |
*out++ = cur; |
if (out - buffer > buffer_size - 100) { |
if (out - buffer > buffer_size - XML_PARSER_BUFFER_SIZE) { |
int index = out - buffer; |
int index = out - buffer; |
|
|
growBuffer(buffer); |
growBuffer(buffer); |
Line 2016 xmlStrcat(xmlChar *cur, const xmlChar *a
|
Line 2064 xmlStrcat(xmlChar *cur, const xmlChar *a
|
* |
* |
* Is this a sequence of blank chars that one can ignore ? |
* Is this a sequence of blank chars that one can ignore ? |
* |
* |
* TODO: Whether white space are significant has to be checked accordingly |
|
* to DTD informations if available |
|
* |
|
* Returns 1 if ignorable 0 otherwise. |
* Returns 1 if ignorable 0 otherwise. |
*/ |
*/ |
|
|
Line 2284 xmlChar *
|
Line 2329 xmlChar *
|
xmlParseQuotedString(xmlParserCtxtPtr ctxt) { |
xmlParseQuotedString(xmlParserCtxtPtr ctxt) { |
xmlChar *buf = NULL; |
xmlChar *buf = NULL; |
int len = 0; |
int len = 0; |
int size = 100; |
int size = XML_PARSER_BUFFER_SIZE; |
xmlChar c; |
xmlChar c; |
|
|
buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); |
buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); |
Line 2668 xmlChar *
|
Line 2713 xmlChar *
|
xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) { |
xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) { |
xmlChar *buf = NULL; |
xmlChar *buf = NULL; |
int len = 0; |
int len = 0; |
int size = 100; |
int size = XML_PARSER_BUFFER_SIZE; |
xmlChar c; |
xmlChar c; |
xmlChar stop; |
xmlChar stop; |
xmlChar *ret = NULL; |
xmlChar *ret = NULL; |
Line 2823 xmlParseAttValue(xmlParserCtxtPtr ctxt)
|
Line 2868 xmlParseAttValue(xmlParserCtxtPtr ctxt)
|
/* |
/* |
* allocate a translation buffer. |
* allocate a translation buffer. |
*/ |
*/ |
buffer_size = 100; |
buffer_size = XML_PARSER_BUFFER_SIZE; |
buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); |
buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); |
if (buffer == NULL) { |
if (buffer == NULL) { |
perror("xmlParseAttValue: malloc failed"); |
perror("xmlParseAttValue: malloc failed"); |
Line 2836 xmlParseAttValue(xmlParserCtxtPtr ctxt)
|
Line 2881 xmlParseAttValue(xmlParserCtxtPtr ctxt)
|
*/ |
*/ |
cur = CUR; |
cur = CUR; |
while ((cur != limit) && (cur != '<')) { |
while ((cur != limit) && (cur != '<')) { |
|
|
if (cur == 0) break; |
if (cur == 0) break; |
if ((cur == '&') && (NXT(1) == '#')) { |
if ((cur == '&') && (NXT(1) == '#')) { |
int val = xmlParseCharRef(ctxt); |
int val = xmlParseCharRef(ctxt); |
Line 2925 xmlChar *
|
Line 2969 xmlChar *
|
xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) { |
xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) { |
xmlChar *buf = NULL; |
xmlChar *buf = NULL; |
int len = 0; |
int len = 0; |
int size = 100; |
int size = XML_PARSER_BUFFER_SIZE; |
xmlChar cur; |
xmlChar cur; |
xmlChar stop; |
xmlChar stop; |
|
|
Line 2996 xmlChar *
|
Line 3040 xmlChar *
|
xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) { |
xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) { |
xmlChar *buf = NULL; |
xmlChar *buf = NULL; |
int len = 0; |
int len = 0; |
int size = 100; |
int size = XML_PARSER_BUFFER_SIZE; |
xmlChar cur; |
xmlChar cur; |
xmlChar stop; |
xmlChar stop; |
|
|
Line 3064 xmlParsePubidLiteral(xmlParserCtxtPtr ct
|
Line 3108 xmlParsePubidLiteral(xmlParserCtxtPtr ct
|
|
|
void |
void |
xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) { |
xmlParseCharData(xmlParserCtxtPtr ctxt, int cdata) { |
xmlChar buf[1000]; |
xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE]; |
int nbchar = 0; |
int nbchar = 0; |
xmlChar cur; |
xmlChar cur; |
|
|
SHRINK; |
SHRINK; |
/* |
|
* !!!!!!!!!!!! |
|
* NOTE: NXT(0) is used here to avoid breaking on < or & |
|
* entities substitutions. |
|
*/ |
|
cur = CUR; |
cur = CUR; |
while ((IS_CHAR(cur)) && (cur != '<') && |
while ((IS_CHAR(cur)) && (cur != '<') && |
(cur != '&')) { |
(cur != '&')) { |
Line 3082 xmlParseCharData(xmlParserCtxtPtr ctxt,
|
Line 3121 xmlParseCharData(xmlParserCtxtPtr ctxt,
|
if (cdata) break; |
if (cdata) break; |
else { |
else { |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
ctxt->sax->error(ctxt->userData, |
ctxt->sax->warning(ctxt->userData, |
"Sequence ']]>' not allowed in content\n"); |
"Sequence ']]>' not allowed in content\n"); |
ctxt->errNo = XML_ERR_MISPLACED_CDATA_END; |
ctxt->errNo = XML_ERR_MISPLACED_CDATA_END; |
ctxt->wellFormed = 0; |
|
} |
} |
} |
} |
buf[nbchar++] = CUR; |
buf[nbchar++] = CUR; |
if (nbchar == 1000) { |
if (nbchar == XML_PARSER_BIG_BUFFER_SIZE) { |
/* |
/* |
* Ok the segment is to be consumed as chars. |
* Ok the segment is to be consumed as chars. |
*/ |
*/ |
Line 3244 void
|
Line 3282 void
|
xmlParseComment(xmlParserCtxtPtr ctxt) { |
xmlParseComment(xmlParserCtxtPtr ctxt) { |
xmlChar *buf = NULL; |
xmlChar *buf = NULL; |
int len = 0; |
int len = 0; |
int size = 100; |
int size = XML_PARSER_BUFFER_SIZE; |
xmlChar q; |
xmlChar q; |
xmlChar r; |
xmlChar r; |
xmlChar cur; |
xmlChar cur; |
|
xmlParserInputState state; |
|
|
/* |
/* |
* Check that there is a comment right here. |
* Check that there is a comment right here. |
Line 3255 xmlParseComment(xmlParserCtxtPtr ctxt) {
|
Line 3294 xmlParseComment(xmlParserCtxtPtr ctxt) {
|
if ((CUR != '<') || (NXT(1) != '!') || |
if ((CUR != '<') || (NXT(1) != '!') || |
(NXT(2) != '-') || (NXT(3) != '-')) return; |
(NXT(2) != '-') || (NXT(3) != '-')) return; |
|
|
|
state = ctxt->instate; |
ctxt->instate = XML_PARSER_COMMENT; |
ctxt->instate = XML_PARSER_COMMENT; |
SHRINK; |
SHRINK; |
SKIP(4); |
SKIP(4); |
buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); |
buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); |
if (buf == NULL) { |
if (buf == NULL) { |
fprintf(stderr, "malloc of %d byte failed\n", size); |
fprintf(stderr, "malloc of %d byte failed\n", size); |
|
ctxt->instate = state; |
return; |
return; |
} |
} |
q = CUR; |
q = CUR; |
Line 3283 xmlParseComment(xmlParserCtxtPtr ctxt) {
|
Line 3324 xmlParseComment(xmlParserCtxtPtr ctxt) {
|
buf = xmlRealloc(buf, size * sizeof(xmlChar)); |
buf = xmlRealloc(buf, size * sizeof(xmlChar)); |
if (buf == NULL) { |
if (buf == NULL) { |
fprintf(stderr, "realloc of %d byte failed\n", size); |
fprintf(stderr, "realloc of %d byte failed\n", size); |
|
ctxt->instate = state; |
return; |
return; |
} |
} |
} |
} |
Line 3310 xmlParseComment(xmlParserCtxtPtr ctxt) {
|
Line 3352 xmlParseComment(xmlParserCtxtPtr ctxt) {
|
ctxt->sax->comment(ctxt->userData, buf); |
ctxt->sax->comment(ctxt->userData, buf); |
xmlFree(buf); |
xmlFree(buf); |
} |
} |
|
ctxt->instate = state; |
} |
} |
|
|
/** |
/** |
Line 3362 void
|
Line 3405 void
|
xmlParsePI(xmlParserCtxtPtr ctxt) { |
xmlParsePI(xmlParserCtxtPtr ctxt) { |
xmlChar *buf = NULL; |
xmlChar *buf = NULL; |
int len = 0; |
int len = 0; |
int size = 100; |
int size = XML_PARSER_BUFFER_SIZE; |
xmlChar cur; |
xmlChar cur; |
xmlChar *target; |
xmlChar *target; |
|
xmlParserInputState state; |
|
|
if ((CUR == '<') && (NXT(1) == '?')) { |
if ((CUR == '<') && (NXT(1) == '?')) { |
|
state = ctxt->instate; |
|
ctxt->instate = XML_PARSER_PI; |
/* |
/* |
* this is a Processing Instruction. |
* this is a Processing Instruction. |
*/ |
*/ |
Line 3382 xmlParsePI(xmlParserCtxtPtr ctxt) {
|
Line 3428 xmlParsePI(xmlParserCtxtPtr ctxt) {
|
buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); |
buf = (xmlChar *) xmlMalloc(size * sizeof(xmlChar)); |
if (buf == NULL) { |
if (buf == NULL) { |
fprintf(stderr, "malloc of %d byte failed\n", size); |
fprintf(stderr, "malloc of %d byte failed\n", size); |
|
ctxt->instate = state; |
return; |
return; |
} |
} |
cur = CUR; |
cur = CUR; |
Line 3401 xmlParsePI(xmlParserCtxtPtr ctxt) {
|
Line 3448 xmlParsePI(xmlParserCtxtPtr ctxt) {
|
buf = xmlRealloc(buf, size * sizeof(xmlChar)); |
buf = xmlRealloc(buf, size * sizeof(xmlChar)); |
if (buf == NULL) { |
if (buf == NULL) { |
fprintf(stderr, "realloc of %d byte failed\n", size); |
fprintf(stderr, "realloc of %d byte failed\n", size); |
|
ctxt->instate = state; |
return; |
return; |
} |
} |
} |
} |
Line 3440 xmlParsePI(xmlParserCtxtPtr ctxt) {
|
Line 3488 xmlParsePI(xmlParserCtxtPtr ctxt) {
|
ctxt->errNo = XML_ERR_PI_NOT_STARTED; |
ctxt->errNo = XML_ERR_PI_NOT_STARTED; |
ctxt->wellFormed = 0; |
ctxt->wellFormed = 0; |
} |
} |
|
ctxt->instate = state; |
} |
} |
} |
} |
|
|
Line 3980 xmlParseEnumeratedType(xmlParserCtxtPtr
|
Line 4029 xmlParseEnumeratedType(xmlParserCtxtPtr
|
* |
* |
* [ VC: IDREF ] |
* [ VC: IDREF ] |
* Values of type IDREF must match the Name production, and values |
* Values of type IDREF must match the Name production, and values |
* of type IDREFS must match Names; TODO each IDREF Name must match the value |
* 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 |
* of an ID attribute on some element in the XML document; i.e. IDREF |
* values must match the value of some ID attribute. |
* values must match the value of some ID attribute. |
* |
* |
* [ VC: Entity Name ] |
* [ VC: Entity Name ] |
* Values of type ENTITY must match the Name production, values |
* Values of type ENTITY must match the Name production, values |
* of type ENTITIES must match Names; TODO each Entity Name must match the |
* of type ENTITIES must match Names; each Entity Name must match the |
* name of an unparsed entity declared in the DTD. |
* name of an unparsed entity declared in the DTD. |
* |
* |
* [ VC: Name Token ] |
* [ VC: Name Token ] |
Line 5565 xmlParseDocTypeDecl(xmlParserCtxtPtr ctx
|
Line 5614 xmlParseDocTypeDecl(xmlParserCtxtPtr ctx
|
ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI); |
ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI); |
|
|
/* |
/* |
|
* Cleanup |
|
*/ |
|
if (URI != NULL) xmlFree(URI); |
|
if (ExternalID != NULL) xmlFree(ExternalID); |
|
if (name != NULL) xmlFree(name); |
|
|
|
/* |
|
* Is there any internal subset declarations ? |
|
* they are handled separately in xmlParseInternalSubset() |
|
*/ |
|
if (CUR == '[') |
|
return; |
|
|
|
/* |
|
* We should be at the end of the DOCTYPE declaration. |
|
*/ |
|
if (CUR != '>') { |
|
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
|
ctxt->sax->error(ctxt->userData, "DOCTYPE unproperly terminated\n"); |
|
ctxt->wellFormed = 0; |
|
ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED; |
|
} |
|
NEXT; |
|
} |
|
|
|
/** |
|
* xmlParseInternalsubset : |
|
* @ctxt: an XML parser context |
|
* |
|
* parse the internal subset declaration |
|
* |
|
* [28 end] ('[' (markupdecl | PEReference | S)* ']' S?)? '>' |
|
*/ |
|
|
|
void |
|
xmlParseInternalSubset(xmlParserCtxtPtr ctxt) { |
|
/* |
* Is there any DTD definition ? |
* Is there any DTD definition ? |
*/ |
*/ |
if (CUR == '[') { |
if (CUR == '[') { |
Line 5592 xmlParseDocTypeDecl(xmlParserCtxtPtr ctx
|
Line 5678 xmlParseDocTypeDecl(xmlParserCtxtPtr ctx
|
if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) { |
if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) { |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
ctxt->sax->error(ctxt->userData, |
ctxt->sax->error(ctxt->userData, |
"xmlParseDocTypeDecl: error detected in Markup declaration\n"); |
"xmlParseInternalSubset: error detected in Markup declaration\n"); |
ctxt->wellFormed = 0; |
ctxt->wellFormed = 0; |
ctxt->errNo = XML_ERR_INTERNAL_ERROR; |
ctxt->errNo = XML_ERR_INTERNAL_ERROR; |
break; |
break; |
Line 5611 xmlParseDocTypeDecl(xmlParserCtxtPtr ctx
|
Line 5697 xmlParseDocTypeDecl(xmlParserCtxtPtr ctx
|
ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED; |
ctxt->errNo = XML_ERR_DOCTYPE_NOT_FINISHED; |
} |
} |
NEXT; |
NEXT; |
|
|
/* |
|
* Cleanup |
|
*/ |
|
if (URI != NULL) xmlFree(URI); |
|
if (ExternalID != NULL) xmlFree(ExternalID); |
|
if (name != NULL) xmlFree(name); |
|
} |
} |
|
|
/** |
/** |
Line 5830 failed:
|
Line 5909 failed:
|
/** |
/** |
* xmlParseEndTag: |
* xmlParseEndTag: |
* @ctxt: an XML parser context |
* @ctxt: an XML parser context |
* @tagname: the tag name as parsed in the opening tag. |
|
* |
* |
* parse an end of tag |
* parse an end of tag |
* |
* |
Line 5842 failed:
|
Line 5920 failed:
|
*/ |
*/ |
|
|
void |
void |
xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlChar *tagname) { |
xmlParseEndTag(xmlParserCtxtPtr ctxt) { |
xmlChar *name; |
xmlChar *name; |
|
xmlChar *oldname; |
|
|
GROW; |
GROW; |
if ((CUR != '<') || (NXT(1) != '/')) { |
if ((CUR != '<') || (NXT(1) != '/')) { |
Line 5876 xmlParseEndTag(xmlParserCtxtPtr ctxt, xm
|
Line 5955 xmlParseEndTag(xmlParserCtxtPtr ctxt, xm
|
* start-tag. |
* start-tag. |
* |
* |
*/ |
*/ |
if (xmlStrcmp(name, tagname)) { |
if (xmlStrcmp(name, ctxt->name)) { |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
ctxt->sax->error(ctxt->userData, |
ctxt->sax->error(ctxt->userData, |
"Opening and ending tag mismatch: %s and %s\n", tagname, name); |
"Opening and ending tag mismatch: %s and %s\n", ctxt->name, name); |
|
|
ctxt->errNo = XML_ERR_TAG_NAME_MISMATCH; |
ctxt->errNo = XML_ERR_TAG_NAME_MISMATCH; |
ctxt->wellFormed = 0; |
ctxt->wellFormed = 0; |
Line 5893 xmlParseEndTag(xmlParserCtxtPtr ctxt, xm
|
Line 5972 xmlParseEndTag(xmlParserCtxtPtr ctxt, xm
|
|
|
if (name != NULL) |
if (name != NULL) |
xmlFree(name); |
xmlFree(name); |
|
oldname = namePop(ctxt); |
|
if (oldname != NULL) { |
|
#ifdef DEBUG_STACK |
|
fprintf(stderr,"Close: popped %s\n", oldname); |
|
#endif |
|
xmlFree(oldname); |
|
} |
return; |
return; |
} |
} |
|
|
Line 5915 void
|
Line 6000 void
|
xmlParseCDSect(xmlParserCtxtPtr ctxt) { |
xmlParseCDSect(xmlParserCtxtPtr ctxt) { |
xmlChar *buf = NULL; |
xmlChar *buf = NULL; |
int len = 0; |
int len = 0; |
int size = 100; |
int size = XML_PARSER_BUFFER_SIZE; |
xmlChar r, s; |
xmlChar r, s; |
xmlChar cur; |
xmlChar cur; |
|
|
Line 6113 void
|
Line 6198 void
|
xmlParseElement(xmlParserCtxtPtr ctxt) { |
xmlParseElement(xmlParserCtxtPtr ctxt) { |
const xmlChar *openTag = CUR_PTR; |
const xmlChar *openTag = CUR_PTR; |
xmlChar *name; |
xmlChar *name; |
|
xmlChar *oldname; |
xmlParserNodeInfo node_info; |
xmlParserNodeInfo node_info; |
xmlNodePtr ret; |
xmlNodePtr ret; |
|
|
Line 6127 xmlParseElement(xmlParserCtxtPtr ctxt) {
|
Line 6213 xmlParseElement(xmlParserCtxtPtr ctxt) {
|
if (name == NULL) { |
if (name == NULL) { |
return; |
return; |
} |
} |
|
namePush(ctxt, name); |
ret = ctxt->node; |
ret = ctxt->node; |
|
|
/* |
/* |
Line 6145 xmlParseElement(xmlParserCtxtPtr ctxt) {
|
Line 6232 xmlParseElement(xmlParserCtxtPtr ctxt) {
|
SKIP(2); |
SKIP(2); |
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL)) |
ctxt->sax->endElement(ctxt->userData, name); |
ctxt->sax->endElement(ctxt->userData, name); |
xmlFree(name); |
oldname = namePop(ctxt); |
|
if (oldname != NULL) { |
|
#ifdef DEBUG_STACK |
|
fprintf(stderr,"Close: popped %s\n", oldname); |
|
#endif |
|
xmlFree(oldname); |
|
} |
return; |
return; |
} |
} |
if (CUR == '>') { |
if (CUR == '>') { |
Line 6162 xmlParseElement(xmlParserCtxtPtr ctxt) {
|
Line 6255 xmlParseElement(xmlParserCtxtPtr ctxt) {
|
* end of parsing of this node. |
* end of parsing of this node. |
*/ |
*/ |
nodePop(ctxt); |
nodePop(ctxt); |
xmlFree(name); |
oldname = namePop(ctxt); |
|
if (oldname != NULL) { |
|
#ifdef DEBUG_STACK |
|
fprintf(stderr,"Close: popped %s\n", oldname); |
|
#endif |
|
xmlFree(oldname); |
|
} |
|
|
/* |
/* |
* Capture end position and add node |
* Capture end position and add node |
Line 6192 xmlParseElement(xmlParserCtxtPtr ctxt) {
|
Line 6291 xmlParseElement(xmlParserCtxtPtr ctxt) {
|
* end of parsing of this node. |
* end of parsing of this node. |
*/ |
*/ |
nodePop(ctxt); |
nodePop(ctxt); |
xmlFree(name); |
oldname = namePop(ctxt); |
|
if (oldname != NULL) { |
|
#ifdef DEBUG_STACK |
|
fprintf(stderr,"Close: popped %s\n", oldname); |
|
#endif |
|
xmlFree(oldname); |
|
} |
return; |
return; |
} |
} |
|
|
/* |
/* |
* parse the end of tag: '</' should be here. |
* parse the end of tag: '</' should be here. |
*/ |
*/ |
xmlParseEndTag(ctxt, name); |
xmlParseEndTag(ctxt); |
xmlFree(name); |
|
|
|
/* |
/* |
* Capture end position and add node |
* Capture end position and add node |
Line 6771 xmlParseDocument(xmlParserCtxtPtr ctxt)
|
Line 6875 xmlParseDocument(xmlParserCtxtPtr ctxt)
|
(NXT(6) == 'Y') && (NXT(7) == 'P') && |
(NXT(6) == 'Y') && (NXT(7) == 'P') && |
(NXT(8) == 'E')) { |
(NXT(8) == 'E')) { |
xmlParseDocTypeDecl(ctxt); |
xmlParseDocTypeDecl(ctxt); |
|
if (CUR == '[') { |
|
ctxt->instate = XML_PARSER_DTD; |
|
xmlParseInternalSubset(ctxt); |
|
} |
ctxt->instate = XML_PARSER_PROLOG; |
ctxt->instate = XML_PARSER_PROLOG; |
xmlParseMisc(ctxt); |
xmlParseMisc(ctxt); |
} |
} |
Line 6779 xmlParseDocument(xmlParserCtxtPtr ctxt)
|
Line 6887 xmlParseDocument(xmlParserCtxtPtr ctxt)
|
* Time to start parsing the tree itself |
* Time to start parsing the tree itself |
*/ |
*/ |
GROW; |
GROW; |
ctxt->instate = XML_PARSER_CONTENT; |
if (CUR != '<') { |
xmlParseElement(ctxt); |
|
ctxt->instate = XML_PARSER_EPILOG; |
|
|
|
/* |
|
* The Misc part at the end |
|
*/ |
|
xmlParseMisc(ctxt); |
|
|
|
if (CUR != 0) { |
|
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
ctxt->sax->error(ctxt->userData, |
ctxt->sax->error(ctxt->userData, |
"Extra content at the end of the document\n"); |
"Start tag expect, '<' not found\n"); |
|
ctxt->errNo = XML_ERR_DOCUMENT_EMPTY; |
ctxt->wellFormed = 0; |
ctxt->wellFormed = 0; |
ctxt->errNo = XML_ERR_DOCUMENT_END; |
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); |
|
|
|
if (CUR != 0) { |
|
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; |
|
ctxt->errNo = XML_ERR_DOCUMENT_END; |
|
} |
|
ctxt->instate = XML_PARSER_EOF; |
} |
} |
ctxt->instate = XML_PARSER_EOF; |
|
|
|
/* |
/* |
* SAX: end of the document processing. |
* SAX: end of the document processing. |
Line 6816 xmlParseDocument(xmlParserCtxtPtr ctxt)
|
Line 6934 xmlParseDocument(xmlParserCtxtPtr ctxt)
|
* xmlParseLookupSequence: |
* xmlParseLookupSequence: |
* @ctxt: an XML parser context |
* @ctxt: an XML parser context |
* @first: the first char to lookup |
* @first: the first char to lookup |
* @next: the next 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) or just (first) if next |
* Try to find if a sequence (first, next, third) or just (first next) or |
* is zero is available in the input stream. |
* (first) is available in the input stream. |
* Since XML-1.0 is an LALR(2) grammar a sequence of 2 char should be |
* This function has a side effect of (possibly) incrementing ctxt->checkIndex |
* enought. If this doesn't prove true this function call may change. |
* to avoid rescanning sequences of bytes, it DOES change the state of the |
|
* parser, do not use liberally. |
* |
* |
* Returns 1 if the full sequence is available, 0 otherwise. |
* Returns the index to the current parsing point if the full sequence |
|
* is available, -1 otherwise. |
*/ |
*/ |
int |
int |
xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first, xmlChar next) { |
xmlParseLookupSequence(xmlParserCtxtPtr ctxt, xmlChar first, |
return(0); |
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) |
|
fprintf(stderr, "PP: lookup '%c' found at %d\n", |
|
first, base); |
|
else if (third == 0) |
|
fprintf(stderr, "PP: lookup '%c%c' found at %d\n", |
|
first, next, base); |
|
else |
|
fprintf(stderr, "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) |
|
fprintf(stderr, "PP: lookup '%c' failed\n", first); |
|
else if (third == 0) |
|
fprintf(stderr, "PP: lookup '%c%c' failed\n", first, next); |
|
else |
|
fprintf(stderr, "PP: lookup '%c%c%c' failed\n", first, next, third); |
|
#endif |
|
return(-1); |
} |
} |
|
|
/** |
/** |
Line 6841 xmlParseLookupSequence(xmlParserCtxtPtr
|
Line 7015 xmlParseLookupSequence(xmlParserCtxtPtr
|
int |
int |
xmlParseTry(xmlParserCtxtPtr ctxt) { |
xmlParseTry(xmlParserCtxtPtr ctxt) { |
int ret = 0; |
int ret = 0; |
|
xmlParserInputPtr in; |
|
int avail; |
|
xmlChar cur, next; |
|
|
|
#ifdef DEBUG_PUSH |
|
switch (ctxt->instate) { |
|
case XML_PARSER_EOF: |
|
fprintf(stderr, "PP: try EOF\n"); break; |
|
case XML_PARSER_START: |
|
fprintf(stderr, "PP: try START\n"); break; |
|
case XML_PARSER_MISC: |
|
fprintf(stderr, "PP: try MISC\n");break; |
|
case XML_PARSER_COMMENT: |
|
fprintf(stderr, "PP: try COMMENT\n");break; |
|
case XML_PARSER_PROLOG: |
|
fprintf(stderr, "PP: try PROLOG\n");break; |
|
case XML_PARSER_START_TAG: |
|
fprintf(stderr, "PP: try START_TAG\n");break; |
|
case XML_PARSER_CONTENT: |
|
fprintf(stderr, "PP: try CONTENT\n");break; |
|
case XML_PARSER_CDATA_SECTION: |
|
fprintf(stderr, "PP: try CDATA_SECTION\n");break; |
|
case XML_PARSER_END_TAG: |
|
fprintf(stderr, "PP: try END_TAG\n");break; |
|
case XML_PARSER_ENTITY_DECL: |
|
fprintf(stderr, "PP: try ENTITY_DECL\n");break; |
|
case XML_PARSER_ENTITY_VALUE: |
|
fprintf(stderr, "PP: try ENTITY_VALUE\n");break; |
|
case XML_PARSER_ATTRIBUTE_VALUE: |
|
fprintf(stderr, "PP: try ATTRIBUTE_VALUE\n");break; |
|
case XML_PARSER_DTD: |
|
fprintf(stderr, "PP: try DTD\n");break; |
|
case XML_PARSER_EPILOG: |
|
fprintf(stderr, "PP: try EPILOG\n");break; |
|
case XML_PARSER_PI: |
|
fprintf(stderr, "PP: try PI\n");break; |
|
} |
|
#endif |
|
|
while (1) { |
while (1) { |
|
/* |
|
* Pop-up of finished entities. |
|
*/ |
|
while ((CUR == 0) && (ctxt->inputNr > 1)) |
|
xmlPopInput(ctxt); |
|
|
|
in = ctxt->input; |
|
if (in == NULL) break; |
|
if (in->buf == NULL) |
|
avail = in->length - (in->cur - in->base); |
|
else |
|
avail = in->buf->buffer->use - (in->cur - in->base); |
|
if (avail < 1) |
|
goto done; |
switch (ctxt->instate) { |
switch (ctxt->instate) { |
case XML_PARSER_EOF: |
case XML_PARSER_EOF: |
return(0); |
/* |
|
* Document parsing is done ! |
|
*/ |
|
goto done; |
|
case XML_PARSER_START: |
|
/* |
|
* Very first chars read from the document flow. |
|
*/ |
|
cur = in->cur[0]; |
|
if (IS_BLANK(cur)) { |
|
if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) |
|
ctxt->sax->setDocumentLocator(ctxt->userData, |
|
&xmlDefaultSAXLocator); |
|
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
|
ctxt->sax->error(ctxt->userData, |
|
"Extra spaces at the beginning of the document are not allowed\n"); |
|
ctxt->errNo = XML_ERR_DOCUMENT_START; |
|
ctxt->wellFormed = 0; |
|
SKIP_BLANKS; |
|
ret++; |
|
if (in->buf == NULL) |
|
avail = in->length - (in->cur - in->base); |
|
else |
|
avail = in->buf->buffer->use - (in->cur - in->base); |
|
} |
|
if (avail < 2) |
|
goto done; |
|
|
|
cur = in->cur[0]; |
|
next = in->cur[1]; |
|
if (cur == 0) { |
|
if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) |
|
ctxt->sax->setDocumentLocator(ctxt->userData, |
|
&xmlDefaultSAXLocator); |
|
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
|
ctxt->sax->error(ctxt->userData, "Document is empty\n"); |
|
ctxt->errNo = XML_ERR_DOCUMENT_EMPTY; |
|
ctxt->wellFormed = 0; |
|
ctxt->instate = XML_PARSER_EOF; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "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 (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0) |
|
return(ret); |
|
if ((ctxt->sax) && (ctxt->sax->setDocumentLocator)) |
|
ctxt->sax->setDocumentLocator(ctxt->userData, |
|
&xmlDefaultSAXLocator); |
|
if ((in->cur[2] == 'x') && |
|
(in->cur[3] == 'm') && |
|
(in->cur[4] == 'l')) { |
|
ret += 5; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing XML Decl\n"); |
|
#endif |
|
xmlParseXMLDecl(ctxt); |
|
if ((ctxt->sax) && (ctxt->sax->startDocument)) |
|
ctxt->sax->startDocument(ctxt->userData); |
|
ctxt->instate = XML_PARSER_MISC; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering MISC\n"); |
|
#endif |
|
} else { |
|
ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION); |
|
if ((ctxt->sax) && (ctxt->sax->startDocument)) |
|
ctxt->sax->startDocument(ctxt->userData); |
|
ctxt->instate = XML_PARSER_MISC; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "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->sax->startDocument(ctxt->userData); |
|
ctxt->instate = XML_PARSER_MISC; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering MISC\n"); |
|
#endif |
|
} |
|
break; |
|
case XML_PARSER_MISC: |
|
SKIP_BLANKS; |
|
if (in->buf == NULL) |
|
avail = in->length - (in->cur - in->base); |
|
else |
|
avail = in->buf->buffer->use - (in->cur - in->base); |
|
if (avail < 2) |
|
goto done; |
|
cur = in->cur[0]; |
|
next = in->cur[1]; |
|
if ((cur == '<') && (next == '?')) { |
|
if (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing PI\n"); |
|
#endif |
|
xmlParsePI(ctxt); |
|
} else if ((cur == '<') && (next == '!') && |
|
(in->cur[2] == '-') && (in->cur[3] == '-')) { |
|
if (xmlParseLookupSequence(ctxt, '-', '>', 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing Comment\n"); |
|
#endif |
|
xmlParseComment(ctxt); |
|
ctxt->instate = XML_PARSER_MISC; |
|
} else if ((cur == '<') && (next == '!') && |
|
(in->cur[2] == 'D') && (in->cur[3] == 'O') && |
|
(in->cur[4] == 'C') && (in->cur[5] == 'T') && |
|
(in->cur[6] == 'Y') && (in->cur[7] == 'P') && |
|
(in->cur[8] == 'E')) { |
|
if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing internal subset\n"); |
|
#endif |
|
xmlParseDocTypeDecl(ctxt); |
|
if (CUR == '[') { |
|
ctxt->instate = XML_PARSER_DTD; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering DTD\n"); |
|
#endif |
|
} else { |
|
ctxt->instate = XML_PARSER_PROLOG; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering PROLOG\n"); |
|
#endif |
|
} |
|
} else if ((cur == '<') && (next == '!') && |
|
(avail < 9)) { |
|
goto done; |
|
} else { |
|
ctxt->instate = XML_PARSER_START_TAG; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering START_TAG\n"); |
|
#endif |
|
} |
|
break; |
case XML_PARSER_PROLOG: |
case XML_PARSER_PROLOG: |
|
SKIP_BLANKS; |
|
if (in->buf == NULL) |
|
avail = in->length - (in->cur - in->base); |
|
else |
|
avail = in->buf->buffer->use - (in->cur - in->base); |
|
if (avail < 2) |
|
goto done; |
|
cur = in->cur[0]; |
|
next = in->cur[1]; |
|
if ((cur == '<') && (next == '?')) { |
|
if (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing PI\n"); |
|
#endif |
|
xmlParsePI(ctxt); |
|
} else if ((cur == '<') && (next == '!') && |
|
(in->cur[2] == '-') && (in->cur[3] == '-')) { |
|
if (xmlParseLookupSequence(ctxt, '-', '>', 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "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 |
|
fprintf(stderr, "PP: entering START_TAG\n"); |
|
#endif |
|
} |
|
break; |
|
case XML_PARSER_EPILOG: |
|
SKIP_BLANKS; |
|
if (in->buf == NULL) |
|
avail = in->length - (in->cur - in->base); |
|
else |
|
avail = in->buf->buffer->use - (in->cur - in->base); |
|
if (avail < 2) |
|
goto done; |
|
cur = in->cur[0]; |
|
next = in->cur[1]; |
|
if ((cur == '<') && (next == '?')) { |
|
if (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing PI\n"); |
|
#endif |
|
xmlParsePI(ctxt); |
|
ctxt->instate = XML_PARSER_EPILOG; |
|
} else if ((cur == '<') && (next == '!') && |
|
(in->cur[2] == '-') && (in->cur[3] == '-')) { |
|
if (xmlParseLookupSequence(ctxt, '-', '>', 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing Comment\n"); |
|
#endif |
|
xmlParseComment(ctxt); |
|
ctxt->instate = XML_PARSER_EPILOG; |
|
} else if ((cur == '<') && (next == '!') && |
|
(avail < 4)) { |
|
goto done; |
|
} else { |
|
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; |
|
ctxt->errNo = XML_ERR_DOCUMENT_END; |
|
ctxt->instate = XML_PARSER_EOF; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering EOF\n"); |
|
#endif |
|
if ((ctxt->sax) && (ctxt->sax->endDocument != NULL)) |
|
ctxt->sax->endDocument(ctxt->userData); |
|
goto done; |
|
} |
|
break; |
|
case XML_PARSER_START_TAG: { |
|
xmlChar *name, *oldname; |
|
|
|
if (avail < 2) |
|
goto done; |
|
cur = in->cur[0]; |
|
if (cur != '<') { |
|
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL)) |
|
ctxt->sax->error(ctxt->userData, |
|
"Start tag expect, '<' not found\n"); |
|
ctxt->errNo = XML_ERR_DOCUMENT_EMPTY; |
|
ctxt->wellFormed = 0; |
|
ctxt->instate = XML_PARSER_EOF; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering EOF\n"); |
|
#endif |
|
if ((ctxt->sax) && (ctxt->sax->endDocument != NULL)) |
|
ctxt->sax->endDocument(ctxt->userData); |
|
goto done; |
|
} |
|
if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) |
|
goto done; |
|
name = xmlParseStartTag(ctxt); |
|
if (name == NULL) { |
|
ctxt->instate = XML_PARSER_EOF; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering EOF\n"); |
|
#endif |
|
if ((ctxt->sax) && (ctxt->sax->endDocument != NULL)) |
|
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->root)) |
|
ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc); |
|
|
|
/* |
|
* Check for an Empty Element. |
|
*/ |
|
if ((CUR == '/') && (NXT(1) == '>')) { |
|
SKIP(2); |
|
if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL)) |
|
ctxt->sax->endElement(ctxt->userData, name); |
|
xmlFree(name); |
|
oldname = namePop(ctxt); |
|
if (oldname != NULL) { |
|
#ifdef DEBUG_STACK |
|
fprintf(stderr,"Close: popped %s\n", oldname); |
|
#endif |
|
xmlFree(oldname); |
|
} |
|
if (ctxt->name == NULL) { |
|
ctxt->instate = XML_PARSER_EPILOG; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering EPILOG\n"); |
|
#endif |
|
} else { |
|
ctxt->instate = XML_PARSER_CONTENT; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering CONTENT\n"); |
|
#endif |
|
} |
|
break; |
|
} |
|
if (CUR == '>') { |
|
NEXT; |
|
} else { |
|
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; |
|
ctxt->errNo = XML_ERR_GT_REQUIRED; |
|
|
|
/* |
|
* end of parsing of this node. |
|
*/ |
|
nodePop(ctxt); |
|
oldname = namePop(ctxt); |
|
if (oldname != NULL) { |
|
#ifdef DEBUG_STACK |
|
fprintf(stderr,"Close: popped %s\n", oldname); |
|
#endif |
|
xmlFree(oldname); |
|
} |
|
} |
|
xmlFree(name); |
|
ctxt->instate = XML_PARSER_CONTENT; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering CONTENT\n"); |
|
#endif |
|
break; |
|
} |
case XML_PARSER_CONTENT: |
case XML_PARSER_CONTENT: |
|
/* |
|
* Handle preparsed entities and charRef |
|
*/ |
|
if (ctxt->token != 0) { |
|
xmlChar cur[2] = { 0 , 0 } ; |
|
|
|
cur[0] = (xmlChar) ctxt->token; |
|
if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL)) |
|
ctxt->sax->characters(ctxt->userData, cur, 1); |
|
ctxt->token = 0; |
|
} |
|
if (avail < 2) |
|
goto done; |
|
cur = in->cur[0]; |
|
next = in->cur[1]; |
|
if ((cur == '<') && (next == '?')) { |
|
if (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing PI\n"); |
|
#endif |
|
xmlParsePI(ctxt); |
|
} else if ((cur == '<') && (next == '!') && |
|
(in->cur[2] == '-') && (in->cur[3] == '-')) { |
|
if (xmlParseLookupSequence(ctxt, '-', '>', 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing Comment\n"); |
|
#endif |
|
xmlParseComment(ctxt); |
|
ctxt->instate = XML_PARSER_CONTENT; |
|
} else if ((cur == '<') && (in->cur[1] == '!') && |
|
(in->cur[2] == '[') && (NXT(3) == 'C') && |
|
(in->cur[4] == 'D') && (NXT(5) == 'A') && |
|
(in->cur[6] == 'T') && (NXT(7) == 'A') && |
|
(in->cur[8] == '[')) { |
|
SKIP(9); |
|
ctxt->instate = XML_PARSER_CDATA_SECTION; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "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 |
|
fprintf(stderr, "PP: entering END_TAG\n"); |
|
#endif |
|
break; |
|
} else if (cur == '<') { |
|
ctxt->instate = XML_PARSER_START_TAG; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering START_TAG\n"); |
|
#endif |
|
break; |
|
} else if (cur == '&') { |
|
if (xmlParseLookupSequence(ctxt, ';', 0, 0) < 0) |
|
goto done; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing Reference\n"); |
|
#endif |
|
/* TODO: check generation of subtrees if noent !!! */ |
|
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 |
|
* callbacks beween the push and pull versions |
|
* of the parser. |
|
*/ |
|
if ((ctxt->inputNr == 1) && |
|
(avail < XML_PARSER_BIG_BUFFER_SIZE)) { |
|
if (xmlParseLookupSequence(ctxt, '<', 0, 0) < 0) |
|
goto done; |
|
} |
|
ctxt->checkIndex = 0; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: Parsing char data\n"); |
|
#endif |
|
xmlParseCharData(ctxt, 0); |
|
} |
|
/* |
|
* Pop-up of finished entities. |
|
*/ |
|
while ((CUR == 0) && (ctxt->inputNr > 1)) |
|
xmlPopInput(ctxt); |
|
break; |
|
case XML_PARSER_CDATA_SECTION: { |
|
/* |
|
* The Push mode need to have the SAX callback for |
|
* cdataBlock merge back contiguous callbacks. |
|
*/ |
|
int base; |
|
|
|
in = ctxt->input; |
|
base = xmlParseLookupSequence(ctxt, ']', ']', '>'); |
|
if (base < 0) { |
|
if (avail >= XML_PARSER_BIG_BUFFER_SIZE + 2) { |
|
if (ctxt->sax != NULL) { |
|
if (ctxt->sax->cdataBlock != NULL) |
|
ctxt->sax->cdataBlock(ctxt->userData, in->cur, |
|
XML_PARSER_BIG_BUFFER_SIZE); |
|
} |
|
SKIP(XML_PARSER_BIG_BUFFER_SIZE); |
|
ctxt->checkIndex = 0; |
|
} |
|
goto done; |
|
} else { |
|
if ((ctxt->sax != NULL) && (base > 0)) { |
|
if (ctxt->sax->cdataBlock != NULL) |
|
ctxt->sax->cdataBlock(ctxt->userData, |
|
in->cur, base); |
|
} |
|
SKIP(base + 3); |
|
ctxt->checkIndex = 0; |
|
ctxt->instate = XML_PARSER_CONTENT; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering CONTENT\n"); |
|
#endif |
|
} |
|
break; |
|
} |
|
case XML_PARSER_END_TAG: { |
|
if (avail < 2) |
|
goto done; |
|
if (xmlParseLookupSequence(ctxt, '>', 0, 0) < 0) |
|
goto done; |
|
xmlParseEndTag(ctxt); |
|
if (ctxt->name == NULL) { |
|
ctxt->instate = XML_PARSER_EPILOG; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering EPILOG\n"); |
|
#endif |
|
} else { |
|
ctxt->instate = XML_PARSER_CONTENT; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "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 = in->cur - in->base; |
|
if (base < 0) return(0); |
|
if (ctxt->checkIndex > base) |
|
base = ctxt->checkIndex; |
|
buf = in->buf->buffer->content; |
|
for (;base < in->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 (base +1 >= in->buf->buffer->use) |
|
break; |
|
if (buf[base + 1] == ']') { |
|
/* conditional crap, skip both ']' ! */ |
|
base++; |
|
continue; |
|
} |
|
for (i = 0;base + i < in->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) |
|
fprintf(stderr, "PP: lookup of int subset end filed\n"); |
|
#endif |
|
goto done; |
|
|
|
found_end_int_subset: |
|
xmlParseInternalSubset(ctxt); |
|
ctxt->instate = XML_PARSER_PROLOG; |
|
ctxt->checkIndex = 0; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering PROLOG\n"); |
|
#endif |
|
break; |
|
} |
|
case XML_PARSER_COMMENT: |
|
fprintf(stderr, "PP: internal error, state == COMMENT\n"); |
|
ctxt->instate = XML_PARSER_CONTENT; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering CONTENT\n"); |
|
#endif |
|
break; |
|
case XML_PARSER_PI: |
|
fprintf(stderr, "PP: internal error, state == PI\n"); |
|
ctxt->instate = XML_PARSER_CONTENT; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering CONTENT\n"); |
|
#endif |
|
break; |
case XML_PARSER_ENTITY_DECL: |
case XML_PARSER_ENTITY_DECL: |
|
fprintf(stderr, "PP: internal error, state == ENTITY_DECL\n"); |
|
ctxt->instate = XML_PARSER_DTD; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering DTD\n"); |
|
#endif |
|
break; |
case XML_PARSER_ENTITY_VALUE: |
case XML_PARSER_ENTITY_VALUE: |
|
fprintf(stderr, "PP: internal error, state == ENTITY_VALUE\n"); |
|
ctxt->instate = XML_PARSER_CONTENT; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: entering DTD\n"); |
|
#endif |
|
break; |
case XML_PARSER_ATTRIBUTE_VALUE: |
case XML_PARSER_ATTRIBUTE_VALUE: |
case XML_PARSER_DTD: |
fprintf(stderr, "PP: internal error, state == ATTRIBUTE_VALUE\n"); |
case XML_PARSER_EPILOG: |
ctxt->instate = XML_PARSER_START_TAG; |
case XML_PARSER_COMMENT: |
#ifdef DEBUG_PUSH |
case XML_PARSER_CDATA_SECTION: |
fprintf(stderr, "PP: entering START_TAG\n"); |
break; |
#endif |
|
break; |
} |
} |
} |
} |
|
done: |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: done %d\n", ret); |
|
#endif |
return(ret); |
return(ret); |
} |
} |
|
|
Line 6872 xmlParseTry(xmlParserCtxtPtr ctxt) {
|
Line 7674 xmlParseTry(xmlParserCtxtPtr ctxt) {
|
* |
* |
* Returns zero if no error, the xmlParserErrors otherwise. |
* Returns zero if no error, the xmlParserErrors otherwise. |
*/ |
*/ |
xmlParserErrors |
int |
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size, |
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size, |
int terminate) { |
int terminate) { |
if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) && |
if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) && |
(ctxt->input->buf != 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); |
xmlParserInputBufferPush(ctxt->input->buf, size, chunk); |
|
ctxt->input->base = ctxt->input->buf->buffer->content + base; |
|
ctxt->input->cur = ctxt->input->base + cur; |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: pushed %d\n", size); |
|
#endif |
|
|
|
xmlParseTry(ctxt); |
|
} else if (ctxt->instate != XML_PARSER_EOF) |
|
xmlParseTry(ctxt); |
|
if (terminate) { |
|
if ((ctxt->instate != XML_PARSER_EOF) && |
|
(ctxt->instate != XML_PARSER_EPILOG)) { |
|
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; |
|
ctxt->errNo = XML_ERR_DOCUMENT_END; |
|
} |
|
if (ctxt->instate != XML_PARSER_EOF) { |
|
if ((ctxt->sax) && (ctxt->sax->endDocument != NULL)) |
|
ctxt->sax->endDocument(ctxt->userData); |
|
} |
|
ctxt->instate = XML_PARSER_EOF; |
} |
} |
return((xmlParserErrors) ctxt->errNo); |
return((xmlParserErrors) ctxt->errNo); |
} |
} |
Line 6889 xmlParseChunk(xmlParserCtxtPtr ctxt, con
|
Line 7717 xmlParseChunk(xmlParserCtxtPtr ctxt, con
|
************************************************************************/ |
************************************************************************/ |
|
|
/** |
/** |
|
* 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 |
|
* |
|
* Create a parser context for using the XML parser in push mode |
|
* 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 |
|
*/ |
|
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 here. !!! |
|
*/ |
|
if ((chunk != NULL) && (size >= 4)) |
|
enc = xmlDetectCharEncoding((const xmlChar *) chunk); |
|
|
|
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 |
|
inputStream->filename = xmlMemStrdup(filename); |
|
inputStream->buf = buf; |
|
inputStream->base = inputStream->buf->buffer->content; |
|
inputStream->cur = inputStream->buf->buffer->content; |
|
|
|
inputPush(ctxt, inputStream); |
|
|
|
if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) && |
|
(ctxt->input->buf != NULL)) { |
|
xmlParserInputBufferPush(ctxt->input->buf, size, chunk); |
|
#ifdef DEBUG_PUSH |
|
fprintf(stderr, "PP: pushed %d\n", size); |
|
#endif |
|
} |
|
|
|
return(ctxt); |
|
} |
|
|
|
/** |
* xmlCreateDocParserCtxt : |
* xmlCreateDocParserCtxt : |
* @cur: a pointer to an array of xmlChar |
* @cur: a pointer to an array of xmlChar |
* |
* |
Line 7397 xmlSAXUserParseFile(xmlSAXHandlerPtr sax
|
Line 8308 xmlSAXUserParseFile(xmlSAXHandlerPtr sax
|
if (ctxt->sax != &xmlDefaultSAXHandler) |
if (ctxt->sax != &xmlDefaultSAXHandler) |
xmlFree(ctxt->sax); |
xmlFree(ctxt->sax); |
ctxt->sax = sax; |
ctxt->sax = sax; |
ctxt->userData = user_data; |
if (user_data != NULL) |
|
ctxt->userData = user_data; |
|
|
xmlParseDocument(ctxt); |
xmlParseDocument(ctxt); |
|
|