|
|
1.1 root 1: /* Copyright AT&T Bell Laboratories, 1993 */
2: /* Convert string to unsigned long.
3: ** Assumes ASCII properties - contiguity of 0-9, A-Z, a-z,
4: ** digits less than letters, lower case maskable to upper.
5: */
6: #include <ctype.h>
7: #include <errno.h>
8:
9: #define DIGIT(x) ((x)<='9'? (x)-'0': TOUPPER(x)+10-'A')
10: #define TOUPPER(x) ((x) & ~('a'-'A'))
11: #define MBASE ('z' - 'a' + 1 + 10)
12: #define T_ULONG_MAX ~(unsigned long)0
13:
14: unsigned long
15: strtoul(str, nptr, base)
16: char *str;
17: char **nptr;
18: int base;
19: {
20: register unsigned long val;
21: register int c;
22: int xx;
23: int overflow = 0, neg = 0;
24: unsigned long multmax;
25:
26: if (nptr)
27: *nptr = str; /* in case no number is formed */
28: c = *str;
29: while (isspace(c))
30: c = *++str;
31: switch(c) {
32: case '-':
33: neg = 1;
34: case'+':
35: c = *++str;
36: }
37: if (base == 0)
38: if (c != '0')
39: base = 10;
40: else if (TOUPPER(str[1]) == 'X')
41: base = 16;
42: else
43: base = 8;
44: if (base < 2 || base > MBASE)
45: return (0); /* base is invalid -- should be a fatal error */
46: if (!isalnum(c) || DIGIT(c) >= base)
47: return (0); /* no number formed */
48: if (base == 16 && c == '0' && (TOUPPER(str[1]) == 'X') &&
49: isxdigit(str[2]))
50: c = *(str += 2); /* skip over leading "0x" or "0X" */
51:
52: multmax = T_ULONG_MAX / (unsigned)base;
53: for (val = DIGIT(c); isalnum(c = *++str) && (xx = DIGIT(c)) < base; )
54: if (val > multmax || (val = val*base + xx) < xx)
55: overflow = 1;
56: if (nptr)
57: *nptr = str;
58: if (overflow) {
59: errno = ERANGE;
60: return T_ULONG_MAX;
61: } else
62: return neg? -val: val;
63: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.