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;
}