aboutsummaryrefslogtreecommitdiff
path: root/libs/libc/conv.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libc/conv.c')
-rw-r--r--libs/libc/conv.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/libs/libc/conv.c b/libs/libc/conv.c
new file mode 100644
index 0000000..670fdb3
--- /dev/null
+++ b/libs/libc/conv.c
@@ -0,0 +1,145 @@
+// MIT License, Copyright (c) 2020 Marvin Borner
+
+#include <conv.h>
+#include <def.h>
+#include <math.h>
+#include <mem.h>
+#include <str.h>
+
+static const char HTOA_TABLE[] = "0123456789ABCDEF";
+static const char ITOA_TABLE[] = "0123456789";
+
+int atoi(const char *str)
+{
+ u32 s_str = strlen(str);
+ if (!s_str)
+ return 0;
+
+ u8 negative = 0;
+ if (str[0] == '-')
+ negative = 1;
+
+ u32 i = 0;
+ if (negative)
+ i++;
+
+ int ret = 0;
+ for (; i < s_str; i++) {
+ ret += (str[i] - '0') * pow(10, (int)((s_str - i) - 1));
+ }
+
+ if (negative)
+ ret *= -1;
+ return ret;
+}
+
+char *htoa(u32 n)
+{
+ char *ret = (char *)malloc(10);
+
+ int i = 0;
+ while (n) {
+ ret[i++] = HTOA_TABLE[n & 0xF];
+ n >>= 4;
+ }
+
+ if (!i) {
+ ret[0] = '0';
+ i++;
+ }
+
+ for (; i <= 9; i++)
+ ret[i] = 0;
+
+ char *aux = strdup(ret);
+ free(ret);
+ ret = aux;
+
+ strinv(ret);
+ return ret;
+}
+
+int htoi(const char *str)
+{
+ u32 s_str = strlen(str);
+
+ u32 i = 0;
+ int ret = 0;
+ for (; i < s_str; i++) {
+ char c = str[i];
+ int aux = 0;
+ if (c >= '0' && c <= '9')
+ aux = c - '0';
+ else if (c >= 'A' && c <= 'F')
+ aux = (c - 'A') + 10;
+
+ ret += aux * pow(16, (int)((s_str - i) - 1));
+ }
+
+ return ret;
+}
+
+char *itoa(int n)
+{
+ if (!n) {
+ char *ret = (char *)malloc(2);
+ ret[0] = '0';
+ ret[1] = 0;
+ return ret;
+ }
+ u8 negative = (u8)(n < 0);
+ if (negative)
+ n *= -1;
+
+ int sz;
+ for (sz = 0; n % pow(10, sz) != n; sz++) {
+ }
+
+ char *ret = (char *)malloc((u32)(sz + 1));
+
+ for (int i = 0; i < sz; i++) {
+ int digit = (n % pow(10, i + 1)) / pow(10, i);
+ ret[i] = ITOA_TABLE[digit];
+ }
+ ret[sz] = 0;
+
+ if (negative) {
+ char *aux = (char *)malloc((u32)(sz + 2));
+ strcpy(aux, ret);
+ aux[sz] = '-';
+ aux[sz + 1] = 0;
+ free(ret);
+ ret = aux;
+ }
+
+ strinv(ret);
+ return ret;
+}
+
+char *conv_base(int value, char *result, int base, int is_signed)
+{
+ if (base < 2 || base > 36) {
+ *result = '\0';
+ return result;
+ }
+
+ char *ptr = result, *ptr1 = result, tmp_char;
+ int tmp_value;
+
+ do {
+ tmp_value = value;
+ value /= base;
+ *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"
+ [35 + (tmp_value - value * base)];
+ } while (value);
+
+ if (is_signed && tmp_value < 0)
+ *ptr++ = '-';
+ *ptr-- = '\0';
+ while (ptr1 < ptr) {
+ tmp_char = *ptr;
+ *ptr-- = *ptr1;
+ *ptr1++ = tmp_char;
+ }
+ return result;
+}