Diff for /embedaddon/libxml2/pattern.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2013/07/22 01:22:20 version 1.1.1.3, 2014/06/15 19:53:31
Line 3 Line 3
  *   *
  * Reference:   * Reference:
  *   http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/   *   http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/
 *   to some extent  *   to some extent
  *   http://www.w3.org/TR/1999/REC-xml-19991116   *   http://www.w3.org/TR/1999/REC-xml-19991116
  *   *
  * See Copyright for the status of this software.   * See Copyright for the status of this software.
Line 56 Line 56
 * NOTE: Those private flags (XML_STREAM_xxx) are used  * NOTE: Those private flags (XML_STREAM_xxx) are used
 *   in _xmlStreamCtxt->flag. They extend the public  *   in _xmlStreamCtxt->flag. They extend the public
 *   xmlPatternFlags, so be carefull not to interfere with the  *   xmlPatternFlags, so be carefull not to interfere with the
*   reserved values for xmlPatternFlags. *   reserved values for xmlPatternFlags.
 */  */
 #define XML_STREAM_FINAL_IS_ANY_NODE 1<<14  #define XML_STREAM_FINAL_IS_ANY_NODE 1<<14
 #define XML_STREAM_FROM_ROOT 1<<15  #define XML_STREAM_FROM_ROOT 1<<15
Line 162  struct _xmlStepOp { Line 162  struct _xmlStepOp {
 #define PAT_FROM_CUR    (1<<9)  #define PAT_FROM_CUR    (1<<9)
   
 struct _xmlPattern {  struct _xmlPattern {
    void *data;                 /* the associated template */    void *data;         /* the associated template */
     xmlDictPtr dict;            /* the optional dictionary */      xmlDictPtr dict;            /* the optional dictionary */
     struct _xmlPattern *next;   /* next pattern if | is used */      struct _xmlPattern *next;   /* next pattern if | is used */
     const xmlChar *pattern;     /* the pattern */      const xmlChar *pattern;     /* the pattern */
Line 181  struct _xmlPatParserContext { Line 181  struct _xmlPatParserContext {
     int            error;               /* error code */      int            error;               /* error code */
     xmlDictPtr     dict;                /* the dictionary if any */      xmlDictPtr     dict;                /* the dictionary if any */
     xmlPatternPtr  comp;                /* the result */      xmlPatternPtr  comp;                /* the result */
    xmlNodePtr     elem;                /* the current node if any */        xmlNodePtr     elem;                /* the current node if any */
     const xmlChar **namespaces;         /* the namespaces definitions */      const xmlChar **namespaces;         /* the namespaces definitions */
     int   nb_namespaces;                /* the number of namespaces */      int   nb_namespaces;                /* the number of namespaces */
 };  };
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
 *                      Type functions                                  * *                      Type functions                                  *
 *                                                                      * *                                                                      *
  ************************************************************************/   ************************************************************************/
   
 /**  /**
Line 327  xmlNewPatParserContext(const xmlChar *pattern, xmlDict Line 327  xmlNewPatParserContext(const xmlChar *pattern, xmlDict
 static void  static void
 xmlFreePatParserContext(xmlPatParserContextPtr ctxt) {  xmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
     if (ctxt == NULL)      if (ctxt == NULL)
        return;            return;
     memset(ctxt, -1, sizeof(xmlPatParserContext));      memset(ctxt, -1, sizeof(xmlPatParserContext));
     xmlFree(ctxt);      xmlFree(ctxt);
 }  }
Line 455  xmlReversePattern(xmlPatternPtr comp) { Line 455  xmlReversePattern(xmlPatternPtr comp) {
 }  }
   
 /************************************************************************  /************************************************************************
 *                                                                      * *                                                                        *
 *              The interpreter for the precompiled patterns            * *              The interpreter for the precompiled patterns            *
 *                                                                      * *                                                                      *
  ************************************************************************/   ************************************************************************/
   
 static int  static int
Line 709  rollback: Line 709  rollback:
  *                                                                      *   *                                                                      *
  ************************************************************************/   ************************************************************************/
   
#define TODO                                                            \#define TODO                                                            \
     xmlGenericError(xmlGenericErrorContext,                             \      xmlGenericError(xmlGenericErrorContext,                             \
             "Unimplemented block at %s:%d\n",                           \              "Unimplemented block at %s:%d\n",                           \
             __FILE__, __LINE__);              __FILE__, __LINE__);
Line 719  rollback: Line 719  rollback:
 #define PEEKPREV(val) ctxt->cur[-(val)]  #define PEEKPREV(val) ctxt->cur[-(val)]
 #define CUR_PTR ctxt->cur  #define CUR_PTR ctxt->cur
   
#define SKIP_BLANKS                                                     \#define SKIP_BLANKS                                                     \
     while (IS_BLANK_CH(CUR)) NEXT      while (IS_BLANK_CH(CUR)) NEXT
   
 #define CURRENT (*ctxt->cur)  #define CURRENT (*ctxt->cur)
 #define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)  #define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
   
   
#define PUSH(op, val, val2)                                             \#define PUSH(op, val, val2)                                             \
     if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;      if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
   
 #define XSLT_ERROR(X)                                                   \  #define XSLT_ERROR(X)                                                   \
Line 772  xmlPatScanLiteral(xmlPatParserContextPtr ctxt) { Line 772  xmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
             if (ctxt->dict)              if (ctxt->dict)
                 ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);                  ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
             else              else
                ret = xmlStrndup(q, cur - q);                       ret = xmlStrndup(q, cur - q);
         }          }
         cur += len;          cur += len;
         CUR_PTR = cur;          CUR_PTR = cur;
Line 791  xmlPatScanLiteral(xmlPatParserContextPtr ctxt) { Line 791  xmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
             if (ctxt->dict)              if (ctxt->dict)
                 ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);                  ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
             else              else
                ret = xmlStrndup(q, cur - q);                       ret = xmlStrndup(q, cur - q);
         }          }
         cur += len;          cur += len;
         CUR_PTR = cur;          CUR_PTR = cur;
Line 808  xmlPatScanLiteral(xmlPatParserContextPtr ctxt) { Line 808  xmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
  * xmlPatScanName:   * xmlPatScanName:
  * @ctxt:  the XPath Parser context   * @ctxt:  the XPath Parser context
  *   *
 * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' |  * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' |
  *                  CombiningChar | Extender   *                  CombiningChar | Extender
  *   *
  * [5] Name ::= (Letter | '_' | ':') (NameChar)*   * [5] Name ::= (Letter | '_' | ':') (NameChar)*
Line 833  xmlPatScanName(xmlPatParserContextPtr ctxt) { Line 833  xmlPatScanName(xmlPatParserContextPtr ctxt) {
   
     while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||      while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
            (val == '.') || (val == '-') ||             (val == '.') || (val == '-') ||
           (val == '_') ||            (val == '_') ||
            (IS_COMBINING(val)) ||             (IS_COMBINING(val)) ||
            (IS_EXTENDER(val))) {             (IS_EXTENDER(val))) {
         cur += len;          cur += len;
Line 842  xmlPatScanName(xmlPatParserContextPtr ctxt) { Line 842  xmlPatScanName(xmlPatParserContextPtr ctxt) {
     if (ctxt->dict)      if (ctxt->dict)
         ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);          ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q);
     else      else
        ret = xmlStrndup(q, cur - q);            ret = xmlStrndup(q, cur - q);
     CUR_PTR = cur;      CUR_PTR = cur;
     return(ret);      return(ret);
 }  }
Line 922  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) { Line 922  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
     xmlChar *token = NULL;      xmlChar *token = NULL;
     xmlChar *name = NULL;      xmlChar *name = NULL;
     xmlChar *URL = NULL;      xmlChar *URL = NULL;
    
     SKIP_BLANKS;      SKIP_BLANKS;
     name = xmlPatScanNCName(ctxt);      name = xmlPatScanNCName(ctxt);
     if (name == NULL) {      if (name == NULL) {
Line 939  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) { Line 939  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
     if (CUR == ':') {      if (CUR == ':') {
         int i;          int i;
         xmlChar *prefix = name;          xmlChar *prefix = name;
        
         NEXT;          NEXT;
   
        if (IS_BLANK_CH(CUR)) {             if (IS_BLANK_CH(CUR)) {
             ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);              ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
             XML_PAT_FREE_STRING(ctxt, prefix);              XML_PAT_FREE_STRING(ctxt, prefix);
             ctxt->error = 1;              ctxt->error = 1;
Line 957  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) { Line 957  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
             (prefix[2] == 'l') &&              (prefix[2] == 'l') &&
             (prefix[3] == 0))              (prefix[3] == 0))
         {          {
            XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE);                  XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE);
         } else {          } else {
             for (i = 0;i < ctxt->nb_namespaces;i++) {              for (i = 0;i < ctxt->nb_namespaces;i++) {
                 if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {                  if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
                    XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])                                     XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
                     break;                      break;
                 }                  }
             }              }
Line 969  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) { Line 969  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
                 ERROR5(NULL, NULL, NULL,                  ERROR5(NULL, NULL, NULL,
                     "xmlCompileAttributeTest : no namespace bound to prefix %s\n",                      "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
                     prefix);                      prefix);
                ctxt->error = 1;                            ctxt->error = 1;
                 goto error;                  goto error;
             }              }
         }          }
Line 983  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) { Line 983  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
                     "xmlCompileAttributeTest : Name expected\n");                      "xmlCompileAttributeTest : Name expected\n");
                 ctxt->error = 1;                  ctxt->error = 1;
                 goto error;                  goto error;
            }                   }
         } else {          } else {
             PUSH(XML_OP_ATTR, token, URL);              PUSH(XML_OP_ATTR, token, URL);
         }          }
Line 993  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) { Line 993  xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
     return;      return;
 error:  error:
     if (URL != NULL)      if (URL != NULL)
        XML_PAT_FREE_STRING(ctxt, URL)          XML_PAT_FREE_STRING(ctxt, URL)
     if (token != NULL)      if (token != NULL)
         XML_PAT_FREE_STRING(ctxt, token);          XML_PAT_FREE_STRING(ctxt, token);
 }  }
Line 1006  error: Line 1006  error:
  * form suitable for fast matching.   * form suitable for fast matching.
  *   *
  * [3]    Step    ::=    '.' | NameTest   * [3]    Step    ::=    '.' | NameTest
 * [4]    NameTest    ::=    QName | '*' | NCName ':' '*'  * [4]    NameTest    ::=    QName | '*' | NCName ':' '*'
  */   */
   
 static void  static void
Line 1037  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) { Line 1037  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
         }          }
         NEXT;          NEXT;
         xmlCompileAttributeTest(ctxt);          xmlCompileAttributeTest(ctxt);
        if (ctxt->error != 0)         if (ctxt->error != 0)
             goto error;              goto error;
         return;          return;
     }      }
Line 1062  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) { Line 1062  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
         NEXT;          NEXT;
         if (CUR != ':') {          if (CUR != ':') {
             xmlChar *prefix = name;              xmlChar *prefix = name;
            int i;                      int i;
   
             if (hasBlanks || IS_BLANK_CH(CUR)) {              if (hasBlanks || IS_BLANK_CH(CUR)) {
                 ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);                  ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
Line 1111  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) { Line 1111  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
             }              }
         } else {          } else {
             NEXT;              NEXT;
            if (xmlStrEqual(name, (const xmlChar *) "child")) {                     if (xmlStrEqual(name, (const xmlChar *) "child")) {
                 XML_PAT_FREE_STRING(ctxt, name);                  XML_PAT_FREE_STRING(ctxt, name);
                 name = xmlPatScanName(ctxt);                  name = xmlPatScanName(ctxt);
                 if (name == NULL) {                  if (name == NULL) {
Line 1129  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) { Line 1129  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
                 if (CUR == ':') {                  if (CUR == ':') {
                     xmlChar *prefix = name;                      xmlChar *prefix = name;
                     int i;                      int i;
                    
                     NEXT;                      NEXT;
                     if (IS_BLANK_CH(CUR)) {                      if (IS_BLANK_CH(CUR)) {
                         ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);                          ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
Line 1145  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) { Line 1145  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
                         (prefix[2] == 'l') &&                          (prefix[2] == 'l') &&
                         (prefix[3] == 0))                          (prefix[3] == 0))
                     {                      {
                        XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)                                               XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE)
                     } else {                      } else {
                         for (i = 0;i < ctxt->nb_namespaces;i++) {                          for (i = 0;i < ctxt->nb_namespaces;i++) {
                             if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {                              if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
                                XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])                                                         XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i])
                                 break;                                  break;
                             }                              }
                         }                          }
Line 1197  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) { Line 1197  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
                     "The 'element' or 'attribute' axis is expected.\n", NULL);                      "The 'element' or 'attribute' axis is expected.\n", NULL);
                 ctxt->error = 1;                  ctxt->error = 1;
                 goto error;                  goto error;
            }                   }
         }          }
     } else if (CUR == '*') {      } else if (CUR == '*') {
         if (name != NULL) {          if (name != NULL) {
Line 1212  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) { Line 1212  xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
     return;      return;
 error:  error:
     if (URL != NULL)      if (URL != NULL)
        XML_PAT_FREE_STRING(ctxt, URL)          XML_PAT_FREE_STRING(ctxt, URL)
     if (token != NULL)      if (token != NULL)
         XML_PAT_FREE_STRING(ctxt, token)          XML_PAT_FREE_STRING(ctxt, token)
     if (name != NULL)      if (name != NULL)
Line 1226  error: Line 1226  error:
  * Compile the Path Pattern and generates a precompiled   * Compile the Path Pattern and generates a precompiled
  * form suitable for fast matching.   * form suitable for fast matching.
  *   *
 * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )  * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )
  */   */
 static void  static void
 xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {  xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
Line 1236  xmlCompilePathPattern(xmlPatParserContextPtr ctxt) { Line 1236  xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
     } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {      } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {
         ctxt->comp->flags |= PAT_FROM_CUR;          ctxt->comp->flags |= PAT_FROM_CUR;
     }      }
        
     if ((CUR == '/') && (NXT(1) == '/')) {      if ((CUR == '/') && (NXT(1) == '/')) {
         PUSH(XML_OP_ANCESTOR, NULL, NULL);          PUSH(XML_OP_ANCESTOR, NULL, NULL);
         NEXT;          NEXT;
Line 1299  xmlCompilePathPattern(xmlPatParserContextPtr ctxt) { Line 1299  xmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
                     ERROR5(NULL, NULL, NULL,                      ERROR5(NULL, NULL, NULL,
                     "Incomplete expression '%s'.\n", ctxt->base);                      "Incomplete expression '%s'.\n", ctxt->base);
                     ctxt->error = 1;                      ctxt->error = 1;
                    goto error;                                 goto error;
                 }                  }
                 xmlCompileStepPattern(ctxt);                  xmlCompileStepPattern(ctxt);
                 if (ctxt->error != 0)                  if (ctxt->error != 0)
Line 1323  error: Line 1323  error:
  * Compile the Path Pattern and generates a precompiled   * Compile the Path Pattern and generates a precompiled
  * form suitable for fast matching.   * form suitable for fast matching.
  *   *
 * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )  * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )
  */   */
 static void  static void
 xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) {  xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) {
Line 1378  xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) { Line 1378  xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) {
     */      */
     do {      do {
         xmlCompileStepPattern(ctxt);          xmlCompileStepPattern(ctxt);
        if (ctxt->error != 0)         if (ctxt->error != 0)
             goto error;              goto error;
         SKIP_BLANKS;          SKIP_BLANKS;
         if (CUR != '/')          if (CUR != '/')
Line 1397  xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) { Line 1397  xmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) {
         }          }
         if (CUR == 0)          if (CUR == 0)
             goto error_unfinished;              goto error_unfinished;
        
     } while (CUR != 0);      } while (CUR != 0);
   
     if (CUR != 0) {      if (CUR != 0) {
Line 1413  error: Line 1413  error:
 error_unfinished:  error_unfinished:
     ctxt->error = 1;      ctxt->error = 1;
     ERROR5(NULL, NULL, NULL,      ERROR5(NULL, NULL, NULL,
        "Unfinished expression '%s'.\n", ctxt->base);            "Unfinished expression '%s'.\n", ctxt->base);
     return;      return;
 }  }
   
Line 1568  xmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlC Line 1568  xmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlC
 /**  /**
  * xmlStreamCompile:   * xmlStreamCompile:
  * @comp: the precompiled pattern   * @comp: the precompiled pattern
 *  *
  * Tries to stream compile a pattern   * Tries to stream compile a pattern
  *   *
  * Returns -1 in case of failure and 0 in case of success.   * Returns -1 in case of failure and 0 in case of success.
Line 1605  xmlStreamCompile(xmlPatternPtr comp) { Line 1605  xmlStreamCompile(xmlPatternPtr comp) {
         xmlDictReference(stream->dict);          xmlDictReference(stream->dict);
     }      }
   
    i = 0;            i = 0;
     if (comp->flags & PAT_FROM_ROOT)      if (comp->flags & PAT_FROM_ROOT)
         stream->flags |= XML_STREAM_FROM_ROOT;          stream->flags |= XML_STREAM_FROM_ROOT;
   
Line 1621  xmlStreamCompile(xmlPatternPtr comp) { Line 1621  xmlStreamCompile(xmlPatternPtr comp) {
                 break;                  break;
             case XML_OP_NS:              case XML_OP_NS:
                 s = xmlStreamCompAddStep(stream, NULL, step.value,                  s = xmlStreamCompAddStep(stream, NULL, step.value,
                    XML_ELEMENT_NODE, flags);                               XML_ELEMENT_NODE, flags);
                 if (s < 0)                  if (s < 0)
                     goto error;                      goto error;
                 prevs = s;                  prevs = s;
                flags = 0;                              flags = 0;
                break;                      break;
             case XML_OP_ATTR:              case XML_OP_ATTR:
                 flags |= XML_STREAM_STEP_ATTR;                  flags |= XML_STREAM_STEP_ATTR;
                 prevs = -1;                  prevs = -1;
Line 1636  xmlStreamCompile(xmlPatternPtr comp) { Line 1636  xmlStreamCompile(xmlPatternPtr comp) {
                 if (s < 0)                  if (s < 0)
                     goto error;                      goto error;
                 break;                  break;
            case XML_OP_ELEM:                       case XML_OP_ELEM:
                 if ((step.value == NULL) && (step.value2 == NULL)) {                  if ((step.value == NULL) && (step.value2 == NULL)) {
                     /*                      /*
                     * We have a "." or "self::node()" here.                      * We have a "." or "self::node()" here.
Line 1655  xmlStreamCompile(xmlPatternPtr comp) { Line 1655  xmlStreamCompile(xmlPatternPtr comp) {
                         if (comp->nbStep == i + 1) {                          if (comp->nbStep == i + 1) {
                             stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;                              stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE;
                         }                          }
                        flags |= XML_STREAM_STEP_NODE;                                          flags |= XML_STREAM_STEP_NODE;
                         s = xmlStreamCompAddStep(stream, NULL, NULL,                          s = xmlStreamCompAddStep(stream, NULL, NULL,
                             XML_STREAM_ANY_NODE, flags);                              XML_STREAM_ANY_NODE, flags);
                         if (s < 0)                          if (s < 0)
Line 1671  xmlStreamCompile(xmlPatternPtr comp) { Line 1671  xmlStreamCompile(xmlPatternPtr comp) {
                             stream->steps[prevs].flags |= XML_STREAM_STEP_IN_SET;                              stream->steps[prevs].flags |= XML_STREAM_STEP_IN_SET;
                             prevs = -1;                              prevs = -1;
                         }                          }
                        break;                          break;
   
                     } else {                      } else {
                         /* Just skip this one. */                          /* Just skip this one. */
                         continue;                          continue;
                     }                      }
                 }                  }
                /* An element node. */                          /* An element node. */
                 s = xmlStreamCompAddStep(stream, step.value, step.value2,                  s = xmlStreamCompAddStep(stream, step.value, step.value2,
                    XML_ELEMENT_NODE, flags);                               XML_ELEMENT_NODE, flags);
                 if (s < 0)                  if (s < 0)
                     goto error;                      goto error;
                 prevs = s;                  prevs = s;
                flags = 0;                              flags = 0;
                break;                          break;
             case XML_OP_CHILD:              case XML_OP_CHILD:
                 /* An element node child. */                  /* An element node child. */
                 s = xmlStreamCompAddStep(stream, step.value, step.value2,                  s = xmlStreamCompAddStep(stream, step.value, step.value2,
                    XML_ELEMENT_NODE, flags);                               XML_ELEMENT_NODE, flags);
                 if (s < 0)                  if (s < 0)
                     goto error;                      goto error;
                 prevs = s;                  prevs = s;
                 flags = 0;                  flags = 0;
                break;                      break;
             case XML_OP_ALL:              case XML_OP_ALL:
                 s = xmlStreamCompAddStep(stream, NULL, NULL,                  s = xmlStreamCompAddStep(stream, NULL, NULL,
                    XML_ELEMENT_NODE, flags);                               XML_ELEMENT_NODE, flags);
                 if (s < 0)                  if (s < 0)
                     goto error;                      goto error;
                 prevs = s;                  prevs = s;
                 flags = 0;                  flags = 0;
                 break;                  break;
            case XML_OP_PARENT:             case XML_OP_PARENT:
                 break;                  break;
             case XML_OP_ANCESTOR:              case XML_OP_ANCESTOR:
                 /* Skip redundant continuations. */                  /* Skip redundant continuations. */
Line 1717  xmlStreamCompile(xmlPatternPtr comp) { Line 1717  xmlStreamCompile(xmlPatternPtr comp) {
                     stream->flags |= XML_STREAM_DESC;                      stream->flags |= XML_STREAM_DESC;
                 break;                  break;
         }          }
    }        }
     if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) {      if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) {
         /*          /*
         * If this should behave like a real pattern, we will mark          * If this should behave like a real pattern, we will mark
Line 1729  xmlStreamCompile(xmlPatternPtr comp) { Line 1729  xmlStreamCompile(xmlPatternPtr comp) {
   
         if (stream->nbStep > 0) {          if (stream->nbStep > 0) {
             if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0)              if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0)
                stream->steps[0].flags |= XML_STREAM_STEP_DESC;                     stream->steps[0].flags |= XML_STREAM_STEP_DESC;
         }          }
     }      }
     if (stream->nbStep <= s)      if (stream->nbStep <= s)
Line 1922  xmlStreamPushInternal(xmlStreamCtxtPtr stream, Line 1922  xmlStreamPushInternal(xmlStreamCtxtPtr stream,
             if ((nodeType != XML_ATTRIBUTE_NODE) &&              if ((nodeType != XML_ATTRIBUTE_NODE) &&
                 (((stream->flags & XML_PATTERN_NOTPATTERN) == 0) ||                  (((stream->flags & XML_PATTERN_NOTPATTERN) == 0) ||
                 (stream->level == 0))) {                  (stream->level == 0))) {
                    ret = 1;                                ret = 1;
             }              }
             stream->level++;              stream->level++;
             goto stream_next;              goto stream_next;
Line 1931  xmlStreamPushInternal(xmlStreamCtxtPtr stream, Line 1931  xmlStreamPushInternal(xmlStreamCtxtPtr stream,
             /*              /*
             * Skip blocked expressions.              * Skip blocked expressions.
             */              */
            stream->level++;            stream->level++;
             goto stream_next;              goto stream_next;
         }          }
   
Line 1974  xmlStreamPushInternal(xmlStreamCtxtPtr stream, Line 1974  xmlStreamPushInternal(xmlStreamCtxtPtr stream,
                 * If there are "//", then we need to process every "//"                  * If there are "//", then we need to process every "//"
                 * occuring in the states, plus any other state for this                  * occuring in the states, plus any other state for this
                 * level.                  * level.
                */                              */
                 stepNr = stream->states[2 * i];                  stepNr = stream->states[2 * i];
   
                 /* TODO: should not happen anymore: dead states */                  /* TODO: should not happen anymore: dead states */
Line 1992  xmlStreamPushInternal(xmlStreamCtxtPtr stream, Line 1992  xmlStreamPushInternal(xmlStreamCtxtPtr stream,
                 if ((tmp < stream->level) && (!desc))                  if ((tmp < stream->level) && (!desc))
                     goto next_state;                      goto next_state;
             }              }
            /*             /*
             * Check for correct node-type.              * Check for correct node-type.
             */              */
             step = comp->steps[stepNr];              step = comp->steps[stepNr];
Line 2006  xmlStreamPushInternal(xmlStreamCtxtPtr stream, Line 2006  xmlStreamPushInternal(xmlStreamCtxtPtr stream,
                     goto next_state;                      goto next_state;
                 } else if (step.nodeType != XML_STREAM_ANY_NODE)                  } else if (step.nodeType != XML_STREAM_ANY_NODE)
                     goto next_state;                      goto next_state;
            }                   }
             /*              /*
             * Compare local/namespace-name.              * Compare local/namespace-name.
             */              */
Line 2027  xmlStreamPushInternal(xmlStreamCtxtPtr stream, Line 2027  xmlStreamPushInternal(xmlStreamCtxtPtr stream,
                 xmlStrEqual(step.name, name) &&                  xmlStrEqual(step.name, name) &&
                 ((step.ns == ns) || xmlStrEqual(step.ns, ns)))                  ((step.ns == ns) || xmlStrEqual(step.ns, ns)))
             {              {
                match = 1;                          match = 1;
            }                }
#if 0 #if 0
 /*  /*
 * TODO: Pointer comparison won't work, since not guaranteed that the given  * TODO: Pointer comparison won't work, since not guaranteed that the given
 *  values are in the same dict; especially if it's the namespace name,  *  values are in the same dict; especially if it's the namespace name,
Line 2044  xmlStreamPushInternal(xmlStreamCtxtPtr stream, Line 2044  xmlStreamPushInternal(xmlStreamCtxtPtr stream,
                 } else {                  } else {
                     match = ((step.name == name) && (step.ns == ns));                      match = ((step.name == name) && (step.ns == ns));
                 }                  }
#endif /* if 0 ------------------------------------------------------- */           #endif /* if 0 ------------------------------------------------------- */
            if (match) {                            if (match) {
                 final = step.flags & XML_STREAM_STEP_FINAL;                  final = step.flags & XML_STREAM_STEP_FINAL;
                 if (desc) {                  if (desc) {
                     if (final) {                      if (final) {
Line 2070  xmlStreamPushInternal(xmlStreamCtxtPtr stream, Line 2070  xmlStreamPushInternal(xmlStreamCtxtPtr stream,
                     */                      */
                     ret = 1;                      ret = 1;
                 }                  }
            }                   }
             if (((comp->flags & XML_STREAM_DESC) == 0) &&              if (((comp->flags & XML_STREAM_DESC) == 0) &&
                 ((! match) || final))  {                  ((! match) || final))  {
                 /*                  /*
Line 2101  next_state: Line 2101  next_state:
             * Re/enter the expression if it is a "descendant" one,              * Re/enter the expression if it is a "descendant" one,
             * or if we are at the 1st level of evaluation.              * or if we are at the 1st level of evaluation.
             */              */
            
             if (stream->level == 1) {              if (stream->level == 1) {
                 if (XML_STREAM_XS_IDC(stream)) {                  if (XML_STREAM_XS_IDC(stream)) {
                     /*                      /*
Line 2111  next_state: Line 2111  next_state:
                     goto stream_next;                      goto stream_next;
                 } else                  } else
                     goto compare;                      goto compare;
            }                   }
             /*              /*
             * A "//" is always reentrant.              * A "//" is always reentrant.
             */              */
Line 2121  next_state: Line 2121  next_state:
             /*              /*
             * XS-IDC: Process the 2nd level, since the missing              * XS-IDC: Process the 2nd level, since the missing
             * "self::node()" is responsible for the 2nd level being              * "self::node()" is responsible for the 2nd level being
            * the real start level.                     * the real start level.
            */                  */
             if ((stream->level == 2) && XML_STREAM_XS_IDC(stream))              if ((stream->level == 2) && XML_STREAM_XS_IDC(stream))
                 goto compare;                  goto compare;
   
             goto stream_next;              goto stream_next;
         }          }
        
 compare:  compare:
         /*          /*
         * Check expected node-type.          * Check expected node-type.
Line 2137  compare: Line 2137  compare:
             if (nodeType == XML_ATTRIBUTE_NODE)              if (nodeType == XML_ATTRIBUTE_NODE)
                 goto stream_next;                  goto stream_next;
             else if (step.nodeType != XML_STREAM_ANY_NODE)              else if (step.nodeType != XML_STREAM_ANY_NODE)
                goto stream_next;                            goto stream_next;
         }          }
         /*          /*
         * Compare local/namespace-name.          * Compare local/namespace-name.
Line 2159  compare: Line 2159  compare:
             xmlStrEqual(step.name, name) &&              xmlStrEqual(step.name, name) &&
             ((step.ns == ns) || xmlStrEqual(step.ns, ns)))              ((step.ns == ns) || xmlStrEqual(step.ns, ns)))
         {          {
            match = 1;                  match = 1;
        }                   }
         final = step.flags & XML_STREAM_STEP_FINAL;          final = step.flags & XML_STREAM_STEP_FINAL;
        if (match) {                if (match) {
             if (final)              if (final)
                 ret = 1;                  ret = 1;
             else              else
Line 2187  compare: Line 2187  compare:
 stream_next:  stream_next:
         stream = stream->next;          stream = stream->next;
     } /* while stream != NULL */      } /* while stream != NULL */
 
     if (err > 0)      if (err > 0)
         ret = -1;          ret = -1;
 #ifdef DEBUG_STREAMING  #ifdef DEBUG_STREAMING
Line 2279  xmlStreamPushAttr(xmlStreamCtxtPtr stream, Line 2279  xmlStreamPushAttr(xmlStreamCtxtPtr stream,
 int  int
 xmlStreamPop(xmlStreamCtxtPtr stream) {  xmlStreamPop(xmlStreamCtxtPtr stream) {
     int i, lev;      int i, lev;
    
     if (stream == NULL)      if (stream == NULL)
         return(-1);          return(-1);
     while (stream != NULL) {      while (stream != NULL) {
Line 2298  xmlStreamPop(xmlStreamCtxtPtr stream) { Line 2298  xmlStreamPop(xmlStreamCtxtPtr stream) {
             stream->level--;              stream->level--;
         /*          /*
          * Check evolution of existing states           * Check evolution of existing states
         */              */
         for (i = stream->nbState -1; i >= 0; i--) {          for (i = stream->nbState -1; i >= 0; i--) {
             /* discard obsoleted states */              /* discard obsoleted states */
             lev = stream->states[(2 * i) + 1];              lev = stream->states[(2 * i) + 1];
Line 2326  xmlStreamPop(xmlStreamCtxtPtr stream) { Line 2326  xmlStreamPop(xmlStreamCtxtPtr stream) {
  */   */
 int  int
 xmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt)  xmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt)
{    {
     if (streamCtxt == NULL)      if (streamCtxt == NULL)
         return(-1);          return(-1);
     while (streamCtxt != NULL) {      while (streamCtxt != NULL) {
        if (streamCtxt->comp->flags & XML_STREAM_FINAL_IS_ANY_NODE)             if (streamCtxt->comp->flags & XML_STREAM_FINAL_IS_ANY_NODE)
             return(1);              return(1);
         streamCtxt = streamCtxt->next;          streamCtxt = streamCtxt->next;
     }      }
Line 2381  xmlPatterncompile(const xmlChar *pattern, xmlDict *dic Line 2381  xmlPatterncompile(const xmlChar *pattern, xmlDict *dic
             }              }
             or++;              or++;
         }          }
        if (ctxt == NULL) goto error;           if (ctxt == NULL) goto error;
         cur = xmlNewPattern();          cur = xmlNewPattern();
         if (cur == NULL) goto error;          if (cur == NULL) goto error;
         /*          /*
         * Assign string dict.          * Assign string dict.
         */          */
        if (dict) {                 if (dict) {
             cur->dict = dict;              cur->dict = dict;
             xmlDictReference(dict);              xmlDictReference(dict);
         }          }
Line 2570  xmlPatternMaxDepth(xmlPatternPtr comp) { Line 2570  xmlPatternMaxDepth(xmlPatternPtr comp) {
  * part of the set.   * part of the set.
  *   *
  * Returns -1 in case of error otherwise the depth,   * Returns -1 in case of error otherwise the depth,
 *          *
  */   */
 int  int
 xmlPatternMinDepth(xmlPatternPtr comp) {  xmlPatternMinDepth(xmlPatternPtr comp) {

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>