diff options
Diffstat (limited to 'xpath.c')
-rw-r--r-- | xpath.c | 50 |
1 files changed, 34 insertions, 16 deletions
@@ -2648,9 +2648,10 @@ xmlXPathPopExternal (xmlXPathParserContextPtr ctxt) { #define UPPER_DOUBLE 1E9 #define LOWER_DOUBLE 1E-5 +#define LOWER_DOUBLE_EXP 5 #define INTEGER_DIGITS DBL_DIG -#define FRACTION_DIGITS (DBL_DIG + 1) +#define FRACTION_DIGITS (DBL_DIG + 1 + (LOWER_DOUBLE_EXP)) #define EXPONENT_DIGITS (3 + 2) /** @@ -2701,8 +2702,16 @@ xmlXPathFormatNumber(double number, char buffer[], int buffersize) *ptr = 0; } } else { - /* 3 is sign, decimal point, and terminating zero */ - char work[DBL_DIG + EXPONENT_DIGITS + 3]; + /* + For the dimension of work, + DBL_DIG is number of significant digits + EXPONENT is only needed for "scientific notation" + 3 is sign, decimal point, and terminating zero + LOWER_DOUBLE_EXP is max number of leading zeroes in fraction + Note that this dimension is slightly (a few characters) + larger than actually necessary. + */ + char work[DBL_DIG + EXPONENT_DIGITS + 3 + LOWER_DOUBLE_EXP]; int integer_place, fraction_place; char *ptr; char *after_fraction; @@ -2725,24 +2734,25 @@ xmlXPathFormatNumber(double number, char buffer[], int buffersize) size = snprintf(work, sizeof(work),"%*.*e", integer_place, fraction_place, number); while ((size > 0) && (work[size] != 'e')) size--; - after_fraction = work + size; } else { /* Use regular notation */ - if (absolute_value > 0.0) - integer_place = 1 + (int)log10(absolute_value); - else - integer_place = 0; - fraction_place = (integer_place > 0) - ? DBL_DIG - integer_place - : DBL_DIG; + if (absolute_value > 0.0) { + integer_place = (int)log10(absolute_value); + if (integer_place > 0) + fraction_place = DBL_DIG - integer_place - 1; + else + fraction_place = DBL_DIG - integer_place; + } else { + fraction_place = 1; + } size = snprintf(work, sizeof(work), "%0.*f", fraction_place, number); - after_fraction = work + size; } /* Remove fractional trailing zeroes */ + after_fraction = work + size; ptr = after_fraction; while (*(--ptr) == '0') ; @@ -3184,6 +3194,11 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) { turtle_comparison: + if (miscNode1 != NULL) + node1 = miscNode1; + if (miscNode2 != NULL) + node2 = miscNode2; + if (node1 == node2->prev) return(1); if (node1 == node2->next) @@ -4602,12 +4617,13 @@ xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes, xmlNodePtr node) { return(ret); l = xmlXPathNodeSetGetLength(nodes); - for (i = l; i > 0; i--) { + for (i = l - 1; i >= 0; i--) { cur = xmlXPathNodeSetItem(nodes, i); if (cur == node) break; xmlXPathNodeSetAddUnique(ret, cur); } + xmlXPathNodeSetSort(ret); /* bug 413451 */ return(ret); } @@ -5573,7 +5589,10 @@ xmlXPathCastNumberToString (double val) { */ xmlChar * xmlXPathCastNodeToString (xmlNodePtr node) { - return(xmlNodeGetContent(node)); +xmlChar *ret; + if ((ret = xmlNodeGetContent(node)) == NULL) + ret = xmlStrdup((const xmlChar *) ""); + return(ret); } /** @@ -14678,8 +14697,7 @@ xmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp, do { tmp = valuePop(pctxt); if (tmp != NULL) { - if (tmp != NULL) - stack++; + stack++; xmlXPathReleaseObject(ctxt, tmp); } } while (tmp != NULL); |