|
|
researchv10 Norman
/* Copyright AT&T Bell Laboratories, 1993 */
/* Convert string to unsigned long.
** Assumes ASCII properties - contiguity of 0-9, A-Z, a-z,
** digits less than letters, lower case maskable to upper.
*/
#include <ctype.h>
#include <errno.h>
#define DIGIT(x) ((x)<='9'? (x)-'0': TOUPPER(x)+10-'A')
#define TOUPPER(x) ((x) & ~('a'-'A'))
#define MBASE ('z' - 'a' + 1 + 10)
#define T_ULONG_MAX ~(unsigned long)0
unsigned long
strtoul(str, nptr, base)
char *str;
char **nptr;
int base;
{
register unsigned long val;
register int c;
int xx;
int overflow = 0, neg = 0;
unsigned long multmax;
if (nptr)
*nptr = str; /* in case no number is formed */
c = *str;
while (isspace(c))
c = *++str;
switch(c) {
case '-':
neg = 1;
case'+':
c = *++str;
}
if (base == 0)
if (c != '0')
base = 10;
else if (TOUPPER(str[1]) == 'X')
base = 16;
else
base = 8;
if (base < 2 || base > MBASE)
return (0); /* base is invalid -- should be a fatal error */
if (!isalnum(c) || DIGIT(c) >= base)
return (0); /* no number formed */
if (base == 16 && c == '0' && (TOUPPER(str[1]) == 'X') &&
isxdigit(str[2]))
c = *(str += 2); /* skip over leading "0x" or "0X" */
multmax = T_ULONG_MAX / (unsigned)base;
for (val = DIGIT(c); isalnum(c = *++str) && (xx = DIGIT(c)) < base; )
if (val > multmax || (val = val*base + xx) < xx)
overflow = 1;
if (nptr)
*nptr = str;
if (overflow) {
errno = ERANGE;
return T_ULONG_MAX;
} else
return neg? -val: val;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.