Diff for /XML/parser.c between versions 1.139 and 1.140

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 &lt; or &amp;  
      *       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);
           

Removed from v.1.139  
changed lines
  Added in v.1.140


Webmaster