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

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