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]

RE: [PATCH] gethex doesn't cope with multibyte decimalpoints


A question related to the decimal point search, new method:
+	while (s0 < s1) {
+		if (!strncmp ((char *) s0, (char *) decimalpoint,
dplen)) {
+			s0 += dplen;
 
This appears to assume that the decimal is either a single normal or
multi-byte character--as opposed to the original code which assumed that
it was a single byte (plain char).  (It also assumes that if it is mb,
that
the encoding allows the dplen skip.  I'm not entirely up to speed on
mb characters, but I think that this is safe for standard encodings
like UTF-n.)  That is, it looks like the patch has taken a step to
allow one multi-byte character, but not for strings (of either type) as
the problem statement called for.
 
So perhaps should it be the following instead?
+	while (s0 < s1) {
+		if (!strncmp ((char *) s0, (char *) decimalpoint,
dplen)) {
+			s0++;
(That is, step through 1 byte at a time instead of by dlen at a time?)
 
Craig

-----Original Message-----
From: newlib-owner@sourceware.org [mailto:newlib-owner@sourceware.org]
On Behalf Of Corinna Vinschen
Sent: Friday, February 06, 2009 8:56 AM
To: newlib@sourceware.org
Subject: [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]