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