trio upgrade and integration
diff --git a/xpath.c b/xpath.c
index 7d4fc32..f170917 100644
--- a/xpath.c
+++ b/xpath.c
@@ -16,16 +16,9 @@
  * for VMS
  */
 
-#ifdef WIN32
-#include "win32config.h"
-#else
-#include "config.h"
-#endif
-
-#include <libxml/xmlversion.h>
+#include "libxml.h"
 #ifdef LIBXML_XPATH_ENABLED
 
-#include <stdio.h>
 #include <string.h>
 
 #ifdef HAVE_SYS_TYPES_H
@@ -935,112 +928,57 @@
 	    if (buffersize > (int)sizeof("NaN"))
 		sprintf(buffer, "NaN");
 	} else {
-	    char work[INTEGER_DIGITS + FRACTION_DIGITS + EXPONENT_DIGITS + 1];
-	    char *pointer;
-	    char *start;
-	    int i;
-	    int digits;
-	    int is_negative;
-	    int use_scientific;
-	    int exponent;
-	    int indx;
-	    int count;
-	    double n;
+	    /* 3 is sign, decimal point, and terminating zero */
+	    char work[DBL_DIG + EXPONENT_DIGITS + 3];
+	    int integer_place, fraction_place;
+	    char *ptr;
+	    char *after_fraction;
+	    double absolute_value;
+	    int size;
 
-	    i = digits = 0;
-	    is_negative = (number < 0.0);
-	    if (is_negative)
-		number = -number;
+	    absolute_value = fabs(number);
 
-	    /* Scale number */
-	    n = log10(number);
-	    exponent = (isinf(n) == -1) ? 0 : (int)n;
-	    use_scientific = (((number <= LOWER_DOUBLE) ||
-			       (number > UPPER_DOUBLE)) &&
-			      (number != 0));
-	    if (use_scientific) {
-		number /= pow(10.0, (double)exponent);
-		while (number < 1.0) {
-		    number *= 10.0;
-		    exponent--;
-		}
+	    /*
+	     * First choose format - scientific or regular floating point.
+	     * In either case, result is in work, and after_fraction points
+	     * just past the fractional part.
+	    */
+	    if ( ((absolute_value > UPPER_DOUBLE) ||
+		  (absolute_value < LOWER_DOUBLE)) &&
+		 (absolute_value != 0.0) ) {
+		/* Use scientific notation */
+		integer_place = DBL_DIG + EXPONENT_DIGITS + 1;
+		fraction_place = DBL_DIG - 1;
+		snprintf(work, sizeof(work),"%*.*e",
+			 integer_place, fraction_place, number);
+		after_fraction = strchr(work + DBL_DIG, 'e');
 	    }
-	    
-	    /* Integer part is build from back */
-	    pointer = &work[INTEGER_DIGITS + 1];
-	    if (number < 1.0) {
-		*(--pointer) = '0';
-		digits++;
-	    } else {
-		n = number;
-		for (i = 1; i < INTEGER_DIGITS - 1; i++) {
-		    indx = (int)n % 10;
-		    *(--pointer) = "0123456789"[indx];
-		    n /= 10.0;
-		    if (n < 1.0)
-			break;
-		}
-		digits += i;
-	    }
-	    if (is_negative) {
-		*(--pointer) = '-';
-		digits++;
-	    }
-	    start = pointer;
-
-	    /* Fraction part is build from front */
-	    i = 0;
-	    pointer = &work[INTEGER_DIGITS + 1];
-	    if (number - floor(number) > DBL_EPSILON) {
-		*(pointer++) = '.';
-		i++;
-		n = number;
-		count = 0;
-		while (i < FRACTION_DIGITS) {
-		    n -= floor(n);
-		    n *= 10.0;
-		    indx = (int)n % 10;
-		    *(pointer++) = "0123456789"[indx];
-		    i++;
-		    if ((indx != 0) || (count > 0))
-			count++;
-		    if ((n > 10.0) || (count > FRACTION_DIGITS / 2))
-			break;
-		}
-	    }
-	    /* Remove trailing zeroes */
-	    while ((pointer[-1] == '0') && (i > 0)) {
-		pointer--;
-		i--;
-	    }
-	    digits += i;
-	    
-	    if (use_scientific) {
-		*(pointer++) = 'e';
-		digits++;
-		if (exponent < 0) {
-		    *(pointer++) = '-';
-		    exponent = -exponent;
-		} else {
-		    *(pointer++) = '+';
-		}
-		digits++;
-		if (exponent >= 100)
-		    pointer += 2;
-		else if (exponent >= 10)
-		    pointer += 1;
-		while (exponent >= 1) {
-		    *(pointer--) = "0123456789"[exponent % 10];
-		    exponent /= 10;
-		    digits++;
-		}
+	    else {
+		/* Use regular notation */
+		integer_place = 1 + (int)log10(absolute_value);
+		fraction_place = (integer_place > 0)
+		    ? DBL_DIG - integer_place
+		    : DBL_DIG;
+		size = snprintf(work, sizeof(work), "%0.*f",
+				fraction_place, number);
+		after_fraction = work + size;
 	    }
 
-	    if (digits >= buffersize)
-		digits = buffersize - 1;
-	    
-	    memcpy(buffer, start, digits);
-	    buffer[digits] = 0;
+	    /* Remove fractional trailing zeroes */
+	    ptr = after_fraction;
+	    while (*(--ptr) == '0')
+		;
+	    if (*ptr != '.')
+	        ptr++;
+	    strcpy(ptr, after_fraction);
+
+	    /* Finally copy result back to caller */
+	    size = strlen(work) + 1;
+	    if (size > buffersize) {
+		work[buffersize - 1] = 0;
+		size = buffersize;
+	    }
+	    memcpy(buffer, work, size);
 	}
 	break;
     }
@@ -5200,6 +5138,8 @@
  * xmlXPathStringEvalNumber:
  * @str:  A string to scan
  *
+ *  [30a]  Float  ::= Number ('e' Digits?)?
+ *
  *  [30]   Number ::=   Digits ('.' Digits?)?
  *                    | '.' Digits 
  *  [31]   Digits ::=   [0-9]+
@@ -5217,7 +5157,9 @@
     double mult = 1;
     int ok = 0;
     int isneg = 0;
-
+    int exponent = 0;
+    int is_exponent_negative = 0;
+    
     while (IS_BLANK(*cur)) cur++;
     if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
         return(xmlXPathNAN);
@@ -5242,9 +5184,22 @@
 	    cur++;
 	}
     }
+    if ((*cur == 'e') || (*cur == 'E')) {
+      cur++;
+      if (*cur == '-') {
+	is_exponent_negative = 1;
+	cur++;
+      }
+      while ((*cur >= '0') && (*cur <= '9')) {
+	exponent = exponent * 10 + (*cur - '0');
+	cur++;
+      }
+    }
     while (IS_BLANK(*cur)) cur++;
     if (*cur != 0) return(xmlXPathNAN);
     if (isneg) ret = -ret;
+    if (is_exponent_negative) exponent = -exponent;
+    ret *= pow(10.0, (double)exponent);
     return(ret);
 }
 
@@ -5264,6 +5219,8 @@
     double ret = 0.0;
     double mult = 1;
     int ok = 0;
+    int exponent = 0;
+    int is_exponent_negative = 0;
 
     CHECK_ERROR;
     if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) {
@@ -5285,6 +5242,20 @@
 	    NEXT;
 	}
     }
+    if ((CUR == 'e') || (CUR == 'E')) {
+      NEXT;
+      if (CUR == '-') {
+	is_exponent_negative = 1;
+	NEXT;
+      }
+      while ((CUR >= '0') && (CUR <= '9')) {
+	exponent = exponent * 10 + (CUR - '0');
+	NEXT;
+      }
+    }
+    if (is_exponent_negative)
+      exponent = -exponent;
+    ret *= pow(10.0, (double)exponent);
     PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0,
 	           xmlXPathNewFloat(ret), NULL);
 }