Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / stdlib.c
index 469f51c..e05ddc2 100644 (file)
@@ -5,29 +5,36 @@
 #include <acess/sys.h>\r
 #include <stdlib.h>\r
 #include <stdio.h>\r
-#include <errno.h>\r
-#include <ctype.h>\r
-#include <limits.h>\r
 #include "lib.h"\r
 \r
-#define _stdout        1\r
-#define _stdin 0\r
+extern void    _stdio_cleanup(void);\r
 \r
-extern void    *_crt0_exit_handler;\r
+#define MAX_ATEXIT_HANDLERS    64      // Standard defines >=32\r
 \r
 // === PROTOTYPES ===\r
 EXPORT int     atoi(const char *str);\r
 EXPORT void    exit(int status);\r
 \r
 // === GLOBALS ===\r
-void   (*g_stdlib_exithandler)(void);\r
+typedef void (*stdlib_exithandler_t)(void);\r
+stdlib_exithandler_t   g_stdlib_exithandlers[MAX_ATEXIT_HANDLERS];\r
+ int   g_stdlib_num_exithandlers;\r
 \r
 // === CODE ===\r
-void atexit(void (*__func)(void))\r
+void _call_atexit_handlers(void)\r
 {\r
-       g_stdlib_exithandler = __func;\r
-       // TODO: Replace with meta-function to allow multiple atexit() handlers\r
-       _crt0_exit_handler = __func;    \r
+        int    i;\r
+       for( i = g_stdlib_num_exithandlers; i --; )\r
+               g_stdlib_exithandlers[i]();\r
+       _stdio_cleanup();\r
+}\r
+\r
+EXPORT void atexit(void (*__func)(void))\r
+{\r
+       if( g_stdlib_num_exithandlers < MAX_ATEXIT_HANDLERS )\r
+       {\r
+               g_stdlib_exithandlers[g_stdlib_num_exithandlers++] = __func;\r
+       }\r
 }\r
 \r
 /**\r
@@ -36,8 +43,7 @@ void atexit(void (*__func)(void))
  */\r
 EXPORT void exit(int status)\r
 {\r
-       if( g_stdlib_exithandler )\r
-               g_stdlib_exithandler();\r
+       _call_atexit_handlers();\r
        _exit(status);\r
 }\r
 \r
@@ -71,95 +77,6 @@ EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void
        }\r
 }\r
 \r
-EXPORT long long strtoll(const char *str, char **end, int base)\r
-{\r
-        int    neg = 0;\r
-       long long       ret = 0;\r
-       \r
-       if( !str || base < 0 || base > 36 || base == 1 ) {\r
-               if(end)\r
-                       *end = (char*)str;\r
-               errno = EINVAL;\r
-               return 0;\r
-       }\r
-\r
-       while( isspace(*str) )\r
-               str++;\r
-       \r
-       // Check for negative (or positive) sign\r
-       if(*str == '-' || *str == '+') {\r
-               neg = (*str == '-');\r
-               str++;\r
-       }\r
-       \r
-       if( base == 0 || base == 16 ) {\r
-               if( *str == '0' && str[1] == 'x' ) {\r
-                       str += 2;\r
-                       base = 16;\r
-               }\r
-       }\r
-       \r
-       if( base == 0 && *str == '0' ) {\r
-               str ++;\r
-               base = 8;\r
-       }\r
-\r
-       if( base == 0 )\r
-               base = 10;\r
-\r
-       while( *str )\r
-       {\r
-                int    next = -1;\r
-               if( base <= 10 ) {\r
-                       if( '0' <= *str && *str <= '0'+base-1 )\r
-                               next = *str - '0';\r
-               }\r
-               else {\r
-                       if( '0' <= *str && *str <= '9' )\r
-                               next = *str - '0';\r
-                       if( 'A' <= *str && *str <= 'A'+base-10-1 )\r
-                               next = *str - 'A';\r
-                       if( 'a' <= *str && *str <= 'a'+base-10-1 )\r
-                               next = *str - 'a';\r
-               }\r
-               if( next < 0 )\r
-                       break;\r
-               ret *= base;\r
-               ret += next;\r
-               str ++;\r
-       }\r
-\r
-       if( neg )\r
-               ret = -ret;     \r
-\r
-       if(end)\r
-               *end = (char*)str;\r
-       return ret;\r
-}\r
-\r
-EXPORT long strtol(const char *str, char **end, int base)\r
-{\r
-       long long tmp = strtoll(str, end, base);\r
-       if( tmp > LONG_MAX || tmp < LONG_MIN ) {\r
-               errno = ERANGE;\r
-               return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;\r
-       }\r
-       return tmp;\r
-}\r
-\r
-/**\r
- * \fn EXPORT int atoi(const char *str)\r
- * \brief Convert a string to an integer\r
- */\r
-EXPORT int atoi(const char *str)\r
-{\r
-       long long       tmp = strtoll(str, NULL, 0);\r
-       if( tmp > INT_MAX || tmp < INT_MIN ) {\r
-               errno = ERANGE;\r
-               return (tmp > INT_MAX) ? INT_MAX : INT_MIN;\r
-       }\r
-       return tmp;\r
-}\r
 \r
 int abs(int j) { return j < 0 ? -j : j; }\r
 long int labs(long int j) { return j < 0 ? -j : j; }\r

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