diff options
Diffstat (limited to 'libk')
-rw-r--r-- | libk/makefile | 11 | ||||
-rw-r--r-- | libk/stdlib.h | 14 | ||||
-rw-r--r-- | libk/stdlib/console.cc | 28 | ||||
-rw-r--r-- | libk/string.cc | 26 | ||||
-rw-r--r-- | libk/string.h | 69 | ||||
-rw-r--r-- | libk/types.h | 30 |
6 files changed, 178 insertions, 0 deletions
diff --git a/libk/makefile b/libk/makefile new file mode 100644 index 0000000..faf5b79 --- /dev/null +++ b/libk/makefile @@ -0,0 +1,11 @@ + +CXX_OBJ := string.o stdlib/console.o + +libk.a: $(CXX_OBJ) + $(AR) rcs $@ $(CXX_OBJ) + +$(CXX_OBJ): %.o : %.cc + $(CXX) -target $(TARGET) $(CXX_FLAGS) -I$(CURDIR) -c $^ -o $@ + +clean: + rm libk.a $(CXX_OBJ) diff --git a/libk/stdlib.h b/libk/stdlib.h new file mode 100644 index 0000000..3e6619d --- /dev/null +++ b/libk/stdlib.h @@ -0,0 +1,14 @@ +#pragma once + +#include <string.h> + +class Console { +public: + virtual void write(const String &msg) = 0; +}; + +void console_set(Console *ptr); + +void printk(const String &msg); + +__attribute__((__noreturn__)) void abort(); diff --git a/libk/stdlib/console.cc b/libk/stdlib/console.cc new file mode 100644 index 0000000..dbc9b86 --- /dev/null +++ b/libk/stdlib/console.cc @@ -0,0 +1,28 @@ +#include "stdlib.h" + +static Console *global_console = nullptr; + +void console_set(Console *ptr) { + if (ptr != nullptr) { + global_console = ptr; + } +} + +void printk(const String &msg) { + if (global_console == nullptr) + return; + + global_console->write(msg); +} + +void abort() { + /* + * On gcc, a 'while(true) {}' will infinitely loop + * but clang will optimize it away on -O2 if it's empty + * therefore, add no-op + */ + while (true) { + asm volatile("nop"); + } + __builtin_unreachable(); +} diff --git a/libk/string.cc b/libk/string.cc new file mode 100644 index 0000000..5cd4bb2 --- /dev/null +++ b/libk/string.cc @@ -0,0 +1,26 @@ +#include "string.h" + +// TODO + +// int strcpy(char *dst, const char *stc); +// void strcat(void *dst, const void *src); +// char* strncpy(char *dest, const char *src, int length); +// int strncmp(const char *s1, const char *s2, int c); + +/* strcmp - compare two C-strings */ +constexpr int strcmp(const char *s1, const char *s2) +{ + const auto s1_len = strlen(s1); + for(size_t i = 0; i < s1_len; ++i) { + if(s1[i] == s2[i]) continue; + if(s1[i] > s2[i]) return 1; + if(s1[i] < s2[i]) return -1; + } + return 0; +} + +static_assert(strcmp("one", "one") == 0); +static_assert(strcmp("one", "two") < 0); +static_assert(strcmp("foo", "bar") > 0); + + diff --git a/libk/string.h b/libk/string.h new file mode 100644 index 0000000..deb6fde --- /dev/null +++ b/libk/string.h @@ -0,0 +1,69 @@ +#pragma once +#include "types.h" + +constexpr size_t strlen(const char *str) { + int len = 0; + while (str[len]) + ++len; + return len; +} + +/* reverse: reverse string s in place */ +constexpr void reverse(char s[]) { + int i, j; + char c; + + for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } +} + +/* itoa: convert n to characters in s */ +template <int base = 10> constexpr void itoa(int n, char s[]) { + int i, sign; + + if ((sign = n) < 0) /* record sign */ + n = -n; /* make n positive */ + + i = 0; + do { /* generate digits in reverse order */ + s[i++] = "0123456789abcdef"[n % base]; /* get next digit */ + } while ((n /= base) > 0); /* delete it */ + + if (sign < 0) + s[i++] = '-'; + + s[i] = '\0'; + + reverse(s); +} + +class String { +public: + class Iterator { + friend class String; + + public: + char next() { return p->buffer[pos++]; } + operator bool() const { return (pos < p->m_length); } + + private: + Iterator(const String *s) : p(s) {} + + size_t pos = 0; + const String *p; + }; + + friend class Iterator; + + String(const char *d) : buffer{d}, m_length{strlen(d)} {} + String(const char *d, size_t l) : buffer{d}, m_length{l} {} + + Iterator begin() const { return Iterator(this); } + +private: + const char *const buffer; + const size_t m_length; +}; diff --git a/libk/types.h b/libk/types.h new file mode 100644 index 0000000..0818342 --- /dev/null +++ b/libk/types.h @@ -0,0 +1,30 @@ +#pragma once + +typedef unsigned short size_t; +static_assert(sizeof(size_t) >= 2); + + +typedef unsigned char uint8_t; +static_assert(sizeof(uint8_t) == 1); + +typedef unsigned short uint16_t; +static_assert(sizeof(uint16_t) == 2); + +typedef unsigned int uint32_t; +static_assert(sizeof(uint32_t) == 4); + +//typedef unsigned long uint64_t; +//static_assert(sizeof(uint64_t) == 8); + + +typedef char int8_t; +static_assert(sizeof(int8_t) == 1); + +typedef short int16_t; +static_assert(sizeof(int16_t) == 2); + +typedef int int32_t; +static_assert(sizeof(int32_t) == 4); + +//typedef long int64_t; +//static_assert(sizeof(int64_t) == 8); |