mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-30 22:43:14 +03:00
Patches bug fixes and on new function:
- xpath.c: fixed the comaprision of values and nodelists, need to compare nodelist still ... - debugXML.c: avoided a possible core dump - HTMLparser.c: cleanup - nanohttp.c: contributed fix. - tree.c: fixes in properties handling added xmlSetNsProp needed by libxslt - xpathInternals.h: exported xmlXPathBooleanFunction, added a comment - TODO: updated Daniel
This commit is contained in:
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
|||||||
|
Mon Jan 15 20:24:18 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
|
* xpath.c: fixed the comaprision of values and nodelists,
|
||||||
|
need to compare nodelist still ...
|
||||||
|
* debugXML.c: avoided a possible core dump
|
||||||
|
* HTMLparser.c: cleanup
|
||||||
|
* nanohttp.c: contributed fix.
|
||||||
|
* tree.c: fixes in properties handling added xmlSetNsProp
|
||||||
|
needed by libxslt
|
||||||
|
* xpathInternals.h: exported xmlXPathBooleanFunction, added a
|
||||||
|
comment
|
||||||
|
* TODO: updated
|
||||||
|
|
||||||
Sat Jan 6 22:05:09 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
Sat Jan 6 22:05:09 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
|
||||||
|
|
||||||
* parser.c parserInternals.c: applied Bjorn Reese optimization
|
* parser.c parserInternals.c: applied Bjorn Reese optimization
|
||||||
|
12
HTMLparser.c
12
HTMLparser.c
@ -926,7 +926,7 @@ htmlCheckParagraph(htmlParserCtxtPtr ctxt) {
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
if (!htmlOmittedDefaultValue)
|
if (!htmlOmittedDefaultValue)
|
||||||
return;
|
return(0);
|
||||||
for (i = 0; htmlNoContentElements[i] != NULL; i++) {
|
for (i = 0; htmlNoContentElements[i] != NULL; i++) {
|
||||||
if (xmlStrEqual(tag, BAD_CAST htmlNoContentElements[i])) {
|
if (xmlStrEqual(tag, BAD_CAST htmlNoContentElements[i])) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -4575,6 +4575,16 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
|
|||||||
#ifdef DEBUG_PUSH
|
#ifdef DEBUG_PUSH
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
"HPP: entering CONTENT\n");
|
"HPP: entering CONTENT\n");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case XML_PARSER_IGNORE:
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"HPP: internal error, state == XML_PARSER_IGNORE\n");
|
||||||
|
ctxt->instate = XML_PARSER_CONTENT;
|
||||||
|
ctxt->checkIndex = 0;
|
||||||
|
#ifdef DEBUG_PUSH
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"HPP: entering CONTENT\n");
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
5
TODO
5
TODO
@ -35,7 +35,12 @@ TODO:
|
|||||||
- htmlParseDoc has parameter encoding which is not used.
|
- htmlParseDoc has parameter encoding which is not used.
|
||||||
Function htmlCreateDocParserCtxt ignore it.
|
Function htmlCreateDocParserCtxt ignore it.
|
||||||
- bug reported by Michael Meallin on validation problems
|
- bug reported by Michael Meallin on validation problems
|
||||||
|
=> Actually means I need to add support (and warn) for non-deterministic
|
||||||
|
content model.
|
||||||
- fix realloc() usage.
|
- fix realloc() usage.
|
||||||
|
- compliance to XML-Namespace checking, see section 6 of
|
||||||
|
http://www.w3.org/TR/REC-xml-names/
|
||||||
|
- Fix output of <tst val="x
y"/>
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
=====
|
=====
|
||||||
|
@ -510,7 +510,7 @@ void xmlDebugDumpOneNode(FILE *output, xmlNodePtr node, int depth) {
|
|||||||
case XML_ELEMENT_NODE:
|
case XML_ELEMENT_NODE:
|
||||||
fprintf(output, shift);
|
fprintf(output, shift);
|
||||||
fprintf(output, "ELEMENT ");
|
fprintf(output, "ELEMENT ");
|
||||||
if (node->ns != NULL) {
|
if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
|
||||||
xmlDebugDumpString(output, node->ns->prefix);
|
xmlDebugDumpString(output, node->ns->prefix);
|
||||||
fprintf(output, ":");
|
fprintf(output, ":");
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,10 @@ typedef xmlIDTable *xmlIDTablePtr;
|
|||||||
typedef struct _xmlHashTable xmlRefTable;
|
typedef struct _xmlHashTable xmlRefTable;
|
||||||
typedef xmlRefTable *xmlRefTablePtr;
|
typedef xmlRefTable *xmlRefTablePtr;
|
||||||
|
|
||||||
|
/* helper */
|
||||||
|
xmlChar * xmlSplitQName2 (const xmlChar *name,
|
||||||
|
xmlChar **prefix);
|
||||||
|
|
||||||
/* Notation */
|
/* Notation */
|
||||||
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
|
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
|
||||||
xmlDtdPtr dtd,
|
xmlDtdPtr dtd,
|
||||||
|
@ -110,6 +110,7 @@ xmlXPathParserContextPtr
|
|||||||
xmlXPathContextPtr ctxt);
|
xmlXPathContextPtr ctxt);
|
||||||
void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
|
void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
|
||||||
|
|
||||||
|
/* TODO: remap to xmlXPathValuePop and Push */
|
||||||
xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
|
xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
|
||||||
int valuePush (xmlXPathParserContextPtr ctxt,
|
int valuePush (xmlXPathParserContextPtr ctxt,
|
||||||
xmlXPathObjectPtr value);
|
xmlXPathObjectPtr value);
|
||||||
@ -204,6 +205,7 @@ void xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
|||||||
void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
||||||
void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
||||||
void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
||||||
|
void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -377,6 +377,7 @@ xmlNanoHTTPNewCtxt(const char *URL) {
|
|||||||
memset(ret, 0, sizeof(xmlNanoHTTPCtxt));
|
memset(ret, 0, sizeof(xmlNanoHTTPCtxt));
|
||||||
ret->port = 80;
|
ret->port = 80;
|
||||||
ret->returnValue = 0;
|
ret->returnValue = 0;
|
||||||
|
ret->fd = -1;
|
||||||
|
|
||||||
xmlNanoHTTPScanURL(ret, URL);
|
xmlNanoHTTPScanURL(ret, URL);
|
||||||
|
|
||||||
|
83
tree.c
83
tree.c
@ -2425,6 +2425,8 @@ xmlCopyNamespaceList(xmlNsPtr cur) {
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static xmlNodePtr
|
||||||
|
xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
|
||||||
/**
|
/**
|
||||||
* xmlCopyProp:
|
* xmlCopyProp:
|
||||||
* @target: the element where the attribute will be grafted
|
* @target: the element where the attribute will be grafted
|
||||||
@ -2439,7 +2441,9 @@ xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
|
|||||||
xmlAttrPtr ret;
|
xmlAttrPtr ret;
|
||||||
|
|
||||||
if (cur == NULL) return(NULL);
|
if (cur == NULL) return(NULL);
|
||||||
if (cur->parent != NULL)
|
if (target != NULL)
|
||||||
|
ret = xmlNewDocProp(target->doc, cur->name, NULL);
|
||||||
|
else if (cur->parent != NULL)
|
||||||
ret = xmlNewDocProp(cur->parent->doc, cur->name, NULL);
|
ret = xmlNewDocProp(cur->parent->doc, cur->name, NULL);
|
||||||
else if (cur->children != NULL)
|
else if (cur->children != NULL)
|
||||||
ret = xmlNewDocProp(cur->children->doc, cur->name, NULL);
|
ret = xmlNewDocProp(cur->children->doc, cur->name, NULL);
|
||||||
@ -2459,11 +2463,11 @@ xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
|
|||||||
if (cur->children != NULL) {
|
if (cur->children != NULL) {
|
||||||
xmlNodePtr tmp;
|
xmlNodePtr tmp;
|
||||||
|
|
||||||
ret->children = xmlCopyNodeList(cur->children);
|
ret->children = xmlStaticCopyNodeList(cur->children, ret->doc, (xmlNodePtr) ret);
|
||||||
ret->last = NULL;
|
ret->last = NULL;
|
||||||
tmp = ret->children;
|
tmp = ret->children;
|
||||||
while (tmp != NULL) {
|
while (tmp != NULL) {
|
||||||
tmp->parent = (xmlNodePtr)ret;
|
/* tmp->parent = (xmlNodePtr)ret; */
|
||||||
if (tmp->next == NULL)
|
if (tmp->next == NULL)
|
||||||
ret->last = tmp;
|
ret->last = tmp;
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
@ -4022,10 +4026,14 @@ xmlGetProp(xmlNodePtr node, const xmlChar *name) {
|
|||||||
*/
|
*/
|
||||||
xmlChar *
|
xmlChar *
|
||||||
xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *namespace) {
|
xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *namespace) {
|
||||||
xmlAttrPtr prop = node->properties;
|
xmlAttrPtr prop;
|
||||||
xmlDocPtr doc;
|
xmlDocPtr doc;
|
||||||
xmlNsPtr ns;
|
xmlNsPtr ns;
|
||||||
|
|
||||||
|
if (node == NULL)
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
prop = node->properties;
|
||||||
if (namespace == NULL)
|
if (namespace == NULL)
|
||||||
return(xmlGetProp(node, name));
|
return(xmlGetProp(node, name));
|
||||||
while (prop != NULL) {
|
while (prop != NULL) {
|
||||||
@ -4118,6 +4126,73 @@ xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
|
|||||||
return(prop);
|
return(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlSetNsProp:
|
||||||
|
* @node: the node
|
||||||
|
* @ns: the namespace definition
|
||||||
|
* @name: the attribute name
|
||||||
|
* @value: the attribute value
|
||||||
|
*
|
||||||
|
* Set (or reset) an attribute carried by a node.
|
||||||
|
* The ns structure must be in scope, this is not checked.
|
||||||
|
*
|
||||||
|
* Returns the attribute pointer.
|
||||||
|
*/
|
||||||
|
xmlAttrPtr
|
||||||
|
xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
|
||||||
|
const xmlChar *value) {
|
||||||
|
xmlAttrPtr prop;
|
||||||
|
|
||||||
|
if ((node == NULL) || (name == NULL))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
if (ns == NULL)
|
||||||
|
return(xmlSetProp(node, name, value));
|
||||||
|
if (ns->href == NULL)
|
||||||
|
return(NULL);
|
||||||
|
prop = node->properties;
|
||||||
|
|
||||||
|
while (prop != NULL) {
|
||||||
|
/*
|
||||||
|
* One need to have
|
||||||
|
* - same attribute names
|
||||||
|
* - and the attribute carrying that namespace
|
||||||
|
* or
|
||||||
|
* no namespace on the attribute and the element carrying it
|
||||||
|
*/
|
||||||
|
if ((xmlStrEqual(prop->name, name)) &&
|
||||||
|
(((prop->ns == NULL) && (node->ns != NULL) &&
|
||||||
|
(xmlStrEqual(node->ns->href, ns->href))) ||
|
||||||
|
((prop->ns != NULL) && (xmlStrEqual(prop->ns->href, ns->href))))) {
|
||||||
|
if (prop->children != NULL)
|
||||||
|
xmlFreeNodeList(prop->children);
|
||||||
|
prop->children = NULL;
|
||||||
|
prop->last = NULL;
|
||||||
|
prop->ns = ns;
|
||||||
|
if (value != NULL) {
|
||||||
|
xmlChar *buffer;
|
||||||
|
xmlNodePtr tmp;
|
||||||
|
|
||||||
|
buffer = xmlEncodeEntitiesReentrant(node->doc, value);
|
||||||
|
prop->children = xmlStringGetNodeList(node->doc, buffer);
|
||||||
|
prop->last = NULL;
|
||||||
|
tmp = prop->children;
|
||||||
|
while (tmp != NULL) {
|
||||||
|
tmp->parent = (xmlNodePtr) prop;
|
||||||
|
if (tmp->next == NULL)
|
||||||
|
prop->last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
xmlFree(buffer);
|
||||||
|
}
|
||||||
|
return(prop);
|
||||||
|
}
|
||||||
|
prop = prop->next;
|
||||||
|
}
|
||||||
|
prop = xmlNewNsProp(node, ns, name, value);
|
||||||
|
return(prop);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlNodeIsText:
|
* xmlNodeIsText:
|
||||||
* @node: the node
|
* @node: the node
|
||||||
|
4
valid.h
4
valid.h
@ -81,6 +81,10 @@ typedef xmlIDTable *xmlIDTablePtr;
|
|||||||
typedef struct _xmlHashTable xmlRefTable;
|
typedef struct _xmlHashTable xmlRefTable;
|
||||||
typedef xmlRefTable *xmlRefTablePtr;
|
typedef xmlRefTable *xmlRefTablePtr;
|
||||||
|
|
||||||
|
/* helper */
|
||||||
|
xmlChar * xmlSplitQName2 (const xmlChar *name,
|
||||||
|
xmlChar **prefix);
|
||||||
|
|
||||||
/* Notation */
|
/* Notation */
|
||||||
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
|
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
|
||||||
xmlDtdPtr dtd,
|
xmlDtdPtr dtd,
|
||||||
|
202
xpath.c
202
xpath.c
@ -1485,6 +1485,178 @@ void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
|||||||
arg = valuePop(ctxt); \
|
arg = valuePop(ctxt); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathCompareNodeSetFloat:
|
||||||
|
* @ctxt: the XPath Parser context
|
||||||
|
* @inf: less than (1) or greater than (0)
|
||||||
|
* @strict: is the comparison strict
|
||||||
|
* @arg: the node set
|
||||||
|
* @f: the value
|
||||||
|
*
|
||||||
|
* Implement the compare operation between a nodeset and a number
|
||||||
|
* @ns < @val (1, 1, ...
|
||||||
|
* @ns <= @val (1, 0, ...
|
||||||
|
* @ns > @val (0, 1, ...
|
||||||
|
* @ns >= @val (0, 0, ...
|
||||||
|
*
|
||||||
|
* If one object to be compared is a node-set and the other is a number,
|
||||||
|
* then the comparison will be true if and only if there is a node in the
|
||||||
|
* node-set such that the result of performing the comparison on the number
|
||||||
|
* to be compared and on the result of converting the string-value of that
|
||||||
|
* node to a number using the number function is true.
|
||||||
|
*
|
||||||
|
* Returns 0 or 1 depending on the results of the test.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict,
|
||||||
|
xmlXPathObjectPtr arg, xmlXPathObjectPtr f) {
|
||||||
|
int i, ret = 0;
|
||||||
|
xmlNodeSetPtr ns;
|
||||||
|
xmlChar *str2;
|
||||||
|
|
||||||
|
if ((f == NULL) || (arg == NULL) || (arg->type != XPATH_NODESET)) {
|
||||||
|
xmlXPathFreeObject(arg);
|
||||||
|
xmlXPathFreeObject(f);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
ns = arg->nodesetval;
|
||||||
|
for (i = 0;i < ns->nodeNr;i++) {
|
||||||
|
str2 = xmlNodeGetContent(ns->nodeTab[i]);
|
||||||
|
if (str2 != NULL) {
|
||||||
|
valuePush(ctxt,
|
||||||
|
xmlXPathNewString(str2));
|
||||||
|
xmlFree(str2);
|
||||||
|
xmlXPathNumberFunction(ctxt, 1);
|
||||||
|
valuePush(ctxt, xmlXPathObjectCopy(f));
|
||||||
|
ret = xmlXPathCompareValues(ctxt, inf, strict);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xmlXPathFreeObject(arg);
|
||||||
|
xmlXPathFreeObject(f);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathCompareNodeSetString:
|
||||||
|
* @ctxt: the XPath Parser context
|
||||||
|
* @inf: less than (1) or greater than (0)
|
||||||
|
* @strict: is the comparison strict
|
||||||
|
* @arg: the node set
|
||||||
|
* @s: the value
|
||||||
|
*
|
||||||
|
* Implement the compare operation between a nodeset and a string
|
||||||
|
* @ns < @val (1, 1, ...
|
||||||
|
* @ns <= @val (1, 0, ...
|
||||||
|
* @ns > @val (0, 1, ...
|
||||||
|
* @ns >= @val (0, 0, ...
|
||||||
|
*
|
||||||
|
* If one object to be compared is a node-set and the other is a string,
|
||||||
|
* then the comparison will be true if and only if there is a node in
|
||||||
|
* the node-set such that the result of performing the comparison on the
|
||||||
|
* string-value of the node and the other string is true.
|
||||||
|
*
|
||||||
|
* Returns 0 or 1 depending on the results of the test.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict,
|
||||||
|
xmlXPathObjectPtr arg, xmlXPathObjectPtr s) {
|
||||||
|
int i, ret = 0;
|
||||||
|
xmlNodeSetPtr ns;
|
||||||
|
xmlChar *str2;
|
||||||
|
|
||||||
|
if ((s == NULL) || (arg == NULL) || (arg->type != XPATH_NODESET)) {
|
||||||
|
xmlXPathFreeObject(arg);
|
||||||
|
xmlXPathFreeObject(s);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
ns = arg->nodesetval;
|
||||||
|
for (i = 0;i < ns->nodeNr;i++) {
|
||||||
|
str2 = xmlNodeGetContent(ns->nodeTab[i]);
|
||||||
|
if (str2 != NULL) {
|
||||||
|
valuePush(ctxt,
|
||||||
|
xmlXPathNewString(str2));
|
||||||
|
xmlFree(str2);
|
||||||
|
valuePush(ctxt, xmlXPathObjectCopy(s));
|
||||||
|
ret = xmlXPathCompareValues(ctxt, inf, strict);
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xmlXPathFreeObject(arg);
|
||||||
|
xmlXPathFreeObject(s);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathCompareNodeSets:
|
||||||
|
* @ctxt: the XPath Parser context
|
||||||
|
* @op: less than (-1), equal (0) or greater than (1)
|
||||||
|
* @strict: is the comparison strict
|
||||||
|
* @ns1: the fist node set
|
||||||
|
* @ns2: the second node set
|
||||||
|
*
|
||||||
|
* Implement the compare operation on nodesets:
|
||||||
|
*
|
||||||
|
* If both objects to be compared are node-sets, then the comparison will be true if
|
||||||
|
* and only if there is a node in the first node-set and a node in the second node-set
|
||||||
|
* such that the result of performing the comparison on the string-values of the two
|
||||||
|
* nodes is true.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlXPathCompareNodeSets(xmlXPathParserContextPtr ctxt, int inf, int strict,
|
||||||
|
xmlXPathObjectPtr ns1, xmlXPathObjectPtr ns2) {
|
||||||
|
TODO
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXPathCompareNodeSetValue:
|
||||||
|
* @ctxt: the XPath Parser context
|
||||||
|
* @inf: less than (1) or greater than (0)
|
||||||
|
* @strict: is the comparison strict
|
||||||
|
* @arg: the node set
|
||||||
|
* @val: the value
|
||||||
|
*
|
||||||
|
* Implement the compare operation between a nodeset and a value
|
||||||
|
* @ns < @val (1, 1, ...
|
||||||
|
* @ns <= @val (1, 0, ...
|
||||||
|
* @ns > @val (0, 1, ...
|
||||||
|
* @ns >= @val (0, 0, ...
|
||||||
|
*
|
||||||
|
* If one object to be compared is a node-set and the other is a boolean, then the
|
||||||
|
* comparison will be true if and only if the result of performing the comparison
|
||||||
|
* on the boolean and on the result of converting the node-set to a boolean using
|
||||||
|
* the boolean function is true.
|
||||||
|
*
|
||||||
|
* Returns 0 or 1 depending on the results of the test.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict,
|
||||||
|
xmlXPathObjectPtr arg, xmlXPathObjectPtr val) {
|
||||||
|
if ((val == NULL) || (arg == NULL) || (arg->type != XPATH_NODESET))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
switch(val->type) {
|
||||||
|
case XPATH_NUMBER:
|
||||||
|
return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val));
|
||||||
|
case XPATH_NODESET:
|
||||||
|
return(xmlXPathCompareNodeSets(ctxt, inf, strict, arg, val));
|
||||||
|
case XPATH_STRING:
|
||||||
|
return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val));
|
||||||
|
case XPATH_BOOLEAN:
|
||||||
|
valuePush(ctxt, arg);
|
||||||
|
xmlXPathBooleanFunction(ctxt, 1);
|
||||||
|
valuePush(ctxt, val);
|
||||||
|
return(xmlXPathCompareValues(ctxt, inf, strict));
|
||||||
|
default:
|
||||||
|
TODO
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathEqualNodeSetString
|
* xmlXPathEqualNodeSetString
|
||||||
* @arg: the nodeset object argument
|
* @arg: the nodeset object argument
|
||||||
@ -1781,10 +1953,11 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlXPathCompareValues:
|
* xmlXPathCompareValues:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
* @inf: less than (1) or greater than (2)
|
* @inf: less than (1) or greater than (0)
|
||||||
* @strict: is the comparison strict
|
* @strict: is the comparison strict
|
||||||
*
|
*
|
||||||
* Implement the compare operation on XPath objects:
|
* Implement the compare operation on XPath objects:
|
||||||
@ -1802,6 +1975,8 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
|||||||
* will be true if and only if the first number is greater than the second
|
* will be true if and only if the first number is greater than the second
|
||||||
* number. The >= comparison will be true if and only if the first number
|
* number. The >= comparison will be true if and only if the first number
|
||||||
* is greater than or equal to the second number.
|
* is greater than or equal to the second number.
|
||||||
|
*
|
||||||
|
* Returns 1 if the comparaison succeeded, 0 if it failed
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
|
xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
|
||||||
@ -1809,20 +1984,29 @@ xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
|
|||||||
xmlXPathObjectPtr arg1, arg2;
|
xmlXPathObjectPtr arg1, arg2;
|
||||||
|
|
||||||
arg2 = valuePop(ctxt);
|
arg2 = valuePop(ctxt);
|
||||||
if ((arg2 == NULL) || (arg2->type == XPATH_NODESET)) {
|
if (arg2 == NULL) {
|
||||||
if (arg2 != NULL)
|
|
||||||
xmlXPathFreeObject(arg2);
|
|
||||||
XP_ERROR0(XPATH_INVALID_OPERAND);
|
XP_ERROR0(XPATH_INVALID_OPERAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
arg1 = valuePop(ctxt);
|
arg1 = valuePop(ctxt);
|
||||||
if ((arg1 == NULL) || (arg1->type == XPATH_NODESET)) {
|
if (arg1 == NULL) {
|
||||||
if (arg1 != NULL)
|
|
||||||
xmlXPathFreeObject(arg1);
|
|
||||||
xmlXPathFreeObject(arg2);
|
xmlXPathFreeObject(arg2);
|
||||||
XP_ERROR0(XPATH_INVALID_OPERAND);
|
XP_ERROR0(XPATH_INVALID_OPERAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((arg2->type == XPATH_NODESET) || (arg1->type == XPATH_NODESET)) {
|
||||||
|
if ((arg2->type == XPATH_NODESET) && (arg1->type == XPATH_NODESET)) {
|
||||||
|
ret = xmlXPathCompareNodeSets(ctxt, inf, strict, arg1, arg2);
|
||||||
|
} else {
|
||||||
|
if (arg1->type == XPATH_NODESET) {
|
||||||
|
ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict, arg1, arg2);
|
||||||
|
} else {
|
||||||
|
ret = xmlXPathCompareNodeSetValue(ctxt, !inf, !strict, arg2, arg2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
if (arg1->type != XPATH_NUMBER) {
|
if (arg1->type != XPATH_NUMBER) {
|
||||||
valuePush(ctxt, arg1);
|
valuePush(ctxt, arg1);
|
||||||
xmlXPathNumberFunction(ctxt, 1);
|
xmlXPathNumberFunction(ctxt, 1);
|
||||||
@ -4674,6 +4858,10 @@ xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
#endif
|
#endif
|
||||||
lc = 1;
|
lc = 1;
|
||||||
break;
|
break;
|
||||||
|
} else if ((NXT(len) == '<') || (NXT(len) == '>') ||
|
||||||
|
(NXT(len) == '=')) {
|
||||||
|
lc = 1;
|
||||||
|
break;
|
||||||
} else {
|
} else {
|
||||||
XP_ERROR(XPATH_EXPR_ERROR);
|
XP_ERROR(XPATH_EXPR_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -110,6 +110,7 @@ xmlXPathParserContextPtr
|
|||||||
xmlXPathContextPtr ctxt);
|
xmlXPathContextPtr ctxt);
|
||||||
void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
|
void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
|
||||||
|
|
||||||
|
/* TODO: remap to xmlXPathValuePop and Push */
|
||||||
xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
|
xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
|
||||||
int valuePush (xmlXPathParserContextPtr ctxt,
|
int valuePush (xmlXPathParserContextPtr ctxt,
|
||||||
xmlXPathObjectPtr value);
|
xmlXPathObjectPtr value);
|
||||||
@ -204,6 +205,7 @@ void xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
|||||||
void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
||||||
void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
||||||
void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
||||||
|
void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user