fixed problem with negative periods (bug 154021) changed expected output,
authorWilliam M. Brack <wbrack@src.gnome.org>
Thu, 30 Sep 2004 18:33:30 +0000 (18:33 +0000)
committerWilliam M. Brack <wbrack@src.gnome.org>
Thu, 30 Sep 2004 18:33:30 +0000 (18:33 +0000)
* libexslt/date.c: fixed problem with negative periods
  (bug 154021)
* tests/exslt/date/sum.2.out: changed expected output, now
  agrees with comments in sum.2.xml test data file

ChangeLog
libexslt/date.c
libxslt/xsltwin32config.h
tests/exslt/date/sum.2.out

index b3a906d..3b7c0db 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu Sep 30 11:28:03 PDT 2004 William Brack <wbrack@mmm.com.hk>
+
+       * libexslt/date.c: fixed problem with negative periods
+         (bug 154021)
+       * tests/exslt/date/sum.2.out: changed expected output, now
+         agrees with comments in sum.2.xml test data file
+         
 Thu Sep 30 08:19:28 CEST 2004 Daniel Veillard <daniel@veillard.com>
 
        * libxslt/templates.c: patch from Mark Vakoc about an incorrect
index 672f1b4..29cbdfe 100644 (file)
@@ -1651,27 +1651,22 @@ _exsltDateDifference (exsltDateValPtr x, exsltDateValPtr y, int flag)
 }
 
 /**
- * _exsltDateAddDuration:
- * @x: an #exsltDateValPtr of type #XS_DURATION
- * @y: an #exsltDateValPtr of type #XS_DURATION
+ * _exsltDateAddDurCalc
+ * @ret: an exsltDateValPtr for the return value:
+ * @x: an exsltDateValPtr for the first operand
+ * @y: an exsltDateValPtr for the second operand
  *
- * Compute a new duration from @x and @y.
+ * Add two durations, catering for possible negative values.
+ * The sum is placed in @ret.
  *
- * Returns date/time pointer or NULL.
+ * Returns 1 for success, 0 if error detected.
  */
-static exsltDateValPtr
-_exsltDateAddDuration (exsltDateValPtr x, exsltDateValPtr y)
+static int
+_exsltDateAddDurCalc (exsltDateValPtr ret, exsltDateValPtr x,
+                     exsltDateValPtr y)
 {
-    exsltDateValPtr ret;
     long carry;
 
-    if ((x == NULL) || (y == NULL))
-        return NULL;
-
-    ret = exsltDateCreateDate(XS_DURATION);
-    if (ret == NULL)
-        return NULL;
-
     /* months */
     ret->value.dur.mon = x->value.dur.mon + y->value.dur.mon;
 
@@ -1680,6 +1675,16 @@ _exsltDateAddDuration (exsltDateValPtr x, exsltDateValPtr y)
     carry = (long)FQUOTIENT(ret->value.dur.sec, SECS_PER_DAY);
     if (ret->value.dur.sec != 0.0) {
         ret->value.dur.sec = MODULO(ret->value.dur.sec, SECS_PER_DAY);
+       /*
+        * Our function MODULO always gives us a positive value, so
+        * if we end up with a "-ve" carry we need to adjust it
+        * appropriately (bug 154021)
+        */
+       if ((carry < 0) && (ret->value.dur.sec != 0)) {
+           /* change seconds to equiv negative modulus */
+           ret->value.dur.sec = ret->value.dur.sec - SECS_PER_DAY;
+           carry++;
+       }
     }
 
     /* days */
@@ -1693,11 +1698,37 @@ _exsltDateAddDuration (exsltDateValPtr x, exsltDateValPtr y)
          (ret->value.dur.mon < 0)) ||
         (((ret->value.dur.day < 0) || (ret->value.dur.sec < 0)) &&
          (ret->value.dur.mon > 0))) {
-       exsltDateFreeDate(ret);
-        return NULL;
+        return 0;
     }
+    return 1;
+}
 
-    return ret;
+/**
+ * _exsltDateAddDuration:
+ * @x: an #exsltDateValPtr of type #XS_DURATION
+ * @y: an #exsltDateValPtr of type #XS_DURATION
+ *
+ * Compute a new duration from @x and @y.
+ *
+ * Returns date/time pointer or NULL.
+ */
+static exsltDateValPtr
+_exsltDateAddDuration (exsltDateValPtr x, exsltDateValPtr y)
+{
+    exsltDateValPtr ret;
+
+    if ((x == NULL) || (y == NULL))
+        return NULL;
+
+    ret = exsltDateCreateDate(XS_DURATION);
+    if (ret == NULL)
+        return NULL;
+
+    if (_exsltDateAddDurCalc(ret, x, y))
+        return ret;
+
+    exsltDateFreeDate(ret);
+    return NULL;
 }
 
 /****************************************************************
@@ -2729,7 +2760,6 @@ exsltDateSumFunction (xmlXPathParserContextPtr ctxt, int nargs)
     xmlChar *tmp;
     exsltDateValPtr x, total;
     xmlChar *ret;
-    long carry;
     int i;
 
     if (nargs != 1) {
@@ -2762,7 +2792,7 @@ exsltDateSumFunction (xmlXPathParserContextPtr ctxt, int nargs)
     }
 
     for (i = 0; i < ns->nodeNr; i++) {
-
+       int result;
        tmp = xmlXPathCastNodeToString (ns->nodeTab[i]);
        if (tmp == NULL) {
            xmlXPathFreeNodeSet (ns);
@@ -2779,22 +2809,16 @@ exsltDateSumFunction (xmlXPathParserContextPtr ctxt, int nargs)
            return;
        }
 
-       /* months */
-       total->value.dur.mon += x->value.dur.mon;
-
-       /* seconds */
-       total->value.dur.sec += x->value.dur.sec;
-       carry = (long) FQUOTIENT (total->value.dur.sec, SECS_PER_DAY);
-       if (total->value.dur.sec != 0.0) {
-           total->value.dur.sec =
-               MODULO (total->value.dur.sec, SECS_PER_DAY);
-       }
-
-       /* days */
-       total->value.dur.day += x->value.dur.day + carry;
+       result = _exsltDateAddDurCalc(total, total, x);
 
        exsltDateFreeDate (x);
        xmlFree (tmp);
+       if (!result) {
+           exsltDateFreeDate (total);
+           xmlXPathFreeNodeSet (ns);
+           xmlXPathReturnEmptyString (ctxt);
+           return;
+       }
     }
 
     ret = exsltDateFormatDuration (&(total->value.dur));
index 09a424c..c468a9d 100644 (file)
@@ -44,7 +44,7 @@ extern "C" {
  *
  * extra version information, used to show a CVS compilation
  */
-#define LIBXML_VERSION_EXTRA "-CVS951"
+#define LIBXML_VERSION_EXTRA "-CVS954"
 
 /**
  * WITH_XSLT_DEBUG:
index 27f7535..8c9cdda 100644 (file)
@@ -2,9 +2,9 @@
 sum    : 
 result : 
 sum    : P1M + -P1D
-result : -P1M1D
+result : 
 sum    : P1M + -P1D + P1D
-result : P1M
+result : 
 sum    : P1M + P1D + -P1D
 result : P1M
 sum    :