summaryrefslogtreecommitdiff
path: root/libk/src/stdlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'libk/src/stdlib.c')
-rw-r--r--libk/src/stdlib.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/libk/src/stdlib.c b/libk/src/stdlib.c
new file mode 100644
index 0000000..fb832ce
--- /dev/null
+++ b/libk/src/stdlib.c
@@ -0,0 +1,164 @@
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#define ATOX(name, type) \
+ type name(const char* s) { \
+ for(; isspace(*s); s++); \
+ int neg = 0; \
+ switch (*s) { \
+ case '-': \
+ neg = 1; \
+ /* FALLTHRU */ \
+ case '+': \
+ s++; \
+ break; \
+ } \
+ type num = 0; \
+ for (; *s == '0'; s++); \
+ for (; isdigit(*s); s++) { \
+ num *= 10; \
+ num += *s - '0'; \
+ } \
+ return num * (neg ? -1 : 1); \
+ }
+
+ATOX(atoi, int)
+ATOX(atol, long int)
+ATOX(atoll, long long int)
+
+char itoc(int i) {
+ if(i < 10) {
+ return '0' + i;
+ } else {
+ return 'a' + (i - 10);
+ }
+}
+
+int ctoi(char c) {
+ if(c < 'A') {
+ return c - '0';
+ } else if(c < 'a') {
+ return c - 'A' + 10;
+ } else {
+ return c - 'a' + 10;
+ }
+}
+
+#define UXTOA(type, name) \
+ char *name(unsigned type n, char *buffer, int radix) { \
+ if (n == 0) { \
+ buffer[0] = '0'; \
+ buffer[1] = '\0'; \
+ return buffer; \
+ } \
+ char *start = buffer; \
+ for (; n; n /= radix) { \
+ *buffer++ = itoc(n % radix); \
+ } \
+ *buffer-- = '\0'; \
+ while(buffer > start) { \
+ char tmp = *start; \
+ *start++ = *buffer; \
+ *buffer-- = tmp; \
+ } \
+ return buffer; \
+ }
+
+UXTOA(int, utoa)
+UXTOA(long int, ultoa)
+
+#define XTOA(type, name) \
+ char *name(type n, char* buffer, int radix) { \
+ if (n == 0) { \
+ buffer[0] = '0'; \
+ buffer[1] = '\0'; \
+ return buffer; \
+ } \
+ if (n < 0) { \
+ *buffer++ = '-'; \
+ n = -n; \
+ } \
+ char *start = buffer; \
+ for (; n; n /= radix) { \
+ *buffer++ = itoc(n % radix); \
+ } \
+ *buffer-- = '\0'; \
+ while(buffer > start) { \
+ char tmp = *start; \
+ *start++ = *buffer; \
+ *buffer-- = tmp; \
+ } \
+ return buffer; \
+ }
+
+XTOA(int, itoa)
+XTOA(long int, ltoa)
+
+char *ftoa(float f, char *buffer) {
+ char *b = buffer;
+ if (f < 0 || f == -0)
+ *buffer++ = '-';
+ int n, i=0, k=0;
+ n = (int) f;
+ while (n > 0) {
+ f /= 10;
+ n = (int)f;
+ i++;
+ }
+ *(buffer+i) = '.';
+ f *= 10;
+ n = (int) f;
+ f -= n;
+ while ((n > 0.1) || (i > k)) {
+ if (k == i)
+ k++;
+ *(buffer+k) = '0' + n;
+ f *= 10;
+ n = (int) f;
+ f -= n;
+ k++;
+ }
+ *(buffer+k) = '\0';
+ return b;
+}
+
+#define STRTOX(name, type) \
+ type name(const char *s, char **endptr, int radix) { \
+ *endptr = NULL; \
+ for(; isspace(*s); s++); \
+ int neg = 0; \
+ switch (*s) { \
+ case '-': \
+ neg = 1; \
+ /* FALLTHRU */ \
+ case '+': \
+ s++; \
+ break; \
+ } \
+ if (!radix) { \
+ if (*s == '0') { \
+ s++; \
+ if (*s == 'x' || *s == 'X') { \
+ s++; \
+ radix = 16; \
+ } else { \
+ radix = 8; \
+ } \
+ } else { \
+ radix = 10; \
+ } \
+ } \
+ for (; *s == '0'; s++, *endptr = (void*) s); \
+ type num = 0; \
+ for (; isdigit(*s); s++, *endptr = (void*) s) { \
+ num *= radix; \
+ num += *s - '0'; \
+ } \
+ return num * (neg ? -1 : 1); \
+ }
+
+STRTOX(strtoi, int)
+STRTOX(strtol, long int)
+STRTOX(strtoll, long long int)