mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-21 14:53:44 +03:00
fixed remaining known bugs in the XPath streaming, and switched XPath to
* pattern.c xpath.c: fixed remaining known bugs in the XPath streaming, and switched XPath to use it by default when possible Daniel
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
Mon Feb 21 11:41:41 CET 2005 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
|
* pattern.c xpath.c: fixed remaining known bugs in the XPath streaming,
|
||||||
|
and switched XPath to use it by default when possible
|
||||||
|
|
||||||
Sat Feb 19 19:25:14 CET 2005 Daniel Veillard <daniel@veillard.com>
|
Sat Feb 19 19:25:14 CET 2005 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
* xmlschemastypes.c: a bit of cleanup
|
* xmlschemastypes.c: a bit of cleanup
|
||||||
|
59
pattern.c
59
pattern.c
@@ -231,6 +231,7 @@ xmlFreePatternList(xmlPatternPtr comp) {
|
|||||||
while (comp != NULL) {
|
while (comp != NULL) {
|
||||||
cur = comp;
|
cur = comp;
|
||||||
comp = comp->next;
|
comp = comp->next;
|
||||||
|
cur->next = NULL;
|
||||||
xmlFreePattern(cur);
|
xmlFreePattern(cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1081,6 +1082,10 @@ xmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
|
|||||||
xmlFree(name);
|
xmlFree(name);
|
||||||
}
|
}
|
||||||
} else if (CUR == '*') {
|
} else if (CUR == '*') {
|
||||||
|
if (name != NULL) {
|
||||||
|
ctxt->error = 1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
NEXT;
|
NEXT;
|
||||||
PUSH(XML_OP_ALL, token, NULL);
|
PUSH(XML_OP_ALL, token, NULL);
|
||||||
} else {
|
} else {
|
||||||
@@ -1350,7 +1355,19 @@ xmlStreamCompile(xmlPatternPtr comp) {
|
|||||||
stream->dict = comp->dict;
|
stream->dict = comp->dict;
|
||||||
xmlDictReference(stream->dict);
|
xmlDictReference(stream->dict);
|
||||||
}
|
}
|
||||||
for (i = 0;i < comp->nbStep;i++) {
|
|
||||||
|
/*
|
||||||
|
* Skip leading ./ on relative paths
|
||||||
|
*/
|
||||||
|
i = 0;
|
||||||
|
while ((comp->flags & PAT_FROM_CUR) && (comp->nbStep > i + 2) &&
|
||||||
|
(comp->steps[i].op == XML_OP_ELEM) &&
|
||||||
|
(comp->steps[i].value == NULL) &&
|
||||||
|
(comp->steps[i].value2 == NULL) &&
|
||||||
|
(comp->steps[i + 1].op == XML_OP_PARENT)) {
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
for (;i < comp->nbStep;i++) {
|
||||||
switch (comp->steps[i].op) {
|
switch (comp->steps[i].op) {
|
||||||
case XML_OP_END:
|
case XML_OP_END:
|
||||||
break;
|
break;
|
||||||
@@ -1374,8 +1391,15 @@ xmlStreamCompile(xmlPatternPtr comp) {
|
|||||||
if (s < 0)
|
if (s < 0)
|
||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
case XML_OP_CHILD:
|
|
||||||
case XML_OP_ELEM:
|
case XML_OP_ELEM:
|
||||||
|
if ((comp->steps[i].value == NULL) &&
|
||||||
|
(comp->steps[i].value2 == NULL) &&
|
||||||
|
(comp->nbStep > i + 2) &&
|
||||||
|
(comp->steps[i + 1].op == XML_OP_PARENT)) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case XML_OP_CHILD:
|
||||||
s = xmlStreamCompAddStep(stream, comp->steps[i].value,
|
s = xmlStreamCompAddStep(stream, comp->steps[i].value,
|
||||||
comp->steps[i].value2, flags);
|
comp->steps[i].value2, flags);
|
||||||
flags = 0;
|
flags = 0;
|
||||||
@@ -1389,6 +1413,13 @@ xmlStreamCompile(xmlPatternPtr comp) {
|
|||||||
goto error;
|
goto error;
|
||||||
break;
|
break;
|
||||||
case XML_OP_PARENT:
|
case XML_OP_PARENT:
|
||||||
|
if ((comp->nbStep > i + 1) &&
|
||||||
|
(comp->steps[i + 1].op == XML_OP_ELEM) &&
|
||||||
|
(comp->steps[i + 1].value == NULL) &&
|
||||||
|
(comp->steps[i + 1].value2 == NULL)) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case XML_OP_ANCESTOR:
|
case XML_OP_ANCESTOR:
|
||||||
flags |= XML_STREAM_STEP_DESC;
|
flags |= XML_STREAM_STEP_DESC;
|
||||||
@@ -1816,6 +1847,8 @@ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict,
|
|||||||
xmlPatParserContextPtr ctxt = NULL;
|
xmlPatParserContextPtr ctxt = NULL;
|
||||||
const xmlChar *or, *start;
|
const xmlChar *or, *start;
|
||||||
xmlChar *tmp = NULL;
|
xmlChar *tmp = NULL;
|
||||||
|
int type = 0;
|
||||||
|
int streamable = 1;
|
||||||
|
|
||||||
if (pattern == NULL)
|
if (pattern == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@@ -1851,6 +1884,18 @@ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict,
|
|||||||
xmlFreePatParserContext(ctxt);
|
xmlFreePatParserContext(ctxt);
|
||||||
|
|
||||||
|
|
||||||
|
if (streamable) {
|
||||||
|
if (type == 0) {
|
||||||
|
type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR);
|
||||||
|
} else if (type == PAT_FROM_ROOT) {
|
||||||
|
if (cur->flags & PAT_FROM_CUR)
|
||||||
|
streamable = 0;
|
||||||
|
} else if (type == PAT_FROM_CUR) {
|
||||||
|
if (cur->flags & PAT_FROM_ROOT)
|
||||||
|
streamable = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (streamable)
|
||||||
xmlStreamCompile(cur);
|
xmlStreamCompile(cur);
|
||||||
if (xmlReversePattern(cur) < 0)
|
if (xmlReversePattern(cur) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@@ -1860,6 +1905,16 @@ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict,
|
|||||||
}
|
}
|
||||||
start = or;
|
start = or;
|
||||||
}
|
}
|
||||||
|
if (streamable == 0) {
|
||||||
|
cur = ret;
|
||||||
|
while (cur != NULL) {
|
||||||
|
if (cur->stream != NULL) {
|
||||||
|
xmlFreeStreamComp(cur->stream);
|
||||||
|
cur->stream = NULL;
|
||||||
|
}
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
return(ret);
|
return(ret);
|
||||||
error:
|
error:
|
||||||
if (ctxt != NULL) xmlFreePatParserContext(ctxt);
|
if (ctxt != NULL) xmlFreePatParserContext(ctxt);
|
||||||
|
22
xpath.c
22
xpath.c
@@ -56,16 +56,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LIBXML_PATTERN_ENABLED
|
#ifdef LIBXML_PATTERN_ENABLED
|
||||||
/* currently only in testing for DV as it's not yet solid enough for XSLT */
|
#define XPATH_STREAMING
|
||||||
/*
|
|
||||||
* TODO:
|
|
||||||
* - fix the | where there is both relative and absolute expressions
|
|
||||||
* probably need new pattens APIs to separate both e.g "//b | a "
|
|
||||||
* - fix also the 0 depth trick used for "/" and "." when or'ed
|
|
||||||
* - double check /. is a noop
|
|
||||||
* - libxslt tests show a mem leak of a few bytes
|
|
||||||
*/
|
|
||||||
/* #define XPATH_STREAMING */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TODO \
|
#define TODO \
|
||||||
@@ -10963,13 +10954,14 @@ xmlXPathRunStreamEval(xmlXPathContextPtr ctxt, xmlPatternPtr comp) {
|
|||||||
from_root = xmlPatternFromRoot(comp);
|
from_root = xmlPatternFromRoot(comp);
|
||||||
if (from_root < 0)
|
if (from_root < 0)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
/* printf("stream eval: depth %d from root %d\n", max_depth, from_root); */
|
#if 0
|
||||||
|
printf("stream eval: depth %d from root %d\n", max_depth, from_root);
|
||||||
|
#endif
|
||||||
|
|
||||||
retval = xmlXPathNewNodeSet(NULL);
|
retval = xmlXPathNewNodeSet(NULL);
|
||||||
if (retval == NULL)
|
if (retval == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
/* FIXME '. | /' */
|
|
||||||
if ((from_root) && (max_depth == 0)) {
|
if ((from_root) && (max_depth == 0)) {
|
||||||
xmlXPathNodeSetAddUnique(retval->nodesetval, (xmlNodePtr) ctxt->doc);
|
xmlXPathNodeSetAddUnique(retval->nodesetval, (xmlNodePtr) ctxt->doc);
|
||||||
return(retval);
|
return(retval);
|
||||||
@@ -11085,8 +11077,10 @@ scan_children:
|
|||||||
|
|
||||||
} while ((cur != NULL) && (depth >= 0));
|
} while ((cur != NULL) && (depth >= 0));
|
||||||
done:
|
done:
|
||||||
/* printf("stream eval: checked %d nodes selected %d\n",
|
#if 0
|
||||||
nb_nodes, retval->nodesetval->nodeNr); */
|
printf("stream eval: checked %d nodes selected %d\n",
|
||||||
|
nb_nodes, retval->nodesetval->nodeNr);
|
||||||
|
#endif
|
||||||
xmlFreeStreamCtxt(patstream);
|
xmlFreeStreamCtxt(patstream);
|
||||||
return(retval);
|
return(retval);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user