summaryrefslogtreecommitdiff
path: root/euler/source/std
diff options
context:
space:
mode:
Diffstat (limited to 'euler/source/std')
-rw-r--r--euler/source/std/cctype.cpp7
-rw-r--r--euler/source/std/cstdio.cpp59
-rw-r--r--euler/source/std/cstdlib.cpp19
-rw-r--r--euler/source/std/cstring.cpp36
-rw-r--r--euler/source/std/string.cpp86
5 files changed, 207 insertions, 0 deletions
diff --git a/euler/source/std/cctype.cpp b/euler/source/std/cctype.cpp
new file mode 100644
index 0000000..a35d1a5
--- /dev/null
+++ b/euler/source/std/cctype.cpp
@@ -0,0 +1,7 @@
+#include <cctype>
+
+extern "C" int isspace(int ch) {
+ return
+ ch == ' ' || ch == '\f' || ch == '\n' ||
+ ch == '\r' || ch == '\t' || ch == '\v';
+}
diff --git a/euler/source/std/cstdio.cpp b/euler/source/std/cstdio.cpp
new file mode 100644
index 0000000..8c12a7c
--- /dev/null
+++ b/euler/source/std/cstdio.cpp
@@ -0,0 +1,59 @@
+#include <cstdio>
+
+extern "C" FILE *fopen(const char *filename, const char *mode) {
+
+ bool r = false, w = false, a = false, p = false, x = false;
+ for (size_t i = 0; mode[i] != '\0'; ++i)
+ if (mode[i] == 'r') r = true;
+ else if (mode[i] == 'w') w = true;
+ else if (mode[i] == 'a') a = true;
+ else if (mode[i] == 'p') p = true;
+ else if (mode[i] == 'x') x = true;
+
+ euler::syscall::stream_handle handle;
+ if (euler::syscall::open_file(filename, !r, x, handle) !=
+ euler::syscall::stream_result::success)
+ return 0;
+
+ if (w && euler::syscall::set_stream_length(handle, 0) !=
+ euler::syscall::stream_result::success)
+ return 0;
+
+ if (a && euler::syscall::seek_stream(
+ handle, euler::syscall::seek_from::end, 0) !=
+ euler::syscall::stream_result::success) {
+ euler::syscall::close_stream(handle);
+ return 0;
+ }
+
+ uint64_t length;
+ if (euler::syscall::get_stream_length(handle, length) !=
+ euler::syscall::stream_result::success) {
+ euler::syscall::close_stream(handle);
+ return 0;
+ }
+
+ return new euler::file_stream(handle, r || p, length, a ? length : 0);
+
+}
+
+extern "C" void fclose(FILE *stream) {
+ stream->close();
+ delete stream;
+}
+
+extern "C" int fseek(FILE *stream, long offset, int origin) {
+
+ if (origin < 0 || origin > 2)
+ return -1;
+
+ return (int)stream->seek((euler::syscall::seek_from)origin, offset);
+
+}
+
+extern "C" size_t fread(
+ void *buffer, size_t size, size_t count, FILE *stream) {
+
+ return (stream->read(size * count, buffer).first - 1) / size + 1;
+
+}
diff --git a/euler/source/std/cstdlib.cpp b/euler/source/std/cstdlib.cpp
new file mode 100644
index 0000000..cfb4b48
--- /dev/null
+++ b/euler/source/std/cstdlib.cpp
@@ -0,0 +1,19 @@
+#include <euler/heap.hpp>
+#include <cstdlib>
+
+extern "C" [[noreturn]] void abort() noexcept {
+ //TODO
+ while (1)
+ ;
+}
+
+extern "C" void *malloc(size_t size) {
+ size_t *block = (size_t *)euler::heap::get_block(size + 8);
+ *block = size;
+ return block + 1;
+}
+
+extern "C" void free(void *ptr) {
+ size_t *block = (size_t *)ptr - 1;
+ euler::heap::return_block(block, *block + 8);
+}
diff --git a/euler/source/std/cstring.cpp b/euler/source/std/cstring.cpp
new file mode 100644
index 0000000..3e5a56c
--- /dev/null
+++ b/euler/source/std/cstring.cpp
@@ -0,0 +1,36 @@
+#include <cstring>
+
+extern "C" void *memset(void *dest, int ch, size_t count) {
+ unsigned char c = static_cast<unsigned char>(ch);
+ unsigned char *d = (unsigned char *)dest;
+ for (size_t i = 0; i < count; ++i)
+ d[i] = c;
+ return dest;
+}
+
+extern "C" void *memcpy(void *dest, const void *src, size_t count) {
+ unsigned char *d = (unsigned char *)dest;
+ const unsigned char *s = (const unsigned char *)src;
+ for (size_t i = 0; i < count; ++i)
+ d[i] = s[i];
+ return dest;
+}
+
+extern "C" int strcmp(const char *lhs, const char *rhs) {
+ const unsigned char *l = (const unsigned char *)lhs;
+ const unsigned char *r = (const unsigned char *)rhs;
+ while (*l == *r) {
+ if (*l == 0)
+ return 0;
+ ++l;
+ ++r;
+ }
+ return *l < *r ? -1 : 1;
+}
+
+extern "C" size_t strlen(const char *str) {
+ size_t len = 0;
+ while (str[len] != '\0')
+ ++len;
+ return len;
+}
diff --git a/euler/source/std/string.cpp b/euler/source/std/string.cpp
new file mode 100644
index 0000000..31c47a5
--- /dev/null
+++ b/euler/source/std/string.cpp
@@ -0,0 +1,86 @@
+#include <cctype>
+#include <string>
+
+namespace std {
+
+ int stoi(const std::string &str, size_t *pos, int base) {
+ //TODO: exceptions
+
+ size_t i = 0;
+ while (isspace(str[i]))
+ ++i;
+
+ bool is_negative = false;
+ if (str[i] == '-') {
+ is_negative = true;
+ ++i;
+ }
+ else if (str[i] == '+')
+ ++i;
+
+ if ((base == 16 || base == 0) && str[i] == '0' &&
+ (str[i + 1] == 'x' || str[i + 1] == 'X')) {
+ base = 16;
+ i += 2;
+ }
+
+ else if ((base == 8 || base == 0) && str[i] == '0') {
+ base = 8;
+ ++i;
+ }
+
+ else if (base == 0)
+ base = 10;
+
+ int value = 0;
+
+ while (true) {
+ char c = str[i];
+ if (c >= '0' && c < '0' + base)
+ value = value * base + c - '0';
+ else if (c >= 'a' && c < 'a' + base - 10)
+ value = value * base + c - 'a' + 10;
+ else if (c >= 'A' && c < 'A' + base - 10)
+ value = value * base + c - 'A' + 10;
+ else
+ break;
+ }
+
+ if (pos != 0)
+ *pos = i;
+
+ return is_negative ? -value : value;
+
+ }
+
+ std::string to_string(int value) {
+
+ int max_place = 1;
+ int places = 1;
+ while (max_place <= value / 10) {
+ max_place *= 10;
+ ++places;
+ }
+
+ std::string s;
+ s.resize(places);
+
+ for (int i = 0; i < places; ++i) {
+ s[i] = (value / max_place) % 10 + '0';
+ max_place /= 10;
+ }
+
+ return s;
+
+ }
+
+ std::string operator +(std::string &&lhs, std::string &&rhs) {
+ std::string s = std::move(lhs);
+ s.resize(lhs.size() + rhs.size());
+ for (size_t i = 0; i < rhs.size(); ++i)
+ s[lhs.size() + i] = rhs[i];
+ rhs.clear();
+ return s;
+ }
+
+}