+Mon Oct 21 20:56:31 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+ * libxslt/numbers.c libxslt/numbersInternals.h libxslt/xsltutils.[ch]:
+ fixed bug #78501 when using a non ascii character for the
+ number formatting grouping separator.
+ * tests/docs/Makefile.am tests/docs/bug-95.xml
+ tests/general/Makefile.am tests/general/bug-95.*: added the
+ example in the regression tests for this case
+ * libxslt/attributes.c: cleaning up a problem introduced in last
+ patch
+
Mon Oct 21 09:31:55 CEST 2002 Igor Zlatkovic <igor@stud.fh-frankfurt.de>
* libxslt/attributes.c: fixed minor typo in a call to
URL = ns->href;
if (fromset) {
- attr = xmlHasNsProp(ctxt->insert, name, ns->href);
+ if (URL != NULL)
+ attr = xmlHasNsProp(ctxt->insert, name, URL);
+ else
+ attr = xmlHasProp(ctxt->insert, name);
if (attr != NULL)
return;
}
#include <libxml/parserInternals.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
+#include <libxml/encoding.h>
#include "xsltutils.h"
#include "pattern.h"
#include "templates.h"
xmlChar digit_zero,
int width,
int digitsPerGroup,
- xmlChar groupingCharacter)
+ int groupingCharacter,
+ int groupingCharacterLen)
{
- xmlChar temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 1];
+ xmlChar temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 4];
xmlChar *pointer;
int i;
if ((i > 0) && (groupingCharacter != 0) &&
(digitsPerGroup > 0) &&
((i % digitsPerGroup) == 0)) {
- *(--pointer) = groupingCharacter;
+ pointer -= groupingCharacterLen;
+ xmlCopyCharMultiByte(pointer, groupingCharacter);
}
if (pointer > temp_string)
*(--pointer) = digit_zero + (int)fmod(number, 10.0);
token->token,
token->width,
data->digitsPerGroup,
- data->groupingCharacter);
+ data->groupingCharacter,
+ data->groupingCharacterLen);
}
break;
}
int prefix_length, suffix_length = 0, nprefix_length, nsuffix_length;
double scale;
int j;
+ int self_grouping_len;
xsltFormatNumberInfo format_info;
/* delayed_multiplier allows a 'trailing' percent or permille to be treated as suffix */
int delayed_multiplier = 0;
/* Here we process the "number" part of the format. It gets a little messy because of */
/* the percent/per-mille - if that appears at the end, it may be part of the suffix */
/* instead of part of the number, so the variable delayed_multiplier is used to handle it */
+ self_grouping_len = xmlStrlen(self->grouping);
while ((*the_format != 0) &&
(*the_format != self->decimalPoint[0]) &&
(*the_format != self->patternSeparator[0])) {
format_info.integer_digits++;
if (format_info.group >= 0)
format_info.group++;
- } else if (*the_format == self->grouping[0]) {
+ } else if ((self_grouping_len > 0) &&
+ (!xmlStrncmp(the_format, self->grouping, self_grouping_len))) {
/* Reset group count */
format_info.group = 0;
+ the_format += self_grouping_len;
+ continue;
} else if (*the_format == self->percent[0]) {
if (format_info.is_multiplier_set) {
found_error = 1;
number = fabs(number) * (double)format_info.multiplier;
scale = pow(10.0, (double)(format_info.frac_digits + format_info.frac_hash));
number = floor((scale * number + 0.5)) / scale;
- if ((self->grouping != NULL) && (self->grouping[0] != 0))
+ if ((self->grouping != NULL) && (self->grouping[0] != 0)) {
+ int sep, len;
+ sep = xsltGetUTF8Char(self->grouping, &len);
xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
format_info.integer_digits,
format_info.group,
- (xmlChar) self->grouping[0]);
- else
+ sep, len);
+ } else
xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
format_info.integer_digits,
format_info.group,
- (xmlChar) ',');
+ ',', 1);
/* Special case: java treats '.#' like '.0', '.##' like '.0#', etc. */
if ((format_info.integer_digits + format_info.integer_hash +
}
xsltNumberFormatDecimal(buffer, floor(number), self->zeroDigit[0],
format_info.frac_digits + j,
- 0, (xmlChar)0);
+ 0, 0, 0);
}
}
/* Put the suffix into the buffer */
xmlChar *format;
int has_format;
int digitsPerGroup;
- xmlChar groupingCharacter;
+ int groupingCharacter;
+ int groupingCharacterLen;
xmlDocPtr doc;
xmlNodePtr node;
} xsltNumberData, *xsltNumberDataPtr;
#include <libxml/valid.h>
#include <libxml/hash.h>
#include <libxml/uri.h>
+#include <libxml/encoding.h>
#include <libxml/xmlerror.h>
#include "xslt.h"
#include "xsltutils.h"
prop = xsltGetNsProp(cur, (const xmlChar *)"grouping-separator",
XSLT_NAMESPACE);
if (prop != NULL) {
- comp->numdata.groupingCharacter = prop[0];
+ comp->numdata.groupingCharacter =
+ xsltGetUTF8Char(prop, &(comp->numdata.groupingCharacterLen));
xmlFree(prop);
}
return(NULL);
}
+/**
+ * xsltGetUTF8Char:
+ * @utf: a sequence of UTF-8 encoded bytes
+ * @len: a pointer to @bytes len
+ *
+ * Read one UTF8 Char from @utf
+ * Function copied from libxml2 xmlGetUTF8Char() ... to discard ultimately
+ * and use the original API
+ *
+ * Returns the char value or -1 in case of error and update @len with the
+ * number of bytes used
+ */
+int
+xsltGetUTF8Char(const unsigned char *utf, int *len) {
+ unsigned int c;
+
+ if (utf == NULL)
+ goto error;
+ if (len == NULL)
+ goto error;
+ if (*len < 1)
+ goto error;
+
+ c = utf[0];
+ if (c & 0x80) {
+ if (*len < 2)
+ goto error;
+ if ((utf[1] & 0xc0) != 0x80)
+ goto error;
+ if ((c & 0xe0) == 0xe0) {
+ if (*len < 3)
+ goto error;
+ if ((utf[2] & 0xc0) != 0x80)
+ goto error;
+ if ((c & 0xf0) == 0xf0) {
+ if (*len < 4)
+ goto error;
+ if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
+ goto error;
+ *len = 4;
+ /* 4-byte code */
+ c = (utf[0] & 0x7) << 18;
+ c |= (utf[1] & 0x3f) << 12;
+ c |= (utf[2] & 0x3f) << 6;
+ c |= utf[3] & 0x3f;
+ } else {
+ /* 3-byte code */
+ *len = 3;
+ c = (utf[0] & 0xf) << 12;
+ c |= (utf[1] & 0x3f) << 6;
+ c |= utf[2] & 0x3f;
+ }
+ } else {
+ /* 2-byte code */
+ *len = 2;
+ c = (utf[0] & 0x1f) << 6;
+ c |= utf[1] & 0x3f;
+ }
+ } else {
+ /* 1-byte code */
+ *len = 1;
+ }
+ return(c);
+
+error:
+ *len = 0;
+ return(-1);
+}
+
/************************************************************************
* *
/*
* Our own version of namespaced atributes lookup.
*/
-xmlChar * xsltGetNsProp (xmlNodePtr node,
+xmlChar * xsltGetNsProp (xmlNodePtr node,
const xmlChar *name,
const xmlChar *nameSpace);
+int xsltGetUTF8Char (const unsigned char *utf,
+ int *len);
/*
* XSLT specific error and debug reporting functions.
bug-92.xml \
bug-93.xml \
bug-94.xml \
+ bug-95.xml \
character.xml \
array.xml \
items.xml
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<Kapital>
+ <Vklad><Kc>1234567890.12</Kc></Vklad>
+</Kapital>
+
bug-93.out bug-93.xsl \
bug-93-inc.out bug-93-inc.xsl \
bug-94.out bug-94.xsl \
+ bug-95.out bug-95.xsl \
character.out character.xsl \
character2.out character2.xsl \
itemschoose.out itemschoose.xsl \
--- /dev/null
+<html>
+<title>Example xsltproc</title>
+<body>1 234 567 890,12 Kè</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output method="html" encoding="ISO-8859-1"/>
+
+<xsl:decimal-format name="czf"
+ decimal-separator=","
+ grouping-separator=" "/>
+
+<xsl:template match="Kapital">
+<html>
+<title>Example xsltproc</title>
+<body>
+ <xsl:apply-templates select="Vklad"/>
+</body>
+</html>
+</xsl:template>
+
+<xsl:template match="Vklad" >
+<xsl:value-of select="format-number(Kc, '# ###,00 Kè', 'czf')"/>
+</xsl:template>
+
+</xsl:stylesheet>