applied a patch from Ken Neighbors fixing some format-number
authorDaniel Veillard <veillard@src.gnome.org>
Sat, 15 Jun 2002 13:45:04 +0000 (13:45 +0000)
committerDaniel Veillard <veillard@src.gnome.org>
Sat, 15 Jun 2002 13:45:04 +0000 (13:45 +0000)
* libxslt/numbers.c libxslt/numbersInternals.h: applied a
  patch from Ken Neighbors fixing some format-number inconsistencies
* tests/numbers/format-number.out tests/numbers/format-number.xml
  tests/numbers/format-number.xsl: the patch also included
  updates to the regression tests
Daniel

ChangeLog
libxslt/numbers.c
libxslt/numbersInternals.h
tests/numbers/format-number.out
tests/numbers/format-number.xml
tests/numbers/format-number.xsl

index 410e0e8..690fe85 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sat Jun 15 15:44:58 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+       * libxslt/numbers.c libxslt/numbersInternals.h: applied a
+         patch from Ken Neighbors fixing some format-number inconsistencies
+       * tests/numbers/format-number.out tests/numbers/format-number.xml
+         tests/numbers/format-number.xsl: the patch also included
+         updates to the regression tests
+
 Mon Jun 10 14:55:31 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
        * libxslt/numbers.c: patch from Richard Jinks t correct a bug in
index 851e27a..b31e586 100644 (file)
@@ -109,16 +109,19 @@ xsltNumberFormatDecimal(xmlBufferPtr buffer,
     /* Build buffer from back */
     pointer = &temp_string[sizeof(temp_string)];
     *(--pointer) = 0;
-    for (i = 1; i < (int)sizeof(temp_string); i++) {
-       *(--pointer) = digit_zero + (int)fmod(number, 10.0);
-       number /= 10.0;
+    i = 0;
+    while (pointer > temp_string) {
        if ((i >= width) && (fabs(number) < 1.0))
            break; /* for */
-       if ((groupingCharacter != 0) &&
+       if ((i > 0) && (groupingCharacter != 0) &&
            (digitsPerGroup > 0) &&
            ((i % digitsPerGroup) == 0)) {
            *(--pointer) = groupingCharacter;
        }
+       if (pointer > temp_string)
+           *(--pointer) = digit_zero + (int)fmod(number, 10.0);
+       number /= 10.0;
+       ++i;
     }
     xmlBufferCat(buffer, pointer);
 }
@@ -871,11 +874,13 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
        return XPATH_MEMORY_ERROR;
     }
 
+    format_info.integer_hash = 0;
     format_info.integer_digits = 0;
     format_info.frac_digits = 0;
     format_info.frac_hash = 0;
     format_info.group = -1;
     format_info.multiplier = 1;
+    format_info.add_decimal = FALSE;
     format_info.is_multiplier_set = FALSE;
     format_info.is_negative_pattern = FALSE;
 
@@ -906,6 +911,7 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
                found_error = 1;
                goto OUTPUT_NUMBER;
            }
+           format_info.integer_hash++;
            if (format_info.group >= 0)
                format_info.group++;
        } else if (*the_format == self->zeroDigit[0]) {
@@ -934,8 +940,10 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
     }
 
     /* We have finished the integer part, now work on fraction */
-    if (*the_format == self->decimalPoint[0])
+    if (*the_format == self->decimalPoint[0]) {
+        format_info.add_decimal = TRUE;
        the_format++;           /* Skip over the decimal */
+    }
     
     while (*the_format != 0) {
        
@@ -1070,11 +1078,13 @@ OUTPUT_NUMBER:
                 "xsltFormatNumberConversion : error in format string, using default\n");
        default_sign = (number < 0.0) ? 1 : 0;
        prefix_length = suffix_length = 0;
+       format_info.integer_hash = 0;
        format_info.integer_digits = 1;
        format_info.frac_digits = 1;
        format_info.frac_hash = 4;
        format_info.group = -1;
        format_info.multiplier = 1;
+       format_info.add_decimal = TRUE;
     }
 
     /* Ready to output our number.  First see if "default sign" is required */
@@ -1105,9 +1115,26 @@ OUTPUT_NUMBER:
                                format_info.group,
                                (xmlChar) ',');
 
+    /* Special case: java treats '.#' like '.0', '.##' like '.0#', etc. */
+    if ((format_info.integer_digits + format_info.integer_hash +
+        format_info.frac_digits == 0) && (format_info.frac_hash > 0)) {
+        ++format_info.frac_digits;
+       --format_info.frac_hash;
+    }
+
+    /* Add leading zero, if required */
+    if ((floor(number) == 0) &&
+       (format_info.integer_digits + format_info.frac_digits == 0)) {
+        xmlBufferAdd(buffer, self->zeroDigit, 1);
+    }
+
     /* Next the fractional part, if required */
-    if (format_info.frac_digits + format_info.frac_hash > 0) {
-       number -= floor(number);
+    if (format_info.frac_digits + format_info.frac_hash == 0) {
+        if (format_info.add_decimal)
+           xmlBufferAdd(buffer, self->decimalPoint, 1);
+    }
+    else {
+      number -= floor(number);
        if ((number != 0) || (format_info.frac_digits != 0)) {
            xmlBufferAdd(buffer, self->decimalPoint, 1);
            number = floor(scale * number + 0.5);
index b4d9359..c599f0d 100644 (file)
@@ -40,11 +40,13 @@ typedef struct _xsltNumberData {
  * This data structure lists the various parameters needed to format numbers.
  */
 typedef struct _xsltFormatNumberInfo {
+    int            integer_hash;       /* Number of '#' in integer part */
     int            integer_digits;     /* Number of '0' in integer part */
     int            frac_digits;        /* Number of '0' in fractional part */
     int            frac_hash;          /* Number of '#' in fractional part */
     int            group;              /* Number of chars per display 'group' */
     int     multiplier;                /* Scaling for percent or permille */
+    char    add_decimal;       /* Flag for whether decimal point appears in pattern */
     char    is_multiplier_set; /* Flag to catch multiple occurences of percent/permille */
     char    is_negative_pattern;/* Flag for processing -ve prefix/suffix */
 } xsltFormatNumberInfo, *xsltFormatNumberInfoPtr;
index 3d9d9d5..d00139e 100644 (file)
@@ -1,7 +1,94 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
-<pi>
-  one prefix3.14suffix
-  two -_3.14_
-  three -_003.1415_
-  four _(3.1)_
-  five prefix3*14suffix</pi>
+<format-number>
+  <fixes>
+    one prefix3.14suffix
+    two -_3.14_
+    three -_003.1415_
+    four _(3.1)_
+    five prefix3*14suffix
+  </fixes>
+  <point-test>
+    format-number(-1.0,'#'  ) = -1
+    format-number(-0.5,'#'  ) = -1
+    format-number( 0.0,'#'  ) = 0
+    format-number( 0.5,'#'  ) = 1
+    format-number( 1.0,'#'  ) = 1
+  </point-test>
+  <point-test>
+    format-number(-1.0,'0'  ) = -1
+    format-number(-0.5,'0'  ) = -1
+    format-number( 0.0,'0'  ) = 0
+    format-number( 0.5,'0'  ) = 1
+    format-number( 1.0,'0'  ) = 1
+  </point-test>
+  <point-test>
+    format-number(-1.0, '.' ) = -1.
+    format-number(-0.5, '.' ) = -1.
+    format-number( 0.0, '.' ) = 0.
+    format-number( 0.5, '.' ) = 1.
+    format-number( 1.0, '.' ) = 1.
+  </point-test>
+  <point-test>
+    format-number(-1.0,'#.' ) = -1.
+    format-number(-0.5,'#.' ) = -1.
+    format-number( 0.0,'#.' ) = 0.
+    format-number( 0.5,'#.' ) = 1.
+    format-number( 1.0,'#.' ) = 1.
+  </point-test>
+  <point-test>
+    format-number(-1.0,'0.' ) = -1.
+    format-number(-0.5,'0.' ) = -1.
+    format-number( 0.0,'0.' ) = 0.
+    format-number( 0.5,'0.' ) = 1.
+    format-number( 1.0,'0.' ) = 1.
+  </point-test>
+  <point-test>
+    format-number(-1.0, '.#') = -1.0
+    format-number(-0.5, '.#') = -.5
+    format-number( 0.0, '.#') = .0
+    format-number( 0.5, '.#') = .5
+    format-number( 1.0, '.#') = 1.0
+  </point-test>
+  <point-test>
+    format-number(-1.0, '.##') = -1.0
+    format-number(-0.5, '.##') = -.5
+    format-number( 0.0, '.##') = .0
+    format-number( 0.5, '.##') = .5
+    format-number( 1.0, '.##') = 1.0
+  </point-test>
+  <point-test>
+    format-number(-1.0, '.0') = -1.0
+    format-number(-0.5, '.0') = -.5
+    format-number( 0.0, '.0') = .0
+    format-number( 0.5, '.0') = .5
+    format-number( 1.0, '.0') = 1.0
+  </point-test>
+  <point-test>
+    format-number(-1.0,'#.#') = -1
+    format-number(-0.5,'#.#') = -0.5
+    format-number( 0.0,'#.#') = 0
+    format-number( 0.5,'#.#') = 0.5
+    format-number( 1.0,'#.#') = 1
+  </point-test>
+  <point-test>
+    format-number(-1.0,'0.0') = -1.0
+    format-number(-0.5,'0.0') = -0.5
+    format-number( 0.0,'0.0') = 0.0
+    format-number( 0.5,'0.0') = 0.5
+    format-number( 1.0,'0.0') = 1.0
+  </point-test>
+  <point-test>
+    format-number(-1.0,'#.0') = -1.0
+    format-number(-0.5,'#.0') = -.5
+    format-number( 0.0,'#.0') = .0
+    format-number( 0.5,'#.0') = .5
+    format-number( 1.0,'#.0') = 1.0
+  </point-test>
+  <point-test>
+    format-number(-1.0,'0.#') = -1
+    format-number(-0.5,'0.#') = -0.5
+    format-number( 0.0,'0.#') = 0
+    format-number( 0.5,'0.#') = 0.5
+    format-number( 1.0,'0.#') = 1
+  </point-test>
+</format-number>
index 0ca0212..f1985fb 100644 (file)
@@ -1,4 +1,13 @@
-<functions>
-  <pi>3.1415</pi>
-  <negpi>-3.1415</negpi>
-</functions>
+<format-number>
+  <fixes>
+    <pi>3.1415</pi>
+    <negpi>-3.1415</negpi>
+  </fixes>
+  <point-test>
+    <number>-1.0</number>
+    <number>-0.5</number>
+    <number> 0.0</number>
+    <number> 0.5</number>
+    <number> 1.0</number>
+  </point-test>
+</format-number>
index 4c34ce8..a2cabc6 100644 (file)
  decimal-separator = "*"
 />
 
-<xsl:template match="functions">
- <pi>
-  one <xsl:value-of select="format-number(pi, 'prefix#,#,###.##suffix')"/>
-  two <xsl:value-of select="format-number(negpi, '_#,#,###.##_')"/>
-  three <xsl:value-of select="format-number(negpi, '_#,#,000.000##_')"/>
-  four <xsl:value-of select="format-number(negpi, '_#.#_;_(#.#)_')"/>
-  five <xsl:value-of select="format-number(pi, 'prefix#,#,###*##suffix','special')"/>
- </pi>
+<xsl:template match="/format-number">
+  <format-number>
+    <xsl:apply-templates/>
+  </format-number>
+</xsl:template>
+
+<xsl:template match="/format-number/fixes">
+  <fixes>
+    one <xsl:value-of select="format-number(pi, 'prefix#,#,###.##suffix')"/>
+    two <xsl:value-of select="format-number(negpi, '_#,#,###.##_')"/>
+    three <xsl:value-of select="format-number(negpi, '_#,#,000.000##_')"/>
+    four <xsl:value-of select="format-number(negpi, '_#.#_;_(#.#)_')"/>
+    five <xsl:value-of select="format-number(pi, 'prefix#,#,###*##suffix','special')"/>
+    <xsl:text>&#10;  </xsl:text>
+  </fixes>
+</xsl:template>
+
+<xsl:template match="/format-number/point-test">
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>,'#'  )<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'#')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>,'0'  )<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'0')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>, '.' )<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'.')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>,'#.' )<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'#.')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>,'0.' )<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'0.')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>, '.#')<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'.#')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>, '.##')<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'.##')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>, '.0')<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'.0')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>,'#.#')<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'#.#')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>,'0.0')<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'0.0')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>,'#.0')<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'#.0')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test><xsl:text>&#10;  </xsl:text>
+
+  <point-test>
+    <xsl:for-each select="number">
+    format-number(<xsl:value-of select="."/>,'0.#')<xsl:text> = </xsl:text>
+    <xsl:value-of select="format-number(.,'0.#')"/>
+    </xsl:for-each>
+    <xsl:text>&#10;  </xsl:text>
+  </point-test>
 </xsl:template>
 
 </xsl:stylesheet>