| OLD | NEW |
| 1 /* | 1 /* |
| 2 * xpath.c: XML Path Language implementation | 2 * xpath.c: XML Path Language implementation |
| 3 * XPath is a language for addressing parts of an XML document, | 3 * XPath is a language for addressing parts of an XML document, |
| 4 * designed to be used by both XSLT and XPointer | 4 * designed to be used by both XSLT and XPointer |
| 5 *f | 5 *f |
| 6 * Reference: W3C Recommendation 16 November 1999 | 6 * Reference: W3C Recommendation 16 November 1999 |
| 7 * http://www.w3.org/TR/1999/REC-xpath-19991116 | 7 * http://www.w3.org/TR/1999/REC-xpath-19991116 |
| 8 * Public reference: | 8 * Public reference: |
| 9 * http://www.w3.org/TR/xpath | 9 * http://www.w3.org/TR/xpath |
| 10 * | 10 * |
| (...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 comp->steps[comp->nbStep].value5 = (xmlChar *) | 1125 comp->steps[comp->nbStep].value5 = (xmlChar *) |
| 1126 (void *)xmlDictLookup(comp->dict, value5, -1); | 1126 (void *)xmlDictLookup(comp->dict, value5, -1); |
| 1127 xmlFree(value5); | 1127 xmlFree(value5); |
| 1128 } else | 1128 } else |
| 1129 comp->steps[comp->nbStep].value5 = NULL; | 1129 comp->steps[comp->nbStep].value5 = NULL; |
| 1130 } else { | 1130 } else { |
| 1131 comp->steps[comp->nbStep].value4 = value4; | 1131 comp->steps[comp->nbStep].value4 = value4; |
| 1132 comp->steps[comp->nbStep].value5 = value5; | 1132 comp->steps[comp->nbStep].value5 = value5; |
| 1133 } | 1133 } |
| 1134 comp->steps[comp->nbStep].cache = NULL; | 1134 comp->steps[comp->nbStep].cache = NULL; |
| 1135 comp->steps[comp->nbStep].cacheURI = NULL; |
| 1135 return(comp->nbStep++); | 1136 return(comp->nbStep++); |
| 1136 } | 1137 } |
| 1137 | 1138 |
| 1138 /** | 1139 /** |
| 1139 * xmlXPathCompSwap: | 1140 * xmlXPathCompSwap: |
| 1140 * @comp: the compiled expression | 1141 * @comp: the compiled expression |
| 1141 * @op: operation index | 1142 * @op: operation index |
| 1142 * | 1143 * |
| 1143 * Swaps 2 operations in the compiled expression | 1144 * Swaps 2 operations in the compiled expression |
| 1144 */ | 1145 */ |
| (...skipping 13580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14725 xmlDictReference(comp->dict); | 14726 xmlDictReference(comp->dict); |
| 14726 return(comp); | 14727 return(comp); |
| 14727 } | 14728 } |
| 14728 xmlFreePattern(stream); | 14729 xmlFreePattern(stream); |
| 14729 } | 14730 } |
| 14730 return(NULL); | 14731 return(NULL); |
| 14731 } | 14732 } |
| 14732 #endif /* XPATH_STREAMING */ | 14733 #endif /* XPATH_STREAMING */ |
| 14733 | 14734 |
| 14734 static void | 14735 static void |
| 14735 xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op) | 14736 xmlXPathOptimizeExpressionInternal(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr o
p) |
| 14736 { | 14737 { |
| 14738 /* Already optimized? */ |
| 14739 if (op->cacheURI != NULL) |
| 14740 return; |
| 14741 |
| 14737 /* | 14742 /* |
| 14738 * Try to rewrite "descendant-or-self::node()/foo" to an optimized | 14743 * Try to rewrite "descendant-or-self::node()/foo" to an optimized |
| 14739 * internal representation. | 14744 * internal representation. |
| 14740 */ | 14745 */ |
| 14741 | 14746 |
| 14742 if ((op->op == XPATH_OP_COLLECT /* 11 */) && | 14747 if ((op->op == XPATH_OP_COLLECT /* 11 */) && |
| 14743 (op->ch1 != -1) && | 14748 (op->ch1 != -1) && |
| 14744 (op->ch2 == -1 /* no predicate */)) | 14749 (op->ch2 == -1 /* no predicate */)) |
| 14745 { | 14750 { |
| 14746 xmlXPathStepOpPtr prevop = &comp->steps[op->ch1]; | 14751 xmlXPathStepOpPtr prevop = &comp->steps[op->ch1]; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 14777 */ | 14782 */ |
| 14778 op->ch1 = prevop->ch1; | 14783 op->ch1 = prevop->ch1; |
| 14779 op->value = AXIS_DESCENDANT_OR_SELF; | 14784 op->value = AXIS_DESCENDANT_OR_SELF; |
| 14780 break; | 14785 break; |
| 14781 default: | 14786 default: |
| 14782 break; | 14787 break; |
| 14783 } | 14788 } |
| 14784 } | 14789 } |
| 14785 } | 14790 } |
| 14786 | 14791 |
| 14792 /* Mark the node. */ |
| 14793 op->cacheURI = (void*)(~0); |
| 14794 |
| 14787 /* Recurse */ | 14795 /* Recurse */ |
| 14788 if (op->ch1 != -1) | 14796 if (op->ch1 != -1) |
| 14789 xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]); | 14797 xmlXPathOptimizeExpressionInternal(comp, &comp->steps[op->ch1]); |
| 14790 if (op->ch2 != -1) | 14798 if (op->ch2 != -1) |
| 14791 » xmlXPathOptimizeExpression(comp, &comp->steps[op->ch2]); | 14799 » xmlXPathOptimizeExpressionInternal(comp, &comp->steps[op->ch2]); |
| 14800 } |
| 14801 |
| 14802 static void |
| 14803 xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, int root) |
| 14804 { |
| 14805 int i; |
| 14806 /* The expression tree/graph traversal is linear, visiting |
| 14807 * each node at most once. Mark each xmlXPathStepOp node |
| 14808 * upon visiting, taking care of clearing out the marks |
| 14809 * afterwards. |
| 14810 */ |
| 14811 xmlXPathOptimizeExpressionInternal(comp, &comp->steps[root]); |
| 14812 for (i = 0; i <= root; ++i) |
| 14813 comp->steps[i].cacheURI = NULL; |
| 14792 } | 14814 } |
| 14793 | 14815 |
| 14794 /** | 14816 /** |
| 14795 * xmlXPathCtxtCompile: | 14817 * xmlXPathCtxtCompile: |
| 14796 * @ctxt: an XPath context | 14818 * @ctxt: an XPath context |
| 14797 * @str: the XPath expression | 14819 * @str: the XPath expression |
| 14798 * | 14820 * |
| 14799 * Compile an XPath expression | 14821 * Compile an XPath expression |
| 14800 * | 14822 * |
| 14801 * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL. | 14823 * Returns the xmlXPathCompExprPtr resulting from the compilation or NULL. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14840 } | 14862 } |
| 14841 xmlXPathFreeParserContext(pctxt); | 14863 xmlXPathFreeParserContext(pctxt); |
| 14842 | 14864 |
| 14843 if (comp != NULL) { | 14865 if (comp != NULL) { |
| 14844 comp->expr = xmlStrdup(str); | 14866 comp->expr = xmlStrdup(str); |
| 14845 #ifdef DEBUG_EVAL_COUNTS | 14867 #ifdef DEBUG_EVAL_COUNTS |
| 14846 comp->string = xmlStrdup(str); | 14868 comp->string = xmlStrdup(str); |
| 14847 comp->nb = 0; | 14869 comp->nb = 0; |
| 14848 #endif | 14870 #endif |
| 14849 if ((comp->nbStep > 1) && (comp->last >= 0)) { | 14871 if ((comp->nbStep > 1) && (comp->last >= 0)) { |
| 14850 » xmlXPathOptimizeExpression(comp, &comp->steps[comp->last]); | 14872 » xmlXPathOptimizeExpression(comp, comp->last); |
| 14851 } | 14873 } |
| 14852 } | 14874 } |
| 14853 return(comp); | 14875 return(comp); |
| 14854 } | 14876 } |
| 14855 | 14877 |
| 14856 /** | 14878 /** |
| 14857 * xmlXPathCompile: | 14879 * xmlXPathCompile: |
| 14858 * @str: the XPath expression | 14880 * @str: the XPath expression |
| 14859 * | 14881 * |
| 14860 * Compile an XPath expression | 14882 * Compile an XPath expression |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15022 while (*ctxt->cur != 0) ctxt->cur++; | 15044 while (*ctxt->cur != 0) ctxt->cur++; |
| 15023 } else | 15045 } else |
| 15024 #endif | 15046 #endif |
| 15025 { | 15047 { |
| 15026 xmlXPathCompileExpr(ctxt, 1); | 15048 xmlXPathCompileExpr(ctxt, 1); |
| 15027 if ((ctxt->error == XPATH_EXPRESSION_OK) && | 15049 if ((ctxt->error == XPATH_EXPRESSION_OK) && |
| 15028 (ctxt->comp != NULL) && | 15050 (ctxt->comp != NULL) && |
| 15029 (ctxt->comp->nbStep > 1) && | 15051 (ctxt->comp->nbStep > 1) && |
| 15030 (ctxt->comp->last >= 0)) | 15052 (ctxt->comp->last >= 0)) |
| 15031 { | 15053 { |
| 15032 » xmlXPathOptimizeExpression(ctxt->comp, | 15054 » xmlXPathOptimizeExpression(ctxt->comp, ctxt->comp->last); |
| 15033 » » &ctxt->comp->steps[ctxt->comp->last]); | |
| 15034 } | 15055 } |
| 15035 } | 15056 } |
| 15036 CHECK_ERROR; | 15057 CHECK_ERROR; |
| 15037 xmlXPathRunEval(ctxt, 0); | 15058 xmlXPathRunEval(ctxt, 0); |
| 15038 } | 15059 } |
| 15039 | 15060 |
| 15040 /** | 15061 /** |
| 15041 * xmlXPathEval: | 15062 * xmlXPathEval: |
| 15042 * @str: the XPath expression | 15063 * @str: the XPath expression |
| 15043 * @ctx: the XPath context | 15064 * @ctx: the XPath context |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15368 xmlXPathTranslateFunction); | 15389 xmlXPathTranslateFunction); |
| 15369 | 15390 |
| 15370 xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri", | 15391 xmlXPathRegisterFuncNS(ctxt, (const xmlChar *)"escape-uri", |
| 15371 (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions", | 15392 (const xmlChar *)"http://www.w3.org/2002/08/xquery-functions", |
| 15372 xmlXPathEscapeUriFunction); | 15393 xmlXPathEscapeUriFunction); |
| 15373 } | 15394 } |
| 15374 | 15395 |
| 15375 #endif /* LIBXML_XPATH_ENABLED */ | 15396 #endif /* LIBXML_XPATH_ENABLED */ |
| 15376 #define bottom_xpath | 15397 #define bottom_xpath |
| 15377 #include "elfgcchack.h" | 15398 #include "elfgcchack.h" |
| OLD | NEW |