* AcessOS Basic C Library\r
* stdlib.c\r
*/\r
-/**\r
- * \todo Move half of these to stdio\r
- */\r
#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
}\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
+EXPORT long long strtoll(const char *str, char **end, int base)\r
{\r
- int neg = 0;\r
- int ret = 0;\r
- \r
- // NULL Check\r
- if(!str) return 0;\r
+ int neg;\r
+ long long ret = 0;\r
\r
- while(*str == ' ' || *str == '\t') str++;\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\r
- if(*str == '-') {\r
- neg = 1;\r
+ // Check for negative (or positive) sign\r
+ if(*str == '-' || *str == '+') {\r
+ neg = (*str == '-');\r
str++;\r
}\r
\r
- if(*str == '0') {\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
- if(*str == 'x') {\r
- str++;\r
- // Hex\r
- while( ('0' <= *str && *str <= '9')\r
- || ('A' <= *str && *str <= 'F' )\r
- || ('a' <= *str && *str <= 'f' )\r
- )\r
- {\r
- ret *= 16;\r
- if(*str <= '9') {\r
- ret += *str - '0';\r
- } else if (*str <= 'F') {\r
- ret += *str - 'A' + 10;\r
- } else {\r
- ret += *str - 'a' + 10;\r
- }\r
- str++;\r
- }\r
- } else {\r
- // Octal\r
- while( '0' <= *str && *str <= '7' )\r
- {\r
- ret *= 8;\r
- ret += *str - '0';\r
- str++;\r
- }\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
- // Decimal\r
- while( '0' <= *str && *str <= '9' )\r
- {\r
- ret *= 10;\r
- ret += *str - '0';\r
- str++;\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
- // Negate if needed\r
- if(neg) ret = -ret;\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
\r