This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi,This isn't going to work unfortunately. The decimal point location (decpt) is calculated by adding 1 to the string pointer s which in the multibyte case is wrong. This value is used to figure out the exponent to adjust the result by (see the calculation of e). Changing to reading left to right makes the calculation of the result wrong if the number of hex digits is larger than 8. For example, if you have 10 hex digits, you want the bottom 8 to form one long integer and the top 2 digits by themselves not the other way around.
AFAICS, there's a bug in gethex(). The function assumes that the decimalpoint is a single char. This is incorrect for multibyte charsets. Actually the decimalpoint var should be a multibyte char and comparisons in the code should always compare the entire string, isn't it? I attached a patch. Note especially the change of the while loop which now has to step forward instead of backward since backward stepping screws up multibyte comparisons.
Corinna
* libc/stdlib/gdtoa-gethex.c (gethex): Allow multibyte decimal point. Fix compiler warnings due to different signedness of pointer types.
Index: libc/stdlib/gdtoa-gethex.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdlib/gdtoa-gethex.c,v
retrieving revision 1.1
diff -u -p -r1.1 gdtoa-gethex.c
--- libc/stdlib/gdtoa-gethex.c 22 Jun 2006 17:59:52 -0000 1.1
+++ libc/stdlib/gdtoa-gethex.c 6 Feb 2009 13:53:12 -0000
@@ -152,10 +152,12 @@ _DEFUN(gethex, (ptr, sp, fpi, exp, bp, s
__ULong L, lostbits, *x;
Long e, e1;
#ifdef USE_LOCALE
- unsigned char decimalpoint = *localeconv()->decimal_point;
+ unsigned char *decimalpoint = (unsigned char *)
+ localeconv()->decimal_point;
#else
-#define decimalpoint '.'
+#define decimalpoint "."
#endif
+ size_t dplen = strlen ((char *) decimalpoint);
if (!hexdig['0'])
hexdig_init();
@@ -170,7 +172,7 @@ _DEFUN(gethex, (ptr, sp, fpi, exp, bp, s
e = 0;
if (!hexdig[*s]) {
zret = 1;
- if (*s != decimalpoint)
+ if (!strncmp ((char *) s, (char *) decimalpoint, dplen))
goto pcheck;
decpt = ++s;
if (!hexdig[*s])
@@ -184,7 +186,7 @@ _DEFUN(gethex, (ptr, sp, fpi, exp, bp, s
}
while(hexdig[*s])
s++;
- if (*s == decimalpoint && !decpt) {
+ if (!strncmp ((char *) s, (char *) decimalpoint, dplen) && !decpt) {
decpt = ++s;
while(hexdig[*s])
s++;
@@ -225,15 +227,17 @@ _DEFUN(gethex, (ptr, sp, fpi, exp, bp, s
x = b->_x;
n = 0;
L = 0;
- while(s1 > s0) {
- if (*--s1 == decimalpoint)
+ while (s0 < s1) {
+ if (!strncmp ((char *) s0, (char *) decimalpoint, dplen)) {
+ s0 += dplen;
continue;
+ }
if (n == 32) {
*x++ = L;
L = 0;
n = 0;
}
- L |= (hexdig[*s1] & 0x0f) << n;
+ L = (L << 4) | (hexdig[*s0++] & 0x0f);
n += 4;
}
*x++ = L;
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |