summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorderaadt <>1995-12-21 14:58:39 +0000
committerderaadt <>1995-12-21 14:58:39 +0000
commit0ec9503a81eeeb5a23e8654cc0e76fca89ab163b (patch)
tree5139e3085b6bfe3f9b0ebfb69133325f13456ead
parent0fd8d706013540776674a583d2456224f1631724 (diff)
downloadopenbsd-0ec9503a81eeeb5a23e8654cc0e76fca89ab163b.tar.gz
openbsd-0ec9503a81eeeb5a23e8654cc0e76fca89ab163b.tar.bz2
openbsd-0ec9503a81eeeb5a23e8654cc0e76fca89ab163b.zip
from netbsd; Rearrange to avoid sign problems with GCC.
-rw-r--r--src/lib/libc/stdlib/strtol.c65
-rw-r--r--src/lib/libc/stdlib/strtoq.c54
-rw-r--r--src/lib/libc/stdlib/strtoul.c39
-rw-r--r--src/lib/libc/stdlib/strtouq.c30
4 files changed, 115 insertions, 73 deletions
diff --git a/src/lib/libc/stdlib/strtol.c b/src/lib/libc/stdlib/strtol.c
index 6f374abd5f..021fdc0d2a 100644
--- a/src/lib/libc/stdlib/strtol.c
+++ b/src/lib/libc/stdlib/strtol.c
@@ -33,12 +33,12 @@
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/ 35/*static char *sccsid = "from: @(#)strtol.c 5.4 (Berkeley) 2/23/91";*/
36static char *rcsid = "$Id: strtol.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; 36static char *rcsid = "$Id: strtol.c,v 1.2 1995/12/21 14:58:36 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 37#endif /* LIBC_SCCS and not lint */
38 38
39#include <limits.h>
40#include <ctype.h> 39#include <ctype.h>
41#include <errno.h> 40#include <errno.h>
41#include <limits.h>
42#include <stdlib.h> 42#include <stdlib.h>
43 43
44 44
@@ -54,25 +54,28 @@ strtol(nptr, endptr, base)
54 char **endptr; 54 char **endptr;
55 register int base; 55 register int base;
56{ 56{
57 register const char *s = nptr; 57 register const char *s;
58 register unsigned long acc; 58 register long acc, cutoff;
59 register int c; 59 register int c;
60 register unsigned long cutoff; 60 register int neg, any, cutlim;
61 register int neg = 0, any, cutlim;
62 61
63 /* 62 /*
64 * Skip white space and pick up leading +/- sign if any. 63 * Skip white space and pick up leading +/- sign if any.
65 * If base is 0, allow 0x for hex and 0 for octal, else 64 * If base is 0, allow 0x for hex and 0 for octal, else
66 * assume decimal; if base is already 16, allow 0x. 65 * assume decimal; if base is already 16, allow 0x.
67 */ 66 */
67 s = nptr;
68 do { 68 do {
69 c = *s++; 69 c = *s++;
70 } while (isspace(c)); 70 } while (isspace(c));
71 if (c == '-') { 71 if (c == '-') {
72 neg = 1; 72 neg = 1;
73 c = *s++; 73 c = *s++;
74 } else if (c == '+') 74 } else {
75 c = *s++; 75 neg = 0;
76 if (c == '+')
77 c = *s++;
78 }
76 if ((base == 0 || base == 16) && 79 if ((base == 0 || base == 16) &&
77 c == '0' && (*s == 'x' || *s == 'X')) { 80 c == '0' && (*s == 'x' || *s == 'X')) {
78 c = s[1]; 81 c = s[1];
@@ -99,9 +102,16 @@ strtol(nptr, endptr, base)
99 * Set any if any `digits' consumed; make it negative to indicate 102 * Set any if any `digits' consumed; make it negative to indicate
100 * overflow. 103 * overflow.
101 */ 104 */
102 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 105 cutoff = neg ? LONG_MIN : LONG_MAX;
103 cutlim = cutoff % (unsigned long)base; 106 cutlim = cutoff % base;
104 cutoff /= (unsigned long)base; 107 cutoff /= base;
108 if (neg) {
109 if (cutlim > 0) {
110 cutlim -= base;
111 cutoff += 1;
112 }
113 cutlim = -cutlim;
114 }
105 for (acc = 0, any = 0;; c = *s++) { 115 for (acc = 0, any = 0;; c = *s++) {
106 if (isdigit(c)) 116 if (isdigit(c))
107 c -= '0'; 117 c -= '0';
@@ -111,19 +121,30 @@ strtol(nptr, endptr, base)
111 break; 121 break;
112 if (c >= base) 122 if (c >= base)
113 break; 123 break;
114 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 124 if (any < 0)
115 any = -1; 125 continue;
116 else { 126 if (neg) {
117 any = 1; 127 if (acc < cutoff || acc == cutoff && c > cutlim) {
118 acc *= base; 128 any = -1;
119 acc += c; 129 acc = LONG_MIN;
130 errno = ERANGE;
131 } else {
132 any = 1;
133 acc *= base;
134 acc -= c;
135 }
136 } else {
137 if (acc > cutoff || acc == cutoff && c > cutlim) {
138 any = -1;
139 acc = LONG_MAX;
140 errno = ERANGE;
141 } else {
142 any = 1;
143 acc *= base;
144 acc += c;
145 }
120 } 146 }
121 } 147 }
122 if (any < 0) {
123 acc = neg ? LONG_MIN : LONG_MAX;
124 errno = ERANGE;
125 } else if (neg)
126 acc = -acc;
127 if (endptr != 0) 148 if (endptr != 0)
128 *endptr = (char *) (any ? s - 1 : nptr); 149 *endptr = (char *) (any ? s - 1 : nptr);
129 return (acc); 150 return (acc);
diff --git a/src/lib/libc/stdlib/strtoq.c b/src/lib/libc/stdlib/strtoq.c
index fc559e9d7f..003c020d71 100644
--- a/src/lib/libc/stdlib/strtoq.c
+++ b/src/lib/libc/stdlib/strtoq.c
@@ -37,9 +37,9 @@ static char sccsid[] = "@(#)strtoq.c 5.1 (Berkeley) 6/26/92";
37 37
38#include <sys/types.h> 38#include <sys/types.h>
39 39
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h> 43#include <stdlib.h>
44 44
45/* 45/*
@@ -55,9 +55,8 @@ strtoq(nptr, endptr, base)
55 register int base; 55 register int base;
56{ 56{
57 register const char *s; 57 register const char *s;
58 register u_quad_t acc; 58 register quad_t acc, cutoff;
59 register int c; 59 register int c;
60 register u_quad_t qbase, cutoff;
61 register int neg, any, cutlim; 60 register int neg, any, cutlim;
62 61
63 /* 62 /*
@@ -104,10 +103,16 @@ strtoq(nptr, endptr, base)
104 * Set any if any `digits' consumed; make it negative to indicate 103 * Set any if any `digits' consumed; make it negative to indicate
105 * overflow. 104 * overflow.
106 */ 105 */
107 qbase = (unsigned)base; 106 cutoff = neg ? QUAD_MIN : QUAD_MAX;
108 cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; 107 cutlim = cutoff % base;
109 cutlim = cutoff % qbase; 108 cutoff /= base;
110 cutoff /= qbase; 109 if (neg) {
110 if (cutlim > 0) {
111 cutlim -= base;
112 cutoff += 1;
113 }
114 cutlim = -cutlim;
115 }
111 for (acc = 0, any = 0;; c = *s++) { 116 for (acc = 0, any = 0;; c = *s++) {
112 if (isdigit(c)) 117 if (isdigit(c))
113 c -= '0'; 118 c -= '0';
@@ -117,19 +122,30 @@ strtoq(nptr, endptr, base)
117 break; 122 break;
118 if (c >= base) 123 if (c >= base)
119 break; 124 break;
120 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 125 if (any < 0)
121 any = -1; 126 continue;
122 else { 127 if (neg) {
123 any = 1; 128 if (acc < cutoff || acc == cutoff && c > cutlim) {
124 acc *= qbase; 129 any = -1;
125 acc += c; 130 acc = QUAD_MIN;
131 errno = ERANGE;
132 } else {
133 any = 1;
134 acc *= base;
135 acc -= c;
136 }
137 } else {
138 if (acc > cutoff || acc == cutoff && c > cutlim) {
139 any = -1;
140 acc = QUAD_MAX;
141 errno = ERANGE;
142 } else {
143 any = 1;
144 acc *= base;
145 acc += c;
146 }
126 } 147 }
127 } 148 }
128 if (any < 0) {
129 acc = neg ? QUAD_MIN : QUAD_MAX;
130 errno = ERANGE;
131 } else if (neg)
132 acc = -acc;
133 if (endptr != 0) 149 if (endptr != 0)
134 *endptr = (char *) (any ? s - 1 : nptr); 150 *endptr = (char *) (any ? s - 1 : nptr);
135 return (acc); 151 return (acc);
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
index 00f7210fa1..1522bec584 100644
--- a/src/lib/libc/stdlib/strtoul.c
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -33,12 +33,12 @@
33 33
34#if defined(LIBC_SCCS) && !defined(lint) 34#if defined(LIBC_SCCS) && !defined(lint)
35/*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/ 35/*static char *sccsid = "from: @(#)strtoul.c 5.3 (Berkeley) 2/23/91";*/
36static char *rcsid = "$Id: strtoul.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $"; 36static char *rcsid = "$Id: strtoul.c,v 1.2 1995/12/21 14:58:38 deraadt Exp $";
37#endif /* LIBC_SCCS and not lint */ 37#endif /* LIBC_SCCS and not lint */
38 38
39#include <limits.h>
40#include <ctype.h> 39#include <ctype.h>
41#include <errno.h> 40#include <errno.h>
41#include <limits.h>
42#include <stdlib.h> 42#include <stdlib.h>
43 43
44/* 44/*
@@ -53,23 +53,26 @@ strtoul(nptr, endptr, base)
53 char **endptr; 53 char **endptr;
54 register int base; 54 register int base;
55{ 55{
56 register const char *s = nptr; 56 register const char *s;
57 register unsigned long acc; 57 register unsigned long acc, cutoff;
58 register int c; 58 register int c;
59 register unsigned long cutoff; 59 register int neg, any, cutlim;
60 register int neg = 0, any, cutlim;
61 60
62 /* 61 /*
63 * See strtol for comments as to the logic used. 62 * See strtol for comments as to the logic used.
64 */ 63 */
64 s = nptr;
65 do { 65 do {
66 c = *s++; 66 c = *s++;
67 } while (isspace(c)); 67 } while (isspace(c));
68 if (c == '-') { 68 if (c == '-') {
69 neg = 1; 69 neg = 1;
70 c = *s++; 70 c = *s++;
71 } else if (c == '+') 71 } else {
72 c = *s++; 72 neg = 0;
73 if (c == '+')
74 c = *s++;
75 }
73 if ((base == 0 || base == 16) && 76 if ((base == 0 || base == 16) &&
74 c == '0' && (*s == 'x' || *s == 'X')) { 77 c == '0' && (*s == 'x' || *s == 'X')) {
75 c = s[1]; 78 c = s[1];
@@ -78,8 +81,9 @@ strtoul(nptr, endptr, base)
78 } 81 }
79 if (base == 0) 82 if (base == 0)
80 base = c == '0' ? 8 : 10; 83 base = c == '0' ? 8 : 10;
81 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 84
82 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 85 cutoff = ULONG_MAX / (unsigned long)base;
86 cutlim = ULONG_MAX % (unsigned long)base;
83 for (acc = 0, any = 0;; c = *s++) { 87 for (acc = 0, any = 0;; c = *s++) {
84 if (isdigit(c)) 88 if (isdigit(c))
85 c -= '0'; 89 c -= '0';
@@ -89,18 +93,19 @@ strtoul(nptr, endptr, base)
89 break; 93 break;
90 if (c >= base) 94 if (c >= base)
91 break; 95 break;
92 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 96 if (any < 0)
97 continue;
98 if (acc > cutoff || acc == cutoff && c > cutlim) {
93 any = -1; 99 any = -1;
94 else { 100 acc = ULONG_MAX;
101 errno = ERANGE;
102 } else {
95 any = 1; 103 any = 1;
96 acc *= base; 104 acc *= (unsigned long)base;
97 acc += c; 105 acc += c;
98 } 106 }
99 } 107 }
100 if (any < 0) { 108 if (neg && any > 0)
101 acc = ULONG_MAX;
102 errno = ERANGE;
103 } else if (neg)
104 acc = -acc; 109 acc = -acc;
105 if (endptr != 0) 110 if (endptr != 0)
106 *endptr = (char *) (any ? s - 1 : nptr); 111 *endptr = (char *) (any ? s - 1 : nptr);
diff --git a/src/lib/libc/stdlib/strtouq.c b/src/lib/libc/stdlib/strtouq.c
index cc647d8d28..3ab2c232dd 100644
--- a/src/lib/libc/stdlib/strtouq.c
+++ b/src/lib/libc/stdlib/strtouq.c
@@ -37,9 +37,9 @@ static char sccsid[] = "@(#)strtouq.c 5.1 (Berkeley) 6/26/92";
37 37
38#include <sys/types.h> 38#include <sys/types.h>
39 39
40#include <limits.h>
41#include <errno.h>
42#include <ctype.h> 40#include <ctype.h>
41#include <errno.h>
42#include <limits.h>
43#include <stdlib.h> 43#include <stdlib.h>
44 44
45/* 45/*
@@ -54,10 +54,9 @@ strtouq(nptr, endptr, base)
54 char **endptr; 54 char **endptr;
55 register int base; 55 register int base;
56{ 56{
57 register const char *s = nptr; 57 register const char *s;
58 register u_quad_t acc; 58 register u_quad_t acc, cutoff;
59 register int c; 59 register int c;
60 register u_quad_t qbase, cutoff;
61 register int neg, any, cutlim; 60 register int neg, any, cutlim;
62 61
63 /* 62 /*
@@ -83,9 +82,9 @@ strtouq(nptr, endptr, base)
83 } 82 }
84 if (base == 0) 83 if (base == 0)
85 base = c == '0' ? 8 : 10; 84 base = c == '0' ? 8 : 10;
86 qbase = (unsigned)base; 85
87 cutoff = (u_quad_t)UQUAD_MAX / qbase; 86 cutoff = UQUAD_MAX / (u_quad_t)base;
88 cutlim = (u_quad_t)UQUAD_MAX % qbase; 87 cutlim = UQUAD_MAX % (u_quad_t)base;
89 for (acc = 0, any = 0;; c = *s++) { 88 for (acc = 0, any = 0;; c = *s++) {
90 if (isdigit(c)) 89 if (isdigit(c))
91 c -= '0'; 90 c -= '0';
@@ -95,18 +94,19 @@ strtouq(nptr, endptr, base)
95 break; 94 break;
96 if (c >= base) 95 if (c >= base)
97 break; 96 break;
98 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 97 if (any < 0)
98 continue;
99 if (acc > cutoff || acc == cutoff && c > cutlim) {
99 any = -1; 100 any = -1;
100 else { 101 acc = UQUAD_MAX;
102 errno = ERANGE;
103 } else {
101 any = 1; 104 any = 1;
102 acc *= qbase; 105 acc *= (u_quad_t)base;
103 acc += c; 106 acc += c;
104 } 107 }
105 } 108 }
106 if (any < 0) { 109 if (neg && any > 0)
107 acc = UQUAD_MAX;
108 errno = ERANGE;
109 } else if (neg)
110 acc = -acc; 110 acc = -acc;
111 if (endptr != 0) 111 if (endptr != 0)
112 *endptr = (char *) (any ? s - 1 : nptr); 112 *endptr = (char *) (any ? s - 1 : nptr);