|
|
1.1 ! root 1: /* ! 2: * strtol : convert a string to long. ! 3: * ! 4: * Andy Wilson, 2-Oct-89. ! 5: */ ! 6: ! 7: #include <errno.h> ! 8: #include <ctype.h> ! 9: #include <stdio.h> ! 10: #include "ansidecl.h" ! 11: ! 12: #ifndef ULONG_MAX ! 13: #define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */ ! 14: #endif ! 15: ! 16: extern int errno; ! 17: ! 18: unsigned long ! 19: strtoul(s, ptr, base) ! 20: CONST char *s; char **ptr; int base; ! 21: { ! 22: unsigned long total = 0; ! 23: unsigned digit; ! 24: CONST char *start=s; ! 25: int did_conversion=0; ! 26: int overflow = 0; ! 27: int negate = 0; ! 28: unsigned long maxdiv, maxrem; ! 29: ! 30: if (s==NULL) ! 31: { ! 32: errno = ERANGE; ! 33: if (!ptr) ! 34: *ptr = (char *)start; ! 35: return 0L; ! 36: } ! 37: ! 38: while (isspace(*s)) ! 39: s++; ! 40: if (*s == '+') ! 41: s++; ! 42: else if (*s == '-') ! 43: s++, negate = 1; ! 44: if (base==0 || base==16) /* the 'base==16' is for handling 0x */ ! 45: { ! 46: int tmp; ! 47: ! 48: /* ! 49: * try to infer base from the string ! 50: */ ! 51: if (*s != '0') ! 52: tmp = 10; /* doesn't start with 0 - assume decimal */ ! 53: else if (s[1] == 'X' || s[1] == 'x') ! 54: tmp = 16, s += 2; /* starts with 0x or 0X - hence hex */ ! 55: else ! 56: tmp = 8; /* starts with 0 - hence octal */ ! 57: if (base==0) ! 58: base = (int)tmp; ! 59: } ! 60: ! 61: maxdiv = ULONG_MAX / base; ! 62: maxrem = ULONG_MAX % base; ! 63: ! 64: while ((digit = *s) != '\0') ! 65: { ! 66: if (digit >= '0' && digit < ('0'+base)) ! 67: digit -= '0'; ! 68: else ! 69: if (base > 10) ! 70: { ! 71: if (digit >= 'a' && digit < ('a'+(base-10))) ! 72: digit = digit - 'a' + 10; ! 73: else if (digit >= 'A' && digit < ('A'+(base-10))) ! 74: digit = digit - 'A' + 10; ! 75: else ! 76: break; ! 77: } ! 78: else ! 79: break; ! 80: did_conversion = 1; ! 81: if (total > maxdiv ! 82: || (total == maxdiv && digit > maxrem)) ! 83: overflow = 1; ! 84: total = (total * base) + digit; ! 85: s++; ! 86: } ! 87: if (overflow) ! 88: { ! 89: errno = ERANGE; ! 90: if (ptr != NULL) ! 91: *ptr = (char *)s; ! 92: return (ULONG_MAX); ! 93: } ! 94: if (ptr != NULL) ! 95: *ptr = (char *) ((did_conversion) ? (char *)s : (char *)start); ! 96: return negate ? -total : total; ! 97: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.