summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/strtoul.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib/strtoul.c')
-rw-r--r--src/lib/libc/stdlib/strtoul.c60
1 files changed, 27 insertions, 33 deletions
diff --git a/src/lib/libc/stdlib/strtoul.c b/src/lib/libc/stdlib/strtoul.c
index 00f7210fa1..d7dddab778 100644
--- a/src/lib/libc/stdlib/strtoul.c
+++ b/src/lib/libc/stdlib/strtoul.c
@@ -1,3 +1,4 @@
1/* $OpenBSD: strtoul.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */
1/* 2/*
2 * Copyright (c) 1990 Regents of the University of California. 3 * Copyright (c) 1990 Regents of the University of California.
3 * All rights reserved. 4 * All rights reserved.
@@ -10,11 +11,7 @@
10 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software 14 * 3. Neither the name of the University nor the names of its contributors
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software 15 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission. 16 * without specific prior written permission.
20 * 17 *
@@ -31,14 +28,9 @@
31 * SUCH DAMAGE. 28 * SUCH DAMAGE.
32 */ 29 */
33 30
34#if defined(LIBC_SCCS) && !defined(lint)
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 $";
37#endif /* LIBC_SCCS and not lint */
38
39#include <limits.h>
40#include <ctype.h> 31#include <ctype.h>
41#include <errno.h> 32#include <errno.h>
33#include <limits.h>
42#include <stdlib.h> 34#include <stdlib.h>
43 35
44/* 36/*
@@ -48,28 +40,28 @@ static char *rcsid = "$Id: strtoul.c,v 1.1.1.1 1995/10/18 08:42:20 deraadt Exp $
48 * alphabets and digits are each contiguous. 40 * alphabets and digits are each contiguous.
49 */ 41 */
50unsigned long 42unsigned long
51strtoul(nptr, endptr, base) 43strtoul(const char *nptr, char **endptr, int base)
52 const char *nptr;
53 char **endptr;
54 register int base;
55{ 44{
56 register const char *s = nptr; 45 const char *s;
57 register unsigned long acc; 46 unsigned long acc, cutoff;
58 register int c; 47 int c;
59 register unsigned long cutoff; 48 int neg, any, cutlim;
60 register int neg = 0, any, cutlim;
61 49
62 /* 50 /*
63 * See strtol for comments as to the logic used. 51 * See strtol for comments as to the logic used.
64 */ 52 */
53 s = nptr;
65 do { 54 do {
66 c = *s++; 55 c = (unsigned char) *s++;
67 } while (isspace(c)); 56 } while (isspace(c));
68 if (c == '-') { 57 if (c == '-') {
69 neg = 1; 58 neg = 1;
70 c = *s++; 59 c = *s++;
71 } else if (c == '+') 60 } else {
72 c = *s++; 61 neg = 0;
62 if (c == '+')
63 c = *s++;
64 }
73 if ((base == 0 || base == 16) && 65 if ((base == 0 || base == 16) &&
74 c == '0' && (*s == 'x' || *s == 'X')) { 66 c == '0' && (*s == 'x' || *s == 'X')) {
75 c = s[1]; 67 c = s[1];
@@ -78,9 +70,10 @@ strtoul(nptr, endptr, base)
78 } 70 }
79 if (base == 0) 71 if (base == 0)
80 base = c == '0' ? 8 : 10; 72 base = c == '0' ? 8 : 10;
81 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 73
82 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 74 cutoff = ULONG_MAX / (unsigned long)base;
83 for (acc = 0, any = 0;; c = *s++) { 75 cutlim = ULONG_MAX % (unsigned long)base;
76 for (acc = 0, any = 0;; c = (unsigned char) *s++) {
84 if (isdigit(c)) 77 if (isdigit(c))
85 c -= '0'; 78 c -= '0';
86 else if (isalpha(c)) 79 else if (isalpha(c))
@@ -89,18 +82,19 @@ strtoul(nptr, endptr, base)
89 break; 82 break;
90 if (c >= base) 83 if (c >= base)
91 break; 84 break;
92 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 85 if (any < 0)
86 continue;
87 if (acc > cutoff || acc == cutoff && c > cutlim) {
93 any = -1; 88 any = -1;
94 else { 89 acc = ULONG_MAX;
90 errno = ERANGE;
91 } else {
95 any = 1; 92 any = 1;
96 acc *= base; 93 acc *= (unsigned long)base;
97 acc += c; 94 acc += c;
98 } 95 }
99 } 96 }
100 if (any < 0) { 97 if (neg && any > 0)
101 acc = ULONG_MAX;
102 errno = ERANGE;
103 } else if (neg)
104 acc = -acc; 98 acc = -acc;
105 if (endptr != 0) 99 if (endptr != 0)
106 *endptr = (char *) (any ? s - 1 : nptr); 100 *endptr = (char *) (any ? s - 1 : nptr);