1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-29 11:41:22 +03:00

- xpath.c textXPath.c xpathInternals.h: applied TOM <ptittom@free.fr>

cleanup patch for XPath
Daniel
This commit is contained in:
Daniel Veillard
2000-10-26 14:07:44 +00:00
parent d6d7f7bf96
commit f6bf921daa
5 changed files with 136 additions and 46 deletions

View File

@ -1,3 +1,8 @@
Thu Oct 26 16:05:25 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
* xpath.c textXPath.c xpathInternals.h: applied TOM <ptittom@free.fr>
cleanup patch for XPath
Wed Oct 25 21:31:10 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org> Wed Oct 25 21:31:10 CEST 2000 Daniel Veillard <Daniel.Veillard@w3.org>
* patched to redirrect all "out of context" error messages to * patched to redirrect all "out of context" error messages to

View File

@ -148,8 +148,8 @@ void xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathLocalPartFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathNamespaceFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs);

View File

@ -183,6 +183,9 @@ int main(int argc, char **argv) {
printf("\tParse the XPath strings and output the result of the parsing\n"); printf("\tParse the XPath strings and output the result of the parsing\n");
printf("\t--debug : dump a debug version of the result\n"); printf("\t--debug : dump a debug version of the result\n");
printf("\t--valid : switch on DTD support in the parser\n"); printf("\t--valid : switch on DTD support in the parser\n");
#if defined(LIBXML_XPTR_ENABLED)
printf("\t--xptr : expressions are XPointer expressions\n");
#endif
printf("\t--expr : debug XPath expressions only\n"); printf("\t--expr : debug XPath expressions only\n");
printf("\t--input filename : or\n"); printf("\t--input filename : or\n");
printf("\t-i filename : read the document from filename\n"); printf("\t-i filename : read the document from filename\n");

164
xpath.c
View File

@ -72,7 +72,7 @@ double xmlXPathStringEvalNumber(const xmlChar *str);
*/ */
double xmlXPathNAN = 0; double xmlXPathNAN = 0;
double xmlXPathPINF = 1; double xmlXPathPINF = 1;
double xmlXPathMINF = -1; double xmlXPathNINF = -1;
#ifndef isinf #ifndef isinf
#ifndef HAVE_ISINF #ifndef HAVE_ISINF
@ -162,8 +162,8 @@ xmlXPathInit(void) {
xmlXPathPINF = 1; xmlXPathPINF = 1;
xmlXPathPINF /= 0; xmlXPathPINF /= 0;
xmlXPathMINF = -1; xmlXPathNINF = -1;
xmlXPathMINF /= 0; xmlXPathNINF /= 0;
initialized = 1; initialized = 1;
} }
@ -2721,7 +2721,25 @@ xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
obj = valuePop(ctxt); obj = valuePop(ctxt);
if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND); if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
if (obj->type == XPATH_NODESET) { if (obj->type == XPATH_NODESET) {
TODO /* ID function in case of NodeSet */ xmlXPathObjectPtr newobj;
int i;
ret = xmlXPathNewNodeSet(NULL);
for (i = 0; i < obj->nodesetval->nodeNr; i++) {
valuePush(ctxt,
xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i]));
xmlXPathStringFunction(ctxt, 1);
xmlXPathIdFunction(ctxt, 1);
newobj = valuePop(ctxt);
ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval,
newobj->nodesetval);
xmlXPathFreeObject(newobj);
}
xmlXPathFreeObject(obj);
valuePush(ctxt, ret);
return;
} }
if (obj->type != XPATH_STRING) { if (obj->type != XPATH_STRING) {
valuePush(ctxt, obj); valuePush(ctxt, obj);
@ -2771,20 +2789,25 @@ xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
} }
/** /**
* xmlXPathLocalPartFunction: * xmlXPathLocalNameFunction:
* @ctxt: the XPath Parser context * @ctxt: the XPath Parser context
* *
* Implement the local-part() XPath function * Implement the local-name() XPath function
* The local-part function returns a string containing the local part * The local-name function returns a string containing the local part
* of the name of the node in the argument node-set that is first in * of the name of the node in the argument node-set that is first in
* document order. If the node-set is empty or the first node has no * document order. If the node-set is empty or the first node has no
* name, an empty string is returned. If the argument is omitted it * name, an empty string is returned. If the argument is omitted it
* defaults to the context node. * defaults to the context node.
*/ */
void void
xmlXPathLocalPartFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr cur; xmlXPathObjectPtr cur;
if (nargs == 0) {
valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
nargs = 1;
}
CHECK_ARITY(1); CHECK_ARITY(1);
CHECK_TYPE(XPATH_NODESET); CHECK_TYPE(XPATH_NODESET);
cur = valuePop(ctxt); cur = valuePop(ctxt);
@ -2799,18 +2822,19 @@ xmlXPathLocalPartFunction(xmlXPathParserContextPtr ctxt, int nargs) {
} }
/** /**
* xmlXPathNamespaceFunction: * xmlXPathNamespaceURIFunction:
* @ctxt: the XPath Parser context * @ctxt: the XPath Parser context
* *
* Implement the namespace() XPath function * Implement the namespace-uri() XPath function
* The namespace function returns a string containing the namespace URI * The namespace-uri function returns a string containing the
* of the expanded name of the node in the argument node-set that is * namespace URI of the expanded name of the node in the argument
* first in document order. If the node-set is empty, the first node has * node-set that is first in document order. If the node-set is empty,
* no name, or the expanded name has no namespace URI, an empty string * the first node has no name, or the expanded name has no namespace
* is returned. If the argument is omitted it defaults to the context node. * URI, an empty string is returned. If the argument is omitted it
* defaults to the context node.
*/ */
void void
xmlXPathNamespaceFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr cur; xmlXPathObjectPtr cur;
if (nargs == 0) { if (nargs == 0) {
@ -2859,6 +2883,11 @@ void
xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr cur; xmlXPathObjectPtr cur;
if (nargs == 0) {
valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
nargs = 1;
}
CHECK_ARITY(1); CHECK_ARITY(1);
CHECK_TYPE(XPATH_NODESET); CHECK_TYPE(XPATH_NODESET);
cur = valuePop(ctxt); cur = valuePop(ctxt);
@ -2920,11 +2949,19 @@ xmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
* number from all other IEEE 754 numeric values. * number from all other IEEE 754 numeric values.
* - The boolean false value is converted to the string false. * - The boolean false value is converted to the string false.
* The boolean true value is converted to the string true. * The boolean true value is converted to the string true.
*
* If the argument is omitted, it defaults to a node-set with the
* context node as its only member.
*/ */
void void
xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr cur; xmlXPathObjectPtr cur;
if (nargs == 0) {
valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
nargs = 1;
}
CHECK_ARITY(1); CHECK_ARITY(1);
cur = valuePop(ctxt); cur = valuePop(ctxt);
if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND); if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
@ -3302,17 +3339,18 @@ xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlBufferPtr target; xmlBufferPtr target;
xmlChar blank; xmlChar blank;
if (nargs < 1) { if (nargs == 0) {
/* Use current context node */ /* Use current context node */
CHECK_ARITY(0); valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
TODO /* source = xmlNodeGetContent(ctxt->context->node); */ xmlXPathStringFunction(ctxt, 1);
} else if (nargs >= 1) { nargs = 1;
/* Use argument */
CHECK_ARITY(1);
obj = valuePop(ctxt);
if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
source = obj->stringval;
} }
CHECK_ARITY(1);
CHECK_TYPE(XPATH_STRING);
obj = valuePop(ctxt);
source = obj->stringval;
target = xmlBufferCreate(); target = xmlBufferCreate();
if (target && source) { if (target && source) {
@ -3338,7 +3376,6 @@ xmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
xmlBufferFree(target); xmlBufferFree(target);
} }
if (obj)
xmlXPathFreeObject(obj); xmlXPathFreeObject(obj);
} }
@ -3530,12 +3567,28 @@ not_equal:
* @ctxt: the XPath Parser context * @ctxt: the XPath Parser context
* *
* Implement the number() XPath function * Implement the number() XPath function
*
* BUG: since we directly call xmlXPathStringEvalNumber(),
* number("-1") isn't evaluated in -1.0 but in NaN.
*/ */
void void
xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr cur; xmlXPathObjectPtr cur;
double res; double res;
if (nargs == 0) {
if (ctxt->context->node == NULL) {
valuePush(ctxt, xmlXPathNewFloat(0.0));
} else {
xmlChar* content = xmlNodeGetContent(ctxt->context->node);
res = xmlXPathStringEvalNumber(content);
valuePush(ctxt, xmlXPathNewFloat(res));
xmlFree(content);
}
return;
}
CHECK_ARITY(1); CHECK_ARITY(1);
cur = valuePop(ctxt); cur = valuePop(ctxt);
switch (cur->type) { switch (cur->type) {
@ -3583,8 +3636,25 @@ xmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
*/ */
void void
xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr cur;
int i;
CHECK_ARITY(1); CHECK_ARITY(1);
TODO /* BUG Sum : don't understand the definition */ CHECK_TYPE(XPATH_NODESET);
cur = valuePop(ctxt);
if (cur->nodesetval->nodeNr == 0) {
valuePush(ctxt, xmlXPathNewFloat(0.0));
} else {
valuePush(ctxt,
xmlXPathNewNodeSet(cur->nodesetval->nodeTab[0]));
for (i = 1; i < cur->nodesetval->nodeNr; i++) {
valuePush(ctxt,
xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i]));
xmlXPathAddValues(ctxt);
}
}
xmlXPathFreeObject(cur);
} }
/** /**
@ -3599,8 +3669,12 @@ void
xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
CHECK_ARITY(1); CHECK_ARITY(1);
CHECK_TYPE(XPATH_NUMBER); CHECK_TYPE(XPATH_NUMBER);
#if 0
ctxt->value->floatval = floor(ctxt->value->floatval);
#else
/* floor(0.999999999999) => 1.0 !!!!!!!!!!! */ /* floor(0.999999999999) => 1.0 !!!!!!!!!!! */
ctxt->value->floatval = (double)((int) ctxt->value->floatval); ctxt->value->floatval = (double)((int) ctxt->value->floatval);
#endif
} }
/** /**
@ -3617,9 +3691,14 @@ xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) {
CHECK_ARITY(1); CHECK_ARITY(1);
CHECK_TYPE(XPATH_NUMBER); CHECK_TYPE(XPATH_NUMBER);
#if 0
ctxt->value->floatval = ceil(ctxt->value->floatval);
#else
f = (double)((int) ctxt->value->floatval); f = (double)((int) ctxt->value->floatval);
if (f != ctxt->value->floatval) if (f != ctxt->value->floatval)
ctxt->value->floatval = f + 1; ctxt->value->floatval = f + 1;
#endif
} }
/** /**
@ -3637,12 +3716,20 @@ xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
CHECK_ARITY(1); CHECK_ARITY(1);
CHECK_TYPE(XPATH_NUMBER); CHECK_TYPE(XPATH_NUMBER);
/* round(0.50000001) => 0 !!!!! */
if ((ctxt->value->floatval == xmlXPathNAN) ||
(ctxt->value->floatval == xmlXPathPINF) ||
(ctxt->value->floatval == xmlXPathNINF) ||
(ctxt->value->floatval == 0.0))
return;
#if 0
f = floor(ctxt->value->floatval);
#else
f = (double)((int) ctxt->value->floatval); f = (double)((int) ctxt->value->floatval);
#endif
if (ctxt->value->floatval < f + 0.5) if (ctxt->value->floatval < f + 0.5)
ctxt->value->floatval = f; ctxt->value->floatval = f;
else if (ctxt->value->floatval == f + 0.5)
ctxt->value->floatval = f; /* !!!! Not following the spec here */
else else
ctxt->value->floatval = f + 1; ctxt->value->floatval = f + 1;
} }
@ -3766,15 +3853,12 @@ xmlXPathParseName(xmlXPathParserContextPtr ctxt) {
* xmlXPathStringEvalNumber: * xmlXPathStringEvalNumber:
* @str: A string to scan * @str: A string to scan
* *
* [30] Number ::= Digits ('.' Digits)? * [30] Number ::= Digits ('.' Digits?)?
* | '.' Digits * | '.' Digits
* [31] Digits ::= [0-9]+ * [31] Digits ::= [0-9]+
* *
* Parse and evaluate a Number in the string * Parse and evaluate a Number in the string
* *
* BUG: "1.' is not valid ... James promised correction
* as Digits ('.' Digits?)?
*
* Returns the double value. * Returns the double value.
*/ */
double double
@ -3813,14 +3897,12 @@ xmlXPathStringEvalNumber(const xmlChar *str) {
* xmlXPathEvalNumber: * xmlXPathEvalNumber:
* @ctxt: the XPath Parser context * @ctxt: the XPath Parser context
* *
* [30] Number ::= Digits ('.' Digits)? * [30] Number ::= Digits ('.' Digits?)?
* | '.' Digits * | '.' Digits
* [31] Digits ::= [0-9]+ * [31] Digits ::= [0-9]+
* *
* Parse and evaluate a Number, then push it on the stack * Parse and evaluate a Number, then push it on the stack
* *
* BUG: "1.' is not valid ... James promised correction
* as Digits ('.' Digits?)?
*/ */
void void
xmlXPathEvalNumber(xmlXPathParserContextPtr ctxt) { xmlXPathEvalNumber(xmlXPathParserContextPtr ctxt) {
@ -5302,14 +5384,14 @@ xmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt)
xmlXPathLastFunction); xmlXPathLastFunction);
xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang", xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",
xmlXPathLangFunction); xmlXPathLangFunction);
xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-part", xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name",
xmlXPathLocalPartFunction); xmlXPathLocalNameFunction);
xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not", xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",
xmlXPathNotFunction); xmlXPathNotFunction);
xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name", xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",
xmlXPathNameFunction); xmlXPathNameFunction);
xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace", xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri",
xmlXPathNamespaceFunction); xmlXPathNamespaceURIFunction);
xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space", xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",
xmlXPathNormalizeFunction); xmlXPathNormalizeFunction);
xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize", xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize",

View File

@ -148,8 +148,8 @@ void xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathLocalPartFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathNamespaceFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs);
void xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs); void xmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs);