summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kc/core/Makefile2
-rw-r--r--lib/string.c147
-rw-r--r--lib/strtoull.c148
-rw-r--r--loader/Makefile2
4 files changed, 149 insertions, 150 deletions
diff --git a/kc/core/Makefile b/kc/core/Makefile
index 394b2dc..eb18a4f 100644
--- a/kc/core/Makefile
+++ b/kc/core/Makefile
@@ -14,7 +14,7 @@ GOBJS := entry_x86_64.o reloc_x86_64.o dynamic_x86_64.o \
kprintf.o serial.o port.o mmu.o kc_main.o memory.o memset.o memcpy.o \
memmove.o memcmp.o cpu.o vm_tree.o exceptions.o panic.o msr.o task.o \
cpu_task.o irq.o kcc_memory.o string.o pic8259.o pic8259_isr.o \
- pit8253.o page_early.o page_stack.o strtoull.o kstdio.o
+ pit8253.o page_early.o page_stack.o kstdio.o
IOBJS :=
# __attribute__((interrupt)) requires -mgeneral-regs-only
diff --git a/lib/string.c b/lib/string.c
index 5d4efb7..f6bc682 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -1,4 +1,5 @@
#include <lib/kstring.h>
+#include <stdbool.h>
size_t strlen(const char *s)
{
@@ -9,3 +10,149 @@ size_t strlen(const char *s)
return l;
}
+static long long valueof(int c, int base)
+{
+ long long result = 0;
+
+ if (base < 2 || base > 36)
+ {
+ // bases less than 2 or greater than 36 are invalid.
+ return -1;
+ }
+
+ // check if value is an ascii numeric character
+ if (c >= '0' && c <= '9')
+ {
+ // simple as
+ result = (long long)(c ^ 0x30);
+ }
+
+ // check if value is an uppercase ASCII alphabetical character
+ else if (
+ (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z'))
+ {
+ // mask in uppercase bit
+ c |= 0x20;
+ // value is 10 plus the alphabetical order of the character
+ result = (long long)(10 + c - 'a');
+ }
+ else
+ {
+ // character has no valid interpretation under base 36
+ return -1LL;
+ }
+
+ if (result > (base - 1))
+ {
+ // character is not valid under given base
+ return -1LL;
+ }
+
+ return result;
+}
+
+unsigned long long strtoull(
+ const char *restrict begin,
+ char **restrict end,
+ int base)
+{
+ long result = 0;
+ const char *current = begin;
+
+ // check for empty string
+ if (*current == 0)
+ {
+ if (end)
+ {
+ *end = (char *)begin;
+ return result;
+ }
+ }
+
+ // skip initial whitespace
+ bool whitespace = true;
+ while (whitespace)
+ {
+ switch (*current)
+ {
+ case 0x9:
+ case 0xa:
+ case 0xb:
+ case 0xc:
+ case 0xd:
+ case 0x20:
+ current++;
+ break;
+ default:
+ whitespace = false;
+ }
+ }
+
+ bool negative = false;
+ // detect if negative sign is used
+ if (*current == '-')
+ {
+ negative = true;
+ current++;
+ }
+
+ // detect base from input
+ if (base == 0)
+ {
+ // base is non-decimal
+ if (current[0] == 0)
+ {
+ if (current[1] == 'b')
+ {
+ base = 2;
+ current += 2;
+ }
+ else if (current[1] == 'x')
+ {
+ base = 16;
+ current += 2;
+ }
+ else
+ {
+ base = 8;
+ current++;
+ }
+ }
+ // base is decimal otherwise
+ else
+ {
+ base = 10;
+ }
+ }
+ // do the actual conversion now
+ while (*current)
+ {
+ long long value = valueof(*current, base);
+
+ // we've reached the end of the conversion
+ if (value == -1)
+ {
+ break;
+ }
+
+ result *= base;
+ result += value;
+ current++;
+ }
+
+ // store the end pointer if needed
+ if (end)
+ {
+ *end = (char *)current;
+ }
+
+ // flip the result if we're meant to
+ if (negative)
+ {
+ result = -result;
+ }
+
+ return result;
+}
+
diff --git a/lib/strtoull.c b/lib/strtoull.c
deleted file mode 100644
index bb71c24..0000000
--- a/lib/strtoull.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include <stdbool.h>
-
-static long long valueof(int c, int base)
-{
- long long result = 0;
-
- if (base < 2 || base > 36)
- {
- // bases less than 2 or greater than 36 are invalid.
- return -1;
- }
-
- // check if value is an ascii numeric character
- if (c >= '0' && c <= '9')
- {
- // simple as
- result = (long long)(c ^ 0x30);
- }
-
- // check if value is an uppercase ASCII alphabetical character
- else if (
- (c >= 'A' && c <= 'Z') ||
- (c >= 'a' && c <= 'z'))
- {
- // mask in uppercase bit
- c |= 0x20;
- // value is 10 plus the alphabetical order of the character
- result = (long long)(10 + c - 'a');
- }
- else
- {
- // character has no valid interpretation under base 36
- return -1LL;
- }
-
- if (result > (base - 1))
- {
- // character is not valid under given base
- return -1LL;
- }
-
- return result;
-}
-
-unsigned long long strtoull(
- const char *restrict begin,
- char **restrict end,
- int base)
-{
- long result = 0;
- const char *current = begin;
-
- // check for empty string
- if (*current == 0)
- {
- if (end)
- {
- *end = (char *)begin;
- return result;
- }
- }
-
- // skip initial whitespace
- bool whitespace = true;
- while (whitespace)
- {
- switch (*current)
- {
- case 0x9:
- case 0xa:
- case 0xb:
- case 0xc:
- case 0xd:
- case 0x20:
- current++;
- break;
- default:
- whitespace = false;
- }
- }
-
- bool negative = false;
- // detect if negative sign is used
- if (*current == '-')
- {
- negative = true;
- current++;
- }
-
- // detect base from input
- if (base == 0)
- {
- // base is non-decimal
- if (current[0] == 0)
- {
- if (current[1] == 'b')
- {
- base = 2;
- current += 2;
- }
- else if (current[1] == 'x')
- {
- base = 16;
- current += 2;
- }
- else
- {
- base = 8;
- current++;
- }
- }
- // base is decimal otherwise
- else
- {
- base = 10;
- }
- }
- // do the actual conversion now
- while (*current)
- {
- long long value = valueof(*current, base);
-
- // we've reached the end of the conversion
- if (value == -1)
- {
- break;
- }
-
- result *= base;
- result += value;
- current++;
- }
-
- // store the end pointer if needed
- if (end)
- {
- *end = (char *)current;
- }
-
- // flip the result if we're meant to
- if (negative)
- {
- result = -result;
- }
-
- return result;
-}
-
diff --git a/loader/Makefile b/loader/Makefile
index f1406a6..48b0e98 100644
--- a/loader/Makefile
+++ b/loader/Makefile
@@ -16,7 +16,7 @@ LDFLAGS := --target=$(GNUEFIARCH)-unknown-windows -nostdlib -ggdb \
all: $(IMAGE)
-OBJS := main_efi.o elf64.o memcmp.o memmove.o kprintf.o strtoull.o memset.o \
+OBJS := main_efi.o elf64.o memcmp.o memmove.o kprintf.o string.o memset.o \
memcpy.o
DEPS := $(OBJS:.o=.d)