Added some code to avoid integer overflow for ceil, floor and round

* xpath.c: Added some code to avoid integer overflow for
  ceil, floor and round functions (bug 301162)
diff --git a/ChangeLog b/ChangeLog
index d616a61..7b68300 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue Apr 19 22:33:18 HKT 2005 William Brack <wbrack@mmm.com.hk>
+
+	* xpath.c: Added some code to avoid integer overflow for
+	  ceil, floor and round functions (bug 301162)
+
 Tue Apr 19 13:21:54 CEST 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
 
 	* xmlschemas.c: Removed workaround for bug #172215, since it
diff --git a/xpath.c b/xpath.c
index 728ba74..c24c313 100644
--- a/xpath.c
+++ b/xpath.c
@@ -7190,6 +7190,18 @@
     xmlXPathFreeObject(cur);
 }
 
+/*
+ * To assure working code on multiple platforms, we want to only depend
+ * upon the characteristic truncation of converting a floating point value
+ * to an integer.  Unfortunately, because of the different storage sizes
+ * of our internal floating point value (double) and integer (int), we
+ * can't directly convert (see bug 301162).  This macro is a messy
+ * 'workaround'
+ */
+#define XTRUNC(f, v)            \
+    f = fmod((v), INT_MAX);     \
+    f = (v) - (f) + (double)((int)(f));
+
 /**
  * xmlXPathFloorFunction:
  * @ctxt:  the XPath Parser context
@@ -7208,7 +7220,7 @@
     CAST_TO_NUMBER;
     CHECK_TYPE(XPATH_NUMBER);
 
-    f = (double)((int) ctxt->value->floatval);
+    XTRUNC(f, ctxt->value->floatval);
     if (f != ctxt->value->floatval) {
 	if (ctxt->value->floatval > 0)
 	    ctxt->value->floatval = f;
@@ -7238,7 +7250,7 @@
 #if 0
     ctxt->value->floatval = ceil(ctxt->value->floatval);
 #else
-    f = (double)((int) ctxt->value->floatval);
+    XTRUNC(f, ctxt->value->floatval);
     if (f != ctxt->value->floatval) {
 	if (ctxt->value->floatval > 0)
 	    ctxt->value->floatval = f + 1;
@@ -7278,7 +7290,7 @@
 	(ctxt->value->floatval == 0.0))
 	return;
 
-    f = (double)((int) ctxt->value->floatval);
+    XTRUNC(f, ctxt->value->floatval);
     if (ctxt->value->floatval < 0) {
 	if (ctxt->value->floatval < f - 0.5)
 	    ctxt->value->floatval = f - 1;