diff --git a/ChangeLog b/ChangeLog index 410e0e81..690fe853 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sat Jun 15 15:44:58 CEST 2002 Daniel Veillard + + * 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 * libxslt/numbers.c: patch from Richard Jinks t correct a bug in diff --git a/libxslt/numbers.c b/libxslt/numbers.c index 851e27a7..b31e5863 100644 --- a/libxslt/numbers.c +++ b/libxslt/numbers.c @@ -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); diff --git a/libxslt/numbersInternals.h b/libxslt/numbersInternals.h index b4d9359e..c599f0d6 100644 --- a/libxslt/numbersInternals.h +++ b/libxslt/numbersInternals.h @@ -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; diff --git a/tests/numbers/format-number.out b/tests/numbers/format-number.out index 3d9d9d50..d00139eb 100644 --- a/tests/numbers/format-number.out +++ b/tests/numbers/format-number.out @@ -1,7 +1,94 @@ - - one prefix3.14suffix - two -_3.14_ - three -_003.1415_ - four _(3.1)_ - five prefix3*14suffix + + + one prefix3.14suffix + two -_3.14_ + three -_003.1415_ + four _(3.1)_ + five prefix3*14suffix + + + 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 + + + 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 + + + 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. + + + 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. + + + 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. + + + 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 + + + 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 + + + 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 + + + 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 + + + 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 + + + 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 + + + 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 + + diff --git a/tests/numbers/format-number.xml b/tests/numbers/format-number.xml index 0ca02123..f1985fb7 100644 --- a/tests/numbers/format-number.xml +++ b/tests/numbers/format-number.xml @@ -1,4 +1,13 @@ - - 3.1415 - -3.1415 - + + + 3.1415 + -3.1415 + + + -1.0 + -0.5 + 0.0 + 0.5 + 1.0 + + diff --git a/tests/numbers/format-number.xsl b/tests/numbers/format-number.xsl index 4c34ce82..a2cabc6b 100644 --- a/tests/numbers/format-number.xsl +++ b/tests/numbers/format-number.xsl @@ -12,14 +12,119 @@ decimal-separator = "*" /> - - - one - two - three - four - five - + + + + + + + + + one + two + three + four + five + + + + + + + + format-number(,'#' ) = + + + + + + + + format-number(,'0' ) = + + + + + + + + format-number(, '.' ) = + + + + + + + + format-number(,'#.' ) = + + + + + + + + format-number(,'0.' ) = + + + + + + + + format-number(, '.#') = + + + + + + + + format-number(, '.##') = + + + + + + + + format-number(, '.0') = + + + + + + + + format-number(,'#.#') = + + + + + + + + format-number(,'0.0') = + + + + + + + + format-number(,'#.0') = + + + + + + + + format-number(,'0.#') = + + + +