2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
5 C99 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)
92 *endptr
= (char *)str
;
97 while (isspace (*str
))
103 if (*str
== '+' || *str
== '-')
107 if (base
== 0 || base
== 16)
109 if (*str
== '0') /* Base 8 or 16 */
112 if (*str
== 'x' || *str
== 'X')
120 else if(base
== 0) /* Any other digit: Base 10 (decimal) */
125 Conversion loop, from FreeBSD's src/lib/libc/stdlib/strtoul.c
127 The previous AROS loop was
128 a) inefficient - it did a division each time around.
129 b) buggy - it returned the wrong value in endptr on overflow.
131 cutoff
= (unsigned long)ULONG_MAX
/ (unsigned long)base
;
132 cutlim
= (unsigned long)ULONG_MAX
% (unsigned long)base
;
147 else if (isalpha(digit
))
149 digit
-= isupper(digit
) ? 'A' - 10 : 'a' - 10;
158 any < 0 when we have overflowed. We still need to find the
159 end of the subject sequence
161 if (any
< 0 || val
> cutoff
|| (val
== cutoff
&& digit
> cutlim
))
168 val
= (val
* base
) + digit
;
188 *endptr
= (char *)str
;