gdtoa-hexnan.c.patch   [plain text]


--- gdtoa-hexnan.c.orig	2010-01-29 16:36:11.000000000 -0800
+++ gdtoa-hexnan.c	2010-01-29 16:40:59.000000000 -0800
@@ -30,7 +30,9 @@ THIS SOFTWARE.
  * with " at " changed at "@" and " dot " changed to ".").	*/
 
 #include "gdtoaimp.h"
+#include <fpmath.h>
 
+#ifndef __APPLE__
  static void
 #ifdef KR_headers
 L_shift(x, x1, i) ULong *x; ULong *x1; int i;
@@ -48,6 +50,7 @@ L_shift(ULong *x, ULong *x1, int i)
 		x[1] >>= i;
 		} while(++x < x1);
 	}
+#endif /* !__APPLE__ */
 
  int
 #ifdef KR_headers
@@ -57,10 +60,21 @@ hexnan(sp, fpi, x0)
 hexnan( CONST char **sp, FPI *fpi, ULong *x0)
 #endif
 {
+#ifdef __APPLE__
+	int nbits, len;
+	char *cp;
+#else /* !__APPLE__ */
 	ULong c, h, *x, *x1, *xe;
+#endif /* __APPLE__ */
 	CONST char *s;
+#ifndef __APPLE__
 	int havedig, hd0, i, nbits;
+#endif /* !__APPLE__ */
 
+#ifdef __APPLE__
+	if (sp == NULL || *sp == NULL || **sp != '(')
+		return STRTOG_NaN;
+#else /* !__APPLE__ */
 	if (!hexdig['0'])
 		hexdig_init_D2A();
 	nbits = fpi->nbits;
@@ -70,7 +84,17 @@ hexnan( CONST char **sp, FPI *fpi, ULong
 	*--x = 0;
 	x1 = xe = x;
 	havedig = hd0 = i = 0;
+#endif /* __APPLE__ */
 	s = *sp;
+#ifdef __APPLE__
+	if ((cp = strchr(s + 1, ')')) == NULL) {
+		return STRTOG_NaN;
+		}
+	else {
+		len = cp - (s + 1);
+		cp = alloca(len + 1);
+		if (!cp)
+#else /* !__APPLE__ */
 	/* allow optional initial 0x or 0X */
 	while((c = *(CONST unsigned char*)(s+1)) && c <= ' ')
 		++s;
@@ -111,7 +135,12 @@ hexnan( CONST char **sp, FPI *fpi, ULong
 					}
 				} while((c = *++s));
 #endif
+#endif /* __APPLE__ */
 			return STRTOG_NaN;
+#ifdef __APPLE__
+		strlcpy(cp, s + 1, len + 1);
+		*sp += len + 2;
+#else /* !__APPLE__ */
 			}
 		havedig++;
 		if (++i > 8) {
@@ -121,7 +150,17 @@ hexnan( CONST char **sp, FPI *fpi, ULong
 			*--x = 0;
 			}
 		*x = (*x << 4) | (h & 0xf);
+#endif /* __APPLE__ */
 		}
+#ifdef __APPLE__
+	nbits = fpi->nbits;
+	/* a hack */
+	if (nbits == 52) {	/* double */
+		union IEEEd2bits u;
+		u.d = nan(cp);
+		x0[1] = u.bits.manh;
+		x0[0] = u.bits.manl;
+#else /* !__APPLE__ */
 	if (!havedig)
 		return STRTOG_NaN;
 	if (x < x1 && i < 8)
@@ -132,12 +171,36 @@ hexnan( CONST char **sp, FPI *fpi, ULong
 			while(x <= xe);
 		do *x1++ = 0;
 			while(x1 <= xe);
+#endif /* __APPLE__ */
 		}
+#ifdef __APPLE__
+	else if (nbits < 52) {	/* float */
+		union IEEEf2bits u;
+		u.f = nanf(cp);
+		x0[0] = u.bits.man;
+#else /* !__APPLE__ */
 	else {
 		/* truncate high-order word if necessary */
 		if ( (i = nbits & (ULbits-1)) !=0)
 			*xe &= ((ULong)0xffffffff) >> (ULbits - i);
+#endif /* __APPLE__ */
 		}
+#ifdef __APPLE__
+	else {			/* long double */
+		union IEEEl2bits u;
+		u.e = nanl(cp);
+#if defined(__ppc__) || defined(__ppc64__)
+		x0[3] = (ULong)(u.bits.manh >> 44);
+		x0[2] = (ULong)(u.bits.manh >> 12);
+		x0[1] = ((ULong)u.bits.manh & 0xfff) << 20 | (ULong)(u.bits.manl >> 32);
+		x0[0] = (ULong)u.bits.manl;
+#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__)
+		x0[1] = (ULong)u.bits.manh;
+		x0[0] = (ULong)u.bits.manl;
+#else
+#error unsupported architecture
+#endif
+#else /* !__APPLE__ */
 	for(x1 = xe;; --x1) {
 		if (*x1 != 0)
 			break;
@@ -145,6 +208,7 @@ hexnan( CONST char **sp, FPI *fpi, ULong
 			*x1 = 1;
 			break;
 			}
+#endif /* __APPLE__ */
 		}
 	return STRTOG_NaNbits;
 	}