9326fb8a1028bd7f60f92514b82e24cd40925e30
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / strtoi.c
1 /*
2  * Acess2 C Library
3  * - By John Hodge (thePowersGang)
4  *
5  * strtoi.c
6  * - strto[u][l]l/atoi implimentation
7  */
8 #include <ctype.h>
9 #include <errno.h>
10 #include <limits.h>
11 #include <stddef.h>
12
13 unsigned long long strtoull(const char *str, char **end, int base)
14 {
15         long long       ret = 0;
16         
17         if( !str || base < 0 || base > 36 || base == 1 ) {
18                 if(end)
19                         *end = (char*)str;
20                 errno = EINVAL;
21                 return 0;
22         }
23
24         // Trim leading spaces
25         while( isspace(*str) )
26                 str++;
27         
28         // Handle base detection for hex
29         if( base == 0 || base == 16 ) {
30                 if( *str == '0' && str[1] == 'x' ) {
31                         str += 2;
32                         base = 16;
33                 }
34         }
35         
36         // Handle base detection for octal
37         if( base == 0 && *str == '0' ) {
38                 str ++;
39                 base = 8;
40         }
41
42         // Fall back on decimal when unknown
43         if( base == 0 )
44                 base = 10;
45
46         while( *str )
47         {
48                  int    next = -1;
49                 if( base <= 10 ) {
50                         if( '0' <= *str && *str <= '0'+base-1 )
51                                 next = *str - '0';
52                 }
53                 else {
54                         if( '0' <= *str && *str <= '9' )
55                                 next = *str - '0';
56                         if( 'A' <= *str && *str <= 'A'+base-10-1 )
57                                 next = *str - 'A';
58                         if( 'a' <= *str && *str <= 'a'+base-10-1 )
59                                 next = *str - 'a';
60                 }
61                 if( next < 0 )
62                         break;
63                 ret *= base;
64                 ret += next;
65                 str ++;
66         }
67
68         if(end)
69                 *end = (char*)str;
70         return ret;
71 }
72
73 unsigned long strtoul(const char *ptr, char **end, int base)
74 {
75         unsigned long long tmp = strtoull(ptr, end, base);
76         
77         if( tmp > ULONG_MAX ) {
78                 errno = ERANGE;
79                 return ULONG_MAX;
80         }
81         
82         return tmp;
83 }
84
85 long long strtoll(const char *str, char **end, int base)
86 {
87          int    neg = 0;
88         unsigned long long      ret;
89
90         if( !str ) {
91                 errno = EINVAL;
92                 return 0;
93         }
94         
95         while( isspace(*str) )
96                 str++;
97         
98         // Check for negative (or positive) sign
99         if(*str == '-' || *str == '+') {
100                 neg = (*str == '-');
101                 str++;
102         }
103
104         ret = strtoull(str, end, base); 
105
106         if( neg )
107                 return -ret;
108         else
109                 return ret;
110 }
111
112 long strtol(const char *str, char **end, int base)
113 {
114         long long tmp = strtoll(str, end, base);
115         if( tmp > LONG_MAX || tmp < LONG_MIN ) {
116                 errno = ERANGE;
117                 return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;
118         }
119         return tmp;
120 }
121
122 /**
123  * \fn int atoi(const char *str)
124  * \brief Convert a string to an integer
125  */
126 int atoi(const char *str)
127 {
128         long long       tmp = strtoll(str, NULL, 0);
129         if( tmp > INT_MAX || tmp < INT_MIN ) {
130                 errno = ERANGE;
131                 return (tmp > INT_MAX) ? INT_MAX : INT_MIN;
132         }
133         return tmp;
134 }

UCC git Repository :: git.ucc.asn.au