1*42116Sbostic /* 2*42116Sbostic * Copyright (c) 1990 Regents of the University of California. 3*42116Sbostic * All rights reserved. 4*42116Sbostic * 5*42116Sbostic * %sccs.include.redist.c% 6*42116Sbostic */ 7*42116Sbostic 8*42116Sbostic #if defined(LIBC_SCCS) && !defined(lint) 9*42116Sbostic static char sccsid[] = "@(#)strtoul.c 5.1 (Berkeley) 05/16/90"; 10*42116Sbostic #endif /* LIBC_SCCS and not lint */ 11*42116Sbostic 12*42116Sbostic #include <limits.h> 13*42116Sbostic #include <ctype.h> 14*42116Sbostic #include <errno.h> 15*42116Sbostic 16*42116Sbostic /* 17*42116Sbostic * Convert a string to an unsigned long integer. 18*42116Sbostic * 19*42116Sbostic * Ignores `locale' stuff. Assumes that the upper and lower case 20*42116Sbostic * alphabets and digits are each contiguous. 21*42116Sbostic */ 22*42116Sbostic unsigned long 23*42116Sbostic strtoul(nptr, endptr, base) 24*42116Sbostic char *nptr, **endptr; 25*42116Sbostic register int base; 26*42116Sbostic { 27*42116Sbostic register char *s = nptr; 28*42116Sbostic register unsigned long acc; 29*42116Sbostic register int c; 30*42116Sbostic register unsigned long cutoff; 31*42116Sbostic register int neg = 0, any, cutlim; 32*42116Sbostic 33*42116Sbostic /* 34*42116Sbostic * See strtol for comments as to the logic used. 35*42116Sbostic */ 36*42116Sbostic do { 37*42116Sbostic c = *s++; 38*42116Sbostic } while (isspace(c)); 39*42116Sbostic if (c == '-') { 40*42116Sbostic neg = 1; 41*42116Sbostic c = *s++; 42*42116Sbostic } else if (c == '+') 43*42116Sbostic c = *s++; 44*42116Sbostic if ((base == 0 || base == 16) && 45*42116Sbostic c == '0' && (*s == 'x' || *s == 'X')) { 46*42116Sbostic c = s[1]; 47*42116Sbostic s += 2; 48*42116Sbostic base = 16; 49*42116Sbostic } 50*42116Sbostic if (base == 0) 51*42116Sbostic base = c == '0' ? 8 : 10; 52*42116Sbostic cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 53*42116Sbostic cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 54*42116Sbostic for (acc = 0, any = 0;; c = *s++) { 55*42116Sbostic if (isdigit(c)) 56*42116Sbostic c -= '0'; 57*42116Sbostic else if (isalpha(c)) 58*42116Sbostic c -= isupper(c) ? 'A' - 10 : 'a' - 10; 59*42116Sbostic else 60*42116Sbostic break; 61*42116Sbostic if (c >= base) 62*42116Sbostic break; 63*42116Sbostic if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 64*42116Sbostic any = -1; 65*42116Sbostic else { 66*42116Sbostic any = 1; 67*42116Sbostic acc *= base; 68*42116Sbostic acc += c; 69*42116Sbostic } 70*42116Sbostic } 71*42116Sbostic if (any < 0) { 72*42116Sbostic acc = ULONG_MAX; 73*42116Sbostic errno = ERANGE; 74*42116Sbostic } else if (neg) 75*42116Sbostic acc = -acc; 76*42116Sbostic if (endptr != 0) 77*42116Sbostic *endptr = any ? s - 1 : nptr; 78*42116Sbostic return (acc); 79*42116Sbostic } 80