X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/9385eb3d10ebe5eb398c52040ec3dbfba9b0cdcf..c957a83bde4df2e2d3d1ed0963656856b48ef0a0:/gdtoa/FreeBSD/gdtoa-gethex.c?ds=inline diff --git a/gdtoa/FreeBSD/gdtoa-gethex.c b/gdtoa/FreeBSD/gdtoa-gethex.c index 0f9ae33..610f747 100644 --- a/gdtoa/FreeBSD/gdtoa-gethex.c +++ b/gdtoa/FreeBSD/gdtoa-gethex.c @@ -26,10 +26,8 @@ THIS SOFTWARE. ****************************************************************/ -/* Please send bug reports to - David M. Gay - dmg@acm.org - */ +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ #include "gdtoaimp.h" @@ -47,11 +45,11 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) { Bigint *b; CONST unsigned char *decpt, *s0, *s, *s1; - int esign, havedig, irv, k, n, nbits, up; + int esign, havedig, irv, k, n, nbits, up, zret; ULong L, lostbits, *x; Long e, e1; #ifdef USE_LOCALE - char decimalpoint = *localeconv()->decimal_point; + unsigned char decimalpoint = *localeconv()->decimal_point; #else #define decimalpoint '.' #endif @@ -65,22 +63,20 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) s0 += havedig; s = s0; decpt = 0; + zret = 0; + e = 0; if (!hexdig[*s]) { - if (*s == decimalpoint) { - decpt = ++s; - if (!hexdig[*s]) - goto ret0; - } - else { - ret0: - *sp = (char*)s; - return havedig ? STRTOG_Zero : STRTOG_NoNumber; - } + zret = 1; + if (*s != decimalpoint) + goto pcheck; + decpt = ++s; + if (!hexdig[*s]) + goto pcheck; while(*s == '0') s++; + if (hexdig[*s]) + zret = 0; havedig = 1; - if (!hexdig[*s]) - goto ret0; s0 = s; } while(hexdig[*s]) @@ -90,9 +86,9 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) while(hexdig[*s]) s++; } - e = 0; if (decpt) e = -(((Long)(s-decpt)) << 2); + pcheck: s1 = s; switch(*s) { case 'p': @@ -117,6 +113,8 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) e += e1; } *sp = (char*)s; + if (zret) + return havedig ? STRTOG_Zero : STRTOG_NoNumber; n = s1 - s0 - 1; for(k = 0; n > 7; n >>= 1) k++; @@ -164,6 +162,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) if (e > fpi->emax) { ovfl: Bfree(b); + *bp = 0; return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; } irv = STRTOG_Normal; @@ -173,7 +172,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) if (n >= nbits) { switch (fpi->rounding) { case FPI_Round_near: - if (n == nbits && n < 2 || any_on(b,n-1)) + if (n == nbits && (n < 2 || any_on(b,n-1))) goto one_bit; break; case FPI_Round_up: @@ -191,6 +190,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) } } Bfree(b); + *bp = 0; return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow; } k = n - 1; @@ -224,18 +224,18 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) k = b->wds; b = increment(b); x = b->x; - if (b->wds > k + if (irv == STRTOG_Denormal) { + if (nbits == fpi->nbits - 1 + && x[nbits >> kshift] & 1 << (nbits & kmask)) + irv = STRTOG_Normal; + } + else if (b->wds > k || (n = nbits & kmask) !=0 && hi0bits(x[k-1]) < 32-n) { rshift(b,1); if (++e > fpi->emax) goto ovfl; } - else if (irv == STRTOG_Denormal) { - k = nbits - 1; - if (x[k >> kshift] & 1 << (k & kmask)) - irv = STRTOG_Normal; - } irv |= STRTOG_Inexhi; } else