[PATCH] gethex doesn't cope with multibyte decimalpoints
Corinna Vinschen
vinschen@redhat.com
Fri Feb 6 13:56:00 GMT 2009
Hi,
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;
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
More information about the Newlib
mailing list