diff options
40 files changed, 610 insertions, 112 deletions
diff --git a/arch/x86_64/arch/bus/cpu.cpp b/arch/x86_64/arch/bus/cpu.cpp index 4b9edffc..a21d910d 100644 --- a/arch/x86_64/arch/bus/cpu.cpp +++ b/arch/x86_64/arch/bus/cpu.cpp @@ -36,7 +36,7 @@ namespace arch::bus auto madt = kapi::acpi::get_table<::acpi::table_signature_v<::acpi::madt>>(); if (!madt) { - kstd::println("[x86_64:BUS] Failed to find ACPI APIC table"); + kstd::println("[ARCH:BUS] Failed to find ACPI APIC table"); return; } diff --git a/arch/x86_64/arch/cpu/initialization.cpp b/arch/x86_64/arch/cpu/initialization.cpp index 49870eb7..83493fe3 100644 --- a/arch/x86_64/arch/cpu/initialization.cpp +++ b/arch/x86_64/arch/cpu/initialization.cpp @@ -123,10 +123,10 @@ namespace arch::cpu gdt_user_code_descriptor, gdt_user_data_descriptor, tss_descriptor, }; - kstd::println("[x86_64:SYS] Reloading Global Descriptor Table."); + kstd::println("[ARCH:SYS] Reloading Global Descriptor Table."); gdt.load(1, 2); - kstd::println("[x86_64:SYS] Initializing Interrupt Descriptor Table."); + kstd::println("[ARCH:SYS] Initializing Interrupt Descriptor Table."); auto static idt = interrupt_descriptor_table{}; idt.load(); } diff --git a/arch/x86_64/arch/cpu/interrupts.cpp b/arch/x86_64/arch/cpu/interrupts.cpp index 99186e2d..c825e8ab 100644 --- a/arch/x86_64/arch/cpu/interrupts.cpp +++ b/arch/x86_64/arch/cpu/interrupts.cpp @@ -141,11 +141,11 @@ namespace arch::cpu if (has_error_code(static_cast<exception>(number))) { kstd::println(kstd::print_sink::stderr, - "[x86_64:CPU] Unhandled exception number {:#04x} received with code {:#04x}", number, code); + "[ARCH:CPU] Unhandled exception number {:#04x} received with code {:#04x}", number, code); } else { - kstd::println(kstd::print_sink::stderr, "[x86_64:CPU] Unhandled exception number {:#04x} received", number); + kstd::println(kstd::print_sink::stderr, "[ARCH:CPU] Unhandled exception number {:#04x} received", number); } } } @@ -155,7 +155,7 @@ namespace arch::cpu if (kapi::interrupts::dispatch(irq_number) == kapi::interrupts::status::unhandled) { - kstd::println(kstd::print_sink::stderr, "[x86_64:CPU] Unhandled interrupt {:#04x} (IRQ{})", number, + kstd::println(kstd::print_sink::stderr, "[ARCH:CPU] Unhandled interrupt {:#04x} (IRQ{})", number, irq_number); } diff --git a/arch/x86_64/arch/devices/init.cpp b/arch/x86_64/arch/devices/init.cpp index 9c20d413..639e8870 100644 --- a/arch/x86_64/arch/devices/init.cpp +++ b/arch/x86_64/arch/devices/init.cpp @@ -46,7 +46,7 @@ namespace arch::devices { if (kapi::acpi::init(*acpi_root_pointer)) { - kstd::println("[x86_64:DEV] ACPI subsystem initialized."); + kstd::println("[ARCH:DEV] ACPI subsystem initialized."); } } @@ -55,7 +55,7 @@ namespace arch::devices auto init_legacy_devices() -> void { - kstd::println("[x86_64:DEV] Initializing ISA bus..."); + kstd::println("[ARCH:DEV] Initializing ISA bus..."); auto root_bus = kapi::devices::get_root_bus(); auto isa_bus = kstd::make_shared<arch::bus::isa>(); diff --git a/arch/x86_64/arch/drivers/cpu/lapic.cpp b/arch/x86_64/arch/drivers/cpu/lapic.cpp index f8aa8e90..c02c3df6 100644 --- a/arch/x86_64/arch/drivers/cpu/lapic.cpp +++ b/arch/x86_64/arch/drivers/cpu/lapic.cpp @@ -126,7 +126,7 @@ namespace arch::drivers::cpu if (!kapi::memory::map_mmio_region(m_mapped_region, kapi::memory::physical_address{mmio->start}, kapi::memory::page_mapper::flags::writable)) { - kstd::println(kstd::print_sink::stderr, "[x86_64:DRV] LAPIC {} MMIO mapping failed!", signature->hardware_id()); + kstd::println(kstd::print_sink::stderr, "[ARCH:DRV] LAPIC {} MMIO mapping failed!", signature->hardware_id()); return kstd::failure(make_error_code(kstd::errc::io_error)); } @@ -142,12 +142,12 @@ namespace arch::drivers::cpu write_register(registers::spurious_interrupt_vector, lapic_enable_bit | spurious_interrupt_vector); - kstd::println("[x86_64:DRV] LAPIC initialized. version: {#x} | max_lvt_entry: {} | eoi_suppression: {:s}", + kstd::println("[ARCH:DRV] LAPIC initialized. version: {#x} | max_lvt_entry: {} | eoi_suppression: {:s}", version, highest_lvt_entry_index, supports_eoi_broadcast_suppression); } else { - kstd::println("[x86_64:DRV] LAPIC {} is not on the BSP, deferring initialization.", signature->hardware_id()); + kstd::println("[ARCH:DRV] LAPIC {} is not on the BSP, deferring initialization.", signature->hardware_id()); } return kstd::success(); diff --git a/arch/x86_64/arch/memory/higher_half_mapper.cpp b/arch/x86_64/arch/memory/higher_half_mapper.cpp index 75adb3c5..974b00a0 100644 --- a/arch/x86_64/arch/memory/higher_half_mapper.cpp +++ b/arch/x86_64/arch/memory/higher_half_mapper.cpp @@ -33,7 +33,7 @@ namespace arch::memory if (entry.present()) { - kapi::system::panic("[x86_64:MEM] Tried to map a page that is already mapped!"); + kapi::system::panic("[ARCH:MEM] Tried to map a page that is already mapped!"); } entry.frame(frame, to_table_flags(flags) | page_table::entry::flags::present); @@ -45,7 +45,7 @@ namespace arch::memory { if (!try_unmap(page)) { - kapi::system::panic("[x86_64:MEM] Tried to unmap a page that is not mapped!"); + kapi::system::panic("[ARCH:MEM] Tried to unmap a page that is not mapped!"); } } diff --git a/arch/x86_64/arch/memory/kernel_mapper.cpp b/arch/x86_64/arch/memory/kernel_mapper.cpp index a15a1d9e..070a7866 100644 --- a/arch/x86_64/arch/memory/kernel_mapper.cpp +++ b/arch/x86_64/arch/memory/kernel_mapper.cpp @@ -50,7 +50,7 @@ namespace arch::memory auto elf_information = m_mbi->maybe_elf_symbols<elf::format::elf64>(); if (!elf_information) { - kapi::system::panic("[x86_64:MEM] ELF section information is not available."); + kapi::system::panic("[ARCH:MEM] ELF section information is not available."); } auto sections = *elf_information; @@ -64,7 +64,7 @@ namespace arch::memory if (allocated_sections.empty()) { - kapi::system::panic("[x86_64:MEM] No allocated ELF sections were found."); + kapi::system::panic("[ARCH:MEM] No allocated ELF sections were found."); } std::ranges::for_each(allocated_sections, @@ -78,7 +78,7 @@ namespace arch::memory auto linear_start_address = kapi::memory::linear_address{section.virtual_load_address}; auto physical_start_address = kapi::memory::physical_address{section.virtual_load_address & ~m_kernel_load_base}; - kstd::println("[x86_64:MEM] mapping {}" + kstd::println("[ARCH:MEM] mapping {}" "\n {} bytes -> page count: {}" "\n {} @ {}", name, section.size, number_of_pages, linear_start_address, physical_start_address); diff --git a/arch/x86_64/kapi/boot_modules.cpp b/arch/x86_64/kapi/boot_modules.cpp index 607aca4e..95ed0287 100644 --- a/arch/x86_64/kapi/boot_modules.cpp +++ b/arch/x86_64/kapi/boot_modules.cpp @@ -25,7 +25,7 @@ namespace kapi::boot_modules auto init(kapi::devices::bus & bus) -> void { - kstd::println("[x86_64:BOOT_MODULES] Attaching boot modules."); + kstd::println("[ARCH:BOOT_MODULES] Attaching boot modules."); auto modules = boot::bootstrap_information.mbi->modules(); diff --git a/arch/x86_64/kapi/cpu.cpp b/arch/x86_64/kapi/cpu.cpp index 2bec841c..11a12656 100644 --- a/arch/x86_64/kapi/cpu.cpp +++ b/arch/x86_64/kapi/cpu.cpp @@ -15,7 +15,7 @@ namespace kapi::cpu if (is_initialized.test_and_set()) { - system::panic("[x86_64] CPU has already been initialized."); + system::panic("[ARCH:CPU] CPU has already been initialized."); } arch::cpu::initialize_descriptors(); diff --git a/arch/x86_64/kapi/devices.cpp b/arch/x86_64/kapi/devices.cpp index 1e2fedd6..39dbc010 100644 --- a/arch/x86_64/kapi/devices.cpp +++ b/arch/x86_64/kapi/devices.cpp @@ -39,7 +39,7 @@ namespace kapi::devices for (auto driver : descriptors) { auto instance = driver->make_instance(); - kstd::println("[x86_64:DRV] registering driver '{}' ({})", instance->name(), driver->name()); + kstd::println("[ARCH:DRV] registering driver '{}' ({})", instance->name(), driver->name()); kapi::devices::driver_registry::get().add(std::move(instance)); } } @@ -54,7 +54,7 @@ namespace kapi::devices { if (!cpu_bus) { - system::panic("[x86_64:DEV] The CPU topology has not yet been initialized!"); + system::panic("[ARCH:DEV] The CPU topology has not yet been initialized!"); } return cpu_bus; @@ -64,7 +64,7 @@ namespace kapi::devices { if (cpu_bus) { - system::panic("[x86_64:DEV] The CPU topology has already been initialized!"); + system::panic("[ARCH:DEV] The CPU topology has already been initialized!"); } cpu_bus = kstd::make_shared<arch::bus::cpu>(); diff --git a/arch/x86_64/kapi/memory.cpp b/arch/x86_64/kapi/memory.cpp index 37b4c7f3..9cf955e5 100644 --- a/arch/x86_64/kapi/memory.cpp +++ b/arch/x86_64/kapi/memory.cpp @@ -45,7 +45,7 @@ namespace kapi::memory auto memory_map = boot::bootstrap_information.mbi->maybe_memory_map(); if (!memory_map) { - system::panic("[x86_64] Failed to create early allocator, no memory map available."); + system::panic("[ARCH:MEM] Failed to create early allocator, no memory map available."); } auto const & mbi = boot::bootstrap_information.mbi; @@ -157,7 +157,7 @@ namespace kapi::memory auto next_free_frame = region_based_allocator->next_free_frame(); if (!next_free_frame) { - system::panic("[x86_64:MEM] No more free memory!"); + system::panic("[ARCH:MEM] No more free memory!"); } std::ranges::for_each(std::views::iota(kapi::memory::frame{}, *next_free_frame), @@ -196,26 +196,26 @@ namespace kapi::memory if (is_initialized.test_and_set()) { - system::panic("[x86_64] Memory management has already been initialized."); + system::panic("[ARCH:MEM] Memory management has already been initialized."); } - kstd::println("[x86_64:MEM] Enabling additional CPU protection features."); + kstd::println("[ARCH:MEM] Enabling additional CPU protection features."); enable_cpu_protections(); region_based_allocator.emplace(collect_memory_information()); set_frame_allocator(*region_based_allocator); - kstd::println("[x86_64:MEM] Establishing higher-half direct mapping."); + kstd::println("[ARCH:MEM] Establishing higher-half direct mapping."); establish_higher_half_direct_mapping(); - kstd::println("[x86_64:MEM] Preparing new paging hierarchy."); + kstd::println("[ARCH:MEM] Preparing new paging hierarchy."); auto new_pml4_frame = kapi::memory::allocate_frame(); if (!new_pml4_frame) { - system::panic("[x86_64:MEM] Failed to allocate new PML4!"); + system::panic("[ARCH:MEM] Failed to allocate new PML4!"); } auto new_pml4 = arch::memory::to_higher_half_pointer<arch::memory::page_table>(new_pml4_frame->start_address()); std::construct_at(new_pml4); @@ -232,7 +232,7 @@ namespace kapi::memory auto old_pml4 = static_cast<arch::memory::page_table *>(current_cr3.address()); (*new_pml4)[256] = (*old_pml4)[256]; - kstd::println("[x86_64:MEM] Switching to new paging hierarchy."); + kstd::println("[ARCH:MEM] Switching to new paging hierarchy."); auto cr3 = arch::cpu::cr3::read(); cr3.frame(*new_pml4_frame); @@ -246,7 +246,7 @@ namespace kapi::memory init_pmm(frame::containing(physical_address{highest_byte}).number() + 1, handoff_to_kernel_pmm); - kstd::println("[x86_64:MEM] Releasing bootstrap memory allocators."); + kstd::println("[ARCH:MEM] Releasing bootstrap memory allocators."); region_based_allocator.reset(); } diff --git a/docs/code_style.md b/docs/code_style.md new file mode 100644 index 00000000..f417a047 --- /dev/null +++ b/docs/code_style.md @@ -0,0 +1,498 @@ +# TeachOS C++ Code Style Guide + +This document codifies the C++ coding idioms used throughout the TeachOS kernel. +It covers language usage, ownership and lifetime models, algorithm selection, error +propagation, class design, and naming conventions. It does **not** cover token-level +formatting, which is enforced automatically by the `.clang-format` configuration. + +--- + +## 1. Language Standard and Vocabulary + +TeachOS targets **C++23** without compiler extensions (`CMAKE_CXX_EXTENSIONS NO`). +Standard library features may be used freely where a hosted implementation is +available (i.e., in `libs/`, `kapi/`, and `kernel/`), but the project ships its own +standard library subset in `libs/kstd/`. **kstd types must be preferred over their +`std::` equivalents** wherever a kstd equivalent exists. + +| Concept | Preferred | Avoid | +|---|---|---| +| Dynamic array | `kstd::vector<T>` | `std::vector<T>` | +| String (owning) | `kstd::string` | `std::string` | +| String view | `std::string_view` | (kstd has no alias; use `std::string_view` directly) | +| Non-owning pointer | `kstd::observer_ptr<T>` | raw `T*` for ownership-neutral access | +| Shared ownership | `kstd::shared_ptr<T>` | `std::shared_ptr<T>` | +| Unique ownership | `kstd::unique_ptr<T>` | `std::unique_ptr<T>` | +| Failable results | `kstd::result<T>` | exceptions, output parameters, `std::optional` for errors | +| Printing | `kstd::println(...)` | `std::println(...)`, `printf` | + +`std::string_view`, `std::span`, `std::array`, `std::optional`, `std::byte`, and the +`std::ranges` and `std::views` namespaces are used directly from the standard library +because they have no kstd equivalents. + +--- + +## 2. Function Declarations — Trailing Return Types + +**All** functions and member functions use trailing return type syntax, including those +returning `void`. + +```cpp +// Correct +auto device_registry::get() -> device_registry &; +auto bitmap_is_set(std::span<std::byte const> bitmap, std::size_t index) -> bool; +auto init() -> void; + +// Wrong +device_registry & device_registry::get(); +bool bitmap_is_set(std::span<std::byte const> bitmap, std::size_t index); +void init(); +``` + +This rule applies to: free functions, member functions, lambdas with explicit return +types, and virtual functions. The only exception is constructors and destructors, +which have no return type at all. + +--- + +## 3. Parameter Passing Conventions + +The choice of passing convention encodes intent and must be consistent. + +### 3.1 View and cheaply copyable types — pass by value + +Types that are designed to be non-owning views or are trivially copyable must be +passed and returned **by value**. Passing them by `const &` is redundant and adds +a pointer indirection with no benefit. + +This applies to: +- `std::string_view` +- `std::span<T>` +- `kstd::observer_ptr<T>` +- `kstd::bytes`, `kstd::pages` and similar unit wrappers +- `kapi::capabilities::facet_id` +- `kapi::memory::page`, `kapi::memory::frame`, `kapi::memory::physical_address`, `kapi::memory::linear_address` + +```cpp +// Correct +auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *; +auto has(std::span<std::byte const> data) -> bool; + +// Wrong +auto resolve(kapi::capabilities::facet_id const & id, std::string_view const & name) -> void *; +``` + +### 3.2 Large or non-trivial types — pass by `const &` + +For types that own heap memory or are non-trivially copyable, use `const &` when the +callee does not take ownership. + +```cpp +auto do_publish(kstd::string const & name) -> kstd::result<void>; +auto add_child(kstd::string const & child_name) -> void; +``` + +### 3.3 Sink parameters — pass by value and move + +When a function is designed to take **ownership** of an argument, accept it by value +and move it into its destination. This makes the transfer explicit at the call site. + +```cpp +// In the header +auto add_child(kstd::shared_ptr<device> child) -> void; +auto do_publish(kstd::shared_ptr<device> device, kstd::string name, ...) -> kstd::result<void>; + +// In the implementation +auto bus::add_child(kstd::shared_ptr<device> child) -> void +{ + m_devices.push_back(std::move(child)); // ownership transferred here +} +``` + +### 3.4 Mutable subsystem references — pass by non-const reference + +Services and subsystems that are mutated in-place (e.g., `page_mapper &`, +`driver_state &`, `kapi::devices::bus &`) are passed by non-const reference. This +expresses that the function operates on a shared, mutable context. + +```cpp +auto remap_kernel(kapi::memory::page_mapper & mapper) -> void; +auto add_directory_entry(inode & directory, inode & child, driver_state & state, write_batch & batch) -> kstd::result<void>; +``` + +--- + +## 4. Error Handling + +### 4.1 Recoverable errors — `kstd::result<T>` + +Functions that can fail in an expected, recoverable way must return `kstd::result<T>` +(an alias for `std::expected<T, kstd::error_code>`). Use the `kstd::success()` and +`kstd::failure()` helpers consistently. + +```cpp +auto mount(kstd::shared_ptr<inode> parent) + -> kstd::result<std::pair<kstd::shared_ptr<inode>, state *>>; + +// In the implementation +if (!device) +{ + return kstd::failure(make_error_code(kstd::errc::invalid_argument)); +} +return kstd::success(result_value); +``` + +Callers must check the result before using its value. The idiomatic check is: + +```cpp +auto result = some_function(); +if (!result) +{ + return kstd::failure(result.error()); // propagate +} +// use *result +``` + +Monadic composition (`transform`, `and_then`, `or_else`) is preferred over +manual if-check-and-return chains when it produces clearer code. + +### 4.2 Unrecoverable errors — `kapi::system::panic` + +Violations of kernel invariants (e.g., a subsystem used before being initialized, +OOM during boot) call `kapi::system::panic(...)`. `panic` is `[[noreturn]]`. It must +not be used for recoverable errors. + +Log prefix convention: `[SUBSYSTEM:TAG] message`. Examples: `[OS:DEV]`, +`[OS:VFS]`, `[ARCH:DRV]`. + +```cpp +if (!instance) +{ + system::panic("[OS:DEV] Device registry has not been initialized."); +} +``` + +### 4.3 No exceptions + +The kernel does not use C++ exceptions. Do not write `throw` or `try`/`catch` in +kernel code. + +--- + +## 5. Ownership and Lifetime + +### 5.1 Shared ownership — `kstd::shared_ptr` + +Use `kstd::shared_ptr<T>` when a resource is co-owned by multiple subsystems and +its lifetime must be extended by any of them (e.g., `device`, `inode`, `dentry`). +Weak back-references that must not extend lifetime use `kstd::weak_ptr<T>`. + +### 5.2 Non-owning references — `kstd::observer_ptr` and raw references + +Use `kstd::observer_ptr<T>` to express a non-owning pointer where null is a valid +state and the holder has no say in the lifetime of the target. Use a raw reference +(`T &` or `T const &`) when null is not valid and the reference is short-lived (i.e., +a function parameter or a local alias). + +Never use raw `T *` to mean "sometimes I own this, sometimes I don't". Ownership must +be expressed unambiguously through the pointer type. + +### 5.3 Driver data — `kstd::shared_ptr<void>` + +Drivers attach their state to a `device` using an untyped `kstd::shared_ptr<void>` +via `device::set_driver_data`. A driver retrieves its state via `device::driver_data`. +This allows the device tree to destroy driver data automatically when the device is +released, without the device knowing the concrete driver type. + +--- + +## 6. Algorithm and Range Usage + +### 6.1 Prefer `std::ranges` algorithms over manual loops + +When processing a range to search, filter, transform, or reduce, use the appropriate +`std::ranges` algorithm or view pipeline instead of writing a raw `for` loop. + +```cpp +// Correct +auto already_published = std::ranges::any_of( + m_entries, [&](auto const & entry) { + return entry.id() == id && entry.device().get() == device.get(); + }); + +std::ranges::for_each(observers, [&](auto observer) { /* ... */ }); + +// Wrong — manual linear scan for a boolean result +for (auto const & entry : m_entries) +{ + if (entry.id() == id && entry.device().get() == device.get()) + { + return true; + } +} +return false; +``` + +Acceptable uses of explicit loops include: +- Accumulation or mutation that modifies state in-place and cannot be cleanly + expressed with a ranges algorithm. +- Low-level routines dealing with raw memory arithmetic (allocators, page mappers). +- Iterator-pair loops in library internals (`kstd::vector`, `kstd::basic_string`). + +### 6.2 Prefer view composition over intermediate containers + +Build processing pipelines using `std::views::filter`, `std::views::transform`, +`std::views::reverse`, `std::views::split`, and `std::ranges::subrange` rather than +materialising intermediate vectors. + +```cpp +// Correct +auto descriptors = std::span{&__start_platform_drivers, &__stop_platform_drivers} + | std::views::filter([](auto p) { return p != nullptr; }); + +auto modules_view = std::ranges::subrange(begin(), end()) + | std::views::filter(filter_modules) + | std::views::transform(transform_module); +``` + +### 6.3 Do not call the same function twice to avoid storing the result + +If an intermediate value is needed more than once, store it in a local variable. This +applies especially to factory calls and heap allocations. + +```cpp +// Wrong — double invocation, two allocations, different objects +for (auto driver : descriptors) +{ + kstd::println("registering driver '{}'", driver->make_instance()->name()); + registry.add(driver->make_instance()); +} + +// Correct +for (auto driver : descriptors) +{ + auto instance = driver->make_instance(); + kstd::println("registering driver '{}'", instance->name()); + registry.add(std::move(instance)); +} +``` + +--- + +## 7. Class and Struct Design + +### 7.1 Prefer `struct` over `class` + +The entire codebase uses `struct` for all type definitions with explicit `private:` +sections where necessary. Do not introduce `class`. + +### 7.2 Member ordering within a type + +Follow this ordering within a `struct`: + +1. Nested types and type aliases. +2. Static data members and static constexpr constants (e.g., `static constexpr auto id = ...`). +3. Constructors and destructor. +4. Public member functions. +5. `protected:` section with virtual hooks. +6. `private:` section with helper functions, then data members. + +Data members are always in the `private` section and always prefixed with `m_`. + +```cpp +struct facet_registry +{ + struct entry { /* ... */ }; // 1. nested type + + facet_registry() = default; // 3. constructor + + auto static init() -> void; // 4. public interface + auto static get() -> facet_registry &; + auto publish(...) -> kstd::result<void>; + +private: + auto do_publish(...) -> kstd::result<void>; // 6a. private helpers + + mutable tracked_mutex m_lock{}; // 6b. data members, m_ prefix + kstd::vector<entry> m_entries; +}; +``` + +### 7.3 `explicit` on single-argument constructors + +Mark every single-argument constructor `explicit` unless an implicit conversion is +intentional and documented. A deliberate implicit constructor must be accompanied by +a comment explaining the decision. + +```cpp +// Correct +explicit device(kstd::string const & name); +constexpr explicit facet_id(std::string_view name); + +// Intentional implicit — documented at the declaration +//! This constructor allows implicit conversion from chunk<...> to page for +//! convenience. It is deliberately not explicit. +constexpr page(chunk other) : chunk{other} {} +``` + +### 7.4 Declare deleted special members explicitly + +If a type is not copyable or not movable, declare the deleted special members +explicitly rather than relying on implicit suppression. + +```cpp +device(device const &) = delete; +auto operator=(device const &) -> device & = delete; +``` + +### 7.5 Virtual destructors + +Every base class with virtual member functions must have a `virtual` destructor, +defaulted if not otherwise needed. + +```cpp +virtual ~driver_descriptor() = default; +virtual ~facet_registry_observer() = default; +``` + +--- + +## 8. Static Singletons + +Several subsystems expose a single global instance via an `init()`/`get()` pair. +Follow this pattern: + +- Store the instance in an anonymous namespace as a `constinit std::optional<T>`. +- `init()` asserts the instance is not yet constructed, then `emplace()`s it. +- `get()` asserts the instance exists and returns a reference to it. +- Both functions panic on violation rather than returning an error code, because + incorrect call order is a programming error, not a recoverable runtime condition. + +```cpp +namespace +{ + auto constinit instance = std::optional<device_registry>{}; +} + +auto device_registry::init() -> void +{ + if (instance) + { + system::panic("[OS:DEV] Device registry has already been initialized."); + } + instance.emplace(); +} + +auto device_registry::get() -> device_registry & +{ + if (!instance) + { + system::panic("[OS:DEV] Device registry has not been initialized."); + } + return *instance; +} +``` + +--- + +## 9. Enumerations + +All enumerations use `enum struct` (scoped enums), never plain `enum`. Specify the +underlying type explicitly when the representation matters (e.g., for hardware +register fields). + +```cpp +// Correct +enum struct state +{ + uninitialized, + present, + bound, +}; + +// Wrong +enum state { uninitialized, present, bound }; +``` + +--- + +## 10. Naming + +| Symbol | Convention | Example | +|---|---|---| +| Types (struct, enum) | `lower_case` | `device_registry`, `facet_id` | +| Functions and methods | `lower_case` | `add_child`, `make_instance` | +| Local variables | `lower_case` | `entry`, `block_index` | +| Private data members | `m_` prefix, `lower_case` | `m_entries`, `m_driver_data` | +| Template type parameters | `CamelCase` | `ValueType`, `FacetType` | +| Constants and constexpr variables | `lower_case` | `page_size`, `direct_block_count` | +| Type aliases | `lower_case` | `value_type`, `size_type` | +| Namespaces | `lower_case` | `kapi::devices`, `kernel::vfs` | + +Namespaces reflect directory structure: `kernel::vfs`, `kernel::filesystems::ext2`, +`arch::devices`, etc. + +--- + +## 11. `[[nodiscard]]` + +Mark any function `[[nodiscard]]` whose return value the caller should not silently +discard. This includes in particular: + +- All functions returning `kstd::result<T>`. +- All query functions (getters, lookups) that return computed data. +- Factory functions and builder utilities. + +```cpp +[[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *; +[[nodiscard]] auto children() const -> kstd::vector<kstd::shared_ptr<device>>; +[[nodiscard]] auto request_resource(resource_type type, std::size_t index = 0) const -> kstd::result<resource>; +``` + +--- + +## 12. `constexpr` and `constinit` + +Mark functions `constexpr` whenever they can be evaluated at compile time or in +constant expressions, even if they are also called at runtime. Mark module-scope +variables `constinit` to guarantee zero-initialization before any dynamic +initialization runs — important in a kernel with no well-defined global +initialization order. + +--- + +## 13. Documentation + +Every non-trivial public type, function, and data member must be documented with a +Doxygen comment using the `//!` line style. + +```cpp +//! A brief one-line description. +//! +//! Optional longer description providing context. +//! +//! @param name Description of the parameter. +//! @return Description of the return value. +//! @warning Any important warnings or preconditions. +auto add_child(kstd::shared_ptr<device> child) -> void; +``` + +Doxygen grouping (`@addtogroup`, `@{`, `@}`) is used to organise the API surface into +logical sections visible in generated documentation. + +--- + +## 14. Header Guards + +All headers use traditional include guards, not `#pragma once`. The guard name follows +the pattern `TEACHOS_<SUBPACKAGE>_<PATH>_HPP`, where each path component is +uppercased and separators are replaced by `_`. + +```cpp +#ifndef TEACHOS_KAPI_DEVICES_BUS_HPP +#define TEACHOS_KAPI_DEVICES_BUS_HPP +// ... +#endif +``` + +The closing `#endif` carries no comment with the guard name. diff --git a/kernel/kapi/cpu.cpp b/kernel/kapi/cpu.cpp index 44331908..61f13edc 100644 --- a/kernel/kapi/cpu.cpp +++ b/kernel/kapi/cpu.cpp @@ -16,7 +16,7 @@ namespace kapi::cpu kstd::println(kstd::print_sink::stderr, "\tWrite: {}", context.is_write_access); kstd::println(kstd::print_sink::stderr, "\tUser: {}", context.is_user_mode); - kapi::system::panic("Halting the system due to an unrecoverable page fault."); + kapi::system::panic("[OS:CPU] Halting the system due to an unrecoverable page fault."); } } // namespace diff --git a/kernel/kapi/devices/driver_registry.cpp b/kernel/kapi/devices/driver_registry.cpp index 7abb121f..405596cd 100644 --- a/kernel/kapi/devices/driver_registry.cpp +++ b/kernel/kapi/devices/driver_registry.cpp @@ -38,7 +38,7 @@ namespace kapi::devices { if (registry.has_value()) { - system::panic("[kernel] Device driver registry has already been initialized."); + system::panic("[OS:DRV] Device driver registry has already been initialized."); } registry.emplace(); @@ -48,7 +48,7 @@ namespace kapi::devices { if (!registry) { - system::panic("[kernel] Device driver registry has not been initialized."); + system::panic("[OS:DRV] Device driver registry has not been initialized."); } return *registry; diff --git a/kernel/kapi/devices/facet_registry.cpp b/kernel/kapi/devices/facet_registry.cpp index b2d12c86..2974c71e 100644 --- a/kernel/kapi/devices/facet_registry.cpp +++ b/kernel/kapi/devices/facet_registry.cpp @@ -29,7 +29,7 @@ namespace kapi::devices { if (registry.has_value()) { - system::panic("[kernel] Device facet registry has already been initialized."); + system::panic("[OS:DEV] Device facet registry has already been initialized."); } registry.emplace(); @@ -39,7 +39,7 @@ namespace kapi::devices { if (!registry) { - system::panic("[kernel] Device facet registry has not been initialized."); + system::panic("[OS:DEV] Device facet registry has not been initialized."); } return *registry; diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index a0445645..1c6fa2c8 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -27,17 +27,17 @@ namespace kapi::memory auto allocate_many(std::size_t) noexcept -> std::optional<std::pair<frame, std::size_t>> override { - system::panic("Tried to allocate frames without an active allocator."); + system::panic("[OS:MEM] Tried to allocate frames without an active allocator."); } auto mark_used(frame) -> void override { - system::panic("Tried to mark frame as used without an active allocator."); + system::panic("[OS:MEM] Tried to mark frame as used without an active allocator."); } auto release_many(std::pair<frame, std::size_t>) -> void override { - system::panic("Tried to release frames without an active allocator."); + system::panic("[OS:MEM] Tried to release frames without an active allocator."); } }; @@ -47,12 +47,12 @@ namespace kapi::memory auto map(page, frame, flags) -> std::byte * override { - system::panic("Tried to map a page without an active mapper."); + system::panic("[OS:MEM] Tried to map a page without an active mapper."); } auto unmap(page) -> void override { - system::panic("Tried to unmap a page without an active mapper."); + system::panic("[OS:MEM] Tried to unmap a page without an active mapper."); } auto try_unmap(page) noexcept -> bool override diff --git a/kernel/kernel/filesystems/ext2/directory_iterator.cpp b/kernel/kernel/filesystems/ext2/directory_iterator.cpp index 2d5a2fe4..b1bb8b4f 100644 --- a/kernel/kernel/filesystems/ext2/directory_iterator.cpp +++ b/kernel/kernel/filesystems/ext2/directory_iterator.cpp @@ -26,7 +26,7 @@ namespace kernel::filesystems::ext2 { if (!inode.is_directory()) { - kapi::system::panic("[FS:ext2] Tried perform directory iteration on non-directory inode {}", inode.number()); + kapi::system::panic("[FS:EXT2] Tried perform directory iteration on non-directory inode {}", inode.number()); } if (m_file_offset >= data_size(*m_inode, *m_state)) @@ -84,7 +84,7 @@ namespace kernel::filesystems::ext2 { if (auto result = do_read(*m_inode, m_buffer, m_file_offset, *m_state); !result) { - kapi::system::panic("[FS:ext2] failed to read directory entry", result.error()); + kapi::system::panic("[FS:EXT2] failed to read directory entry", result.error()); } auto entry = reinterpret_cast<pointer>(m_buffer.data()); @@ -97,7 +97,7 @@ namespace kernel::filesystems::ext2 if (auto result = do_read(*m_inode, m_buffer, m_file_offset, *m_state); !result) { - kapi::system::panic("[FS:ext2] failed to read directory entry", result.error()); + kapi::system::panic("[FS:EXT2] failed to read directory entry", result.error()); } entry = reinterpret_cast<pointer>(m_buffer.data()); diff --git a/kernel/kernel/filesystems/ext2/filesystem.cpp b/kernel/kernel/filesystems/ext2/filesystem.cpp index 1785c0d7..eefd658c 100644 --- a/kernel/kernel/filesystems/ext2/filesystem.cpp +++ b/kernel/kernel/filesystems/ext2/filesystem.cpp @@ -166,7 +166,7 @@ namespace kernel::filesystems::ext2 case kapi::filesystem::file_type::socket: return constants::mode_socket; default: - kapi::system::panic("[EXT2] Not implemented."); + kapi::system::panic("[FS:EXT2] Not implemented."); } }(); } diff --git a/kernel/kernel/filesystems/ext2/inode.cpp b/kernel/kernel/filesystems/ext2/inode.cpp index 4abf8599..5bdd7871 100644 --- a/kernel/kernel/filesystems/ext2/inode.cpp +++ b/kernel/kernel/filesystems/ext2/inode.cpp @@ -93,7 +93,7 @@ namespace kernel::filesystems::ext2 { if (!is_regular()) { - kapi::system::panic("[EXT2] ext2::inode write called on inode that is not of type regular"); + kapi::system::panic("[FS:EXT2] ext2::inode write called on inode that is not of type regular"); } // TODO check maximum file size of filesystem diff --git a/kernel/kernel/filesystems/ext2/write_batch.cpp b/kernel/kernel/filesystems/ext2/write_batch.cpp index 0bec30f4..76865a47 100644 --- a/kernel/kernel/filesystems/ext2/write_batch.cpp +++ b/kernel/kernel/filesystems/ext2/write_batch.cpp @@ -25,7 +25,7 @@ namespace kernel::filesystems::ext2 if (!result) { - kapi::system::panic("[FS:ext2] failed to write block groups descriptor", result.error()); + kapi::system::panic("[FS:EXT2] failed to write block groups descriptor", result.error()); } }); @@ -34,7 +34,7 @@ namespace kernel::filesystems::ext2 auto result = ext2::write_superblock(m_state); if (!result) { - kapi::system::panic("[FS:ext2] failed to write superblock", result.error()); + kapi::system::panic("[FS:EXT2] failed to write superblock", result.error()); } } @@ -42,7 +42,7 @@ namespace kernel::filesystems::ext2 auto result = ext2::write_inode(inode->number(), inode->data(), m_state); if (!result) { - kapi::system::panic("[FS:ext2] failed to write inode", result.error()); + kapi::system::panic("[FS:EXT2] failed to write inode", result.error()); } }); } diff --git a/kernel/kernel/main.cpp b/kernel/kernel/main.cpp index f59b4ad7..ac2e18b8 100644 --- a/kernel/kernel/main.cpp +++ b/kernel/kernel/main.cpp @@ -32,7 +32,7 @@ auto run_demo() -> void auto fd_1 = kapi::filesystem::open("/entrance/tickets.txt"); if (!fd_1) { - kapi::system::panic("demo failed"); + kapi::system::panic("[demo failed]"); } else { diff --git a/kernel/kernel/memory/block_list_allocator.cpp b/kernel/kernel/memory/block_list_allocator.cpp index 993dd470..b5afd1d8 100644 --- a/kernel/kernel/memory/block_list_allocator.cpp +++ b/kernel/kernel/memory/block_list_allocator.cpp @@ -130,7 +130,7 @@ namespace kernel::memory auto frame = kapi::memory::allocate_frame(); if (!frame) { - kapi::system::panic("[OS:Heap] OOM when expanding heap."); + kapi::system::panic("[OS:MEM] OOM when expanding heap."); return false; } diff --git a/kernel/kernel/memory/operators.cpp b/kernel/kernel/memory/operators.cpp index 45ba5152..8c60bb63 100644 --- a/kernel/kernel/memory/operators.cpp +++ b/kernel/kernel/memory/operators.cpp @@ -20,7 +20,7 @@ if (pointer == nullptr) { - kapi::system::panic("[OS:Heap] Out of memory!"); + kapi::system::panic("[OS:MEM] Out of memory!"); } return pointer; diff --git a/kernel/kernel/vfs.cpp b/kernel/kernel/vfs.cpp index 42e98219..cbabda82 100644 --- a/kernel/kernel/vfs.cpp +++ b/kernel/kernel/vfs.cpp @@ -44,7 +44,7 @@ namespace kernel::vfs { if (active_vfs) { - kapi::system::panic("[FILESYSTEM] vfs has already been initialized."); + kapi::system::panic("[OS:VFS] vfs has already been initialized."); } active_vfs.emplace(); @@ -56,13 +56,13 @@ namespace kernel::vfs auto rootfs = driver_registry::get().find("rootfs"); if (!rootfs) { - kapi::system::panic("[OS:FS] rootfs driver is missing!"); + kapi::system::panic("[OS:VFS] rootfs driver is missing!"); } auto root_mount_result = (*rootfs)->mount(nullptr); if (!root_mount_result) { - kapi::system::panic("[FILESYSTEM] failed to mount root FS", root_mount_result.error()); + kapi::system::panic("[OS:VFS] failed to mount root FS", root_mount_result.error()); } auto [root_inode, root_state] = *root_mount_result; @@ -74,13 +74,13 @@ namespace kernel::vfs auto devfs = driver_registry::get().find("devfs"); if (!devfs) { - kapi::system::panic("[OS:FS] devfs driver is missing!"); + kapi::system::panic("[OS:VFS] devfs driver is missing!"); } auto device_fs_mount_result = (*devfs)->mount(nullptr); if (!device_fs_mount_result) { - kapi::system::panic("[FILESYSTEM] failed to mount device FS", device_fs_mount_result.error()); + kapi::system::panic("[OS:VFS] failed to mount device FS", device_fs_mount_result.error()); } auto [device_fs_root, device_fs_data] = *device_fs_mount_result; @@ -95,13 +95,13 @@ namespace kernel::vfs if (!root_devfs_mount) { - kapi::system::panic("[OS:FS] failed to mount initial devfs!", root_devfs_mount.error()); + kapi::system::panic("[OS:VFS] failed to mount initial devfs!", root_devfs_mount.error()); } auto resolved = resolve_path_internal("/dev/ram0"); if (!resolved) { - kapi::system::panic("[OS:FS] Failed to resolve boot disk!", resolved.error()); + kapi::system::panic("[OS:VFS] Failed to resolve boot disk!", resolved.error()); } auto [boot_device_dentry, boot_device_mount_context] = *resolved; @@ -109,14 +109,14 @@ namespace kernel::vfs auto driver = driver_registry::get().match(boot_device_dentry->inode()); if (!driver) { - kstd::println(kstd::print_sink::stderr, "[OS:FS] Missing driver for root disk!"); + kstd::println(kstd::print_sink::stderr, "[OS:VFS] Missing driver for root disk!"); return; } auto mount = mount::create(nullptr, *driver, nullptr, boot_device_mount_context, boot_device_dentry->inode()); if (!mount) { - kapi::system::panic("[OS:FS] failed to mount boot FS", mount.error()); + kapi::system::panic("[OS:VFS] failed to mount boot FS", mount.error()); } m_mount_table.add_mount(*mount); @@ -125,7 +125,7 @@ namespace kernel::vfs { if (auto result = mkdir("/dev"); !result) { - kapi::system::panic("[OS:FS] Failed to create devfs mount point!", result.error()); + kapi::system::panic("[OS:VFS] Failed to create devfs mount point!", result.error()); } real_dev_dentry = resolve_path("/dev"); } @@ -133,7 +133,7 @@ namespace kernel::vfs m_mount_table.move_mount(*root_devfs_mount, *real_dev_dentry, *mount); if (auto result = m_mount_table.remove_mount(root_mount); !result) { - kapi::system::panic("[OS:FS] Failed to unmount early rootfs!", result.error()); + kapi::system::panic("[OS:VFS] Failed to unmount early rootfs!", result.error()); } } @@ -141,7 +141,7 @@ namespace kernel::vfs { if (!active_vfs) { - kapi::system::panic("[FILESYSTEM] vfs has not been initialized."); + kapi::system::panic("[OS:VFS] vfs has not been initialized."); } return *active_vfs; @@ -343,7 +343,7 @@ namespace kernel::vfs auto current_mount = m_mount_table.find_mount("/"); if (!current_mount) { - kapi::system::panic("[FILESYSTEM] no root mount found."); + kapi::system::panic("[OS:VFS] no root mount found."); } auto current_dentry = current_mount->root_dentry(); @@ -410,7 +410,7 @@ namespace kernel::vfs current_mount = m_mount_table.find_mount(next_dentry->absolute_path()); if (!current_mount) { - kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found."); + kapi::system::panic("[OS:VFS] mount for dentry with mounted flag not found."); } next_dentry = current_mount->root_dentry(); diff --git a/kernel/kernel/vfs/dentry.cpp b/kernel/kernel/vfs/dentry.cpp index d9cb835a..092cab7c 100644 --- a/kernel/kernel/vfs/dentry.cpp +++ b/kernel/kernel/vfs/dentry.cpp @@ -22,11 +22,11 @@ namespace kernel::vfs { if (!m_inode) { - kapi::system::panic("[FILESYSTEM] dentry constructed with null inode."); + kapi::system::panic("[OS:VFS] dentry constructed with null inode."); } if (m_name.empty()) { - kapi::system::panic("[FILESYSTEM] dentry constructed with empty name."); + kapi::system::panic("[OS:VFS] dentry constructed with empty name."); } } diff --git a/kernel/kernel/vfs/device_inode.cpp b/kernel/kernel/vfs/device_inode.cpp index ebb39541..e9c70f15 100644 --- a/kernel/kernel/vfs/device_inode.cpp +++ b/kernel/kernel/vfs/device_inode.cpp @@ -25,7 +25,7 @@ namespace kernel::vfs { if (!device) { - kapi::system::panic("[FILESYSTEM] device_inode constructed with null device."); + kapi::system::panic("[OS:VFS] device_inode constructed with null device."); } } @@ -36,7 +36,7 @@ namespace kernel::vfs { if (!device) { - kapi::system::panic("[FILESYSTEM] device_inode constructed with null device."); + kapi::system::panic("[OS:VFS] device_inode constructed with null device."); } } diff --git a/kernel/kernel/vfs/driver_registry.cpp b/kernel/kernel/vfs/driver_registry.cpp index 16d048bf..736cfcbc 100644 --- a/kernel/kernel/vfs/driver_registry.cpp +++ b/kernel/kernel/vfs/driver_registry.cpp @@ -42,7 +42,7 @@ namespace kernel::vfs { if (instance) { - kapi::system::panic("[OS:FS] The filesystem driver registry was already initialized!"); + kapi::system::panic("[OS:VFS] The filesystem driver registry was already initialized!"); } instance.emplace(); @@ -55,7 +55,7 @@ namespace kernel::vfs std::ranges::for_each(instances, [](auto entry) { auto [descriptor, driver] = entry; - kstd::println("[OS:FS] Registering filesystem driver '{}'", descriptor->name()); + kstd::println("[OS:VFS] Registering filesystem driver '{}'", descriptor->name()); instance->add(descriptor->name(), driver); }); } @@ -64,7 +64,7 @@ namespace kernel::vfs { if (!instance) { - kapi::system::panic("[OS:FS] The filesystem driver registry has not been initialized!"); + kapi::system::panic("[OS:VFS] The filesystem driver registry has not been initialized!"); } return *instance; @@ -84,7 +84,7 @@ namespace kernel::vfs auto result = m_drivers.emplace(name, driver); if (!result.second) { - kstd::println(kstd::print_sink::stderr, "[OS:FS] Tried to register duplicate filesystem driver '{}'!", name); + kstd::println(kstd::print_sink::stderr, "[OS:VFS] Tried to register duplicate filesystem driver '{}'!", name); } return result.second; diff --git a/kernel/kernel/vfs/mount.cpp b/kernel/kernel/vfs/mount.cpp index 3f99f733..a48558f1 100644 --- a/kernel/kernel/vfs/mount.cpp +++ b/kernel/kernel/vfs/mount.cpp @@ -28,7 +28,7 @@ namespace kernel::vfs { if (!m_filesystem) { - kapi::system::panic("[FILESYSTEM] mount initialized with null filesystem."); + kapi::system::panic("[OS:VFS] mount initialized with null filesystem."); } } @@ -59,7 +59,7 @@ namespace kernel::vfs { if (!fs) { - kapi::system::panic("[OS:FS] Tried to mount a null filesystem!"); + kapi::system::panic("[OS:VFS] Tried to mount a null filesystem!"); } auto mount_result = fs->mount(backing_inode); @@ -123,7 +123,7 @@ namespace kernel::vfs { if (m_ref_count == 0) { - kapi::system::panic("[FILESYSTEM] decrement_ref_count() was called but ref_count is 0"); + kapi::system::panic("[OS:VFS] decrement_ref_count() was called but ref_count is 0"); } m_ref_count -= 1; diff --git a/kernel/kernel/vfs/open_file_descriptor.cpp b/kernel/kernel/vfs/open_file_descriptor.cpp index 4f0581d2..985aab50 100644 --- a/kernel/kernel/vfs/open_file_descriptor.cpp +++ b/kernel/kernel/vfs/open_file_descriptor.cpp @@ -4,9 +4,9 @@ #include <kernel/vfs/error.hpp> #include <kapi/filesystem.hpp> +#include <kapi/system.hpp> #include <kstd/memory.hpp> -#include <kstd/os/error.hpp> #include <kstd/result.hpp> #include <kstd/units.hpp> @@ -20,7 +20,7 @@ namespace kernel::vfs { if (!dentry) { - kstd::os::panic("[FILESYSTEM] open_file_descriptor constructed with null dentry."); + kapi::system::panic("[OS:VFS] open_file_descriptor constructed with null dentry."); } } diff --git a/kernel/kernel/vfs/open_file_table.cpp b/kernel/kernel/vfs/open_file_table.cpp index 108f4e11..c2f0465a 100644 --- a/kernel/kernel/vfs/open_file_table.cpp +++ b/kernel/kernel/vfs/open_file_table.cpp @@ -24,7 +24,7 @@ namespace kernel::vfs { if (global_open_file_table) { - kapi::system::panic("[FILESYSTEM] Open file table has already been initialized."); + kapi::system::panic("[OS:VFS] Open file table has already been initialized."); } global_open_file_table.emplace(open_file_table{}); @@ -34,7 +34,7 @@ namespace kernel::vfs { if (!global_open_file_table) { - kapi::system::panic("[FILESYSTEM] Open file table has not been initialized."); + kapi::system::panic("[OS:VFS] Open file table has not been initialized."); } return *global_open_file_table; diff --git a/libs/acpi/acpi/data/madt.hpp b/libs/acpi/acpi/data/madt.hpp index 2bff7470..4a929a42 100644 --- a/libs/acpi/acpi/data/madt.hpp +++ b/libs/acpi/acpi/data/madt.hpp @@ -61,7 +61,7 @@ namespace acpi { if (type() != EntryType::this_type) { - kstd::os::panic("Invalid cast"); + kstd::os::panic("[ACPI:DATA] Invalid cast"); } return reinterpret_cast<EntryType const &>(*this); } diff --git a/libs/kstd/kstd/bits/basic_string.hpp b/libs/kstd/kstd/bits/basic_string.hpp index a718bccc..1f8b60af 100644 --- a/libs/kstd/kstd/bits/basic_string.hpp +++ b/libs/kstd/kstd/bits/basic_string.hpp @@ -137,7 +137,7 @@ namespace kstd { if (!source && count) { - os::panic("Tried to construct string from null pointer!"); + os::panic("[KSTD:STR] Tried to construct string from null pointer!"); } if (count > capacity()) @@ -333,7 +333,7 @@ namespace kstd { if (string == nullptr) { - os::panic("Tried to construct string from null pointer!"); + os::panic("[KSTD:STR] Tried to construct string from null pointer!"); } auto incoming_length = traits_type::length(string); @@ -454,7 +454,7 @@ namespace kstd { if (position >= size()) { - os::panic("Invalid index in string element access"); + os::panic("[KSTD:STR] Invalid index in string element access"); } return m_data[position]; @@ -468,7 +468,7 @@ namespace kstd { if (position >= size()) { - os::panic("Invalid index in string element access"); + os::panic("[KSTD:STR] Invalid index in string element access"); } return m_data[position]; @@ -673,7 +673,7 @@ namespace kstd { if (new_capacity > max_size()) { - os::panic("Tried to allocate more memory than possible"); + os::panic("[KSTD:STR] Tried to allocate more memory than possible"); } if (new_capacity <= capacity()) @@ -733,7 +733,7 @@ namespace kstd { if (index > size()) { - os::panic("Index out of bounds while inserting into string"); + os::panic("[KSTD:STR] Index out of bounds while inserting into string"); } if (count == 0uz) @@ -770,7 +770,7 @@ namespace kstd { if (string == nullptr) { - os::panic("Tried to insert nullptr string"); + os::panic("[KSTD:STR] Tried to insert nullptr string"); } return do_insert(index, std::basic_string_view<value_type, traits_type>{string}); @@ -788,7 +788,7 @@ namespace kstd { if (range == nullptr) { - os::panic("Tried to insert nullptr range"); + os::panic("[KSTD:STR] Tried to insert nullptr range"); } return do_insert(index, std::basic_string_view<value_type, traits_type>{range, length}); @@ -880,7 +880,7 @@ namespace kstd { if (string == nullptr) { - os::panic("Attempted to append nullptr string"); + os::panic("[KSTD:STR] Attempted to append nullptr string"); } if (count == 0) @@ -1312,7 +1312,7 @@ namespace kstd { if (rhs == nullptr) { - os::panic("Tried to compare a string with nullptr"); + os::panic("[KSTD:STR] Tried to compare a string with nullptr"); } return lhs == std::basic_string_view<value_type, traits_type>{rhs}; @@ -1322,7 +1322,7 @@ namespace kstd { if (rhs == nullptr) { - os::panic("Tried to compare a string with nullptr"); + os::panic("[KSTD:STR] Tried to compare a string with nullptr"); } return std::basic_string_view<value_type, traits_type>{lhs} == rhs; @@ -1349,7 +1349,7 @@ namespace kstd { if (rhs == nullptr) { - os::panic("Tried to compare a string with nullptr"); + os::panic("[KSTD:STR] Tried to compare a string with nullptr"); } return lhs <=> std::basic_string_view<value_type, traits_type>{rhs}; @@ -1359,7 +1359,7 @@ namespace kstd { if (rhs == nullptr) { - os::panic("Tried to compare a string with nullptr"); + os::panic("[KSTD:STR] Tried to compare a string with nullptr"); } return std::basic_string_view<value_type, traits_type>{lhs} <=> rhs; @@ -1381,7 +1381,7 @@ namespace kstd { if (count > max_size()) { - os::panic("Tried to allocate more memory than possible"); + os::panic("[KSTD:STR] Tried to allocate more memory than possible"); } auto to_allocate = (exact ? count : std::min(std::max(count, 2 * capacity()), max_size())) + 1; @@ -1397,7 +1397,7 @@ namespace kstd { if (index > size()) { - os::panic("Index out of bounds while inserting into string"); + os::panic("[KSTD:STR] Index out of bounds while inserting into string"); } if (view.size() == 0uz) diff --git a/libs/kstd/kstd/bits/format/context.hpp b/libs/kstd/kstd/bits/format/context.hpp index d5f2f4d9..69766592 100644 --- a/libs/kstd/kstd/bits/format/context.hpp +++ b/libs/kstd/kstd/bits/format/context.hpp @@ -41,7 +41,7 @@ namespace kstd { if (id >= args.size()) { - kstd::os::panic("[kstd:format] argument index out of range!"); + kstd::os::panic("[KSTD:FMT] argument index out of range!"); } return args[id]; } diff --git a/libs/kstd/kstd/bits/format/error.hpp b/libs/kstd/kstd/bits/format/error.hpp index c0cb53d7..30cb7523 100644 --- a/libs/kstd/kstd/bits/format/error.hpp +++ b/libs/kstd/kstd/bits/format/error.hpp @@ -15,7 +15,7 @@ namespace kstd::bits::format } else { - kstd::os::panic("Error while formatting a string."); + kstd::os::panic("[KSTD:FMT] Error while formatting a string."); } } diff --git a/libs/kstd/kstd/bits/format/formatter/ordering.hpp b/libs/kstd/kstd/bits/format/formatter/ordering.hpp index 78322262..73d2cac6 100644 --- a/libs/kstd/kstd/bits/format/formatter/ordering.hpp +++ b/libs/kstd/kstd/bits/format/formatter/ordering.hpp @@ -40,7 +40,7 @@ namespace kstd { return context.push(specifiers.alternative_form ? "<" : "less"); } - kstd::os::panic("[kstd:format] Invalid strong ordering value!"); + kstd::os::panic("[KSTD:FMT] Invalid strong ordering value!"); } }; @@ -69,7 +69,7 @@ namespace kstd { return context.push(specifiers.alternative_form ? "<" : "less"); } - kstd::os::panic("[kstd:format] Invalid weak ordering value!"); + kstd::os::panic("[KSTD:FMT] Invalid weak ordering value!"); } }; @@ -102,7 +102,7 @@ namespace kstd { return context.push(specifiers.alternative_form ? "<=>" : "unordered"); } - kstd::os::panic("[kstd:format] Invalid partial ordering value!"); + kstd::os::panic("[KSTD:FMT] Invalid partial ordering value!"); } }; diff --git a/libs/kstd/kstd/bits/mutex/mutex.cpp b/libs/kstd/kstd/bits/mutex/mutex.cpp index f1f43141..6dabb5dd 100644 --- a/libs/kstd/kstd/bits/mutex/mutex.cpp +++ b/libs/kstd/kstd/bits/mutex/mutex.cpp @@ -13,7 +13,7 @@ namespace kstd { if (m_locked.test(std::memory_order_relaxed)) { - os::panic("[KSTD] Tried to destroy a locked mutex."); + os::panic("[KSTD:THR] Tried to destroy a locked mutex."); } } diff --git a/libs/kstd/kstd/bits/observer_ptr.hpp b/libs/kstd/kstd/bits/observer_ptr.hpp index e63e5d77..260d9d33 100644 --- a/libs/kstd/kstd/bits/observer_ptr.hpp +++ b/libs/kstd/kstd/bits/observer_ptr.hpp @@ -130,7 +130,7 @@ namespace kstd { if (m_ptr == nullptr) { - os::panic("[kstd:observer_ptr] Dereferencing a null observer pointer"); + os::panic("[KSTD:MEM] Dereferencing a null observer pointer"); } } diff --git a/libs/kstd/kstd/flat_map.hpp b/libs/kstd/kstd/flat_map.hpp index e140f7dd..c9a33b4a 100644 --- a/libs/kstd/kstd/flat_map.hpp +++ b/libs/kstd/kstd/flat_map.hpp @@ -112,7 +112,7 @@ namespace kstd { if (m_index >= m_containers->keys.size()) { - os::panic("[kstd::flat_map] Iterator out of range"); + os::panic("[KSTD:FLM] Iterator out of range"); } return {m_containers->keys[m_index], m_containers->values[m_index]}; } @@ -199,7 +199,7 @@ namespace kstd { if (it.m_index >= it.m_containers->keys.size()) { - os::panic("[kstd::flat_map] Iterator out of range"); + os::panic("[KSTD:FLM] Iterator out of range"); } return rvalue_reference{static_cast<rvalue_reference::first_type>(it.m_containers->keys[it.m_index]), @@ -470,7 +470,7 @@ namespace kstd { return found->second; } - os::panic("[kstd::flat_map] Key not found"); + os::panic("[KSTD:FLM] Key not found"); } //! Get a reference to the mapped value associated with the given key. @@ -487,7 +487,7 @@ namespace kstd { return found->second; } - os::panic("[kstd::flat_map] Key not found"); + os::panic("[KSTD:FLM] Key not found"); } //! Get a reference to the mapped value associated with the given key, or insert a default one if none exists. diff --git a/libs/kstd/kstd/libc/stdlib.cpp b/libs/kstd/kstd/libc/stdlib.cpp index 7ed051fa..098bcd25 100644 --- a/libs/kstd/kstd/libc/stdlib.cpp +++ b/libs/kstd/kstd/libc/stdlib.cpp @@ -12,7 +12,7 @@ namespace kstd::libc [[noreturn, gnu::weak]] auto free(void *) -> void { - kstd::os::panic("Tried to call free."); + kstd::os::panic("[KSTD:MEM] Tried to call free."); } } diff --git a/libs/kstd/kstd/vector.hpp b/libs/kstd/kstd/vector.hpp index 71c380fc..5a56381b 100644 --- a/libs/kstd/kstd/vector.hpp +++ b/libs/kstd/kstd/vector.hpp @@ -551,7 +551,7 @@ namespace kstd if (new_capacity > max_size()) { - kstd::os::panic("[kstd:vector] Tried to reserve more space than theoretically possible."); + kstd::os::panic("[KSTD:VEC] Tried to reserve more space than theoretically possible."); } reallocate_exactly(new_capacity); @@ -580,7 +580,7 @@ namespace kstd if (new_size > max_size()) { - kstd::os::panic("[kstd:vector] Tried to resize more space than theoretically possible."); + kstd::os::panic("[KSTD:VEC] Tried to resize more space than theoretically possible."); } if (new_size > capacity()) @@ -744,7 +744,7 @@ namespace kstd { if (position == end()) { - os::panic("[kstd:vector] Attempted to erase end()!"); + os::panic("[KSTD:VEC] Attempted to erase end()!"); } auto prefix_size = std::ranges::distance(cbegin(), position); @@ -959,7 +959,7 @@ namespace kstd { if (index >= m_size) { - os::panic("[kstd:vector] Attempted to read element at invalid index"); + os::panic("[KSTD:VEC] Attempted to read element at invalid index"); } } |
