Commit 389e6b72 authored by Daniel Veillard's avatar Daniel Veillard
Browse files

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
parent dbce3d44
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>
* parser.c parserInternals.c: applied Bjorn Reese optimization
......
......@@ -926,7 +926,7 @@ htmlCheckParagraph(htmlParserCtxtPtr ctxt) {
return(1);
}
if (!htmlOmittedDefaultValue)
return;
return(0);
for (i = 0; htmlNoContentElements[i] != NULL; i++) {
if (xmlStrEqual(tag, BAD_CAST htmlNoContentElements[i])) {
#ifdef DEBUG
......@@ -4575,6 +4575,16 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
"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
break;
}
......
......@@ -35,7 +35,12 @@ TODO:
- htmlParseDoc has parameter encoding which is not used.
Function htmlCreateDocParserCtxt ignore it.
- 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.
- compliance to XML-Namespace checking, see section 6 of
http://www.w3.org/TR/REC-xml-names/
- Fix output of <tst val="x&#xA;y"/>
TODO:
=====
......
......@@ -510,7 +510,7 @@ void xmlDebugDumpOneNode(FILE *output, xmlNodePtr node, int depth) {
case XML_ELEMENT_NODE:
fprintf(output, shift);
fprintf(output, "ELEMENT ");
if (node->ns != NULL) {
if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
xmlDebugDumpString(output, node->ns->prefix);
fprintf(output, ":");
}
......
......@@ -81,6 +81,10 @@ typedef xmlIDTable *xmlIDTablePtr;
typedef struct _xmlHashTable xmlRefTable;
typedef xmlRefTable *xmlRefTablePtr;
/* helper */
xmlChar * xmlSplitQName2 (const xmlChar *name,
xmlChar **prefix);
/* Notation */
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
xmlDtdPtr dtd,
......
......@@ -110,6 +110,7 @@ xmlXPathParserContextPtr
xmlXPathContextPtr ctxt);
void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
/* TODO: remap to xmlXPathValuePop and Push */
xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
int valuePush (xmlXPathParserContextPtr ctxt,
xmlXPathObjectPtr value);
......@@ -204,6 +205,7 @@ void xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
#ifdef __cplusplus
}
#endif
......
......@@ -377,6 +377,7 @@ xmlNanoHTTPNewCtxt(const char *URL) {
memset(ret, 0, sizeof(xmlNanoHTTPCtxt));
ret->port = 80;
ret->returnValue = 0;
ret->fd = -1;
xmlNanoHTTPScanURL(ret, URL);
......
......@@ -2425,6 +2425,8 @@ xmlCopyNamespaceList(xmlNsPtr cur) {
return(ret);
}
static xmlNodePtr
xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent);
/**
* xmlCopyProp:
* @target: the element where the attribute will be grafted
......@@ -2439,7 +2441,9 @@ xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
xmlAttrPtr ret;
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);
else if (cur->children != NULL)
ret = xmlNewDocProp(cur->children->doc, cur->name, NULL);
......@@ -2459,11 +2463,11 @@ xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
if (cur->children != NULL) {
xmlNodePtr tmp;
ret->children = xmlCopyNodeList(cur->children);
ret->children = xmlStaticCopyNodeList(cur->children, ret->doc, (xmlNodePtr) ret);
ret->last = NULL;
tmp = ret->children;
while (tmp != NULL) {
tmp->parent = (xmlNodePtr)ret;
/* tmp->parent = (xmlNodePtr)ret; */
if (tmp->next == NULL)
ret->last = tmp;
tmp = tmp->next;
......@@ -4022,10 +4026,14 @@ xmlGetProp(xmlNodePtr node, const xmlChar *name) {
*/
xmlChar *
xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *namespace) {
xmlAttrPtr prop = node->properties;
xmlAttrPtr prop;
xmlDocPtr doc;
xmlNsPtr ns;
if (node == NULL)
return(NULL);
prop = node->properties;
if (namespace == NULL)
return(xmlGetProp(node, name));
while (prop != NULL) {
......@@ -4118,6 +4126,73 @@ xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
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:
* @node: the node
......
......@@ -81,6 +81,10 @@ typedef xmlIDTable *xmlIDTablePtr;
typedef struct _xmlHashTable xmlRefTable;
typedef xmlRefTable *xmlRefTablePtr;
/* helper */
xmlChar * xmlSplitQName2 (const xmlChar *name,
xmlChar **prefix);
/* Notation */
xmlNotationPtr xmlAddNotationDecl (xmlValidCtxtPtr ctxt,
xmlDtdPtr dtd,
......
......@@ -1485,6 +1485,178 @@ void xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs);
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
* @arg: the nodeset object argument
......@@ -1781,10 +1953,11 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
return(ret);
}
/**
* xmlXPathCompareValues:
* @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
*
* 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
* number. The >= comparison will be true if and only if the first number
* is greater than or equal to the second number.
*
* Returns 1 if the comparaison succeeded, 0 if it failed
*/
int
xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
......@@ -1809,20 +1984,29 @@ xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
xmlXPathObjectPtr arg1, arg2;
arg2 = valuePop(ctxt);
if ((arg2 == NULL) || (arg2->type == XPATH_NODESET)) {
if (arg2 != NULL)
xmlXPathFreeObject(arg2);
if (arg2 == NULL) {
XP_ERROR0(XPATH_INVALID_OPERAND);
}
arg1 = valuePop(ctxt);
if ((arg1 == NULL) || (arg1->type == XPATH_NODESET)) {
if (arg1 != NULL)
xmlXPathFreeObject(arg1);
if (arg1 == NULL) {
xmlXPathFreeObject(arg2);
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) {
valuePush(ctxt, arg1);
xmlXPathNumberFunction(ctxt, 1);
......@@ -4674,6 +4858,10 @@ xmlXPathEvalPathExpr(xmlXPathParserContextPtr ctxt) {
#endif
lc = 1;
break;
} else if ((NXT(len) == '<') || (NXT(len) == '>') ||
(NXT(len) == '=')) {
lc = 1;
break;
} else {
XP_ERROR(XPATH_EXPR_ERROR);
}
......
......@@ -110,6 +110,7 @@ xmlXPathParserContextPtr
xmlXPathContextPtr ctxt);
void xmlXPathFreeParserContext (xmlXPathParserContextPtr ctxt);
/* TODO: remap to xmlXPathValuePop and Push */
xmlXPathObjectPtr valuePop (xmlXPathParserContextPtr ctxt);
int valuePush (xmlXPathParserContextPtr ctxt,
xmlXPathObjectPtr value);
......@@ -204,6 +205,7 @@ void xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs);
#ifdef __cplusplus
}
#endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment