aboutsummaryrefslogtreecommitdiff
path: root/kernel/kstd
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-01-16 13:36:38 +0100
committerFelix Morgner <felix.morgner@ost.ch>2026-01-16 13:36:38 +0100
commit7d6f0ed063790042a808f4bf07c50d308b3f2de4 (patch)
tree1a2e1c4ed7e2f3d8e6cdcfb012e554d1a4eb1e5a /kernel/kstd
parent9750405757396d006ab6992fb93baf414b3e2ae8 (diff)
downloadteachos-7d6f0ed063790042a808f4bf07c50d308b3f2de4.tar.xz
teachos-7d6f0ed063790042a808f4bf07c50d308b3f2de4.zip
chore: restructure namespaces
Diffstat (limited to 'kernel/kstd')
-rw-r--r--kernel/kstd/os.cpp16
-rw-r--r--kernel/kstd/print.cpp145
2 files changed, 161 insertions, 0 deletions
diff --git a/kernel/kstd/os.cpp b/kernel/kstd/os.cpp
new file mode 100644
index 0000000..21254c4
--- /dev/null
+++ b/kernel/kstd/os.cpp
@@ -0,0 +1,16 @@
+#include "kapi/system.hpp"
+
+#include <kstd/os/error.hpp>
+
+#include <source_location>
+#include <string_view>
+
+namespace kstd::os
+{
+
+ auto panic(std::string_view message, std::source_location location) -> void
+ {
+ kapi::system::panic(message, location);
+ }
+
+} // namespace kstd::os \ No newline at end of file
diff --git a/kernel/kstd/print.cpp b/kernel/kstd/print.cpp
new file mode 100644
index 0000000..c7d26ba
--- /dev/null
+++ b/kernel/kstd/print.cpp
@@ -0,0 +1,145 @@
+#include "kapi/cio.hpp"
+
+#include <kstd/format>
+#include <kstd/os/print.hpp>
+#include <kstd/print>
+
+#include <array>
+#include <cstddef>
+#include <iterator>
+#include <string_view>
+
+namespace kstd::os
+{
+
+ namespace
+ {
+ struct write_buffer
+ {
+ using output_stream = kapi::cio::output_stream;
+
+ constexpr auto static size = 128uz;
+
+ write_buffer(write_buffer const &) = delete;
+ write_buffer(write_buffer &&) = delete;
+ auto operator=(write_buffer const &) -> write_buffer & = delete;
+ auto operator=(write_buffer &&) -> write_buffer & = delete;
+
+ explicit write_buffer(output_stream stream)
+ : m_stream{stream}
+ {}
+
+ ~write_buffer() noexcept
+ {
+ flush();
+ }
+
+ auto flush() noexcept -> void
+ {
+ if (m_position > 0)
+ {
+ std::string_view chunk{m_buffer.data(), m_position};
+ kapi::cio::write(m_stream, chunk);
+ m_position = 0;
+ }
+ }
+
+ auto static callback(void * object, std::string_view text) -> void
+ {
+ auto * self = static_cast<write_buffer *>(object);
+ for (char const character : text)
+ {
+ if (self->m_position >= size)
+ {
+ self->flush();
+ }
+ self->m_buffer.at(self->m_position++) = character;
+ }
+ }
+
+ private:
+ output_stream m_stream;
+ std::array<char, size> m_buffer{};
+ std::size_t m_position{};
+ };
+
+ } // namespace
+
+ auto vprint(print_sink sink, std::string_view format, kstd::format_args args) -> void
+ {
+ auto writer = write_buffer{(sink == print_sink::stderr) ? kapi::cio::output_stream::stderr
+ : kapi::cio::output_stream::stdout};
+ auto context = kstd::format_context{.writer = write_buffer::callback, .user_data = &writer};
+
+ auto current = format.begin();
+ auto end = format.end();
+ auto next_automatic_index = 0uz;
+
+ while (current != end)
+ {
+ if (*current != '{')
+ {
+ auto start = current;
+ while (current != end && *current != '{')
+ {
+ std::advance(current, 1);
+ }
+ context.push(std::string_view(start, current - start));
+ continue;
+ }
+
+ if (std::next(current) != end && *(std::next(current)) == '{')
+ {
+ context.push('{');
+ std::advance(current, 2);
+ continue;
+ }
+
+ std::advance(current, 1);
+
+ auto index = 0uz;
+ if (current != end && *current >= '0' && *current <= '9')
+ {
+ while (current != end && *current >= '0' && *current <= '9')
+ {
+ index = index * 10 + static_cast<std::size_t>(*current - '0');
+ std::advance(current, 1);
+ }
+ }
+ else
+ {
+ index = next_automatic_index++;
+ }
+
+ auto remaining_fmt = std::string_view{current, static_cast<std::size_t>(std::distance(current, end))};
+
+ auto const arg = args.get(index);
+ if (arg.format)
+ {
+ auto const after_specs = arg.format(arg.value, remaining_fmt, context);
+ auto const consumed = remaining_fmt.size() - after_specs.size();
+ std::advance(current, consumed);
+ }
+ else
+ {
+ context.push("{?}");
+ while (current != end && *current != '}')
+ std::advance(current, 1);
+ }
+
+ if (current != end && *current == '}')
+ {
+ std::advance(current, 1);
+ }
+ else
+ {
+ context.push("{fmt-err}");
+ while (current != end && *current != '}')
+ std::advance(current, 1);
+ if (current != end)
+ std::advance(current, 1);
+ }
+ }
+ }
+
+} // namespace kstd::os