|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1990 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #if defined(LIBC_SCCS) && !defined(lint) ! 21: static char sccsid[] = "@(#)strtoul.c 5.2 (Berkeley) 5/17/90"; ! 22: #endif /* LIBC_SCCS and not lint */ ! 23: ! 24: #include <limits.h> ! 25: #include <ctype.h> ! 26: #include <errno.h> ! 27: #include <stdlib.h> ! 28: ! 29: /* ! 30: * Convert a string to an unsigned long integer. ! 31: * ! 32: * Ignores `locale' stuff. Assumes that the upper and lower case ! 33: * alphabets and digits are each contiguous. ! 34: */ ! 35: unsigned long ! 36: strtoul(nptr, endptr, base) ! 37: char *nptr, **endptr; ! 38: register int base; ! 39: { ! 40: register char *s = nptr; ! 41: register unsigned long acc; ! 42: register int c; ! 43: register unsigned long cutoff; ! 44: register int neg = 0, any, cutlim; ! 45: ! 46: /* ! 47: * See strtol for comments as to the logic used. ! 48: */ ! 49: do { ! 50: c = *s++; ! 51: } while (isspace(c)); ! 52: if (c == '-') { ! 53: neg = 1; ! 54: c = *s++; ! 55: } else if (c == '+') ! 56: c = *s++; ! 57: if ((base == 0 || base == 16) && ! 58: c == '0' && (*s == 'x' || *s == 'X')) { ! 59: c = s[1]; ! 60: s += 2; ! 61: base = 16; ! 62: } ! 63: if (base == 0) ! 64: base = c == '0' ? 8 : 10; ! 65: cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; ! 66: cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; ! 67: for (acc = 0, any = 0;; c = *s++) { ! 68: if (isdigit(c)) ! 69: c -= '0'; ! 70: else if (isalpha(c)) ! 71: c -= isupper(c) ? 'A' - 10 : 'a' - 10; ! 72: else ! 73: break; ! 74: if (c >= base) ! 75: break; ! 76: if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) ! 77: any = -1; ! 78: else { ! 79: any = 1; ! 80: acc *= base; ! 81: acc += c; ! 82: } ! 83: } ! 84: if (any < 0) { ! 85: acc = ULONG_MAX; ! 86: errno = ERANGE; ! 87: } else if (neg) ! 88: acc = -acc; ! 89: if (endptr != 0) ! 90: *endptr = any ? s - 1 : nptr; ! 91: return (acc); ! 92: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.