at_wini also needs a pci_reserve() for the pci compatability device, if
[minix3.git] / lib / ansi / strtol.c
blob9a200cc1614ba815b8ab6392f4d3124b66354eaa
1 /*
2 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3 * See the copyright notice in the ACK home directory, in the file "Copyright".
4 */
5 /* $Header$ */
7 #include <ctype.h>
8 #include <errno.h>
9 #include <limits.h>
10 #include <stdlib.h>
12 static unsigned long
13 string2long(register const char *nptr, char **endptr,
14 int base, int is_signed);
16 long int
17 strtol(register const char *nptr, char **endptr, int base)
19 return (signed long)string2long(nptr, endptr, base, 1);
22 unsigned long int
23 strtoul(register const char *nptr, char **endptr, int base)
25 return (unsigned long)string2long(nptr, endptr, base, 0);
28 #define between(a, c, z) ((unsigned) ((c) - (a)) <= (unsigned) ((z) - (a)))
30 static unsigned long
31 string2long(register const char *nptr, char ** const endptr,
32 int base, int is_signed)
34 register unsigned int v;
35 register unsigned long val = 0;
36 register int c;
37 int ovfl = 0, sign = 1;
38 const char *startnptr = nptr, *nrstart;
40 if (endptr) *endptr = (char *)nptr;
41 while (isspace(*nptr)) nptr++;
42 c = *nptr;
44 if (c == '-' || c == '+') {
45 if (c == '-') sign = -1;
46 nptr++;
48 nrstart = nptr; /* start of the number */
50 /* When base is 0, the syntax determines the actual base */
51 if (base == 0)
52 if (*nptr == '0')
53 if (*++nptr == 'x' || *nptr == 'X') {
54 base = 16;
55 nptr++;
57 else base = 8;
58 else base = 10;
59 else if (base==16 && *nptr=='0' && (*++nptr =='x' || *nptr =='X'))
60 nptr++;
62 for (;;) {
63 c = *nptr;
64 if (between('0', c, '9')) {
65 v = c - '0';
66 } else
67 if (between('a', c, 'z')) {
68 v = c - 'a' + 0xa;
69 } else
70 if (between('A', c, 'Z')) {
71 v = c - 'A' + 0xA;
72 } else {
73 break;
75 if (v >= base) break;
76 if (val > (ULONG_MAX - v) / base) ovfl++;
77 val = (val * base) + v;
78 nptr++;
80 if (endptr) {
81 if (nrstart == nptr) *endptr = (char *)startnptr;
82 else *endptr = (char *)nptr;
85 if (!ovfl) {
86 /* Overflow is only possible when converting a signed long. */
87 if (is_signed
88 && ( (sign < 0 && val > -(unsigned long)LONG_MIN)
89 || (sign > 0 && val > LONG_MAX)))
90 ovfl++;
93 if (ovfl) {
94 errno = ERANGE;
95 if (is_signed)
96 if (sign < 0) return LONG_MIN;
97 else return LONG_MAX;
98 else return ULONG_MAX;
100 return (long) sign * val;