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".
5 /* $Id: strtol.c,v 1.7 1995/08/17 10:03:43 ceriel Exp $ */
13 string2long(register const char *nptr, char **endptr,
14 int base, int is_signed);
17 strtol(register const char *nptr, char **endptr, int base)
19 return (signed long)string2long(nptr, endptr, base, 1);
23 strtoul(register const char *nptr, char **endptr, int base)
25 return (unsigned long)string2long(nptr, endptr, base, 0);
29 string2long(register const char *nptr, char ** const endptr,
30 int base, int is_signed)
32 register unsigned int v;
33 register unsigned long val = 0;
35 int ovfl = 0, sign = 1;
36 const char *startnptr = nptr, *nrstart;
38 if (endptr) *endptr = (char *)nptr;
39 while (isspace(*nptr)) nptr++;
42 if (c == '-' || c == '+') {
43 if (c == '-') sign = -1;
46 nrstart = nptr; /* start of the number */
48 /* When base is 0, the syntax determines the actual base */
51 if (*++nptr == 'x' || *nptr == 'X') {
57 else if (base==16 && *nptr=='0' && (*++nptr =='x' || *nptr =='X'))
60 while (isdigit(c = *nptr) || isalpha(c)) {
63 v = 10 + (isupper(c) ? c - 'A' : c - 'a');
67 if (val > (ULONG_MAX - v) / base) ++ovfl;
68 else val = (val * base) + v;
73 if (nrstart == nptr) *endptr = (char *)startnptr;
74 else *endptr = (char *)nptr;
78 /* Overflow is only possible when converting a signed long.
79 * The "-(LONG_MIN+1)+(unsigned long) 1" construction is there
80 * to prevent overflow warnings on -LONG_MIN.
83 && ( (sign < 0 && val > -(LONG_MIN+1)+(unsigned long) 1)
84 || (sign > 0 && val > LONG_MAX)))
91 if (sign < 0) return LONG_MIN;
93 else return ULONG_MAX;