summaryrefslogtreecommitdiff
path: root/Source/Library
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-18 15:27:34 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-18 15:27:34 +0200
commit323e12f1f9ab33df15dcfed210e807561d98fa8c (patch)
tree7d76e6932d4a979a1f2bfafc94478b66b1479bbc /Source/Library
parentbc2eccdd11c27029096fb3e891073503eb269e27 (diff)
downloadMelon-323e12f1f9ab33df15dcfed210e807561d98fa8c.tar.gz
Melon-323e12f1f9ab33df15dcfed210e807561d98fa8c.zip
Re-organized everything
Diffstat (limited to 'Source/Library')
-rw-r--r--Source/Library/Common/BasicString.class.cpp175
-rw-r--r--Source/Library/Common/BasicString.class.h53
-rw-r--r--Source/Library/Common/Bitset.class.cpp62
-rw-r--r--Source/Library/Common/Bitset.class.h31
-rw-r--r--Source/Library/Common/ByteArray.class.cpp59
-rw-r--r--Source/Library/Common/ByteArray.class.h27
-rw-r--r--Source/Library/Common/CMem.ns.cpp35
-rw-r--r--Source/Library/Common/CMem.ns.h17
-rw-r--r--Source/Library/Common/OrderedArray.class.cpp54
-rw-r--r--Source/Library/Common/OrderedArray.class.h29
-rw-r--r--Source/Library/Common/Rand.ns.cpp18
-rw-r--r--Source/Library/Common/Rand.ns.h12
-rw-r--r--Source/Library/Common/SimpleList.class.h70
-rw-r--r--Source/Library/Common/String.class.cpp181
-rw-r--r--Source/Library/Common/String.class.h46
-rw-r--r--Source/Library/Common/Vector.class.cpp135
-rw-r--r--Source/Library/Common/Vector.class.h36
-rw-r--r--Source/Library/Common/WChar.class.cpp155
-rw-r--r--Source/Library/Common/WChar.class.h89
-rw-r--r--Source/Library/Common/types.h19
-rw-r--r--Source/Library/Makefile33
-rw-r--r--Source/Library/Userland/Syscall/Syscall.wtf.cpp20
-rw-r--r--Source/Library/Userland/Syscall/Syscall.wtf.h9
-rw-r--r--Source/Library/Userland/common.h10
24 files changed, 1375 insertions, 0 deletions
diff --git a/Source/Library/Common/BasicString.class.cpp b/Source/Library/Common/BasicString.class.cpp
new file mode 100644
index 0000000..ceab60b
--- /dev/null
+++ b/Source/Library/Common/BasicString.class.cpp
@@ -0,0 +1,175 @@
+#include <Vector.class.h>
+
+#define FREE if (m_string != 0) delete m_string;
+#define ALLOC m_string = new T[m_length];
+#define VRFY if (m_length == 0) { m_string = NULL; return; }
+
+using namespace CMem;
+
+template <typename T>
+BasicString<T>::BasicString() {
+ m_string = NULL;
+ m_length = 0;
+}
+
+template <typename T>
+BasicString<T>::BasicString(const T* string, u32int length) {
+ m_string = NULL;
+ affect(string, length);
+}
+
+template <typename T>
+BasicString<T>::BasicString(const BasicString<T> &other) {
+ m_string = NULL;
+ affect(other);
+}
+
+template <typename T>
+BasicString<T>::BasicString(const T value, u32int count) {
+ m_string = NULL;
+ affect(value, count);
+}
+
+template <typename T>
+BasicString<T>::~BasicString() {
+ FREE;
+}
+
+template <typename T>
+void BasicString<T>::affect(const BasicString<T> &other) {
+ FREE;
+ m_length = other.m_length;
+ VRFY;
+ ALLOC;
+ memcpy((u8int*)m_string, (u8int*)(other.m_string), m_length * sizeof(T));
+}
+
+template <typename T>
+void BasicString<T>::affect(const T* string, u32int length) {
+ FREE;
+ m_length = length;
+ VRFY;
+ ALLOC;
+ memcpy((u8int*)string, (u8int*)string, m_length * sizeof(T));
+}
+
+template <typename T>
+void BasicString<T>::affect(const T value, u32int count) {
+ FREE;
+ m_length = count;
+ VRFY;
+ ALLOC;
+ for (u32int i = 0; i < count; i++) {
+ m_string[i] = value;
+ }
+}
+
+template <typename T>
+bool BasicString<T>::compare(const BasicString<T> &other) const {
+ if (m_length != other.m_length) return false;
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] != other.m_string[i]) return false;
+ }
+ return true;
+}
+
+template <typename T>
+bool BasicString<T>::compare(const T* string, u32int length) const {
+ if (m_length != length) return false;
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] != string[i]) return false;
+ }
+ return true;
+}
+
+template <typename T>
+BasicString<T> &BasicString<T>::append(const BasicString<T> &other) {
+ T* newdata = new T[m_length + other.m_length];
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ for (u32int i = 0; i < other.m_length; i++) {
+ newdata[i + m_length] = other.m_string[i];
+ }
+ FREE;
+ m_string = newdata;
+ m_length += other.m_length;
+ return *this;
+}
+
+template <typename T>
+BasicString<T> &BasicString<T>::append(const T* string, u32int length) {
+ T* newdata = new T[m_length + length];
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ for (u32int i = 0; i < length; i++) {
+ newdata[i + m_length] = string[i];
+ }
+ FREE;
+ m_string = newdata;
+ m_length += length;
+ return *this;
+}
+
+template <typename T>
+BasicString<T> &BasicString<T>::append(const T other) {
+ T* newdata = new T[m_length + 1];
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ FREE;
+ m_string = newdata;
+ m_string[m_length] = other;
+ m_length++;
+ return *this;
+}
+
+template <typename T>
+BasicString<T> BasicString<T>::concat(const BasicString<T> &other) const {
+ BasicString<T> ret(*this);
+ return (ret.append(other));
+}
+
+template <typename T>
+BasicString<T> BasicString<T>::concat(const T* string, u32int length) const {
+ BasicString<T> ret(*this);
+ return (ret.append(string, length));
+}
+
+template <typename T>
+BasicString<T> BasicString<T>::concat(const T other) const {
+ BasicString<T> ret(*this);
+ return (ret.append(other));
+}
+
+template <typename T>
+void BasicString<T>::clear() {
+ FREE;
+ m_string = 0;
+ m_length = 0;
+}
+
+template <typename T>
+Vector< BasicString<T> > BasicString<T>::split(T sep) const {
+ Vector< BasicString<T> > ret;
+ ret.push(BasicString<T>());
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] == sep) {
+ ret.push(BasicString<T>());
+ } else {
+ ret.back().append(m_string[i]);
+ }
+ }
+ return ret;
+}
+
+template <typename T>
+BasicString<T> BasicString<T>::substr(s32int start, u32int size) {
+ if (start < 0) start = m_length - start;
+ BasicString<T> ret;
+ ret.m_string = new T[size + 1];
+ ret.m_length = size;
+ memcpy((u8int*)ret.m_string, (u8int*)(&m_string[start]), size * sizeof(T));
+ return ret;
+}
diff --git a/Source/Library/Common/BasicString.class.h b/Source/Library/Common/BasicString.class.h
new file mode 100644
index 0000000..17055e8
--- /dev/null
+++ b/Source/Library/Common/BasicString.class.h
@@ -0,0 +1,53 @@
+#ifndef DEF_BASICSTRING_CLASS_H
+#define DEF_BASICSTRING_CLASS_H
+
+#include <common.h>
+
+template <typename T> class Vector;
+
+template <typename T>
+class BasicString {
+ protected:
+ T *m_string;
+ u32int m_length;
+
+ public:
+ BasicString();
+ BasicString(const T* string, u32int length);
+ BasicString(const BasicString<T> &other);
+ BasicString(const T, u32int count = 1);
+ virtual ~BasicString();
+
+ void affect(const BasicString<T> &other);
+ void affect(const T* string, u32int length);
+ void affect(const T value, u32int count = 1);
+ void operator= (const BasicString<T> &other) { affect(other); }
+
+ bool compare(const BasicString<T> &other) const;
+ bool compare(const T* string, u32int length) const;
+ bool operator== (const BasicString<T> &other) const { return compare(other); }
+ bool operator!= (const BasicString<T> &other) const { return !compare(other); }
+
+ BasicString<T>& append(const BasicString<T> &other);
+ BasicString<T>& append(const T* string, u32int length);
+ BasicString<T>& append(const T other);
+ BasicString<T>& operator+= (const BasicString<T> &other) { return append(other); }
+ BasicString<T>& operator+= (const T other) { return append(other); }
+
+ BasicString<T> concat(const BasicString<T> &other) const;
+ BasicString<T> concat(const T* string, u32int length) const;
+ BasicString<T> concat(const T other) const;
+
+ T& operator[] (int index) const { return m_string[index]; }
+
+ u32int size() const { return m_length; }
+ void clear();
+ bool empty() const { return m_length == 0; }
+
+ Vector< BasicString<T> > split(T sep) const;
+ BasicString<T> substr(s32int start, u32int size);
+};
+
+#include "BasicString.class.cpp"
+
+#endif
diff --git a/Source/Library/Common/Bitset.class.cpp b/Source/Library/Common/Bitset.class.cpp
new file mode 100644
index 0000000..ec4e62c
--- /dev/null
+++ b/Source/Library/Common/Bitset.class.cpp
@@ -0,0 +1,62 @@
+#include "Bitset.class.h"
+
+Bitset::Bitset() {
+}
+
+Bitset::Bitset(u32int size) {
+ init(size, (u32int*)Mem::kalloc(INDEX_FROM_BIT(size)));
+}
+
+Bitset::Bitset(u32int size, u32int *ptr) {
+ init(size, ptr);
+}
+
+Bitset::~Bitset() {
+ Mem::kfree(m_data);
+}
+
+void Bitset::init(u32int size, u32int *ptr) {
+ m_size = size;
+ m_data = ptr;
+ for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) {
+ m_data[i] = 0;
+ }
+ m_usedCount = 0;
+}
+
+void Bitset::setBit(u32int number) {
+ u32int idx = INDEX_FROM_BIT(number);
+ u32int off = OFFSET_FROM_BIT(number);
+ m_data[idx] |= (0x1 << off);
+ m_usedCount++;
+}
+
+void Bitset::clearBit(u32int number) {
+ u32int idx = INDEX_FROM_BIT(number);
+ u32int off = OFFSET_FROM_BIT(number);
+ m_data[idx] &= ~(0x1 << off);
+ m_usedCount--;
+}
+
+bool Bitset::testBit(u32int number) {
+ u32int idx = INDEX_FROM_BIT(number);
+ u32int off = OFFSET_FROM_BIT(number);
+ return (m_data[idx] & (0x1 << off));
+}
+
+u32int Bitset::firstFreeBit() {
+ for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) {
+ if (m_data[i] != 0xFFFFFFFF) {
+ for (int j = 0; j < 32; j++) {
+ if (!(m_data[i] & (0x1 << j))) {
+ return (i * 4 * 8) + j;
+ }
+ }
+ }
+ }
+ return (u32int) - 1;
+}
+
+u32int Bitset::usedBits() {
+ return m_usedCount;
+}
diff --git a/Source/Library/Common/Bitset.class.h b/Source/Library/Common/Bitset.class.h
new file mode 100644
index 0000000..8a0707d
--- /dev/null
+++ b/Source/Library/Common/Bitset.class.h
@@ -0,0 +1,31 @@
+#ifndef DEF_BITSET_CLASS_H
+#define DEF_BITSET_CLASS_H
+
+#include <common.h>
+
+#define INDEX_FROM_BIT(a) (a/(8*4))
+#define OFFSET_FROM_BIT(a) (a%(8*4))
+
+class Bitset {
+ private:
+ u32int m_size;
+ u32int *m_data;
+ u32int m_usedCount;
+
+ public:
+ Bitset();
+ Bitset(u32int size);
+ Bitset(u32int size, u32int *ptr);
+ ~Bitset();
+
+ void init(u32int size, u32int *ptr);
+
+ void setBit(u32int number);
+ void clearBit(u32int number);
+ bool testBit(u32int number);
+ u32int firstFreeBit();
+
+ u32int usedBits();
+};
+
+#endif
diff --git a/Source/Library/Common/ByteArray.class.cpp b/Source/Library/Common/ByteArray.class.cpp
new file mode 100644
index 0000000..2a42702
--- /dev/null
+++ b/Source/Library/Common/ByteArray.class.cpp
@@ -0,0 +1,59 @@
+#include "ByteArray.class.h"
+
+//Define size of a uchar_repr_t
+#define CHARSZ(x) (x.c[0] == 0 ? 0 : (x.c[1] == 0 ? 1 : (x.c[2] == 0 ? 2 : (x.c[3] == 0 ? 3 : 4))))
+
+using namespace CMem;
+
+ByteArray::ByteArray(const char* c) : BasicString<u8int>() {
+ m_length = strlen(c);
+ memcpy(m_string, (u8int*)c, m_length);
+}
+
+void ByteArray::affect(const String &string, u8int encoding) {
+ m_length = 0;
+ for (u32int i = 0; i < string.size(); i++) {
+ uchar_repr_t a = string[i].encode(encoding);
+ m_length += CHARSZ(a);
+ }
+ if (m_string != 0) delete m_string;
+ if (m_length == 0) {
+ m_string = 0;
+ return;
+ }
+ m_string = new u8int[m_length];
+ u32int x = 0;
+ for (u32int i = 0; i < string.size(); i++) {
+ uchar_repr_t a = string[i].encode(encoding);
+ memcpy(m_string + x, (u8int*)a.c, CHARSZ(a));
+ x += CHARSZ(a);
+ }
+}
+
+void ByteArray::resize(u32int size) {
+ if (size == m_length) return;
+ if (size == 0) {
+ delete m_string;
+ m_length = 0;
+ m_string = 0;
+ }
+ u8int *nd = new u8int[size];
+ if (size < m_length) {
+ memcpy(nd, m_string, size);
+ } else {
+ memcpy(nd, m_string, m_length);
+ memset(nd + m_length, 0, size - m_length);
+ }
+ delete m_string;
+ m_string = nd;
+ m_length = size;
+}
+
+String ByteArray::toString (u8int encoding) {
+ char* c = new char[m_length + 1];
+ memcpy((u8int*)c, m_string, m_length);
+ c[m_length] = 0; //Add NULL terminator
+ String r(c, encoding);
+ delete c;
+ return r;
+}
diff --git a/Source/Library/Common/ByteArray.class.h b/Source/Library/Common/ByteArray.class.h
new file mode 100644
index 0000000..339e0d4
--- /dev/null
+++ b/Source/Library/Common/ByteArray.class.h
@@ -0,0 +1,27 @@
+#ifndef DEF_BYTEARRAY_CLASS_H
+#define DEF_BYTEARRAY_CLASS_H
+
+#include <String.class.h>
+
+class ByteArray : public BasicString<u8int> {
+ public:
+ ByteArray() : BasicString<u8int>() {}
+ ByteArray(const BasicString<u8int> &bs) : BasicString<u8int>() {
+ m_length = bs.size();
+ m_string = new u8int[m_length];
+ for (u32int i = 0; i < m_length; i++)
+ m_string[i] = bs[i];
+ }
+ ByteArray(const ByteArray& other) : BasicString<u8int>(other) {}
+ ByteArray(const char* c);
+ ByteArray(u32int size) : BasicString<u8int>((u8int)0, size) {}
+ ByteArray(const String &string, u8int encoding = UE_UTF8) : BasicString<u8int>() { affect(string, encoding); }
+
+ void affect(const String& string, u8int encoding = UE_UTF8);
+ void resize(u32int size);
+
+ String toString(u8int encoding = UE_UTF8);
+ operator u8int* () { return m_string; }
+};
+
+#endif
diff --git a/Source/Library/Common/CMem.ns.cpp b/Source/Library/Common/CMem.ns.cpp
new file mode 100644
index 0000000..37cdf0c
--- /dev/null
+++ b/Source/Library/Common/CMem.ns.cpp
@@ -0,0 +1,35 @@
+#include <common.h>
+
+namespace CMem {
+
+//Standard C functions
+u8int *memcpy(u8int *dest, const u8int *src, int count) {
+ for (int i = 0; i < count; i++) {
+ dest[i] = src[i];
+ }
+ return dest;
+}
+
+u8int *memset(u8int *dest, u8int val, int count) {
+ for (int i = 0; i < count; i++) {
+ dest[i] = val;
+ }
+ return dest;
+}
+
+u16int *memsetw(u16int *dest, u16int val, int count) {
+ for (int i = 0; i < count; i++) {
+ dest[i] = val;
+ }
+ return dest;
+}
+
+u32int strlen(const char *str) {
+ u32int i = 0;
+ while (str[i]) {
+ i++;
+ }
+ return i;
+}
+
+}
diff --git a/Source/Library/Common/CMem.ns.h b/Source/Library/Common/CMem.ns.h
new file mode 100644
index 0000000..f0c15da
--- /dev/null
+++ b/Source/Library/Common/CMem.ns.h
@@ -0,0 +1,17 @@
+#ifdef DEF_COMMON
+
+#ifndef DEF_CMEM_NS_H
+#define DEF_CMEM_NS_H
+
+//This namespace contains basic memory managment functions
+
+namespace CMem {
+ u8int *memcpy(u8int *dest, const u8int *src, int count);
+ u8int *memset(u8int *dest, u8int val, int count);
+ u16int *memsetw(u16int *dest, u16int val, int count);
+ u32int strlen(const char *str);
+}
+
+#endif
+
+#endif
diff --git a/Source/Library/Common/OrderedArray.class.cpp b/Source/Library/Common/OrderedArray.class.cpp
new file mode 100644
index 0000000..8b8f24f
--- /dev/null
+++ b/Source/Library/Common/OrderedArray.class.cpp
@@ -0,0 +1,54 @@
+template <typename T>
+OrderedArray<T>::OrderedArray(u32int max_size) {
+ m_array = (T*)Memory::alloc(max_size * sizeof(T*));
+ m_size = 0;
+ m_maxSize = max_size;
+}
+
+template <typename T>
+OrderedArray<T>::OrderedArray(T **addr, u32int max_size) {
+ m_array = addr;
+ memset((u8int*)addr, 0, max_size * sizeof(T*));
+ m_size = 0;
+ m_maxSize = max_size;
+}
+
+template <typename T>
+OrderedArray<T>::~OrderedArray() {
+ //Free memory
+}
+
+template <typename T>
+void OrderedArray<T>::insert(T *element) {
+ if (m_size == m_maxSize) return; //Array is full
+ u32int iterator = 0;
+ while (iterator < m_size && *(m_array[iterator]) < *element) {
+ iterator++;
+ }
+ if (iterator == m_size) {
+ m_array[m_size++] = element;
+ } else {
+ u32int pos = iterator;
+ while (iterator < m_size) {
+ iterator++;
+ m_array[iterator] = m_array[iterator - 1];
+ }
+ m_size++;
+ m_array[pos] = element;
+ }
+}
+
+template <typename T>
+T *OrderedArray<T>::lookup(int index) {
+ return m_array[index];
+}
+
+template <typename T>
+void OrderedArray<T>::remove(int index) {
+ m_size--;
+ while (index < m_size) {
+ m_array[index] = m_array[index + 1];
+ index++;
+ }
+}
+
diff --git a/Source/Library/Common/OrderedArray.class.h b/Source/Library/Common/OrderedArray.class.h
new file mode 100644
index 0000000..3091249
--- /dev/null
+++ b/Source/Library/Common/OrderedArray.class.h
@@ -0,0 +1,29 @@
+#ifndef DEF_ORDARRAY_CLASS
+#define DEF_ORDARRAY_CLASS
+
+#include <common.h>
+
+template <typename T>
+class OrderedArray {
+ private:
+ T *m_array[];
+ u32int m_size;
+ u32int m_maxSize;
+
+ public:
+ OrderedArray(u32int max_size);
+ OrderedArray(T **addr, u32int max_size);
+ ~OrderedArray();
+
+ u32int size() { return m_size; }
+
+ void insert(T *element);
+ T *lookup(int index);
+ void remove(int index);
+
+ T *operator[] (int index) { return lookup(index); }
+};
+
+#include "OrderedArray.class.cpp"
+
+#endif
diff --git a/Source/Library/Common/Rand.ns.cpp b/Source/Library/Common/Rand.ns.cpp
new file mode 100644
index 0000000..e568678
--- /dev/null
+++ b/Source/Library/Common/Rand.ns.cpp
@@ -0,0 +1,18 @@
+#include "Rand.ns.h"
+
+namespace Rand {
+
+u32int m = 2073741824, a = 50000, b = 1534;
+u64int current = RANDOM_SEED;
+
+u64int rand() {
+ current = (u32int)(a*current + b);
+ while (current > m) current -= m;
+ return current;
+}
+
+u64int max() {
+ return m;
+}
+
+}
diff --git a/Source/Library/Common/Rand.ns.h b/Source/Library/Common/Rand.ns.h
new file mode 100644
index 0000000..71d4f60
--- /dev/null
+++ b/Source/Library/Common/Rand.ns.h
@@ -0,0 +1,12 @@
+#ifndef DEF_RAND_NS_H
+#define DEF_RAND_NS_H
+
+#include <common.h>
+
+namespace Rand {
+ u64int rand();
+ u64int max();
+}
+
+#endif
+
diff --git a/Source/Library/Common/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h
new file mode 100644
index 0000000..64e37aa
--- /dev/null
+++ b/Source/Library/Common/SimpleList.class.h
@@ -0,0 +1,70 @@
+#ifndef DEF_SIMPLELIST_CLASS_H
+#define DEF_SIMPLELIST_CLASS_H
+
+/* This class implements a singly linked list. It is also used to represent one of its elements. */
+
+template <typename T>
+class SimpleList {
+ protected:
+ T m_value;
+ SimpleList<T>* m_next;
+
+ public:
+ SimpleList(const T& value, SimpleList<T>* next = 0) : m_value(value), m_next(next) {}
+ ~SimpleList() {
+ if (m_next != 0)
+ delete m_next;
+ }
+
+ T& v() { return m_value; }
+ T& operator* () { return m_value; }
+
+ SimpleList<T>* cons(const T& value) {
+ return new SimpleList<T>(value, this);
+ }
+
+ SimpleList<T>* next() {
+ return m_next;
+ }
+
+ SimpleList<T>* last() {
+ if (m_next == 0) return this;
+ return m_next->last();
+ }
+
+ SimpleList<T>* delThis() {
+ SimpleList<T>* ret = m_next;
+ Mem::kfree(this);
+ return ret;
+ }
+
+ void delNext() {
+ if (m_next == 0) return;
+ SimpleList<T>* temp = m_next;
+ m_next = m_next->m_next;
+ Mem::kfree(temp);
+ }
+
+ SimpleList<T>* removeOnce(const T& value) {
+ if (value == m_value) return delThis();
+ for (SimpleList<T> *iter = this; iter->next() != 0; iter = iter->next()) {
+ if (iter->next()->v() == value) {
+ iter->delNext();
+ break;
+ }
+ }
+ return this;
+ }
+
+ bool isEnd() {
+ return m_next == 0;
+ }
+
+ u32int size() {
+ if (m_next == 0)
+ return 0;
+ return m_next->size() + 1;
+ }
+};
+
+#endif
diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp
new file mode 100644
index 0000000..d8913d9
--- /dev/null
+++ b/Source/Library/Common/String.class.cpp
@@ -0,0 +1,181 @@
+#include "String.class.h"
+#include <Vector.class.h>
+
+using namespace CMem; //strlen and memcpy
+
+String String::hex(u32int number) {
+ String ret;
+ ret.m_length = 10;
+ ret.m_string = new WChar[11];
+ ret.m_string[0] = '0';
+ ret.m_string[1] = 'x';
+ ret.m_string[10] = 0;
+
+ char hexdigits[] = "0123456789ABCDEF";
+ for (unsigned int j = 0; j < 8; j++) {
+ ret.m_string[j + 2] = hexdigits[(number & 0xF0000000) >> 28];
+ number = number << 4;
+ }
+ return ret;
+}
+
+String String::number(s32int number) {
+ if (number == 0) return String("0");
+ bool negative = false;
+ if (number < 0) {
+ negative = true;
+ number = 0 - number;
+ }
+ u32int order = 0, temp = number;
+ char numbers[] = "0123456789";
+ while (temp > 0) {
+ order++;
+ temp /= 10;
+ }
+
+ String ret;
+ ret.m_length = order;
+ ret.m_string = new WChar[order + 1];
+
+ for (u32int i = order; i > 0; i--) {
+ ret.m_string[i - 1] = numbers[number % 10];
+ number /= 10;
+ }
+
+ ret.m_string[order] = 0;
+
+ if (negative) return String("-") += ret;
+
+ return ret;
+}
+
+String::String(const char* string, u8int encoding) {
+ m_string = 0;
+ m_length = 0;
+ affect(string, encoding);
+}
+
+void String::affect (const char* string, u8int encoding) {
+ m_length = WChar::utfLen(string, encoding);
+ if (m_string != 0) delete [] m_string;
+ if (m_length == 0) {
+ m_string = 0;
+ return;
+ }
+ m_string = new WChar[m_length + 1];
+ int i = 0, l = strlen(string), c = 0;
+ while (i < l) {
+ i += m_string[c].affect(string + i, encoding);
+ c++;
+ }
+ m_string[m_length] = 0;
+}
+
+bool String::compare (const char* string, u8int encoding) const {
+ if (m_length != WChar::utfLen(string, encoding)) return false;
+ int i = 0, l = strlen(string), c = 0;
+ WChar tmp;
+ while (i < l) {
+ i += tmp.affect(string + i, encoding);
+ if (m_string[c] != tmp) return false;
+ c++;
+ }
+ return true;
+}
+
+String& String::append (const char* other, u8int encoding) {
+ WChar* newdata = new WChar[m_length + WChar::utfLen(other, encoding) + 1];
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ int i = 0, l = strlen(other), c = 0;
+ while (i < l) {
+ i += newdata[c + m_length].affect(other + i, encoding);
+ c++;
+ }
+ if (m_string != 0) delete [] m_string;
+ m_string = newdata;
+ m_length += strlen(other);
+ m_string[m_length] = 0;
+ return *this;
+}
+
+String String::concat (const String &other) const { //Can be optimized
+ String ret(*this);
+ return (ret += other);
+}
+
+String String::concat (const char* other, u8int encoding) const { //Can be optimized
+ String ret(*this);
+ return (ret.append(other, encoding));
+}
+
+String String::concat (WChar other) const {
+ String ret(*this);
+ return (ret += other);
+}
+
+s64int String::toInt() const {
+ if (m_string == 0) return 0;
+ s32int pos = 0;
+ s64int number = 0;
+ bool negative = false;
+ if (m_string[0].value == '-') {
+ negative = true;
+ pos = 1;
+ }
+ while (m_string[pos] >= '0' && m_string[pos] <= '9') {
+ number *= 10;
+ number += (m_string[pos].value - '0');
+ pos++;
+ }
+ if (negative) return 0 - number;
+ return number;
+}
+
+u64int String::toInt16() const {
+ if (m_string == 0) return 0;
+ u32int pos = 0;
+ u64int number = 0;
+ if (m_string[0].value == '0' && m_string[1].value == 'x') pos = 2;
+ while (1) {
+ char c = m_string[pos];
+ pos++;
+ if (c >= 'a' && c <= 'f') c -= ('a' - 'A'); //To uppercase
+ if (c >= '0' && c <= '9') {
+ number *= 16;
+ number += (c - '0');
+ continue;
+ }
+ if (c >= 'A' && c <= 'F') {
+ number *= 16;
+ number += (c - 'A' + 10);
+ continue;
+ }
+ break;
+ }
+ return number;
+}
+
+Vector<String> String::split(WChar c) const {
+ Vector<String> ret;
+ ret.push(String(""));
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] == c) {
+ ret.push(String(""));
+ } else {
+ ret.back() += m_string[i];
+ }
+ }
+ return ret;
+}
+
+String String::substr(s32int start, u32int size) {
+ if (start < 0) start = m_length - start;
+ String ret;
+ ret.m_string = new WChar[size + 1];
+ ret.m_length = size;
+ memcpy((u8int*)ret.m_string, (const u8int*)(m_string + start), size * sizeof(WChar));
+ ret.m_string[size] = 0;
+ return ret;
+}
diff --git a/Source/Library/Common/String.class.h b/Source/Library/Common/String.class.h
new file mode 100644
index 0000000..3e50d35
--- /dev/null
+++ b/Source/Library/Common/String.class.h
@@ -0,0 +1,46 @@
+#ifndef DEF_STRING_CLASS
+#define DEF_STRING_CLASS
+
+#include <BasicString.class.h>
+#include <WChar.class.h>
+
+class String : public BasicString<WChar> {
+ public:
+ static String hex(u32int number);
+ static String number(s32int number);
+
+ String(const char* string, u8int encoding = UE_UTF8);
+ String() : BasicString<WChar>() {}
+ String(const String &other) : BasicString<WChar> (other) {}
+
+ void affect(const char* string, u8int encoding = UE_UTF8);
+ void operator= (const char* other) { affect(other); }
+ void operator= (const String& other) { BasicString<WChar>::affect(other); }
+
+ bool compare(const char* string, u8int encoding = UE_UTF8) const;
+ bool operator== (const char* other) const { return compare(other); }
+ bool operator!= (const char* other) { return !compare(other); }
+ bool operator== (const String& other) const { return BasicString<WChar>::compare(other); }
+ bool operator!= (const String& other) const { return !BasicString<WChar>::compare(other); }
+
+ String& append(const char* other, u8int encoding = UE_UTF8);
+ String &operator+= (const String &other) { BasicString<WChar>::append(other); return *this; }
+ String &operator+= (const char* other) { return append(other); }
+ String &operator+= (WChar other) { BasicString<WChar>::append(other); return *this; }
+
+ String concat(const String &other) const;
+ String concat(const char* other, u8int encoding = UE_UTF8) const;
+ String concat(WChar other) const;
+ String operator+ (const String &other) const { return concat(other); }
+ String operator+ (const char* other) const { return concat(other); }
+ String operator+ (WChar other) const { return concat(other); }
+
+ s64int toInt() const; //Convert from DEC
+ u64int toInt16() const; //Convert from HEX
+
+ Vector<String> split(WChar c) const;
+
+ String substr(s32int start, u32int size);
+};
+
+#endif
diff --git a/Source/Library/Common/Vector.class.cpp b/Source/Library/Common/Vector.class.cpp
new file mode 100644
index 0000000..02ae9be
--- /dev/null
+++ b/Source/Library/Common/Vector.class.cpp
@@ -0,0 +1,135 @@
+using namespace CMem; //strlen and memcpy
+
+#define DELDATA if (m_data != NULL and m_size != 0) { \
+ for (u32int i = 0; i < m_size; i++) { \
+ m_data[i].~T(); \
+ } \
+ Mem::kfree(m_data); \
+}
+
+template <typename T>
+Vector<T>::Vector() {
+ //DEBUG_HEX((u32int)this); DEBUG(" NEW EMPTY");
+ //DEBUG_HEX(sizeof(T)); DEBUG(" sizeof(T)");
+ m_data = 0;
+ m_size = 0;
+}
+
+template <typename T>
+Vector<T>::Vector(u32int size) {
+ //DEBUG_HEX((u32int)this); DEBUG(" NEW ZERO");
+ m_data = new T[size];
+ m_size = size;
+}
+
+template <typename T>
+Vector<T>::Vector(u32int size, const T& value) {
+ //DEBUG_HEX((u32int)this); DEBUG(" NEW FILLED");
+ //m_data = (T*)Mem::kalloc(size * sizeof(T));
+ m_data = new T[size];
+ m_size = size;
+ for (u32int i = 0; i < m_size; i++) {
+ new (&m_data[i]) T(value);
+ }
+ /*for (u32int i = 0; i < size; i++) {
+ m_data[i] = new(&m_data[i]) T(value);
+ }*/
+}
+
+template <typename T>
+Vector<T>::Vector(const Vector<T> &other) {
+ //DEBUG_HEX((u32int)this); DEBUG(" COPY REF");
+ m_size = other.m_size;
+ m_data = (T*)Mem::kalloc(m_size * sizeof(T));
+ for (u32int i = 0; i < m_size; i++) {
+ new(&m_data[i]) T(other.m_data[i]);
+ }
+}
+
+template <typename T>
+Vector<T>& Vector<T>::operator= (const Vector<T> &other) {
+ //DEBUG_HEX((u32int)this); DEBUG(" COPY EQ");
+ DELDATA;
+ m_size = other.m_size;
+ m_data = (T*)Mem::kalloc(m_size * sizeof(T));
+ for (u32int i = 0; i < m_size; i++) {
+ new(&m_data[i]) T(other.m_data[i]);
+ }
+ return *this;
+}
+
+template <typename T>
+Vector<T>::~Vector() {
+ //DEBUG_HEX((u32int)this); DEBUG(" DELETE");
+ DELDATA;
+ //if (m_data != 0) delete[] m_data;
+}
+
+template <typename T>
+T& Vector<T>::operator[] (u32int index) const {
+ return m_data[index];
+}
+
+template <typename T>
+void Vector<T>::push(const T& element) {
+ T* newdata = (T*)Mem::kalloc((m_size + 1) * sizeof(T));
+ if (m_size != 0 and m_data != 0) {
+ memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
+ }
+ new(&newdata[m_size]) T(element); //Construct by copy
+ //newdata[m_size] = element;
+ m_size++;
+ Mem::kfree(m_data);
+ m_data = newdata;
+}
+
+/* template <typename T>
+void Vector<T>::push(T& element) {
+ T* newdata = (T*)Memory::alloc((m_size + 1) * sizeof(T));
+ memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
+ //memcpy((u8int*)newdata + (m_size * sizeof(T)), (const u8int*) element, sizeof(T)); //Copy
+ new(&newdata[m_size]) T(element); //Construct by copy
+ m_size++;
+ Memory::free(m_data);
+ m_data = newdata;
+} */
+
+template <typename T>
+void Vector<T>::pop() {
+ m_size--;
+ //delete(&m_data[m_size], &m_data[m_size]); //implicitly call destructor with placement delete
+ m_data[m_size].~T(); //Call destructor
+ T* newdata = (T*)Mem::kalloc(m_size * sizeof(T));
+ memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
+ Mem::kfree(m_data);
+ m_data = newdata;
+}
+
+template <typename T>
+T& Vector<T>::back() const {
+ return m_data[m_size - 1];
+}
+
+template <typename T>
+T& Vector<T>::front() const {
+ return m_data[0];
+}
+
+
+template <typename T>
+u32int Vector<T>::size() const {
+ return m_size;
+}
+
+template <typename T>
+bool Vector<T>::empty() const {
+ return m_size == 0;
+}
+
+template <typename T>
+void Vector<T>::clear() {
+ if (empty()) return;
+ DELDATA
+ m_data = 0;
+ m_size = 0;
+}
diff --git a/Source/Library/Common/Vector.class.h b/Source/Library/Common/Vector.class.h
new file mode 100644
index 0000000..436e2f9
--- /dev/null
+++ b/Source/Library/Common/Vector.class.h
@@ -0,0 +1,36 @@
+#ifndef DEF_VECTOR_CLASS
+#define DEF_VECTOR_CLASS
+
+#include <common.h>
+
+template <typename T>
+class Vector {
+ private:
+ T *m_data;
+ u32int m_size;
+
+ public:
+ Vector();
+ Vector(u32int size);
+ Vector(u32int size, const T& value);
+ Vector(const Vector<T> &other);
+ Vector<T>& operator= (const Vector<T> &other);
+ ~Vector();
+
+ T& operator[] (u32int index) const;
+
+ void push(const T& element);
+ //void push(T& element);
+ void pop();
+
+ T& back() const;
+ T& front() const;
+
+ u32int size() const;
+ bool empty() const;
+ void clear();
+};
+
+#include "Vector.class.cpp"
+
+#endif
diff --git a/Source/Library/Common/WChar.class.cpp b/Source/Library/Common/WChar.class.cpp
new file mode 100644
index 0000000..5485bb8
--- /dev/null
+++ b/Source/Library/Common/WChar.class.cpp
@@ -0,0 +1,155 @@
+#include "WChar.class.h"
+
+#ifdef THIS_IS_MELON_KERNEL
+using namespace CMem;
+#endif
+
+#ifdef THIS_IS_MELON_USERLAND
+using namespace CMem;
+#endif
+
+WChar WChar::CP437[] = { //These are the UTF8 equivalents for the 128 extra characters of code page 437
+ "Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å",
+ "É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ",
+ "á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»",
+ "░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐",
+ "└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "¤",
+ "╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀",
+ "α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩",
+ "≡", "±", "≥", "≤", "⌠", "⌡", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■", "⍽"
+};
+
+WChar::WChar() {
+ value = 0;
+}
+
+WChar::WChar(char c) {
+ affectAscii(c);
+}
+
+WChar::WChar(const char* c, u8int encoding) {
+ if (encoding == UE_UTF8) affectUtf8(c);
+ if (encoding == UE_UTF16) affectUtf16(c);
+ if (encoding == UE_UTF32) affectUtf32(c);
+}
+
+u32int WChar::ucharLen(const char* c, u8int encoding) {
+ if (encoding == UE_UTF8) {
+ if ((c[0] & 0x80) == 0) return 1;
+ else if ((c[0] & 0xE0) == 0xC0) return 2;
+ else if ((c[0] & 0xF0) == 0xE0) return 3;
+ else if ((c[0] & 0xF8) == 0xF0) return 4;
+ else return 1;
+ } else if (encoding == UE_UTF16) {
+ if ((c[0] & 0xFC) == 0xD8 and (c[2] & 0xFC) == 0xDC) return 4;
+ else return 2;
+ } else if (encoding == UE_UTF32) {
+ return 4;
+ }
+ return 1;
+}
+
+u32int WChar::utfLen(const char* c, u8int encoding) {
+ int i = 0, l = strlen(c), co = 0;
+ while (i < l) {
+ i += ucharLen(c + i, encoding);
+ co++;
+ }
+ return co;
+}
+
+void WChar::affectAscii(char c) {
+ if (c >= 0) value = c;
+ else value = CP437[c + 128];
+}
+
+u32int WChar::affectUtf8(const char* c) { //Returns the number of bytes for the character
+ if ((c[0] & 0x80) == 0) {
+ value = c[0]; //0x80 = 10000000b
+ return 1;
+ }
+ if ((c[0] & 0xE0) == 0xC0) { // 11100000b, 11000000b
+ value = ((c[0] & 0x1F) << 6) | (c[1] & 0x3F);
+ if (value < 128) value = 0; //Bad value
+ return 2;
+ }
+ if ((c[0] & 0xF0) == 0xE0) { // 11110000b, 11100000b
+ value = ((c[0] & 0x0F) << 12) | ((c[1] & 0x3F) << 6) | (c[2] & 0x3F);
+ if (value < 2048) value = 0; //Bad value
+ if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed
+ if (value >= 0xFFFE and value <= 0xFFFF) value = 0;
+ return 3;
+ }
+ if ((c[0] & 0xF8) == 0xF0) { // 11111000b, 11110000b
+ value = ((c[0] & 0x0E) << 18) | ((c[1] & 0x3F) << 12) | ((c[2] & 0x3F) << 6) | (c[3] & 0x3F);
+ if (value < 65536) value = 0; //Bad value
+ return 4;
+ }
+ value = 0; //Something wrong happenned
+ return 1;
+}
+
+u32int WChar::affectUtf16(const char* c) {
+ if ((c[0] & 0xFC) == 0xD8 and // 11111100b, 11011000b
+ (c[2] & 0xFC) == 0xDC) { // 11111100b, 11011100b
+ u32int w = ((c[0] & 0x03) << 2) | ((c[1] & 0xC0) >> 6);
+ u32int x = (c[1] & 0x3F);
+ u32int y = ((c[2] & 0x03) << 8) | (c[2]);
+ value = ((w + 1) << 16) | (x << 10) | y;
+ if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed
+ if (value >= 0xFFFE and value <= 0xFFFF) value = 0;
+ return 4;
+ } else {
+ value = (c[0] << 8) | (c[1]);
+ if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed
+ if (value >= 0xFFFE and value <= 0xFFFF) value = 0;
+ return 2;
+ }
+}
+
+u32int WChar::affectUtf32(const char* c) {
+ value = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
+ if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed
+ if (value >= 0xFFFE and value <= 0xFFFF) value = 0;
+ return 4;
+}
+
+u8int WChar::toAscii() {
+ if (value < 128) return (char)value;
+ for (int i = 0; i < 128; i++) {
+ if (CP437[i] == value) return (i + 128);
+ }
+ return '?';
+}
+
+uchar_repr_t WChar::toUtf8() {
+ uchar_repr_t r;
+ r.i = 0;
+ if (value < 128) {
+ r.c[0] = value;
+ } else if (value < 4096) {
+ r.c[0] = 0xC0 | ((value & 0x07C0) >> 6);
+ r.c[1] = 0x80 | (value & 0x3F);
+ } else if (value < 65536) {
+ r.c[0] = 0xE0 | ((value & 0xF000) >> 12);
+ r.c[1] = 0x80 | ((value & 0x0FC0) >> 6);
+ r.c[2] = 0x80 | (value & 0x003F);
+ } else {
+ r.c[0] = 0xF0 | ((value & 0x1C0000) >> 18);
+ r.c[1] = 0x80 | ((value & 0x3F000) >> 12);
+ r.c[2] = 0x80 | ((value & 0x0FC0) >> 6);
+ r.c[3] = 0x80 | (value & 0x003F);
+ }
+ return r;
+}
+
+//TODO : code WChar::toUtf16
+
+uchar_repr_t WChar::toUtf32() {
+ uchar_repr_t r;
+ r.c[0] = (value >> 24) & 0xFF;
+ r.c[1] = (value >> 16) & 0xFF;
+ r.c[2] = (value >> 8) & 0xFF;
+ r.c[3] = value & 0xFF;
+ return r;
+}
diff --git a/Source/Library/Common/WChar.class.h b/Source/Library/Common/WChar.class.h
new file mode 100644
index 0000000..3eca3d3
--- /dev/null
+++ b/Source/Library/Common/WChar.class.h
@@ -0,0 +1,89 @@
+#ifndef DEF_UCHAR_CLASS_H
+#define DEF_UCHAR_CLASS_H
+
+#include <types.h>
+
+#ifndef THIS_IS_NOT_MELON
+#include <common.h>
+#endif
+
+enum {
+ UE_UTF8,
+ UE_UTF16,
+ UE_UTF32,
+};
+
+union uchar_repr_t {
+ char c[4];
+ u32int i;
+};
+
+struct WChar {
+ u32int value;
+ static WChar CP437[]; //Codepage 437, used for conversion from/to ascii
+
+ WChar(); //Creates a null character
+ WChar(char c); //From ascii character
+ WChar(const char* c, u8int encoding = UE_UTF8); //From utf8 string
+
+ static u32int ucharLen(const char* c, u8int encoding = UE_UTF8); //Returns count of bytes in one unicode character
+ static u32int utfLen(const char* c, u8int encoding = UE_UTF8); //Returns count of utf8 characters in string
+
+ void affectAscii(char c);
+ u32int affectUtf8(const char* c);
+ u32int affectUtf16(const char* c);
+ u32int affectUtf32(const char* c);
+
+ u32int affect(const char* c, u8int encoding = UE_UTF8) {
+ if (encoding == UE_UTF8) return affectUtf8(c);
+ if (encoding == UE_UTF16) return affectUtf16(c);
+ if (encoding == UE_UTF32) return affectUtf32(c);
+ affectAscii(c[0]); //Default case :/
+ return 1;
+ }
+
+ u8int toAscii();
+
+ uchar_repr_t toUtf8();
+ uchar_repr_t toUtf16();
+ uchar_repr_t toUtf32();
+
+ uchar_repr_t encode(u8int encoding = UE_UTF8) {
+ if (encoding == UE_UTF8) return toUtf8();
+ //if (encoding == UE_UTF16) return toUtf16();
+ if (encoding == UE_UTF32) return toUtf32();
+ uchar_repr_t x;
+ x.c[0] = toAscii();
+ return x;
+ }
+
+ inline WChar operator+ (u32int other) {
+ WChar r;
+ r.value = value + other;
+ return r;
+ }
+ inline WChar operator- (u32int other) {
+ WChar r;
+ r.value = value - other;
+ return r;
+ }
+ inline WChar& operator+= (u32int other) {
+ value += other;
+ return *this;
+ }
+ inline WChar& operator-= (u32int other) {
+ value -= other;
+ return *this;
+ }
+ inline bool operator== (u32int other) {
+ return value == other;
+ }
+ inline u32int operator= (u32int v) {
+ value = v;
+ return v;
+ }
+
+ inline operator u32int () { return value; }
+};
+
+#endif
diff --git a/Source/Library/Common/types.h b/Source/Library/Common/types.h
new file mode 100644
index 0000000..ca6f73d
--- /dev/null
+++ b/Source/Library/Common/types.h
@@ -0,0 +1,19 @@
+#ifndef DEF_TYPES_WTF_H
+#define DEF_TYPES_WTF_H
+
+//This file defines base types. It's made to be used also by C programs
+
+typedef unsigned int addr_t;
+typedef unsigned long long u64int;
+typedef unsigned int u32int;
+typedef unsigned short u16int;
+typedef unsigned char u8int;
+typedef long long s64int;
+typedef int s32int;
+typedef short s16int;
+typedef char s8int;
+
+#define U64 unsigned long long
+#define S64 long long
+
+#endif
diff --git a/Source/Library/Makefile b/Source/Library/Makefile
new file mode 100644
index 0000000..f7d337b
--- /dev/null
+++ b/Source/Library/Makefile
@@ -0,0 +1,33 @@
+.PHONY: clean, mrproper
+
+CXX = g++
+CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I Common -I Userland -D THIS_IS_MELON_USERLAND
+
+LDFLAGS = -r
+LD = ld
+
+Library = Melon.o
+Objects = Common/WChar.class.uo \
+ Common/CMem.ns.uo \
+ Userland/Syscall/Syscall.wtf.uo
+
+all: $(Library)
+ echo "* Done with library"
+
+rebuild: mrproper all
+
+$(Library): $(Objects)
+ echo "* Linking melon library $(Library)..."
+ $(LD) $(LDFLAGS) $^ -o $@
+
+%.uo: %.cpp
+ echo "* Compiling $<..."
+ $(CXX) $(CXXFLAGS) -c $< -o $@
+
+clean:
+ echo "* Removing object files..."
+ rm -rf $(Objects)
+
+mrproper: clean
+ echo "* Removing library..."
+ rm -rf $(Library)
diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.cpp b/Source/Library/Userland/Syscall/Syscall.wtf.cpp
new file mode 100644
index 0000000..2c03b20
--- /dev/null
+++ b/Source/Library/Userland/Syscall/Syscall.wtf.cpp
@@ -0,0 +1,20 @@
+#include "Syscall.wtf.h"
+
+int main();
+
+unsigned int syscall(unsigned int n, unsigned int a, unsigned int b, unsigned int c) {
+ unsigned int r;
+ asm volatile ("int $64;"
+ : "=a"(r) : "a"(n), "b"(a), "c"(b), "d"(c));
+ return r;
+}
+
+extern "C" void start() {
+ unsigned int r = main();
+ asm volatile("int $66" : : "a"(r));
+}
+
+void putch(char c) {
+ unsigned int x = c;
+ syscall(0xFFFFFF01, x);
+}
diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.h b/Source/Library/Userland/Syscall/Syscall.wtf.h
new file mode 100644
index 0000000..b220d14
--- /dev/null
+++ b/Source/Library/Userland/Syscall/Syscall.wtf.h
@@ -0,0 +1,9 @@
+#ifndef DEF_SYSCALL_WTF_H
+#define DEF_SYSCALL_WTF_H
+
+#include <types.h>
+
+void putch(char);
+unsigned int syscall(unsigned int n, unsigned int a, unsigned int b = 0, unsigned int c = 0);
+
+#endif
diff --git a/Source/Library/Userland/common.h b/Source/Library/Userland/common.h
new file mode 100644
index 0000000..27218f7
--- /dev/null
+++ b/Source/Library/Userland/common.h
@@ -0,0 +1,10 @@
+#ifndef DEF_COMMON
+#define DEF_COMMON
+
+#define NULL 0
+
+#include <types.h>
+
+#include <CMem.ns.h>
+
+#endif