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]

[PATCH] gethex doesn't cope with multibyte decimalpoints


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]