Adding usermode tree
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / stdlib.c
1 /*\r
2 AcessOS Basic C Library\r
3 \r
4 stdlib.c\r
5 */\r
6 #include <acess/sys.h>\r
7 #include <stdlib.h>\r
8 #include "lib.h"\r
9 \r
10 int _stdout = 1;\r
11 int _stdin = 2;\r
12 \r
13 EXPORT int      puts(const char *str);\r
14 EXPORT void     itoa(char *buf, unsigned long num, int base, int minLength, char pad);\r
15 EXPORT int      atoi(const char *str);\r
16 EXPORT int      puts(const char *str);\r
17 EXPORT int      ssprintfv(char *format, va_list args);\r
18 EXPORT void     sprintfv(char *buf, char *format, va_list args);\r
19 EXPORT int      printf(const char *format, ...);\r
20 EXPORT int      strlen(const char *str);\r
21 EXPORT int      strcmp(char *str1, char *str2);\r
22 EXPORT int      strncmp(char *str1, char *str2, size_t len);\r
23 EXPORT char     *strcpy(char *dst, const char *src);\r
24 \r
25 // === CODE ===\r
26 EXPORT int putchar(int ch)\r
27 {\r
28         return write(_stdout, 1, (char*)&ch);\r
29 }\r
30 \r
31 EXPORT int      puts(const char *str)\r
32 {\r
33          int    len;\r
34         \r
35         if(!str)        return 0;\r
36         len = strlen(str);\r
37         \r
38         len = write(_stdout, len, (char*)str);\r
39         write(_stdout, 1, "\n");\r
40         return len;\r
41 }\r
42 \r
43 //sprintfv\r
44 /**\r
45  \fn EXPORT void sprintfv(char *buf, char *format, va_list args)\r
46  \brief Prints a formatted string to a buffer\r
47  \param buf     Pointer - Destination Buffer\r
48  \param format  String - Format String\r
49  \param args    VarArgs List - Arguments\r
50 */\r
51 EXPORT void sprintfv(char *buf, char *format, va_list args)\r
52 {\r
53         char    tmp[33];\r
54          int    c, arg, minSize;\r
55          int    pos = 0;\r
56         char    *p;\r
57         char    pad;\r
58 \r
59         tmp[32] = '\0';\r
60         \r
61         while((c = *format++) != 0)\r
62         {\r
63                 //SysDebug("c = '%c'\n", c);\r
64                 if (c != '%') {\r
65                         buf[pos++] = c;\r
66                         continue;\r
67                 }\r
68                 \r
69                 c = *format++;\r
70                 if(c == '%') {\r
71                         buf[pos++] = '%';\r
72                         continue;\r
73                 }\r
74                 \r
75                 // Padding\r
76                 if(c == '0') {\r
77                         pad = '0';\r
78                         c = *format++;\r
79                 } else\r
80                         pad = ' ';\r
81                 minSize = 0;\r
82                 if('1' <= c && c <= '9')\r
83                 {\r
84                         while('0' <= c && c <= '9')\r
85                         {\r
86                                 minSize *= 10;\r
87                                 minSize += c - '0';\r
88                                 c = *format++;\r
89                         }\r
90                 }\r
91         \r
92                 p = tmp;\r
93         \r
94                 // Get Argument\r
95                 arg = va_arg(args, int);\r
96                 // Get Type\r
97                 switch (c) {\r
98                 case 'd':\r
99                 case 'i':\r
100                         if(arg < 0) {\r
101                                 buf[pos++] = '-';\r
102                                 arg = -arg;\r
103                         }\r
104                         itoa(tmp, arg, 10, minSize, pad);\r
105                         goto sprintf_puts;\r
106                 //      break;\r
107                 case 'u':\r
108                         itoa(tmp, arg, 10, minSize, pad);\r
109                         goto sprintf_puts;\r
110                 //      break;\r
111                 case 'x':\r
112                         itoa(tmp, arg, 16, minSize, pad);\r
113                         goto sprintf_puts;\r
114                 //      break;\r
115                 case 'o':\r
116                         itoa(tmp, arg, 8, minSize, pad);\r
117                         goto sprintf_puts;\r
118                 //      break;\r
119                 case 'b':\r
120                         itoa(tmp, arg, 2, minSize, pad);\r
121                         goto sprintf_puts;\r
122                 //      break;\r
123 \r
124                 case 's':\r
125                         p = (void*)arg;\r
126                 sprintf_puts:\r
127                         if(!p)  p = "(null)";\r
128                         while(*p)       buf[pos++] = *p++;\r
129                         break;\r
130 \r
131                 default:\r
132                         buf[pos++] = arg;\r
133                         break;\r
134                 }\r
135     }\r
136         buf[pos++] = '\0';\r
137 }\r
138 /*\r
139 ssprintfv\r
140 - Size, Stream, Print Formated, Variable Argument List\r
141 */\r
142 /**\r
143  \fn EXPORT int ssprintfv(char *format, va_list args)\r
144  \brief Gets the total character count from a formatted string\r
145  \param format  String - Format String\r
146  \param args    VarArgs - Argument List\r
147 */\r
148 EXPORT int ssprintfv(char *format, va_list args)\r
149 {\r
150         char    tmp[33];\r
151          int    c, arg, minSize;\r
152          int    len = 0;\r
153         char    *p;\r
154         char    pad;\r
155 \r
156         tmp[32] = '\0';\r
157         \r
158         while((c = *format++) != 0)\r
159         {\r
160                 if (c != '%') {\r
161                         len++;\r
162                         continue;\r
163                 }\r
164                 \r
165                 c = *format++;\r
166                 \r
167                 // Literal '%'\r
168                 if(c == '%') {\r
169                         len++;\r
170                         continue;\r
171                 }\r
172                 \r
173                 // Padding\r
174                 if(c == '0') {\r
175                         pad = '0';\r
176                         c = *format++;\r
177                 } else\r
178                         pad = ' ';\r
179                 minSize = 0;\r
180                 if('1' <= c && c <= '9')\r
181                 {\r
182                         while('0' <= c && c <= '9')\r
183                         {\r
184                                 minSize *= 10;\r
185                                 minSize += c - '0';\r
186                                 c = *format++;\r
187                         }\r
188                 }\r
189                 \r
190                 p = tmp;\r
191                 arg = va_arg(args, int);\r
192                 switch (c) {                    \r
193                 case 'd':\r
194                 case 'i':\r
195                         if(arg < 0) {\r
196                                 len ++;\r
197                                 arg = -arg;\r
198                         }\r
199                         itoa(tmp, arg, 10, minSize, pad);\r
200                         goto sprintf_puts;\r
201                 case 'u':\r
202                         itoa(tmp, arg, 10, minSize, pad);\r
203                         goto sprintf_puts;\r
204                 case 'x':\r
205                         itoa(tmp, arg, 16, minSize, pad);\r
206                         goto sprintf_puts;\r
207                 case 'o':\r
208                         itoa(tmp, arg, 8, minSize, pad);\r
209                         p = tmp;\r
210                         goto sprintf_puts;\r
211                 case 'b':\r
212                         itoa(tmp, arg, 2, minSize, pad);\r
213                         goto sprintf_puts;\r
214 \r
215                 case 's':\r
216                         p = (char*)arg;\r
217                 sprintf_puts:\r
218                         if(!p)  p = "(null)";\r
219                         while(*p)       len++, p++;\r
220                         break;\r
221 \r
222                 default:\r
223                         len ++;\r
224                         break;\r
225                 }\r
226     }\r
227         return len;\r
228 }\r
229 \r
230 const char cUCDIGITS[] = "0123456789ABCDEF";\r
231 /**\r
232  * \fn static void itoa(char *buf, unsigned long num, int base, int minLength, char pad)\r
233  * \brief Convert an integer into a character string\r
234  */\r
235 EXPORT void itoa(char *buf, unsigned long num, int base, int minLength, char pad)\r
236 {\r
237         char    tmpBuf[32];\r
238          int    pos=0, i;\r
239 \r
240         if(!buf)        return;\r
241         if(base > 16) {\r
242                 buf[0] = 0;\r
243                 return;\r
244         }\r
245         \r
246         while(num > base-1) {\r
247                 tmpBuf[pos] = cUCDIGITS[ num % base ];\r
248                 num = (long) num / base;                //Shift {number} right 1 digit\r
249                 pos++;\r
250         }\r
251 \r
252         tmpBuf[pos++] = cUCDIGITS[ num % base ];                //Last digit of {number}\r
253         i = 0;\r
254         minLength -= pos;\r
255         while(minLength-- > 0)  buf[i++] = pad;\r
256         while(pos-- > 0)                buf[i++] = tmpBuf[pos]; //Reverse the order of characters\r
257         buf[i] = 0;\r
258 }\r
259 \r
260 /**\r
261  */\r
262 EXPORT int atoi(const char *str)\r
263 {\r
264          int    neg = 0;\r
265          int    ret = 0;\r
266         \r
267         // NULL Check\r
268         if(!str)        return 0;\r
269         \r
270         while(*str == ' ' || *str == '\t')      str++;\r
271         \r
272         // Check for negative\r
273         if(*str == '-') {\r
274                 neg = 1;\r
275                 str++;\r
276         }\r
277         \r
278         if(*str == '0') {\r
279                 str ++;\r
280                 if(*str == 'x') {\r
281                         str++;\r
282                         // Hex\r
283                         while( ('0' <= *str && *str <= '9')\r
284                                 || ('A' <= *str && *str <= 'F' )\r
285                                 || ('a' <= *str && *str <= 'f' )\r
286                                 )\r
287                         {\r
288                                 ret *= 16;\r
289                                 if(*str <= '9') {\r
290                                         ret += *str - '0';\r
291                                 } else if (*str <= 'F') {\r
292                                         ret += *str - 'A' + 10;\r
293                                 } else {\r
294                                         ret += *str - 'a' + 10;\r
295                                 }\r
296                                 str++;\r
297                         }\r
298                 } else {\r
299                         // Octal\r
300                         while( '0' <= *str && *str <= '7' )\r
301                         {\r
302                                 ret *= 8;\r
303                                 ret += *str - '0';\r
304                                 str++;\r
305                         }\r
306                 }\r
307         } else {\r
308                 // Decimal\r
309                 while( '0' <= *str && *str <= '9' )\r
310                 {\r
311                         ret *= 10;\r
312                         ret += *str - '0';\r
313                         str++;\r
314                 }\r
315         }\r
316         \r
317         // Negate if needed\r
318         if(neg) ret = -ret;\r
319         return ret;\r
320 }\r
321 \r
322 //printf\r
323 EXPORT int printf(const char *format, ...)\r
324 {\r
325          int    size;\r
326         char    *buf;\r
327         va_list args;\r
328         \r
329         va_start(args, format);\r
330         size = ssprintfv((char*)format, args);\r
331         va_end(args);\r
332         \r
333         buf = (char*)malloc(size+1);\r
334         buf[size] = '\0';\r
335         \r
336         va_start(args, format);\r
337         sprintfv(buf, (char*)format, args);\r
338         va_end(args);\r
339         \r
340         \r
341         write(_stdout, size+1, buf);\r
342         \r
343         free(buf);\r
344         return size;\r
345 }\r
346 \r
347 EXPORT int sprintf(const char *buf, char *format, ...)\r
348 {\r
349         va_list args;\r
350         va_start(args, format);\r
351         sprintfv((char*)buf, (char*)format, args);\r
352         va_end(args);\r
353         return 1;\r
354 }\r
355 \r
356 \r
357 //MEMORY\r
358 EXPORT int strcmp(char *s1, char *s2)\r
359 {\r
360         while(*s1 == *s2 && *s1 != '\0' && *s2 != '\0') {\r
361                 s1++; s2++;\r
362         }\r
363         return (int)*s1 - (int)*s2;\r
364 }\r
365 EXPORT char *strcpy(char *dst, const char *src)\r
366 {\r
367         char *_dst = dst;\r
368         while(*src) {\r
369                 *dst = *src;\r
370                 src++; dst++;\r
371         }\r
372         *dst = '\0';\r
373         return _dst;\r
374 }\r
375 EXPORT int strlen(const char *str)\r
376 {\r
377         int retval;\r
378         for(retval = 0; *str != '\0'; str++)\r
379                 retval++;\r
380         return retval;\r
381 }\r
382 \r
383 EXPORT int strncmp(char *s1, char *s2, size_t len)\r
384 {\r
385         while(--len && *s1 == *s2 && *s1 != '\0' && *s2 != '\0') {\r
386                 s1++; s2++;\r
387         }\r
388         return (int)*s1 - (int)*s2;\r
389 }\r
390 \r
391 EXPORT void *memcpy(void *dest, void *src, unsigned int count)\r
392 {\r
393     char *sp = (char *)src;\r
394     char *dp = (char *)dest;\r
395     for(;count--;) *dp++ = *sp++;\r
396     return dest;\r
397 }\r
398 \r
399 EXPORT void *memmove(void *dest, void *src, unsigned int count)\r
400 {\r
401     char *sp = (char *)src;\r
402     char *dp = (char *)dest;\r
403         // Check if corruption will happen\r
404         if( (unsigned int)dest > (unsigned int)src && (unsigned int)dest < (unsigned int)src+count )\r
405                 for(;count--;) dp[count] = sp[count];\r
406         else\r
407         for(;count--;) *dp++ = *sp++;\r
408     return dest;\r
409 }\r

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