Usermode - A few tweaks to POSIX emulation for dropbear
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / stdlib.c
1 /*\r
2  * AcessOS Basic C Library\r
3  * stdlib.c\r
4  */\r
5 #include <acess/sys.h>\r
6 #include <stdlib.h>\r
7 #include <stdio.h>\r
8 #include <errno.h>\r
9 #include <ctype.h>\r
10 #include <limits.h>\r
11 #include "lib.h"\r
12 \r
13 #define _stdout 1\r
14 #define _stdin  0\r
15 \r
16 extern void     *_crt0_exit_handler;\r
17 \r
18 // === PROTOTYPES ===\r
19 EXPORT int      atoi(const char *str);\r
20 EXPORT void     exit(int status);\r
21 \r
22 // === GLOBALS ===\r
23 void    (*g_stdlib_exithandler)(void);\r
24 \r
25 // === CODE ===\r
26 void atexit(void (*__func)(void))\r
27 {\r
28         g_stdlib_exithandler = __func;\r
29         // TODO: Replace with meta-function to allow multiple atexit() handlers\r
30         _crt0_exit_handler = __func;    \r
31 }\r
32 \r
33 /**\r
34  * \fn EXPORT void exit(int status)\r
35  * \brief Exit\r
36  */\r
37 EXPORT void exit(int status)\r
38 {\r
39         if( g_stdlib_exithandler )\r
40                 g_stdlib_exithandler();\r
41         _exit(status);\r
42 }\r
43 \r
44 /**\r
45  * \fn EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))\r
46  * \brief Sort an array\r
47  * \note Uses a selection sort\r
48  */\r
49 EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))\r
50 {\r
51         size_t  i, j, min;\r
52         // With 0 items, there's nothing to do and with 1 its already sorted\r
53         if(nmemb == 0 || nmemb == 1)    return;\r
54         \r
55         // SORT!\r
56         for( i = 0; i < (nmemb-1); i++ )\r
57         {\r
58                 min = i;\r
59                 for( j = i+1; j < nmemb; j++ )\r
60                 {\r
61                         if(compar(base+size*j, base + size*min) < 0) {\r
62                                 min = j;\r
63                         }\r
64                 }\r
65                 if (i != min) {\r
66                         char    swap[size];\r
67                         memcpy(swap, base+size*i, size);\r
68                         memcpy(base+size*i, base+size*min, size);\r
69                         memcpy(base+size*i, swap, size);\r
70                 }\r
71         }\r
72 }\r
73 \r
74 EXPORT unsigned long long strtoull(const char *str, char **end, int base)\r
75 {\r
76         long long       ret = 0;\r
77         \r
78         if( !str || base < 0 || base > 36 || base == 1 ) {\r
79                 if(end)\r
80                         *end = (char*)str;\r
81                 errno = EINVAL;\r
82                 return 0;\r
83         }\r
84 \r
85         while( isspace(*str) )\r
86                 str++;\r
87         \r
88         if( base == 0 || base == 16 ) {\r
89                 if( *str == '0' && str[1] == 'x' ) {\r
90                         str += 2;\r
91                         base = 16;\r
92                 }\r
93         }\r
94         \r
95         if( base == 0 && *str == '0' ) {\r
96                 str ++;\r
97                 base = 8;\r
98         }\r
99 \r
100         if( base == 0 )\r
101                 base = 10;\r
102 \r
103         while( *str )\r
104         {\r
105                  int    next = -1;\r
106                 if( base <= 10 ) {\r
107                         if( '0' <= *str && *str <= '0'+base-1 )\r
108                                 next = *str - '0';\r
109                 }\r
110                 else {\r
111                         if( '0' <= *str && *str <= '9' )\r
112                                 next = *str - '0';\r
113                         if( 'A' <= *str && *str <= 'A'+base-10-1 )\r
114                                 next = *str - 'A';\r
115                         if( 'a' <= *str && *str <= 'a'+base-10-1 )\r
116                                 next = *str - 'a';\r
117                 }\r
118                 if( next < 0 )\r
119                         break;\r
120                 ret *= base;\r
121                 ret += next;\r
122                 str ++;\r
123         }\r
124 \r
125         if(end)\r
126                 *end = (char*)str;\r
127         return ret;\r
128 }\r
129 \r
130 EXPORT unsigned long strtoul(const char *ptr, char **end, int base)\r
131 {\r
132         unsigned long long tmp = strtoull(ptr, end, base);\r
133         \r
134         if( tmp > ULONG_MAX ) {\r
135                 errno = ERANGE;\r
136                 return ULONG_MAX;\r
137         }\r
138         \r
139         return tmp;\r
140 }\r
141 \r
142 EXPORT long long strtoll(const char *str, char **end, int base)\r
143 {\r
144          int    neg = 0;\r
145         unsigned long long      ret;\r
146 \r
147         if( !str ) {\r
148                 errno = EINVAL;\r
149                 return 0;\r
150         }\r
151         \r
152         while( isspace(*str) )\r
153                 str++;\r
154         \r
155         // Check for negative (or positive) sign\r
156         if(*str == '-' || *str == '+') {\r
157                 neg = (*str == '-');\r
158                 str++;\r
159         }\r
160 \r
161         ret = strtoull(str, end, base); \r
162 \r
163         if( neg )\r
164                 return -ret;\r
165         else\r
166                 return ret;\r
167 }\r
168 \r
169 EXPORT long strtol(const char *str, char **end, int base)\r
170 {\r
171         long long tmp = strtoll(str, end, base);\r
172         if( tmp > LONG_MAX || tmp < LONG_MIN ) {\r
173                 errno = ERANGE;\r
174                 return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;\r
175         }\r
176         return tmp;\r
177 }\r
178 \r
179 /**\r
180  * \fn EXPORT int atoi(const char *str)\r
181  * \brief Convert a string to an integer\r
182  */\r
183 EXPORT int atoi(const char *str)\r
184 {\r
185         long long       tmp = strtoll(str, NULL, 0);\r
186         if( tmp > INT_MAX || tmp < INT_MIN ) {\r
187                 errno = ERANGE;\r
188                 return (tmp > INT_MAX) ? INT_MAX : INT_MIN;\r
189         }\r
190         return tmp;\r
191 }\r
192 \r
193 int abs(int j) { return j < 0 ? -j : j; }\r
194 long int labs(long int j) { return j < 0 ? -j : j; }\r
195 \r

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