|
|
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.