2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 ANSI C function strtoul().
10 #ifndef AROS_NO_LIMITS_H
13 # define ULONG_MAX 4294967295UL
16 /*****************************************************************************
21 unsigned long strtoul (
29 Convert a string of digits into an integer according to the
33 str - The string which should be converted. Leading
34 whitespace are ignored. The number may be prefixed
35 by a '+' or '-'. If base is above 10, then the
36 alphabetic characters from 'A' are used to specify
37 digits above 9 (ie. 'A' or 'a' is 10, 'B' or 'b' is
38 11 and so on until 'Z' or 'z' is 35).
39 endptr - If this is non-NULL, then the address of the first
40 character after the number in the string is stored
42 base - The base for the number. May be 0 or between 2 and 36,
43 including both. 0 means to autodetect the base. strtoul()
44 selects the base by inspecting the first characters
45 of the string. If they are "0x", then base 16 is
46 assumed. If they are "0", then base 8 is assumed. Any
47 other digit will assume base 10. This is like in C.
49 If you give base 16, then an optional "0x" may
50 precede the number in the string.
53 The value of the string. The first character after the number
54 is returned in *endptr, if endptr is non-NULL. If no digits can
55 be converted, *endptr contains str (if non-NULL) and 0 is
61 // Returns 1, ptr points to the 0-Byte
62 strtoul (" \t +0x1", &ptr, 0);
64 // Returns 15. ptr points to the a
65 strtoul ("017a", &ptr, 0);
67 // Returns 215 (5*36 + 35)
68 strtoul ("5z", &ptr, 36);
73 atoi(), atol(), strtod(), strtol(), strtoul()
77 ******************************************************************************/
79 unsigned long val
= 0;
86 if (base
< 0 || base
== 1 || base
> 36)
91 *endptr
= (char *)str
;
96 while (isspace (*str
))
102 if (*str
== '+' || *str
== '-')
108 if (*str
== '0') /* Base 8 or 16 */
111 if (*str
== 'x' || *str
== 'X')
119 else /* Any other digit: Base 10 (decimal) */
124 Conversion loop, from FreeBSD's src/lib/libc/stdlib/strtoul.c
126 The previous AROS loop was
127 a) inefficient - it did a division each time around.
128 b) buggy - it returned the wrong value in endptr on overflow.
130 cutoff
= (unsigned long)ULONG_MAX
/ (unsigned long)base
;
131 cutlim
= (unsigned long)ULONG_MAX
% (unsigned long)base
;
146 else if (isalpha(digit
))
148 digit
-= isupper(digit
) ? 'A' - 10 : 'a' - 10;
157 any < 0 when we have overflowed. We still need to find the
158 end of the subject sequence
160 if (any
< 0 || val
> cutoff
|| (val
== cutoff
&& digit
> cutlim
))
167 val
= (val
* base
) + digit
;
185 *endptr
= (char *)str
;