diff options
Diffstat (limited to 'libk/src/stdlib.c')
-rw-r--r-- | libk/src/stdlib.c | 164 |
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) |