Commit f62ceffb authored by Daniel Veillard's avatar Daniel Veillard
Browse files

General fixes, XPointer improvements:

- HTMLparser.c: some fixes on auto-open of html/head/body
- encoding.c: fixed a compilation error on some gcc env
- xpath.c xpointer.[ch] xpathInternals.h: improved the
  XPointer implementation
- test/XPath/xptr/strpoint test/XPath/xptr/strrange3: added
  related XPointer tests and associated results
Daniel
parent 851c59c2
Sat Nov 25 00:24:49 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
* HTMLparser.c: some fixes on auto-open of html/head/body
* encoding.c: fixed a compilation error on some gcc env
* xpath.c xpointer.[ch] xpathInternals.h: improved the
XPointer implementation
* test/XPath/xptr/strpoint test/XPath/xptr/strrange3: added
related XPointer tests and associated results
Fri Nov 24 14:01:44 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
* doc/xmldtd.html doc/xml.html: following a short step by step
......
......@@ -855,13 +855,13 @@ htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
}
if ((xmlStrEqual(newtag, BAD_CAST"body")) || (xmlStrEqual(newtag, BAD_CAST"head")))
return;
if (ctxt->nameNr <= 1) {
if ((xmlStrEqual(newtag, BAD_CAST"script")) ||
(xmlStrEqual(newtag, BAD_CAST"style")) ||
(xmlStrEqual(newtag, BAD_CAST"meta")) ||
(xmlStrEqual(newtag, BAD_CAST"link")) ||
(xmlStrEqual(newtag, BAD_CAST"title")) ||
(xmlStrEqual(newtag, BAD_CAST"base"))) {
if ((ctxt->nameNr <= 1) &&
((xmlStrEqual(newtag, BAD_CAST"script")) ||
(xmlStrEqual(newtag, BAD_CAST"style")) ||
(xmlStrEqual(newtag, BAD_CAST"meta")) ||
(xmlStrEqual(newtag, BAD_CAST"link")) ||
(xmlStrEqual(newtag, BAD_CAST"title")) ||
(xmlStrEqual(newtag, BAD_CAST"base")))) {
/*
* dropped OBJECT ... i you put it first BODY will be
* assumed !
......@@ -872,14 +872,25 @@ htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
htmlnamePush(ctxt, xmlStrdup(BAD_CAST"head"));
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
} else {
} else if ((!xmlStrEqual(newtag, BAD_CAST"noframes")) &&
(!xmlStrEqual(newtag, BAD_CAST"frame")) &&
(!xmlStrEqual(newtag, BAD_CAST"frameset"))) {
int i;
for (i = 0;i < ctxt->nameNr;i++) {
if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
return;
}
if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"head")) {
return;
}
}
#ifdef DEBUG
xmlGenericError(xmlGenericErrorContext,"Implied element body: pushed body\n");
xmlGenericError(xmlGenericErrorContext,"Implied element body: pushed body\n");
#endif
htmlnamePush(ctxt, xmlStrdup(BAD_CAST"body"));
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
}
htmlnamePush(ctxt, xmlStrdup(BAD_CAST"body"));
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
}
}
......@@ -2932,6 +2943,41 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
*/
htmlCheckImplied(ctxt, name);
/*
* Avoid html at any level > 0, head at any level != 1
* or any attempt to recurse body
*/
if ((ctxt->nameNr > 0) && (xmlStrEqual(name, BAD_CAST"html"))) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"htmlParseStartTag: misplaced <html> tag\n");
ctxt->wellFormed = 0;
xmlFree(name);
return;
}
if ((ctxt->nameNr != 1) &&
(xmlStrEqual(name, BAD_CAST"head"))) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"htmlParseStartTag: misplaced <head> tag\n");
ctxt->wellFormed = 0;
xmlFree(name);
return;
}
if (xmlStrEqual(name, BAD_CAST"body")) {
int i;
for (i = 0;i < ctxt->nameNr;i++) {
if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
ctxt->sax->error(ctxt->userData,
"htmlParseStartTag: misplaced <body> tag\n");
ctxt->wellFormed = 0;
xmlFree(name);
return;
}
}
}
/*
* Now parse the attributes, it ends up with the ending
*
......
......@@ -620,35 +620,31 @@ esac
])
# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
# the libltdl convenience library and INCLTDL to the include flags for
# the libltdl header and adds --enable-ltdl-convenience to the
# configure arguments. Note that LIBLTDL and INCLTDL are not
# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
# with '${top_builddir}/' and INCLTDL will be prefixed with
# '${top_srcdir}/' (note the single quotes!). If your package is not
# flat and you're not using automake, define top_builddir and
# top_srcdir appropriately in the Makefiles.
# the libltdl convenience library, adds --enable-ltdl-convenience to
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
# '${top_builddir}/' (note the single quotes!) if your package is not
# flat, and, if you're not using automake, define top_builddir as
# appropriate in the Makefiles.
AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
case "$enable_ltdl_convenience" in
no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
"") enable_ltdl_convenience=yes
ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
esac
LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
])
# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
# the libltdl installable library and INCLTDL to the include flags for
# the libltdl header and adds --enable-ltdl-install to the configure
# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
# with '${top_srcdir}/' (note the single quotes!). If your package is
# not flat and you're not using automake, define top_builddir and
# top_srcdir appropriately in the Makefiles.
# the libltdl installable library, and adds --enable-ltdl-install to
# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
# to be `${top_builddir}/libltdl'. Make sure you start DIR with
# '${top_builddir}/' (note the single quotes!) if your package is not
# flat, and, if you're not using automake, define top_builddir as
# appropriate in the Makefiles.
# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_CHECK_LIB(ltdl, main,
......@@ -661,8 +657,8 @@ AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
])
if test x"$enable_ltdl_install" = x"yes"; then
ac_configure_args="$ac_configure_args --enable-ltdl-install"
LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
else
ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
LIBLTDL="-lltdl"
......
......@@ -1686,9 +1686,9 @@ xmlIconvWrapper(iconv_t cd,
#ifdef EINVAL
if (errno == EINVAL) {
return -3;
}
} else
#endif
else {
{
return -3;
}
}
......
......@@ -133,6 +133,8 @@ void xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth);
* Existing functions
*/
int xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
xmlXPathObjectPtr res);
void xmlXPathInit(void);
void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt);
......
......@@ -49,6 +49,7 @@ xmlXPathObjectPtr xmlXPtrEval (const xmlChar *str,
void xmlXPtrRangeToFunction (xmlXPathParserContextPtr ctxt,
int nargs);
xmlNodePtr xmlXPtrBuildNodeList (xmlXPathObjectPtr obj);
void xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt);
#ifdef __cplusplus
}
......
......@@ -13,12 +13,12 @@
<meta content="agent,technology,intranet,extranet,management,filtering,ranking,solution,service,intelligent,intelligence,client,server,architecture,developer,development,information,telecommunication,announcement,press,product,profile,contact,multi-agent,meta-search,metasearch,multi-thread,mobile,wireless,shopping,robot,PCS,Copernic,engine,toolkit,CDK,EDK" name="KEYWORDS">
<meta content="MSHTML 5.00.3103.1000" name="GENERATOR">
</head>
<body><frameset border="false" cols="172,*" frameborder="0" framespacing="0">
<frameset border="false" cols="172,*" frameborder="0" framespacing="0">
<frame marginheight="0" marginwidth="0" name="left" noresize scrolling="no" src="doc2_files/side.htm" target="rtop">
<frameset rows="43,*">
<frame marginheight="0" marginwidth="0" name="rtop" noresize scrolling="no" src="doc2_files/top.htm" target="rbottom">
<frame name="rbottom" noresize src="doc2_files/contents.htm" target="_top">
</frameset>
<noframes><body bgcolor="#FFFFFF" text="#000000" link="#000080" vlink="#000080" alink="#000080" topmargin="0" leftmargin="0" marginheight="0" marginwidth="0"><p>This page uses frames, but your browser doesn't support them.</p></body></noframes>
</frameset></body>
</frameset>
</html>
......@@ -37,7 +37,6 @@ SAX.ignorableWhitespace(
SAX.startElement(meta, content='MSHTML 5.00.3103.1000', name='GENERATOR')
SAX.endElement(meta)
SAX.endElement(head)
SAX.startElement(body)
SAX.startElement(frameset, border='false', cols='172,*', frameborder='0', framespacing='0')
SAX.startElement(frame, marginheight='0', marginwidth='0', name='left', noresize, scrolling='no', src='doc2_files/side.htm', target='rtop')
SAX.endElement(frame)
......@@ -64,7 +63,6 @@ SAX.characters(
, 3)
SAX.endElement(noframes)
SAX.endElement(frameset)
SAX.endElement(body)
SAX.endElement(html)
SAX.ignorableWhitespace(
, 1)
......
========================
Expression: xpointer(start-point(string-range(//p,'multiple')))
Object is a Location Set:
1 : Object is a point : index 1 in node TEXT
content=multiple tests
========================
Expression: xpointer(end-point(string-range(//p,'multiple')))
Object is a Location Set:
1 : Object is a point : index 8 in node TEXT
content=multiple tests
========================
Expression: xpointer(start-point(string-range(//p,'test')))
Object is a Location Set:
1 : Object is a point : index 10 in node TEXT
content=a simple test
2 : Object is a point : index 10 in node TEXT
content=multiple tests
3 : Object is a point : index 7 in node TEXT
content=anced test
========================
Expression: xpointer(end-point(string-range(//p,'test')))
Object is a Location Set:
1 : Object is a point : index 13 in node TEXT
content=a simple test
2 : Object is a point : index 13 in node TEXT
content=multiple tests
3 : Object is a point : index 10 in node TEXT
content=anced test
========================
Expression: xpointer(start-point(string-range(//*,'multiple',1,0)))
Object is a Location Set:
1 : Object is a point : index 1 in node TEXT
content=multiple tests
========================
Expression: xpointer(end-point(string-range(//*,'multiple',1,0)))
Object is a Location Set:
1 : Object is a point : index 1 in node TEXT
content=multiple tests
========================
Expression: xpointer(start-point(string-range(//*,'multiple',1,1)))
Object is a Location Set:
1 : Object is a point : index 1 in node TEXT
content=multiple tests
========================
Expression: xpointer(end-point(string-range(//*,'multiple',1,1)))
Object is a Location Set:
1 : Object is a point : index 2 in node TEXT
content=multiple tests
========================
Expression: xpointer(start-point(string-range(//p,'test'))[1])
Object is a Location Set:
1 : Object is a point : index 10 in node TEXT
content=a simple test
========================
Expression: xpointer(string-range(//p, 'test', 1, 0))
Object is a Location Set:
1 : Object is a collapsed range :
index 10 in node
TEXT
content=a simple test
2 : Object is a collapsed range :
index 10 in node
TEXT
content=multiple tests
3 : Object is a collapsed range :
index 7 in node
TEXT
content=anced test
========================
Expression: xpointer(string-range(//*, 'test', 1, 0))
Object is a Location Set:
1 : Object is a collapsed range :
index 10 in node
TEXT
content=a simple test
2 : Object is a collapsed range :
index 10 in node
TEXT
content=multiple tests
3 : Object is a collapsed range :
index 7 in node
TEXT
content=anced test
========================
Expression: xpointer(string-range(//p, 'test', 1, 0)[2])
Object is a Location Set:
1 : Object is a collapsed range :
index 10 in node
TEXT
content=multiple tests
========================
Expression: xpointer(string-range(//*, 'test', 1, 0)[2])
Object is a Location Set:
1 : Object is a collapsed range :
index 10 in node
TEXT
content=multiple tests
xpointer(start-point(string-range(//p,'multiple')))
xpointer(end-point(string-range(//p,'multiple')))
xpointer(start-point(string-range(//p,'test')))
xpointer(end-point(string-range(//p,'test')))
xpointer(start-point(string-range(//*,'multiple',1,0)))
xpointer(end-point(string-range(//*,'multiple',1,0)))
xpointer(start-point(string-range(//*,'multiple',1,1)))
xpointer(end-point(string-range(//*,'multiple',1,1)))
xpointer(start-point(string-range(//p,'test'))[1])
xpointer(string-range(//p, 'test', 1, 0))
xpointer(string-range(//*, 'test', 1, 0))
xpointer(string-range(//p, 'test', 1, 0)[2])
xpointer(string-range(//*, 'test', 1, 0)[2])
......@@ -4421,12 +4421,16 @@ xmlXPathEvalFilterExpr(xmlXPathParserContextPtr ctxt) {
CHECK_ERROR;
SKIP_BLANKS;
if (CUR != '[') return;
CHECK_TYPE(XPATH_NODESET);
while (CUR == '[') {
xmlXPathEvalPredicate(ctxt);
if ((ctxt->value == NULL) ||
((ctxt->value->type != XPATH_NODESET) &&
(ctxt->value->type != XPATH_LOCATIONSET)))
XP_ERROR(XPATH_INVALID_TYPE)
if (ctxt->value->type == XPATH_NODESET)
xmlXPathEvalPredicate(ctxt);
else
xmlXPtrEvalRangePredicate(ctxt);
SKIP_BLANKS;
}
......
......@@ -133,6 +133,8 @@ void xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth);
* Existing functions
*/
int xmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
xmlXPathObjectPtr res);
void xmlXPathInit(void);
void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt);
......
......@@ -275,6 +275,36 @@ xmlXPtrRangeCheckOrder(xmlXPathObjectPtr range) {
}
}
/**
* xmlXPtrRangesEqual:
* @range1: the first range
* @range2: the second range
*
* Compare two ranges
*
* Return 1 if equal, 0 otherwise
*/
int
xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
if (range1 == range2)
return(1);
if ((range1 == NULL) || (range2 == NULL))
return(0);
if (range1->type != range2->type)
return(0);
if (range1->type != XPATH_RANGE)
return(0);
if (range1->user != range2->user)
return(0);
if (range1->index != range2->index)
return(0);
if (range1->user2 != range2->user2)
return(0);
if (range1->index2 != range2->index2)
return(0);
return(1);
}
/**
* xmlXPtrNewRange:
* @start: the starting node
......@@ -594,6 +624,7 @@ xmlXPtrLocationSetCreate(xmlXPathObjectPtr val) {
* @val: a new xmlXPathObjectPtr
*
* add a new xmlXPathObjectPtr ot an existing LocationSet
* If the location already exist in the set @val is freed.
*/
void
xmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
......@@ -604,8 +635,12 @@ xmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
/*
* check against doublons
*/
for (i = 0;i < cur->locNr;i++)
if (cur->locTab[i] == val) return;
for (i = 0;i < cur->locNr;i++) {
if (xmlXPtrRangesEqual(cur->locTab[i], val)) {
xmlXPathFreeObject(val);
return;
}
}
/*
* grow the locTab if needed
......@@ -1656,6 +1691,10 @@ xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
}
newset = xmlXPtrLocationSetCreate(NULL);
if (newset == NULL) {
xmlXPathFreeObject(obj);
XP_ERROR(XPATH_MEMORY_ERROR);
}
oldset = (xmlLocationSetPtr) obj->user;
if (oldset != NULL) {
int i;
......@@ -1680,10 +1719,6 @@ xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
}
point = xmlXPtrNewPoint(node, tmp->index);
}
if (tmp->user2 == NULL) {
point = xmlXPtrNewPoint(node, 0);
} else
point = xmlXPtrNewPoint(node, tmp->index);
break;
}
default:
......@@ -1699,6 +1734,7 @@ xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
}
}
xmlXPathFreeObject(obj);
valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
}
/**
......@@ -1762,7 +1798,7 @@ xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
point = xmlXPtrNewPoint(tmp->user, tmp->index);
break;
case XPATH_RANGE: {
xmlNodePtr node = tmp->user;
xmlNodePtr node = tmp->user2;
if (node != NULL) {
if (node->type == XML_ATTRIBUTE_NODE) {
/* TODO: Namespace Nodes ??? */
......@@ -1770,13 +1806,11 @@ xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPtrFreeLocationSet(newset);
XP_ERROR(XPTR_SYNTAX_ERROR);
}
point = xmlXPtrNewPoint(node, tmp->index);
}
if (tmp->user2 == NULL) {
point = xmlXPtrNewPoint(node, tmp->index2);
} else if (tmp->user == NULL) {
point = xmlXPtrNewPoint(node,
xmlXPtrNbLocChildren(node));
} else
point = xmlXPtrNewPoint(node, tmp->index);
}
break;
}
default:
......@@ -1792,6 +1826,7 @@ xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
}
}
xmlXPathFreeObject(obj);
valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
}
......@@ -2515,6 +2550,8 @@ xmlXPtrGetLastChar(xmlNodePtr *node, int *index) {
len = xmlBufferLength(cur->content);
#endif
break;
} else {
return(-1);
}
}
if (cur == NULL)
......@@ -2756,6 +2793,115 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
if (number) xmlXPathFreeObject(number);
}
/**
* xmlXPtrEvalRangePredicate:
* @ctxt: the XPointer Parser context
*
* [8] Predicate ::= '[' PredicateExpr ']'
* [9] PredicateExpr ::= Expr
*
* Evaluate a predicate as in xmlXPathEvalPredicate() but for
* a Location Set instead of a node set
*/
void
xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) {
const xmlChar *cur;
xmlXPathObjectPtr res;
xmlXPathObjectPtr obj, tmp;
xmlLocationSetPtr newset = NULL;
xmlLocationSetPtr oldset;
int i;
SKIP_BLANKS;
if (CUR != '[') {
XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
}
NEXT;
SKIP_BLANKS;
/*
* Extract the old set, and then evaluate the result of the
* expression for all the element in the set. use it to grow
* up a new set.
*/
CHECK_TYPE(XPATH_LOCATIONSET);
obj = valuePop(ctxt);
oldset = obj->user;
ctxt->context->node = NULL;
if ((oldset == NULL) || (oldset->locNr == 0)) {
ctxt->context->contextSize = 0;
ctxt->context->proximityPosition = 0;
xmlXPathEvalExpr(ctxt);
res = valuePop(ctxt);
if (res != NULL)
xmlXPathFreeObject(res);
valuePush(ctxt, obj);
CHECK_ERROR;
} else {
/*
* Save the expression pointer since we will have to evaluate
* it multiple times. Initialize the new set.
*/
cur = ctxt->cur;
newset = xmlXPtrLocationSetCreate(NULL);
for (i = 0; i < oldset->locNr; i++) {
ctxt->cur = cur;
/*
* Run the evaluation with a node list made of a single item
* in the nodeset.
*/
ctxt->context->node = oldset->locTab[i]->user;
tmp = xmlXPathNewNodeSet(ctxt->context->node);
valuePush(ctxt, tmp);
ctxt->context->contextSize = oldset->locNr;
ctxt->context->proximityPosition = i + 1;
xmlXPathEvalExpr(ctxt);
CHECK_ERROR;
/*
* The result of the evaluation need to be tested to
* decided whether the filter succeeded or not
*/
res = valuePop(ctxt);
if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
xmlXPtrLocationSetAdd(newset,
xmlXPathObjectCopy(oldset->locTab[i]));
}
/*
* Cleanup
*/
if (res != NULL)
xmlXPathFreeObject(res);
if (ctxt->value == tmp) {
res = valuePop(ctxt);
xmlXPathFreeObject(res);
}
ctxt->context->node = NULL;
}