version 1.83, 2000/10/25 19:26:53
|
version 1.84, 2000/10/26 13:05:44
|
Line 72 double xmlXPathStringEvalNumber(const xm
|
Line 72 double xmlXPathStringEvalNumber(const xm
|
*/ |
*/ |
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 |
Line 162 xmlXPathInit(void) {
|
Line 162 xmlXPathInit(void) {
|
xmlXPathPINF = 1; |
xmlXPathPINF = 1; |
xmlXPathPINF /= 0; |
xmlXPathPINF /= 0; |
|
|
xmlXPathMINF = -1; |
xmlXPathNINF = -1; |
xmlXPathMINF /= 0; |
xmlXPathNINF /= 0; |
|
|
initialized = 1; |
initialized = 1; |
} |
} |
Line 2721 xmlXPathIdFunction(xmlXPathParserContext
|
Line 2721 xmlXPathIdFunction(xmlXPathParserContext
|
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); |
Line 2771 xmlXPathIdFunction(xmlXPathParserContext
|
Line 2789 xmlXPathIdFunction(xmlXPathParserContext
|
} |
} |
|
|
/** |
/** |
* 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); |
Line 2799 xmlXPathLocalPartFunction(xmlXPathParser
|
Line 2822 xmlXPathLocalPartFunction(xmlXPathParser
|
} |
} |
|
|
/** |
/** |
* 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) { |
Line 2859 void
|
Line 2883 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); |
Line 2920 xmlXPathNameFunction(xmlXPathParserConte
|
Line 2949 xmlXPathNameFunction(xmlXPathParserConte
|
* 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); |
Line 3302 xmlXPathNormalizeFunction(xmlXPathParser
|
Line 3339 xmlXPathNormalizeFunction(xmlXPathParser
|
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) { |
|
|
Line 3338 xmlXPathNormalizeFunction(xmlXPathParser
|
Line 3376 xmlXPathNormalizeFunction(xmlXPathParser
|
valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); |
valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target))); |
xmlBufferFree(target); |
xmlBufferFree(target); |
} |
} |
if (obj) |
xmlXPathFreeObject(obj); |
xmlXPathFreeObject(obj); |
|
} |
} |
|
|
/** |
/** |
Line 3530 not_equal:
|
Line 3567 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) { |
Line 3583 xmlXPathNumberFunction(xmlXPathParserCon
|
Line 3636 xmlXPathNumberFunction(xmlXPathParserCon
|
*/ |
*/ |
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); |
} |
} |
|
|
/** |
/** |
Line 3599 void
|
Line 3669 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 |
} |
} |
|
|
/** |
/** |
Line 3617 xmlXPathCeilingFunction(xmlXPathParserCo
|
Line 3691 xmlXPathCeilingFunction(xmlXPathParserCo
|
|
|
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 |
} |
} |
|
|
/** |
/** |
Line 3637 xmlXPathRoundFunction(xmlXPathParserCont
|
Line 3716 xmlXPathRoundFunction(xmlXPathParserCont
|
|
|
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; |
} |
} |
Line 3766 xmlXPathParseName(xmlXPathParserContextP
|
Line 3853 xmlXPathParseName(xmlXPathParserContextP
|
* 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 |
Line 3813 xmlXPathStringEvalNumber(const xmlChar *
|
Line 3897 xmlXPathStringEvalNumber(const xmlChar *
|
* 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) { |
Line 5302 xmlXPathRegisterAllFunctions(xmlXPathCon
|
Line 5384 xmlXPathRegisterAllFunctions(xmlXPathCon
|
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", |