gdtoa-strtodg.c.patch   [plain text]


--- gdtoa-strtodg.c.orig	2007-10-04 15:00:21.000000000 -0700
+++ gdtoa-strtodg.c	2007-10-04 17:49:06.000000000 -0700
@@ -29,13 +29,29 @@
 /* Please send bug reports to David M. Gay (dmg at acm dot org,
  * with " at " changed at "@" and " dot " changed to ".").	*/
 
+#include "xlocale_private.h"
+
 #include "gdtoaimp.h"
 
 #ifdef USE_LOCALE
 #include "locale.h"
 #endif
 
- static CONST int
+#define fivesbits __fivesbits_D2A
+#define all_on __all_on_D2A
+#define set_ones __set_ones_D2A
+#define rvOK __rvOK_D2A
+#define mantbits __mantbits_D2A
+
+#ifdef BUILDING_VARIANT
+extern CONST int fivesbits[];
+int all_on(Bigint *b, int n);
+Bigint *set_ones(Bigint *b, int n);
+int rvOK(double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv);
+int mantbits(double d);
+#else /* !BUILDING_VARIANT */
+
+ __private_extern__ CONST int
 fivesbits[] = {	 0,  3,  5,  7, 10, 12, 14, 17, 19, 21,
 		24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
 		47, 49, 52
@@ -122,7 +138,7 @@
 	return STRTOG_Inexlo;
 	}
 
- static int
+ __private_extern__ int
 #ifdef KR_headers
 all_on(b, n) Bigint *b; int n;
 #else
@@ -169,7 +185,7 @@
 	return b;
 	}
 
- static int
+ __private_extern__ int
 rvOK
 #ifdef KR_headers
  (d, fpi, exp, bits, exact, rd, irv)
@@ -290,7 +306,7 @@
 	return rv;
 	}
 
- static int
+ __private_extern__ int
 #ifdef KR_headers
 mantbits(d) double d;
 #else
@@ -313,13 +329,15 @@
 	return P - 32 - lo0bits(&L);
 	}
 
+#endif /* BUILDING_VARIANT */
+
  int
 strtodg
 #ifdef KR_headers
-	(s00, se, fpi, exp, bits)
-	CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits;
+	(s00, se, fpi, exp, bits, loc)
+	CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; locale_t loc;
 #else
-	(CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits)
+	(CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits, locale_t loc)
 #endif
 {
 	int abe, abits, asub;
@@ -332,6 +350,10 @@
 	Long L;
 	ULong y, z;
 	Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
+#ifdef USE_LOCALE
+	char *decimal_point;
+	int decimal_point_len;
+#endif /* USE_LOCALE */
 
 	irv = STRTOG_Zero;
 	denorm = sign = nz0 = nz = 0;
@@ -367,7 +389,7 @@
 		switch(s[1]) {
 		  case 'x':
 		  case 'X':
-			irv = gethex(&s, fpi, exp, &rvb, sign);
+			irv = gethex(&s, fpi, exp, &rvb, sign, loc);
 			if (irv == STRTOG_NoNumber) {
 				s = s00;
 				sign = 0;
@@ -389,14 +411,22 @@
 		else if (nd < 16)
 			z = 10*z + c - '0';
 	nd0 = nd;
+	NORMALIZE_LOCALE(loc);
 #ifdef USE_LOCALE
-	if (c == *localeconv()->decimal_point)
+	decimal_point = localeconv_l(loc)->decimal_point;
+	decimal_point_len = strlen(decimal_point);
+	if (strncmp(s, decimal_point, decimal_point_len) == 0)
 #else
 	if (c == '.')
 #endif
 		{
 		decpt = 1;
+#ifdef USE_LOCALE
+		s += decimal_point_len;
+		c = *s;
+#else
 		c = *++s;
+#endif
 		if (!nd) {
 			for(; c == '0'; c = *++s)
 				nz++;
@@ -668,6 +698,9 @@
 					rvb->x[0] = 0;
 					*exp = emin;
 					irv = STRTOG_Underflow | STRTOG_Inexlo;
+#ifndef NO_ERRNO
+					errno = ERANGE;
+#endif
 					goto ret;
 					}
 				rvb->x[0] = rvb->wds = rvbits = 1;
@@ -684,7 +717,11 @@
 
 	/* Put digits into bd: true value = bd * 10^e */
 
-	bd0 = s2b(s0, nd0, nd, y);
+#ifdef USE_LOCALE
+	bd0 = s2b(s0, nd0, nd, y, decimal_point_len);
+#else
+	bd0 = s2b(s0, nd0, nd, y, 1);
+#endif
 
 	for(;;) {
 		bd = Balloc(bd0->k);
@@ -824,7 +861,7 @@
 				rvb = increment(rvb);
 				if ( (j = rvbits & kmask) !=0)
 					j = ULbits - j;
-				if (hi0bits(rvb->x[(rvb->wds - 1) >> kshift])
+				if (hi0bits(rvb->x[rvb->wds - 1])
 						!= j)
 					rvbits++;
 				irv = STRTOG_Normal | STRTOG_Inexhi;
@@ -1008,5 +1045,9 @@
 		copybits(bits, nbits, rvb);
 		Bfree(rvb);
 		}
+#if !defined(NO_ERRNO) && __DARWIN_UNIX03
+	if (irv & STRTOG_Underflow)
+		errno = ERANGE;
+#endif
 	return irv;
 	}