Rearrange to avoid sign problems with GCC.

This commit is contained in:
mycroft 1995-12-21 03:56:06 +00:00
parent 4fe3e795ba
commit 9b62656910
4 changed files with 84 additions and 50 deletions

View File

@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/ /*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/
static char *rcsid = "$Id: strtol.c,v 1.5 1995/12/20 23:14:48 mycroft Exp $"; static char *rcsid = "$Id: strtol.c,v 1.6 1995/12/21 03:56:06 mycroft Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <ctype.h> #include <ctype.h>
@ -55,9 +55,8 @@ strtol(nptr, endptr, base)
register int base; register int base;
{ {
register const char *s; register const char *s;
register unsigned long acc; register long acc, cutoff;
register int c; register int c;
register unsigned long cutoff;
register int neg, any, cutlim; register int neg, any, cutlim;
/* /*
@ -103,9 +102,16 @@ strtol(nptr, endptr, base)
* Set any if any `digits' consumed; make it negative to indicate * Set any if any `digits' consumed; make it negative to indicate
* overflow. * overflow.
*/ */
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; cutoff = neg ? LONG_MIN : LONG_MAX;
cutlim = cutoff % (unsigned long)base; cutlim = cutoff % base;
cutoff /= (unsigned long)base; cutoff /= base;
if (neg) {
if (cutlim > 0) {
cutlim -= base;
cutoff += 1;
}
cutlim = -cutlim;
}
for (acc = 0, any = 0;; c = *s++) { for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c)) if (isdigit(c))
c -= '0'; c -= '0';
@ -115,19 +121,30 @@ strtol(nptr, endptr, base)
break; break;
if (c >= base) if (c >= base)
break; break;
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) if (any < 0)
any = -1; continue;
else { if (neg) {
any = 1; if (acc < cutoff || acc == cutoff && c > cutlim) {
acc *= (unsigned long)base; any = -1;
acc += c; acc = LONG_MIN;
errno = ERANGE;
} else {
any = 1;
acc *= base;
acc -= c;
}
} else {
if (acc > cutoff || acc == cutoff && c > cutlim) {
any = -1;
acc = LONG_MAX;
errno = ERANGE;
} else {
any = 1;
acc *= base;
acc += c;
}
} }
} }
if (any < 0) {
acc = neg ? LONG_MIN : LONG_MAX;
errno = ERANGE;
} else if (neg)
acc = -acc;
if (endptr != 0) if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr); *endptr = (char *) (any ? s - 1 : nptr);
return (acc); return (acc);

View File

@ -55,9 +55,8 @@ strtoq(nptr, endptr, base)
register int base; register int base;
{ {
register const char *s; register const char *s;
register u_quad_t acc; register quad_t acc, cutoff;
register int c; register int c;
register u_quad_t cutoff;
register int neg, any, cutlim; register int neg, any, cutlim;
/* /*
@ -104,9 +103,16 @@ strtoq(nptr, endptr, base)
* Set any if any `digits' consumed; make it negative to indicate * Set any if any `digits' consumed; make it negative to indicate
* overflow. * overflow.
*/ */
cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; cutoff = neg ? QUAD_MIN : QUAD_MAX;
cutlim = cutoff % (u_quad_t)base; cutlim = cutoff % base;
cutoff /= (u_quad_t)base; cutoff /= base;
if (neg) {
if (cutlim > 0) {
cutlim -= base;
cutoff += 1;
}
cutlim = -cutlim;
}
for (acc = 0, any = 0;; c = *s++) { for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c)) if (isdigit(c))
c -= '0'; c -= '0';
@ -116,19 +122,30 @@ strtoq(nptr, endptr, base)
break; break;
if (c >= base) if (c >= base)
break; break;
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) if (any < 0)
any = -1; continue;
else { if (neg) {
any = 1; if (acc < cutoff || acc == cutoff && c > cutlim) {
acc *= (u_quad_t)base; any = -1;
acc += c; acc = QUAD_MIN;
errno = ERANGE;
} else {
any = 1;
acc *= base;
acc -= c;
}
} else {
if (acc > cutoff || acc == cutoff && c > cutlim) {
any = -1;
acc = QUAD_MAX;
errno = ERANGE;
} else {
any = 1;
acc *= base;
acc += c;
}
} }
} }
if (any < 0) {
acc = neg ? QUAD_MIN : QUAD_MAX;
errno = ERANGE;
} else if (neg)
acc = -acc;
if (endptr != 0) if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr); *endptr = (char *) (any ? s - 1 : nptr);
return (acc); return (acc);

View File

@ -33,7 +33,7 @@
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/ /*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/
static char *rcsid = "$Id: strtoul.c,v 1.5 1995/12/20 23:14:50 mycroft Exp $"; static char *rcsid = "$Id: strtoul.c,v 1.6 1995/12/21 03:56:09 mycroft Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <ctype.h> #include <ctype.h>
@ -54,9 +54,8 @@ strtoul(nptr, endptr, base)
register int base; register int base;
{ {
register const char *s; register const char *s;
register unsigned long acc; register unsigned long acc, cutoff;
register int c; register int c;
register unsigned long cutoff;
register int neg, any, cutlim; register int neg, any, cutlim;
/* /*
@ -94,18 +93,19 @@ strtoul(nptr, endptr, base)
break; break;
if (c >= base) if (c >= base)
break; break;
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) if (any < 0)
continue;
if (acc > cutoff || acc == cutoff && c > cutlim) {
any = -1; any = -1;
else { acc = ULONG_MAX;
errno = ERANGE;
} else {
any = 1; any = 1;
acc *= (unsigned long)base; acc *= (unsigned long)base;
acc += c; acc += c;
} }
} }
if (any < 0) { if (neg && any > 0)
acc = ULONG_MAX;
errno = ERANGE;
} else if (neg)
acc = -acc; acc = -acc;
if (endptr != 0) if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr); *endptr = (char *) (any ? s - 1 : nptr);

View File

@ -55,9 +55,8 @@ strtouq(nptr, endptr, base)
register int base; register int base;
{ {
register const char *s; register const char *s;
register u_quad_t acc; register u_quad_t acc, cutoff;
register int c; register int c;
register u_quad_t cutoff;
register int neg, any, cutlim; register int neg, any, cutlim;
/* /*
@ -95,18 +94,19 @@ strtouq(nptr, endptr, base)
break; break;
if (c >= base) if (c >= base)
break; break;
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) if (any < 0)
continue;
if (acc > cutoff || acc == cutoff && c > cutlim) {
any = -1; any = -1;
else { acc = UQUAD_MAX;
errno = ERANGE;
} else {
any = 1; any = 1;
acc *= (u_quad_t)base; acc *= (u_quad_t)base;
acc += c; acc += c;
} }
} }
if (any < 0) { if (neg && any > 0)
acc = UQUAD_MAX;
errno = ERANGE;
} else if (neg)
acc = -acc; acc = -acc;
if (endptr != 0) if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr); *endptr = (char *) (any ? s - 1 : nptr);