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".
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);
28 #define between(a, c, z) ((unsigned) ((c) - (a)) <= (unsigned) ((z) - (a)))
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;
37 int ovfl
= 0, sign
= 1;
38 const char *startnptr
= nptr
, *nrstart
;
40 if (endptr
) *endptr
= (char *)nptr
;
41 while (isspace(*nptr
)) nptr
++;
44 if (c
== '-' || c
== '+') {
45 if (c
== '-') sign
= -1;
48 nrstart
= nptr
; /* start of the number */
50 /* When base is 0, the syntax determines the actual base */
53 if (*++nptr
== 'x' || *nptr
== 'X') {
59 else if (base
==16 && *nptr
=='0' && (*++nptr
=='x' || *nptr
=='X'))
64 if (between('0', c
, '9')) {
67 if (between('a', c
, 'z')) {
70 if (between('A', c
, 'Z')) {
76 if (val
> (ULONG_MAX
- v
) / base
) ovfl
++;
77 val
= (val
* base
) + v
;
81 if (nrstart
== nptr
) *endptr
= (char *)startnptr
;
82 else *endptr
= (char *)nptr
;
86 /* Overflow is only possible when converting a signed long. */
88 && ( (sign
< 0 && val
> -(unsigned long)LONG_MIN
)
89 || (sign
> 0 && val
> LONG_MAX
)))
96 if (sign
< 0) return LONG_MIN
;
98 else return ULONG_MAX
;
100 return (long) sign
* val
;