3 * - By John Hodge (thePowersGang)
6 * - strto[u][l]l/atoi implimentation
13 unsigned long long strtoull(const char *str, char **end, int base)
15 unsigned long long ret = 0;
17 if( !str || base < 0 || base > 36 || base == 1 ) {
24 // Trim leading spaces
25 while( isspace(*str) )
28 // Handle base detection for hex
29 if( base == 0 || base == 16 ) {
30 if( *str == '0' && (str[1] == 'x' || str[1] == 'X') && isxdigit(str[2]) ) {
36 // Handle base detection for octal
37 if( base == 0 && *str == '0' ) {
42 // Fall back on decimal when unknown
46 // Value before getting within 1 digit of ULLONG_MAX
47 // - Used to avoid overflow in more accurate check
48 unsigned long long max_before_ullong_max = ULLONG_MAX / base;
49 unsigned int space_above = ULLONG_MAX - max_before_ullong_max * base;
54 if( '0' <= *str && *str <= '0'+base-1 )
58 if( '0' <= *str && *str <= '9' )
60 if( 'A' <= *str && *str <= 'A'+base-10-1 )
61 next = *str - 'A' + 10;
62 if( 'a' <= *str && *str <= 'a'+base-10-1 )
63 next = *str - 'a' + 10;
65 //_SysDebug("strtoull - ret=0x%llx,next=%i,str='%s'", ret, next, str);
69 // If we're already out of range, keep eating
70 if( ret == ULLONG_MAX ) {
73 // Keep eating until first unrecognised character
77 // Rough then accurate check against max value
78 if( ret >= max_before_ullong_max )
80 //_SysDebug("strtoull - 0x%llx>0x%llx", ret, max_before_ullong_max);
81 if( (ret - max_before_ullong_max) * base + next > space_above ) {
82 //_SysDebug("strtoull - %u*%u+%u (%u) > %u",
83 // (unsigned int)(ret - max_before_ullong_max), base, next, space_above);
100 unsigned long strtoul(const char *ptr, char **end, int base)
102 unsigned long long tmp = strtoull(ptr, end, base);
104 if( tmp > ULONG_MAX ) {
112 long long strtoll(const char *str, char **end, int base)
121 while( isspace(*str) )
124 // Check for negative (or positive) sign
125 if(*str == '-' || *str == '+')
127 //_SysDebug("strtoll - str[0:1] = '%.2s'", str);
128 if( !isdigit(str[1]) ) {
129 // Non-digit, invalid string
130 if(end) *end = (char*)str;
137 unsigned long long ret = strtoull(str, end, base);
138 //_SysDebug("strtoll - neg=%i,ret=%llu", neg, ret);
141 // Abuses unsigned integer overflow
142 if( ret + LLONG_MIN < ret ) {
150 if( ret > LLONG_MAX ) {
158 long strtol(const char *str, char **end, int base)
160 long long tmp = strtoll(str, end, base);
161 if( tmp > LONG_MAX || tmp < LONG_MIN ) {
163 return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;
169 * \fn int atoi(const char *str)
170 * \brief Convert a string to an integer
172 int atoi(const char *str)
174 long long tmp = strtoll(str, NULL, 0);
175 if( tmp > INT_MAX || tmp < INT_MIN ) {
177 return (tmp > INT_MAX) ? INT_MAX : INT_MIN;
182 long atol(const char *str)
184 long long tmp = strtoll(str, NULL, 0);
185 if( tmp > LONG_MAX || tmp < LONG_MIN ) {
187 return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;
192 long long atoll(const char *str)
194 long long tmp = strtoll(str, NULL, 0);