2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 ANSI C function strtoull().
8 /* This function requires the use of the long long type. */
9 #include <aros/system.h>
10 #if defined(AROS_HAVE_LONG_LONG)
15 #ifndef AROS_NO_LIMITS_H
18 # define ULLONG_MAX 0xffffffffffffffffULL
21 /*****************************************************************************
26 unsigned long long strtoull (
29 const char * restrict str
,
30 char ** restrict endptr
,
34 Convert a string of digits into an integer according to the
38 str - The string which should be converted. Leading
39 whitespace are ignored. The number may be prefixed
40 by a '+' or '-'. If base is above 10, then the
41 alphabetic characters from 'A' are used to specify
42 digits above 9 (ie. 'A' or 'a' is 10, 'B' or 'b' is
43 11 and so on until 'Z' or 'z' is 35).
44 endptr - If this is non-NULL, then the address of the first
45 character after the number in the string is stored
47 base - The base for the number. May be 0 or between 2 and 36,
48 including both. 0 means to autodetect the base. strtoull()
49 selects the base by inspecting the first characters
50 of the string. If they are "0x", then base 16 is
51 assumed. If they are "0", then base 8 is assumed. Any
52 other digit will assume base 10. This is like in C.
54 If you give base 16, then an optional "0x" may
55 precede the number in the string.
58 The value of the string. The first character after the number
59 is returned in *endptr, if endptr is non-NULL. If no digits can
60 be converted, *endptr contains str (if non-NULL) and 0 is
66 // Returns 1, ptr points to the 0-Byte
67 strtoull (" \t +0x1", &ptr, 0);
69 // Returns 15. ptr points to the a
70 strtoull ("017a", &ptr, 0);
72 // Returns 215 (5*36 + 35)
73 strtoull ("5z", &ptr, 36);
82 ******************************************************************************/
84 unsigned long long val
= 0;
87 unsigned long long cutoff
;
91 if (base
< 0 || base
== 1 || base
> 36)
96 *endptr
= (char *)str
;
101 while (isspace (*str
))
106 if (*str
== '+' || *str
== '-')
110 if (base
== 0 || base
== 16)
112 if (*str
== '0') /* Base 8 or 16 */
115 if (*str
== 'x' || *str
== 'X')
123 else if(base
== 0) /* Any other digit: Base 10 (decimal) */
128 Conversion loop, from FreeBSD's src/lib/libc/stdlib/strtoull.c
130 The previous AROS loop was
131 a) inefficient - it did a division each time around.
132 b) buggy - it returned the wrong value in endptr on overflow.
134 cutoff
= (unsigned long long)ULLONG_MAX
/ (unsigned long long)base
;
135 cutlim
= (unsigned long long)ULLONG_MAX
% (unsigned long long)base
;
148 else if (isalpha(digit
))
149 digit
-= isupper(c
) ? '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
;
190 #endif /* AROS_HAVE_LONG_LONG */