Diff for /XML/parser.c between versions 1.15 and 1.16

version 1.15, 1998/05/25 23:58:37 version 1.16, 1998/06/19 04:48:27
Line 127 Line 127
 /*  /*
  * Forward definition for recusive behaviour.   * Forward definition for recusive behaviour.
  */   */
 xmlNodePtr xmlParseElement(CHAR **p, xmlDocPtr doc);  xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt);
   
 /*  /*
  * xmlHandleData : this routine represent's the specific application   * xmlHandleData : this routine represent's the specific application
Line 227  CHAR *xmlStrchr(const CHAR *str, CHAR va Line 227  CHAR *xmlStrchr(const CHAR *str, CHAR va
  * xmlParseName : parse an XML name.   * xmlParseName : parse an XML name.
  */   */
   
 CHAR *xmlParseName(CHAR **p) {  CHAR *xmlParseName(xmlParserCtxtPtr ctxt) {
     CHAR *cur = *p, *q, *ret = NULL;      CHAR *q, *ret = NULL;
   
     /*      /*
      * Name ::= (Letter | '_') (NameChar)*       * Name ::= (Letter | '_') (NameChar)*
      */       */
     if (!IS_LETTER(*cur) && (*cur != '_')) return(NULL);      if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) return(NULL);
     q = cur++;      q = ctxt->cur++;
     while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||      while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
            (*cur == '.') || (*cur == '-') || (*cur == '_') ||             (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') || (ctxt->cur[0] == '_') ||
            (*cur == ':') ||              (ctxt->cur[0] == ':') || 
            (IS_COMBINING(*cur)) || (IS_IGNORABLE(*cur)) ||             (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
            (IS_EXTENDER(*cur)))             (IS_EXTENDER(ctxt->cur[0])))
         cur++;          ctxt->cur++;
           
     ret = xmlStrndup(q, cur - q);      ret = xmlStrndup(q, ctxt->cur - q);
   
     *p = cur;  
     return(ret);      return(ret);
 }  }
   
 /*  /*
  * Parse and return a string between quotes or doublequotes   * Parse and return a string between quotes or doublequotes
  */   */
 CHAR *xmlParseQuotedString(CHAR **p) {  CHAR *xmlParseQuotedString(xmlParserCtxtPtr ctxt) {
     CHAR *ret = NULL;      CHAR *ret = NULL;
     CHAR *cur = *p, *q;      CHAR *q;
   
     if (*cur == '"') {      if (ctxt->cur[0] == '"') {
         cur++;          ctxt->cur++;
         q = cur;          q = ctxt->cur;
         while (IS_CHAR(*cur) && (*cur != '"')) cur++;          while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '"')) ctxt->cur++;
         if (*cur != '"')          if (ctxt->cur[0] != '"')
             fprintf(stderr, "String not closed \"%.50s\n", q);              fprintf(stderr, "String not closed \"%.50s\n", q);
         else {          else {
             ret = xmlStrndup(q, cur - q);              ret = xmlStrndup(q, ctxt->cur - q);
             cur++;              ctxt->cur++;
         }          }
     } else if (*cur == '\''){      } else if (ctxt->cur[0] == '\''){
         cur++;          ctxt->cur++;
         q = cur;          q = ctxt->cur;
         while (IS_CHAR(*cur) && (*cur != '\'')) cur++;          while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '\'')) ctxt->cur++;
         if (*cur != '\'')          if (ctxt->cur[0] != '\'')
             fprintf(stderr, "String not closed '%.50s\n", q);              fprintf(stderr, "String not closed '%.50s\n", q);
         else {          else {
             ret = xmlStrndup(q, cur - q);              ret = xmlStrndup(q, ctxt->cur - q);
             cur++;              ctxt->cur++;
         }          }
     }      }
     *p = cur;  
     return(ret);      return(ret);
 }  }
   
 /*  /*
  * Skip an XML (SGML) comment <!-- .... -->   * Skip an XML (SGML) comment <!-- .... -->
    *
    * TODO !!!! Save the comment in the tree !!!
  */   */
 void xmlParserSkipComment(CHAR **p) {  void xmlParserSkipComment(xmlParserCtxtPtr ctxt) {
     CHAR *cur = *p, *q, *r, *start;      CHAR *q, *r, *start;
   
     /*      /*
      * An extra check may avoid errors and isn't that costly !       * An extra check may avoid errors and isn't that costly !
      */       */
     if ((cur[0] != '<') || (cur[1] != '!') ||      if ((ctxt->cur[0] != '<') || (ctxt->cur[1] != '!') ||
         (cur[2] != '-') || (cur[3] != '-')) return;          (ctxt->cur[2] != '-') || (ctxt->cur[3] != '-')) return;
   
     cur += 4;      ctxt->cur += 4;
     start = q = cur;      start = q = ctxt->cur;
     cur++;      ctxt->cur++;
     r = cur;      r = ctxt->cur;
     cur++;      ctxt->cur++;
     while (IS_CHAR(*cur) &&      while (IS_CHAR(ctxt->cur[0]) &&
            ((*cur == ':') || (*cur != '>') || (*r != '-') || (*q != '-'))) {             ((ctxt->cur[0] == ':') || (ctxt->cur[0] != '>') ||
         cur++;r++;q++;              (*r != '-') || (*q != '-'))) {
           ctxt->cur++;r++;q++;
     }      }
     if (!IS_CHAR(*cur)) {      if (!IS_CHAR(ctxt->cur[0])) {
         fprintf(stderr, "Comment not terminated <!--%.50s\n", start);          fprintf(stderr, "Comment not terminated <!--%.50s\n", start);
         *p = start;          ctxt->cur = start; /* !!! We shouldn't really try to recover !!! */
     } else {      } else {
         cur++;          ctxt->cur++;
         *p = cur;  
     }      }
 }  }
   
Line 314  void xmlParserSkipComment(CHAR **p) { Line 314  void xmlParserSkipComment(CHAR **p) {
  * xmlParseNamespace: parse specific '<?namespace ...' constructs.   * xmlParseNamespace: parse specific '<?namespace ...' constructs.
  */   */
   
 void xmlParseNamespace(CHAR **p, xmlDocPtr doc) {  void xmlParseNamespace(xmlParserCtxtPtr ctxt) {
     CHAR *cur = *p;  
     CHAR *href = NULL;      CHAR *href = NULL;
     CHAR *AS = NULL;      CHAR *AS = NULL;
     int garbage = 0;      int garbage = 0;
Line 323  void xmlParseNamespace(CHAR **p, xmlDocP Line 322  void xmlParseNamespace(CHAR **p, xmlDocP
     /*      /*
      * We know that 'namespace' is here.       * We know that 'namespace' is here.
      */       */
     cur += 9;      ctxt->cur += 9;
     SKIP_BLANKS(cur);      SKIP_BLANKS(ctxt->cur);
   
     while (IS_CHAR(*cur) && (*cur != '>')) {      while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '>')) {
         /*          /*
          * We can have 'href' or 'AS' attributes.           * We can have 'href' or 'AS' attributes.
          */           */
         if ((cur[0] == 'h') && (cur[1] == 'r') && (cur[2] == 'e') &&           if ((ctxt->cur[0] == 'h') && (ctxt->cur[1] == 'r') &&
             (cur[3] == 'f')) {              (ctxt->cur[2] == 'e') && (ctxt->cur[3] == 'f')) {
             garbage = 0;              garbage = 0;
             cur += 4;              ctxt->cur += 4;
             SKIP_BLANKS(cur);              SKIP_BLANKS(ctxt->cur);
   
             if (*cur != '=') continue;              if (ctxt->cur[0] != '=') continue;
             cur++;              ctxt->cur++;
             SKIP_BLANKS(cur);              SKIP_BLANKS(ctxt->cur);
   
             href = xmlParseQuotedString(&cur);              href = xmlParseQuotedString(ctxt);
             SKIP_BLANKS(cur);              SKIP_BLANKS(ctxt->cur);
         } else if ((cur[0] == 'A') && (cur[1] == 'S')) {          } else if ((ctxt->cur[0] == 'A') && (ctxt->cur[1] == 'S')) {
             garbage = 0;              garbage = 0;
             cur += 2;              ctxt->cur += 2;
             SKIP_BLANKS(cur);              SKIP_BLANKS(ctxt->cur);
   
             if (*cur != '=') continue;              if (ctxt->cur[0] != '=') continue;
             cur++;              ctxt->cur++;
             SKIP_BLANKS(cur);              SKIP_BLANKS(ctxt->cur);
   
             AS = xmlParseQuotedString(&cur);              AS = xmlParseQuotedString(ctxt);
             SKIP_BLANKS(cur);              SKIP_BLANKS(ctxt->cur);
         } else if ((cur[0] == '?') && (cur[1] == '>')) {          } else if ((ctxt->cur[0] == '?') && (ctxt->cur[1] == '>')) {
             garbage = 0;              garbage = 0;
             cur ++;              ctxt->cur ++;
         } else {          } else {
             /*              /*
              * Found garbage when parsing the namespace               * Found garbage when parsing the namespace
              */               */
             if (!garbage) fprintf(stderr,              if (!garbage) fprintf(stderr,
                   "\nxmlParseNamespace found garbage: ");                    "\nxmlParseNamespace found garbage: ");
             fprintf(stderr, "%c", *cur);              fprintf(stderr, "%c", ctxt->cur[0]);
             cur++;              ctxt->cur++;
         }          }
     }      }
   
     MOVETO_ENDTAG(cur);      MOVETO_ENDTAG(ctxt->cur);
     cur++;      ctxt->cur++;
   
     /*      /*
      * Register the DTD.       * Register the DTD.
      */       */
     if (href != NULL)      if (href != NULL)
         xmlNewDtd(doc, href, AS);          xmlNewDtd(ctxt->doc, href, AS);
   
     if (AS != NULL) free(AS);      if (AS != NULL) free(AS);
     if (href != NULL) free(href);      if (href != NULL) free(href);
   
     *p = cur;  
 }  }
   
 /*  /*
  * xmlParsePI: parse an XML Processing Instruction.   * xmlParsePI: parse an XML Processing Instruction.
  */   */
   
 void xmlParsePI(CHAR **p, xmlDocPtr doc) {  void xmlParsePI(xmlParserCtxtPtr ctxt) {
     CHAR *cur = *p;      if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) {
   
     if ((cur[0] == '<') && (cur[1] == '?')) {  
         /*          /*
          * this is a Processing Instruction.           * this is a Processing Instruction.
          */           */
         cur += 2;          ctxt->cur += 2;
   
         /*          /*
          * Special for WebDav, support for the Processing Instruction           * Special for WebDav, support for the Processing Instruction
          * '<?namespace ...' contruct in the header of the XML document.           * '<?namespace ...' contruct in the header of the XML document.
          */           */
         if ((cur[0] == 'n') && (cur[1] == 'a') &&          if ((ctxt->cur[0] == 'n') && (ctxt->cur[1] == 'a') &&
             (cur[2] == 'm') && (cur[3] == 'e') &&              (ctxt->cur[2] == 'm') && (ctxt->cur[3] == 'e') &&
             (cur[4] == 's') && (cur[5] == 'p') &&              (ctxt->cur[4] == 's') && (ctxt->cur[5] == 'p') &&
             (cur[6] == 'a') && (cur[7] == 'c') &&              (ctxt->cur[6] == 'a') && (ctxt->cur[7] == 'c') &&
             (cur[8] == 'e')) {              (ctxt->cur[8] == 'e')) {
             xmlParseNamespace(&cur, doc);              xmlParseNamespace(ctxt);
         } else {          } else {
             /* Unknown PI, ignore it ! */              /* Unknown PI, ignore it ! */
             fprintf(stderr, "xmlParsePI : skipping unknown PI %30s\n", cur);              fprintf(stderr, "xmlParsePI : skipping unknown PI %30s\n",
             MOVETO_ENDTAG(cur);                      ctxt->cur);
             cur++;              MOVETO_ENDTAG(ctxt->cur);
               ctxt->cur++;
         }          }
     }      }
     *p = cur;  
 }  }
   
 /*  /*
Line 421  void xmlParsePI(CHAR **p, xmlDocPtr doc) Line 416  void xmlParsePI(CHAR **p, xmlDocPtr doc)
  * Attribute ::= Name Eq AttValue   * Attribute ::= Name Eq AttValue
  */   */
   
 void xmlParseAttribute(CHAR **p, xmlNodePtr node) {  void xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
     CHAR *cur = *p, *q, *name, *value = NULL;      CHAR *q, *name, *value = NULL;
   
     if (!IS_LETTER(*cur) && (*cur != '_')) {      if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) {
         return;          return;
     }      }
     q = cur++;      q = ctxt->cur++;
     while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||      while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
            (*cur == '.') || (*cur == '-') || (*cur == '_') ||             (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
            (*cur == ':') ||              (ctxt->cur[0] == '_') || (ctxt->cur[0] == ':') || 
            (IS_COMBINING(*cur)) || (IS_IGNORABLE(*cur)) ||             (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
            (IS_EXTENDER(*cur)))             (IS_EXTENDER(ctxt->cur[0])))
         cur++;          ctxt->cur++;
     name = xmlStrndup(q, cur - q);      name = xmlStrndup(q, ctxt->cur - q);
   
     /*      /*
      * We should have the equal, we are laxist here and allow attributes       * We should have the equal, we are laxist here and allow attributes
      * without values and extra spaces.       * without values and extra spaces.
      */       */
     SKIP_BLANKS(cur);      SKIP_BLANKS(ctxt->cur);
     if (*cur == '=') {      if (ctxt->cur[0] == '=') {
         cur++;          ctxt->cur++;
         SKIP_BLANKS(cur);          SKIP_BLANKS(ctxt->cur);
         if ((*cur != '\'') && (*cur != '"')) {          if ((ctxt->cur[0] != '\'') && (ctxt->cur[0] != '"')) {
             fprintf(stderr, "Quotes were expected for attribute value %.20s\n",              fprintf(stderr, "Quotes were expected for attribute value %.20s\n",
                     q);                      q);
         } else          } else
             value = xmlParseQuotedString(&cur);              value = xmlParseQuotedString(ctxt);
     }      }
   
     /*      /*
Line 456  void xmlParseAttribute(CHAR **p, xmlNode Line 451  void xmlParseAttribute(CHAR **p, xmlNode
      */       */
     if (name != NULL)      if (name != NULL)
         xmlNewProp(node, name, value);          xmlNewProp(node, name, value);
       
     *p = cur;  
 }  }
   
 /*  /*
  * xmlParseStartTag: parse a start of tag.   * xmlParseStartTag: parse a start of tag.
  */   */
   
 xmlNodePtr xmlParseStartTag(CHAR **p, xmlDocPtr doc) {  xmlNodePtr xmlParseStartTag(xmlParserCtxtPtr ctxt) {
     CHAR *cur = *p, *q, *ns, *name;      CHAR *q, *ns, *name;
     xmlDtdPtr dtd = NULL;      xmlDtdPtr dtd = NULL;
     xmlNodePtr ret = NULL;      xmlNodePtr ret = NULL;
   
Line 483  xmlNodePtr xmlParseStartTag(CHAR **p, xm Line 476  xmlNodePtr xmlParseStartTag(CHAR **p, xm
      *       *
      * STag ::= '<' QName (S Attribute)* S? '>'       * STag ::= '<' QName (S Attribute)* S? '>'
      */       */
     if (*cur != '<') return(NULL);      if (ctxt->cur[0] != '<') return(NULL);
     cur++;      ctxt->cur++;
   
     if (!IS_LETTER(*cur) && (*cur != '_')) return(NULL);      if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) return(NULL);
     q = cur++;      q = ctxt->cur++;
     while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||      while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
            (*cur == '.') || (*cur == '-') || (*cur == '_') ||             (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
            (IS_COMBINING(*cur)) || (IS_IGNORABLE(*cur)) ||             (ctxt->cur[0] == '_') ||
            (IS_EXTENDER(*cur)))             (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
         cur++;             (IS_EXTENDER(ctxt->cur[0])))
           ctxt->cur++;
   
     if (*cur == ':') {      if (ctxt->cur[0] == ':') {
         ns = xmlStrndup(q, cur - q);          ns = xmlStrndup(q, ctxt->cur - q);
                   
         cur++; /* skip the column */          ctxt->cur++; /* skip the column */
         if (!IS_LETTER(*cur) && (*cur != '_')) {          if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) {
             fprintf(stderr,              fprintf(stderr,
                "Start tag : no element name after namespace identifier %.20s\n",                 "Start tag : no element name after namespace identifier %.20s\n",
                     q);                      q);
             free(ns);              free(ns);
             *p = cur;  
             return(NULL);              return(NULL);
         }          }
         q = cur++;          q = ctxt->cur++;
         while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||          while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
                (*cur == '.') || (*cur == '-') || (*cur == '_') ||                 (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
                (*cur == ':') ||                  (ctxt->cur[0] == '_') || (ctxt->cur[0] == ':') || 
                (IS_COMBINING(*cur)) || (IS_IGNORABLE(*cur)) ||                 (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
                (IS_EXTENDER(*cur)))                 (IS_EXTENDER(ctxt->cur[0])))
             cur++;              ctxt->cur++;
         name = xmlStrndup(q, cur - q);          name = xmlStrndup(q, ctxt->cur - q);
   
         /*          /*
          * Search the DTD associated to ns.           * Search the DTD associated to ns.
          */           */
         dtd = xmlSearchDtd(doc, ns);          dtd = xmlSearchDtd(ctxt->doc, ns);
         if (dtd == NULL)          if (dtd == NULL)
             fprintf(stderr, "Start tag : Couldn't find namespace %s\n", ns);              fprintf(stderr, "Start tag : Couldn't find namespace %s\n", ns);
         free(ns);          free(ns);
     } else      } else
         name = xmlStrndup(q, cur - q);          name = xmlStrndup(q, ctxt->cur - q);
   
     ret = xmlNewNode(dtd, name, NULL);      ret = xmlNewNode(dtd, name, NULL);
   
Line 532  xmlNodePtr xmlParseStartTag(CHAR **p, xm Line 525  xmlNodePtr xmlParseStartTag(CHAR **p, xm
      *       *
      * (S Attribute)* S?       * (S Attribute)* S?
      */       */
     SKIP_BLANKS(cur);      SKIP_BLANKS(ctxt->cur);
     while ((IS_CHAR(*cur)) &&      while ((IS_CHAR(ctxt->cur[0])) &&
            (*cur != '>') &&              (ctxt->cur[0] != '>') && 
            ((cur[0] != '/') || (cur[1] != '>'))) {             ((ctxt->cur[0] != '/') || (ctxt->cur[1] != '>'))) {
         if (IS_LETTER(*cur) || (*cur == '_'))          if (IS_LETTER(ctxt->cur[0]) || (ctxt->cur[0] == '_'))
             xmlParseAttribute(&cur, ret);              xmlParseAttribute(ctxt, ret);
         else {          else {
             /* We should warn TODO !!! */              /* We should warn TODO !!! */
             cur++;              ctxt->cur++;
         }          }
         SKIP_BLANKS(cur);          SKIP_BLANKS(ctxt->cur);
     }      }
   
     *p = cur;  
     return(ret);      return(ret);
 }  }
   
Line 554  xmlNodePtr xmlParseStartTag(CHAR **p, xm Line 546  xmlNodePtr xmlParseStartTag(CHAR **p, xm
  * already been read.   * already been read.
  */   */
   
 void xmlParseEndTag(CHAR **p, xmlDocPtr doc, xmlDtdPtr *dtdPtr, CHAR **tagPtr) {  void xmlParseEndTag(xmlParserCtxtPtr ctxt, xmlDtdPtr *dtdPtr, CHAR **tagPtr) {
     CHAR *cur = *p, *q, *ns, *name;      CHAR *q, *ns, *name;
     xmlDtdPtr dtd = NULL;      xmlDtdPtr dtd = NULL;
   
     *dtdPtr = NULL;      *dtdPtr = NULL;
Line 575  void xmlParseEndTag(CHAR **p, xmlDocPtr Line 567  void xmlParseEndTag(CHAR **p, xmlDocPtr
      *       *
      * ETag ::= '</' Name S? '>'       * ETag ::= '</' Name S? '>'
      */       */
     if (!IS_LETTER(*cur) && (*cur != '_')) return;      if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) return;
     q = cur++;      q = ctxt->cur++;
     while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||      while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
            (*cur == '.') || (*cur == '-') || (*cur == '_') ||             (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
            (IS_COMBINING(*cur)) || (IS_IGNORABLE(*cur)) ||             (ctxt->cur[0] == '_') ||
            (IS_EXTENDER(*cur)))             (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
         cur++;             (IS_EXTENDER(ctxt->cur[0])))
           ctxt->cur++;
   
     if (*cur == ':') {      if (ctxt->cur[0] == ':') {
         ns = xmlStrndup(q, cur - q);          ns = xmlStrndup(q, ctxt->cur - q);
                   
         cur++; /* skip the column */          ctxt->cur++; /* skip the column */
         if (!IS_LETTER(*cur) && (*cur != '_')) {          if (!IS_LETTER(ctxt->cur[0]) && (ctxt->cur[0] != '_')) {
             fprintf(stderr,              fprintf(stderr,
                 "End tag : no element name after namespace identifier %.20s\n",                  "End tag : no element name after namespace identifier %.20s\n",
                     q);                      q);
             free(ns);              free(ns);
             *p = cur;  
             return;              return;
         }          }
         q = cur++;          q = ctxt->cur++;
         while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||          while ((IS_LETTER(ctxt->cur[0])) || (IS_DIGIT(ctxt->cur[0])) ||
                (*cur == '.') || (*cur == '-') || (*cur == '_') ||                 (ctxt->cur[0] == '.') || (ctxt->cur[0] == '-') ||
                (*cur == ':') ||                  (ctxt->cur[0] == '_') || (ctxt->cur[0] == ':') || 
                (IS_COMBINING(*cur)) || (IS_IGNORABLE(*cur)) ||                 (IS_COMBINING(ctxt->cur[0])) || (IS_IGNORABLE(ctxt->cur[0])) ||
                (IS_EXTENDER(*cur)))                 (IS_EXTENDER(ctxt->cur[0])))
             cur++;              ctxt->cur++;
         name = xmlStrndup(q, cur - q);          name = xmlStrndup(q, ctxt->cur - q);
   
         /*          /*
          * Search the DTD associated to ns.           * Search the DTD associated to ns.
          */           */
         dtd = xmlSearchDtd(doc, ns);          dtd = xmlSearchDtd(ctxt->doc, ns);
         if (dtd == NULL)          if (dtd == NULL)
             fprintf(stderr, "End tag : Couldn't find namespace %s\n", ns);              fprintf(stderr, "End tag : Couldn't find namespace %s\n", ns);
         free(ns);          free(ns);
     } else      } else
         name = xmlStrndup(q, cur - q);          name = xmlStrndup(q, ctxt->cur - q);
   
     *dtdPtr = dtd;      *dtdPtr = dtd;
     *tagPtr = name;      *tagPtr = name;
Line 620  void xmlParseEndTag(CHAR **p, xmlDocPtr Line 612  void xmlParseEndTag(CHAR **p, xmlDocPtr
     /*      /*
      * We should definitely be at the ending "S? '>'" part       * We should definitely be at the ending "S? '>'" part
      */       */
     SKIP_BLANKS(cur);      SKIP_BLANKS(ctxt->cur);
     if ((!IS_CHAR(*cur)) || (*cur != '>')) {      if ((!IS_CHAR(ctxt->cur[0])) || (ctxt->cur[0] != '>')) {
         fprintf(stderr, "End tag : expected '>', got %.20s\n", cur);          fprintf(stderr, "End tag : expected '>', got %.20s\n", ctxt->cur);
         /*          /*
          * Note : skipping to the next '>' is probably otherkill,           * Note : skipping to the next '>' is probably otherkill,
          * especially in case the '>' is hust missing.           * especially in case the '>' is hust missing.
          *           *
          * Otherwise add:           * Otherwise add:
          *  MOVETO_ENDTAG(cur);           *  MOVETO_ENDTAG(ctxt->cur);
          */           */
     } else      } else
         cur++;          ctxt->cur++;
   
     *p = cur;  
     return;      return;
 }  }
   
 /*  /*
  * xmlParseCDSect: escaped pure raw content.   * xmlParseCDSect: escaped pure raw content.
  */   */
 CHAR *xmlParseCDSect(CHAR **p) {  CHAR *xmlParseCDSect(xmlParserCtxtPtr ctxt) {
     CHAR *cur = *p, *r, *s, *base, *ret;      CHAR *r, *s, *base, *ret;
   
     base = cur;      base = ctxt->cur;
     if (!IS_CHAR(*cur)) {      if (!IS_CHAR(ctxt->cur[0])) {
         fprintf(stderr, "CData section not finished : %.20s\n", base);          fprintf(stderr, "CData section not finished : %.20s\n", base);
         return(NULL);          return(NULL);
     }      }
     r = cur++;      r = ctxt->cur++;
     if (!IS_CHAR(*cur)) {      if (!IS_CHAR(ctxt->cur[0])) {
         fprintf(stderr, "CData section not finished : %.20s\n", base);          fprintf(stderr, "CData section not finished : %.20s\n", base);
         return(NULL);          return(NULL);
     }      }
     s = cur++;      s = ctxt->cur++;
     while (IS_CHAR(*cur) &&      while (IS_CHAR(ctxt->cur[0]) &&
            ((*r != ']') || (*s != ']') || (*cur != '>'))) {             ((*r != ']') || (*s != ']') || (ctxt->cur[0] != '>'))) {
         r++;s++;cur++;          r++;s++;ctxt->cur++;
     }      }
     if (!IS_CHAR(*cur)) {      if (!IS_CHAR(ctxt->cur[0])) {
         fprintf(stderr, "CData section not finished : %.20s\n", base);          fprintf(stderr, "CData section not finished : %.20s\n", base);
         return(NULL);          return(NULL);
     }      }
     ret = xmlStrndup(base, cur-base);      ret = xmlStrndup(base, ctxt->cur-base);
     *p = cur;  
     return(ret);      return(ret);
 }  }
   
Line 678  CHAR *xmlParseCDSect(CHAR **p) { Line 669  CHAR *xmlParseCDSect(CHAR **p) {
  * PI : starts by '<?'   * PI : starts by '<?'
  */   */
   
 xmlNodePtr xmlParseContent(CHAR **p, xmlDocPtr doc, xmlNodePtr node) {  xmlNodePtr xmlParseContent(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
     CHAR *cur = *p, *q, *data = NULL;      CHAR *q, *data = NULL;
     xmlNodePtr ret = NULL;      xmlNodePtr ret = NULL;
   
     /*      /*
      * First case : a Processing Instruction.       * First case : a Processing Instruction.
      */       */
     if ((cur[0] == '<') && (cur[1] == '?')) {      if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) {
         xmlParsePI(&cur, doc);          xmlParsePI(ctxt);
     }      }
     /*      /*
      * Second case : a CDSection       * Second case : a CDSection
      */       */
     if ((cur[0] == '<') && (cur[1] == '!') && (cur[2] == '[') &&      if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '!') &&
         (cur[3] == 'C') && (cur[4] == 'D') && (cur[5] == 'A') &&          (ctxt->cur[2] == '[') && (ctxt->cur[3] == 'C') &&
         (cur[6] == 'T') && (cur[7] == 'A') && (cur[8] == '[')) {          (ctxt->cur[4] == 'D') && (ctxt->cur[5] == 'A') &&
         cur += 9;          (ctxt->cur[6] == 'T') && (ctxt->cur[7] == 'A') &&
         data = xmlParseCDSect(&cur);          (ctxt->cur[8] == '[')) {
           ctxt->cur += 9;
           data = xmlParseCDSect(ctxt);
     }      }
     /*      /*
      * Third case :  a sub-element.       * Third case :  a sub-element.
      */       */
     else if (cur[0] == '<') {      else if (ctxt->cur[0] == '<') {
         ret = xmlParseElement(&cur, doc);          ret = xmlParseElement(ctxt);
     }      }
     /*      /*
      * Last case, text. Note that References are handled directly.       * Last case, text. Note that References are handled directly.
      */       */
     else {      else {
         q = cur;          q = ctxt->cur;
         while (IS_CHAR(*cur) && (*cur != '<')) cur++;          while (IS_CHAR(ctxt->cur[0]) && (ctxt->cur[0] != '<')) ctxt->cur++;
   
         if (!IS_CHAR(*cur)) {          if (!IS_CHAR(ctxt->cur[0])) {
             fprintf(stderr, "Truncated content : %.50s\n", q);              fprintf(stderr, "Truncated content : %.50s\n", q);
             *p = cur;  
             return(NULL);              return(NULL);
         }          }
   
         /*          /*
          * Do the Entities decoding...           * Do the Entities decoding...
          */           */
         data = xmlStrdup(xmlDecodeEntities(doc, q, cur - q));          data = xmlStrdup(xmlDecodeEntities(ctxt->doc, q, ctxt->cur - q));
     }      }
   
     /*      /*
Line 736  xmlNodePtr xmlParseContent(CHAR **p, xml Line 728  xmlNodePtr xmlParseContent(CHAR **p, xml
         }          }
     }      }
   
     *p = cur;  
     return(ret);      return(ret);
 }  }
   
Line 744  xmlNodePtr xmlParseContent(CHAR **p, xml Line 735  xmlNodePtr xmlParseContent(CHAR **p, xml
  * xmlParseElement: parse an XML element   * xmlParseElement: parse an XML element
  */   */
   
 xmlNodePtr xmlParseElement(CHAR **p, xmlDocPtr doc) {  xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt) {
     CHAR *cur = *p;  
     xmlNodePtr ret, child;      xmlNodePtr ret, child;
     CHAR *openTag = *p;      CHAR *openTag = ctxt->cur;
     CHAR *closeTag = *p;      CHAR *closeTag = ctxt->cur;
   
     ret = xmlParseStartTag(&cur, doc);      ret = xmlParseStartTag(ctxt);
     if (ret == NULL) {      if (ret == NULL) {
         *p = cur;  
         return(NULL);          return(NULL);
     }      }
   
     /*      /*
      * Check for an Empty Element.       * Check for an Empty Element.
      */       */
     if ((cur[0] == '/') && (cur[1] == '>')) {      if ((ctxt->cur[0] == '/') && (ctxt->cur[1] == '>')) {
         cur += 2;          ctxt->cur += 2;
         *p = cur;  
         return(ret);          return(ret);
     }      }
     if (cur[0] == '>') cur++;      if (ctxt->cur[0] == '>') ctxt->cur++;
     else {      else {
         fprintf(stderr, "Couldn't find end of Start Tag %.30s\n", *p);          fprintf(stderr, "Couldn't find end of Start Tag %.30s\n", openTag);
         *p = cur;          return(NULL);
         return(ret);  
     }      }
   
     /*      /*
Line 783  xmlNodePtr xmlParseElement(CHAR **p, xml Line 770  xmlNodePtr xmlParseElement(CHAR **p, xml
      *       *
      * The loop stops upon detection of an end of tag '</'       * The loop stops upon detection of an end of tag '</'
      */       */
     while ((IS_CHAR(cur[0])) && ((cur[0] != '<') || (cur[1] != '/'))) {      while ((IS_CHAR(ctxt->cur[0])) &&
         child = xmlParseContent(&cur, doc, ret);             ((ctxt->cur[0] != '<') || (ctxt->cur[1] != '/'))) {
           child = xmlParseContent(ctxt, ret);
         if (child != NULL)          if (child != NULL)
             xmlAddChild(ret, child);              xmlAddChild(ret, child);
     }      }
     if (!IS_CHAR(cur[0])) {      if (!IS_CHAR(ctxt->cur[0])) {
         fprintf(stderr, "Premature end of data in tag %.30s\n", *p);          fprintf(stderr, "Premature end of data in tag %.30s\n", openTag);
         *p = cur;          return(NULL);
         return(ret);  
     }      }
   
     /*      /*
      * parse the end of tag : '</' has been detected.       * parse the end of tag : '</' has been detected.
      */       */
     cur += 2;      ctxt->cur += 2;
     if (*cur == '>') cur++; /* simplified closing </> */      if (ctxt->cur[0] == '>') ctxt->cur++; /* simplified closing </> */
     else {      else {
         CHAR *endTag;          CHAR *endTag;
         xmlDtdPtr endDtd;          xmlDtdPtr endDtd;
   
         xmlParseEndTag(&cur, doc, &endDtd, &endTag);          xmlParseEndTag(ctxt, &endDtd, &endTag);
   
         /*          /*
          * Check that the Name in the ETag is the same as in the STag.           * Check that the Name in the ETag is the same as in the STag.
Line 818  xmlNodePtr xmlParseElement(CHAR **p, xml Line 805  xmlNodePtr xmlParseElement(CHAR **p, xml
         }          }
     }      }
   
     *p = cur;  
     return(ret);      return(ret);
 }  }
   
Line 826  xmlNodePtr xmlParseElement(CHAR **p, xml Line 812  xmlNodePtr xmlParseElement(CHAR **p, xml
  * xmlParseXMLDecl: parse an XML declaration header   * xmlParseXMLDecl: parse an XML declaration header
  */   */
   
 xmlDocPtr xmlParseXMLDecl(CHAR **p) {  void xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
     CHAR *cur = *p;  
     CHAR *version;      CHAR *version;
     xmlDocPtr ret;  
   
     /*      /*
      * We know that '<?XML' is here.       * We know that '<?XML' is here.
      */       */
     cur += 5;      ctxt->cur += 5;
   
     /*      /*
      * Parse the version info       * Parse the version info
      */       */
     SKIP_BLANKS(cur);      SKIP_BLANKS(ctxt->cur);
   
     /*      /*
      * We should have 'version=' here !       * We should have 'version=' here !
      */       */
     if ((cur[0] == 'v') && (cur[1] == 'e') && (cur[2] == 'r') &&       if ((ctxt->cur[0] == 'v') && (ctxt->cur[1] == 'e') &&
         (cur[3] == 's') && (cur[4] == 'i') && (cur[5] == 'o') &&          (ctxt->cur[2] == 'r') && (ctxt->cur[3] == 's') &&
         (cur[6] == 'n') && (cur[7] == '=')) {          (ctxt->cur[4] == 'i') && (ctxt->cur[5] == 'o') &&
         cur += 8;          (ctxt->cur[6] == 'n') && (ctxt->cur[7] == '=')) {
         version = xmlParseQuotedString(&cur);          ctxt->cur += 8;
           version = xmlParseQuotedString(ctxt);
         if (version == NULL)          if (version == NULL)
             ret = xmlNewDoc(XML_DEFAULT_VERSION);              ctxt->doc = xmlNewDoc(XML_DEFAULT_VERSION);
         else {          else {
             ret = xmlNewDoc(version);              ctxt->doc = xmlNewDoc(version);
             free(version);              free(version);
         }          }
     } else {      } else {
         ret = xmlNewDoc(XML_DEFAULT_VERSION);          ctxt->doc = xmlNewDoc(XML_DEFAULT_VERSION);
     }      }
   
     /*      /*
      * We should check for Required Markup Declaration TODO !!!!       * We should check for Required Markup Declaration TODO !!!!
      */       */
     MOVETO_ENDTAG(cur);      MOVETO_ENDTAG(ctxt->cur);
     cur++;      ctxt->cur++;
   
     *p = cur;  
     return(ret);  
 }  }
   
 /*  /*
Line 874  xmlDocPtr xmlParseXMLDecl(CHAR **p) { Line 857  xmlDocPtr xmlParseXMLDecl(CHAR **p) {
  * (Comment | PI | S)*   * (Comment | PI | S)*
  */   */
   
 void xmlParseMisc(CHAR **p, xmlDocPtr doc) {  void xmlParseMisc(xmlParserCtxtPtr ctxt) {
     CHAR *cur = *p;      while (((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) ||
              ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '!') &&
     while (((cur[0] == '<') && (cur[1] == '?')) ||              (ctxt->cur[2] == '-') && (ctxt->cur[2] == '-')) ||
            ((cur[0] == '<') && (cur[1] == '!') &&             IS_BLANK(ctxt->cur[0])) {
             (cur[2] == '-') && (cur[2] == '-')) ||          if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?')) {
            IS_BLANK(*cur)) {              xmlParsePI(ctxt);
         if ((cur[0] == '<') && (cur[1] == '?')) {          } else if (IS_BLANK(ctxt->cur[0])) {
             xmlParsePI(&cur, doc);              ctxt->cur++;
         } else if (IS_BLANK(*cur)) {  
             cur++;  
         } else          } else
             xmlParserSkipComment(&cur);              xmlParserSkipComment(ctxt);
     }      }
   
     *p = cur;  
 }  }
   
 /*  /*
  * xmlParseDoc : parse an XML document and build a tree.   * xmlParseDocument : parse an XML document and build a tree.
  */   */
   
 xmlDocPtr xmlParseDoc(CHAR *cur) {  int xmlParseDocument(xmlParserCtxtPtr ctxt) {
     xmlDocPtr ret;  
   
     /*      /*
      * We should check for encoding here and plug-in some       * We should check for encoding here and plug-in some
      * conversion code TODO !!!!       * conversion code TODO !!!!
Line 907  xmlDocPtr xmlParseDoc(CHAR *cur) { Line 884  xmlDocPtr xmlParseDoc(CHAR *cur) {
     /*      /*
      * Wipe out everything which is before the first '<'       * Wipe out everything which is before the first '<'
      */       */
     SKIP_BLANKS(cur);      SKIP_BLANKS(ctxt->cur);
   
     /*      /*
      * Check for the XMLDecl in the Prolog.       * Check for the XMLDecl in the Prolog.
      */       */
     if ((cur[0] == '<') && (cur[1] == '?') &&      if ((ctxt->cur[0] == '<') && (ctxt->cur[1] == '?') &&
         (cur[2] == 'X') && (cur[3] == 'M') &&          (ctxt->cur[2] == 'X') && (ctxt->cur[3] == 'M') &&
         (cur[4] == 'L')) {          (ctxt->cur[4] == 'L')) {
         ret = xmlParseXMLDecl(&cur);          xmlParseXMLDecl(ctxt);
         /* SKIP_EOL(cur); */          /* SKIP_EOL(cur); */
         SKIP_BLANKS(cur);          SKIP_BLANKS(ctxt->cur);
     } else {      } else {
         ret = xmlNewDoc(XML_DEFAULT_VERSION);          ctxt->doc = xmlNewDoc(XML_DEFAULT_VERSION);
     }      }
   
     /*      /*
      * The Misc part of the Prolog       * The Misc part of the Prolog
      * (Comment | PI | S) *       * (Comment | PI | S) *
      */       */
     xmlParseMisc(&cur, ret);      xmlParseMisc(ctxt);
   
     /*      /*
      * Time to start parsing        * Time to start parsing 
      */       */
     ret->root = xmlParseElement(&cur, ret);      ctxt->doc->root = xmlParseElement(ctxt);
   
       return(0);
   }
   
   /*
    * xmlParseDoc : parse an XML in-memory document and build a tree.
    */
   
   xmlDocPtr xmlParseDoc(CHAR *cur) {
       xmlDocPtr ret;
       xmlParserCtxtPtr ctxt;
   
       if (cur == NULL) return(NULL);
   
       ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
       if (ctxt == NULL) {
           perror("malloc");
           return(NULL);
       }
   
       ctxt->filename = NULL;
       ctxt->base = cur;
       ctxt->cur = cur;
       ctxt->line = 1;
       ctxt->col = 1;
       ctxt->doc = NULL;
   
       xmlParseDocument(ctxt);
       ret = ctxt->doc;
       if (ctxt->filename != NULL)
           free(ctxt->filename);
       free(ctxt);
       
     return(ret);      return(ret);
 }  }
   
Line 946  xmlDocPtr xmlParseFile(const char *filen Line 955  xmlDocPtr xmlParseFile(const char *filen
     int res;      int res;
     struct stat buf;      struct stat buf;
     char *buffer;      char *buffer;
       xmlParserCtxtPtr ctxt;
   
     res = stat(filename, &buf);      res = stat(filename, &buf);
     if (res < 0) return(NULL);      if (res < 0) return(NULL);
Line 971  xmlDocPtr xmlParseFile(const char *filen Line 981  xmlDocPtr xmlParseFile(const char *filen
     }      }
     close(input);      close(input);
   
       ctxt = (xmlParserCtxtPtr) malloc(sizeof(xmlParserCtxt));
       if (ctxt == NULL) {
           perror("malloc");
           return(NULL);
       }
     buffer[buf.st_size] = '\0';      buffer[buf.st_size] = '\0';
     ret = xmlParseDoc(buffer);  
       ctxt->filename = strdup(filename);
       ctxt->base = buffer;
       ctxt->cur = buffer;
       ctxt->line = 1;
       ctxt->col = 1;
       ctxt->doc = NULL;
   
       xmlParseDocument(ctxt);
       ret = ctxt->doc;
     free(buffer);      free(buffer);
       if (ctxt->filename != NULL)
           free(ctxt->filename);
       free(ctxt);
       
     return(ret);      return(ret);
 }  }

Removed from v.1.15  
changed lines
  Added in v.1.16


Webmaster