]> git.ameliathe1st.gay Git - voyage-au-centre-des-fichiers.git/commitdiff
Added actual string formatting to the printing.
authorAmelia Coutard <eliottulio.coutard@gmail.com>
Sat, 15 Oct 2022 10:01:17 +0000 (12:01 +0200)
committerAmelia Coutard <eliottulio.coutard@gmail.com>
Sat, 15 Oct 2022 10:01:17 +0000 (12:01 +0200)
kernel/src/interrupts.cpp
kernel/src/kernel.cpp
kernel/src/paging.cpp
kernel/src/serial.cpp
kernel/src/serial.hpp

index c80d7d19d6dcd526b224202970ac689cafeaee3f..dac7e272c21bff56a53f5be47b808cd1882299b6 100644 (file)
@@ -71,7 +71,7 @@ extern "C" void int_device_not_available() {
 }
 extern "C" void int_double_fault(std::uint32_t err_code) {
        os::print("Interrupt: Double Fault.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_coprocessor_segment_overrun() {
@@ -80,27 +80,27 @@ extern "C" void int_coprocessor_segment_overrun() {
 }
 extern "C" void int_invalid_TSS(std::uint32_t err_code) {
        os::print("Interrupt: Invalid TSS.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_segment_not_present(std::uint32_t err_code) {
        os::print("Interrupt: Segment Not Present.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_stack_segment_fault(std::uint32_t err_code) {
        os::print("Interrupt: Stack-Segment Fault.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_general_protection_fault(std::uint32_t err_code) {
        os::print("Interrupt: General Protection Fault.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_page_fault(std::uint32_t err_code) {
        os::print("Interrupt: Page Fault.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_x87_floating_point_exception() {
@@ -109,7 +109,7 @@ extern "C" void int_x87_floating_point_exception() {
 }
 extern "C" void int_alignment_check(std::uint32_t err_code) {
        os::print("Interrupt: Alignment Check.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_machine_check() {
@@ -126,7 +126,7 @@ extern "C" void int_virtualization_exception() {
 }
 extern "C" void int_control_protection_exception(std::uint32_t err_code) {
        os::print("Interrupt: Control Protection Exception.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_hypervisor_injection_exception() {
@@ -135,12 +135,12 @@ extern "C" void int_hypervisor_injection_exception() {
 }
 extern "C" void int_VMM_communication_exception(std::uint32_t err_code) {
        os::print("Interrupt: VMM Communication Exception.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_security_exception(std::uint32_t err_code) {
        os::print("Interrupt: Security Exception.\n");
-       os::print("Err code: "); os::print(err_code); os::print(".\n");
+       os::print("Err code: {}.\n", err_code);
        while (true) { os::hlt(); }
 }
 extern "C" void int_default() {
index c48b654d5b8cad160eaf2c7893fc62556d861635..2fd9d35066bb6331ee9b7523c39865bdcfc07f7e 100644 (file)
@@ -50,12 +50,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
                                }
                                break;
                        case multiboot2::info::type_t::modules:
-                               os::print(multiboot2::modules_mod_start(it) / 0x1000 * 0x1000);
-                               os::print("->");
-                               os::print(multiboot2::modules_mod_end(it) / 0x1000 * 0x1000);
-                               os::print(": ");
-                               os::print(multiboot2::modules_string(it));
-                               os::printc('\n');
+                               os::print("{}->{}: {}\n", multiboot2::modules_mod_start(it) / 0x1000 * 0x1000, multiboot2::modules_mod_end(it) / 0x1000 * 0x1000, multiboot2::modules_string(it));
                                test_module.start_address = os::phys_ptr<os::paging::page>(multiboot2::modules_mod_start(it) / 0x1000 * 0x1000);
                                test_module.end_address   = os::phys_ptr<os::paging::page>(multiboot2::modules_mod_end(it)   / 0x1000 * 0x1000); // [s,e], not [s,e[
                                break;
@@ -192,12 +187,7 @@ extern "C" void kmain(unsigned long magic, os::phys_ptr<const multiboot2::info_s
                if (std::uint64_t(virt) >= 0xFFFF'8000'0000'0000) {
                        return;
                }
-               os::print(std::uint64_t(virt));
-               os::print("->");
-               os::print(std::uint64_t(phys.get_phys_addr()));
-               os::print(" (");
-               os::print(size);
-               os::print(")\n");
+               os::print("{}->{} ({})\n", std::uint64_t(virt), std::uint64_t(phys.get_phys_addr()), size);
        });
 
        // Allow userspaaaaaaaaace in ring 3. Otherwise, we just immediately page fault.
index 302a67577c4babe468842106a3c601120e22bf1d..1b92b5292793def7bf9c96ff818e70b8448fa6c6 100644 (file)
@@ -62,10 +62,7 @@ void os::paging::page_allocator_t::print_all() const {
        if (is_empty()) {
                os::print("No RAM left.\n");
        } else for (auto it = begin(); it != end(); it = it->next) {
-               os::print(it.get_phys_addr());
-               os::print("->");
-               os::print((it + it->size).get_phys_addr());
-               os::printc('\n');
+               os::print("{}->{}\n", it.get_phys_addr(), (it + it->size).get_phys_addr());
        }
 }
 
index faa41138e6fa926634906ad9b5943be954abf351..8486245fc19a93beb3920c61b4c539eb310b7a93 100644 (file)
@@ -39,40 +39,38 @@ void os::write_serial(std::uint8_t v) {
 void os::printc(char c) {
        write_serial(c);
 }
-void os::print(const char* format, const char* val) {
-       os::assert(format[0] == '\0', "Format string unsupported. TODO.");
+void os::print_formatted(const char* format, const char* val) {
+       os::assert(format[0] == '}', "Format string unsupported. TODO.");
        for (std::size_t i = 0; val[i] != '\0'; i++) {
                os::printc(val[i]);
        }
 }
-void os::print(const char* format, std::uint64_t val) {
-       os::assert(format[0] == '\0', "Format string unsupported. TODO.");
+void os::print_formatted(const char* format, std::uint64_t val) {
+       os::assert(format[0] == '}', "Format string unsupported. TODO.");
        for (int i = 60; i >= 0; i -= 4) {
                const int v = (val >> i) & 0xF;
                os::printc(v < 10 ? v + '0' : v - 10 + 'a');
        }
 }
-void os::print(const char* format, std::int64_t val) {
-       os::assert(format[0] == '\0', "Format string unsupported. TODO.");
+void os::print_formatted(const char* format, std::int64_t val) {
+       os::assert(format[0] == '}', "Format string unsupported. TODO.");
        if (val < 0) {
                os::printc('-');
-               os::print(format, std::uint64_t(-val));
+               os::print_formatted(format, std::uint64_t(-val));
        } else {
                os::printc(' ');
-               os::print(format, std::uint64_t(val));
+               os::print_formatted(format, std::uint64_t(val));
        }
 }
-void os::print(const char* format, std::uint32_t val) { os::print(format, std::uint64_t(val)); }
-void os::print(const char* format, std::uint16_t val) { os::print(format, std::uint64_t(val)); }
-void os::print(const char* format, std::uint8_t val) { os::print(format, std::uint64_t(val)); }
-void os::print(const char* format, std::int32_t val) { os::print(format, std::int64_t(val)); }
-void os::print(const char* format, std::int16_t val) { os::print(format, std::int64_t(val)); }
-void os::print(const char* format, std::int8_t val) { os::print(format, std::int64_t(val)); }
+void os::print_formatted(const char* format, std::uint32_t val) { os::print_formatted(format, std::uint64_t(val)); }
+void os::print_formatted(const char* format, std::uint16_t val) { os::print_formatted(format, std::uint64_t(val)); }
+void os::print_formatted(const char* format, std::uint8_t val) { os::print_formatted(format, std::uint64_t(val)); }
+void os::print_formatted(const char* format, std::int32_t val) { os::print_formatted(format, std::int64_t(val)); }
+void os::print_formatted(const char* format, std::int16_t val) { os::print_formatted(format, std::int64_t(val)); }
+void os::print_formatted(const char* format, std::int8_t val) { os::print_formatted(format, std::int64_t(val)); }
 void os::assert(bool cond, const char* diagnostic) {
        if (!cond) {
-               os::print("Error: ");
-               os::print(diagnostic);
-               os::printc('\n');
+               os::print("Error: {}\n", diagnostic);
                os::cli();
                while (true) { os::hlt(); }
        }
index db4f368826084347cf8b89b43891f9c118e2d965..0aa0f2bd32e456d69f5b7cf4065e8afbdc7b0fc9 100644 (file)
@@ -13,19 +13,77 @@ std::uint8_t read_serial();
 bool serial_transmit_empty();
 void write_serial(std::uint8_t v);
 
+void assert(bool cond, const char* diagnostic);
+
 void printc(char c);
-void print(const char* format, const char* val);
-void print(const char* format, std::uint64_t val);
-void print(const char* format, std::int64_t val);
-void print(const char* format, std::uint32_t val);
-void print(const char* format, std::int32_t val);
-void print(const char* format, std::uint16_t val);
-void print(const char* format, std::int16_t val);
-void print(const char* format, std::uint8_t val);
-void print(const char* format, std::int8_t val);
-template <typename T> void print(const T& val) {
-       print("", val);
+void print_formatted(const char* format, const char* val);
+void print_formatted(const char* format, std::uint64_t val);
+void print_formatted(const char* format, std::int64_t val);
+void print_formatted(const char* format, std::uint32_t val);
+void print_formatted(const char* format, std::int32_t val);
+void print_formatted(const char* format, std::uint16_t val);
+void print_formatted(const char* format, std::int16_t val);
+void print_formatted(const char* format, std::uint8_t val);
+void print_formatted(const char* format, std::int8_t val);
+
+struct print_nth_helper {
+       std::size_t n;
+       const char* format;
+
+       template <typename T> inline print_nth_helper operator%(const T& v) {
+               if (n == 0) {
+                       print_formatted(format, v);
+                       return print_nth_helper{std::size_t(-1), format};
+               } else {
+                       return print_nth_helper{n - 1, format};
+               }
+       }
+};
+
+template<typename... Ts>
+void print(const char* format, const Ts&... vs) {
+       std::size_t arg_n = 0;
+       for (std::size_t i = 0; format[i] != '\0'; i++) {
+               if (format[i] == '{') {
+                       i++;
+                       if (format[i] == '\0') {
+                               os::assert(false, "Error in format string: unterminated '{}'.");
+                       } else if (format[i] == '{') {
+                               printc('{');
+                               continue;
+                       } else {
+                               std::size_t format_spec_end = i;
+                               while (format[format_spec_end] != '}') {
+                                       if (format[format_spec_end++] == '\0') {
+                                               os::assert(false, "Error in format string: unterminated '{}'.");
+                                       }
+                               }
+                               std::size_t n = arg_n;
+                               if ('0' <= format[i] && format[i] <= '9') {
+                                       std::size_t n_ = 0;
+                                       while ('0' <= format[i] && format[i] <= '9') {
+                                               n_ = n_ * 10 + (format[i++] - '0');
+                                       }
+                                       n = n_;
+                               }
+                               if (format[i] == ':') {
+                                       i++;
+                               } else {
+                                       os::assert(format[i] == '}', "Error in format string: ':' required before format spec.");
+                               }
+                               os::assert(n < sizeof...(vs), "Error in format string: not enough arguments.");
+                               (print_nth_helper{n, &format[i]} % ... % vs);
+                               i = format_spec_end;
+                               arg_n++;
+                       }
+               } else if (format[i] == '}') {
+                       os::assert(format[i + 1] == '}', "Error in format strin: unexpected '}'.");
+                       i++;
+                       printc('}');
+               } else {
+                       printc(format[i]);
+               }
+       }
 }
-void assert(bool cond, const char* diagnostic);
 
 }