From de38eb6877e5f250ef8ea1801c44093392fda604 Mon Sep 17 00:00:00 2001 From: apio Date: Thu, 2 Mar 2023 13:38:21 +0100 Subject: [PATCH] luna: Remove pure_cstyle_format It was causing a lot of code duplication. If someone doesn't have errors, just return {} from the callback and unwrap the Result. --- kernel/src/Log.cpp | 10 +- kernel/src/arch/Serial.cpp | 10 +- libc/src/stdio.cpp | 20 ++- libluna/include/luna/Format.h | 4 - libluna/src/Format.cpp | 228 ++++------------------------------ 5 files changed, 57 insertions(+), 215 deletions(-) diff --git a/kernel/src/Log.cpp b/kernel/src/Log.cpp index 20ecc26a..e8c876c7 100644 --- a/kernel/src/Log.cpp +++ b/kernel/src/Log.cpp @@ -38,8 +38,14 @@ static void log_serial(LogLevel level, const char* format, va_list origin) Serial::printf("%4zu.%.3zu ", Timer::ticks(), Timer::ticks_ms() - (Timer::ticks() * 1000)); // NOTE: We do this manually because of a lack of vprintf() in both Serial and TextConsole. - pure_cstyle_format( - format, [](char c, void*) { Serial::putchar((u8)c); }, nullptr, ap); + cstyle_format( + format, + [](char c, void*) -> Result { + Serial::putchar((u8)c); + return {}; + }, + nullptr, ap) + .value(); Serial::putchar('\n'); diff --git a/kernel/src/arch/Serial.cpp b/kernel/src/arch/Serial.cpp index c21c88e8..a4f2eef0 100644 --- a/kernel/src/arch/Serial.cpp +++ b/kernel/src/arch/Serial.cpp @@ -25,8 +25,14 @@ namespace Serial { va_list ap; va_start(ap, format); - auto rc = pure_cstyle_format( - format, [](char c, void*) { putchar((u8)c); }, nullptr, ap); + auto rc = cstyle_format( + format, + [](char c, void*) -> Result { + putchar((u8)c); + return {}; + }, + nullptr, ap) + .value(); va_end(ap); return rc; } diff --git a/libc/src/stdio.cpp b/libc/src/stdio.cpp index 96f9422b..ec90cac1 100644 --- a/libc/src/stdio.cpp +++ b/libc/src/stdio.cpp @@ -55,8 +55,14 @@ extern "C" va_list ap; va_start(ap, format); - int rc = (int)pure_cstyle_format( - format, [](char c, void*) { console_write(&c, 1); }, nullptr, ap); + int rc = (int)cstyle_format( + format, + [](char c, void*) -> Result { + console_write(&c, 1); + return {}; + }, + nullptr, ap) + .value(); va_end(ap); @@ -82,7 +88,13 @@ extern "C" void debug_log_impl(const char* format, va_list ap) { - pure_cstyle_format( - format, [](char c, void*) { console_write(&c, 1); }, nullptr, ap); + cstyle_format( + format, + [](char c, void*) -> Result { + console_write(&c, 1); + return {}; + }, + nullptr, ap) + .value(); console_write("\n", 1); } diff --git a/libluna/include/luna/Format.h b/libluna/include/luna/Format.h index 7fe3bcdc..dcb39f66 100644 --- a/libluna/include/luna/Format.h +++ b/libluna/include/luna/Format.h @@ -4,14 +4,10 @@ #include typedef Result (*callback_t)(char, void*); -typedef void (*pure_callback_t)(char, void*); // Used to format anything that can fail (writing to C FILEs, etc...) Result cstyle_format(const char* format, callback_t callback, void* arg, va_list ap); -// Used to format anything that cannot fail (formatting to a string, writing to the serial port (kernel-only)) -usize pure_cstyle_format(const char* format, pure_callback_t callback, void* arg, va_list ap); - // Convenience function which outputs into a fixed-size buffer (not unlike vsnprintf) usize vstring_format(char* buf, usize max, const char* format, va_list ap); diff --git a/libluna/src/Format.cpp b/libluna/src/Format.cpp index cd756852..1a6cad2e 100644 --- a/libluna/src/Format.cpp +++ b/libluna/src/Format.cpp @@ -26,13 +26,6 @@ struct format_state void* arg; }; -struct pure_format_state -{ - usize count; - pure_callback_t callback; - void* arg; -}; - struct conv_state { flags_t flags; @@ -46,12 +39,6 @@ static Result format_putchar(char c, format_state& state) return state.callback(c, state.arg); } -static void pure_format_putchar(char c, pure_format_state& state) -{ - state.count++; - return state.callback(c, state.arg); -} - static Result format_puts(const char* s, format_state& state) { while (*s) @@ -63,15 +50,6 @@ static Result format_puts(const char* s, format_state& state) return {}; } -static void pure_format_puts(const char* s, pure_format_state& state) -{ - while (*s) - { - pure_format_putchar(*s, state); - s++; - } -} - static Result start_pad(const conv_state& vstate, format_state& state, usize start) { if (!(vstate.flags & FLAG_LEFT_ALIGN)) @@ -82,14 +60,6 @@ static Result start_pad(const conv_state& vstate, format_state& state, usi return {}; } -static void pure_start_pad(const conv_state& vstate, pure_format_state& state, usize start) -{ - if (!(vstate.flags & FLAG_LEFT_ALIGN)) - { - while (start++ < vstate.width) pure_format_putchar(' ', state); - } -} - static Result end_pad(const conv_state& vstate, format_state& state, usize start) { if (vstate.flags & FLAG_LEFT_ALIGN) @@ -100,14 +70,6 @@ static Result end_pad(const conv_state& vstate, format_state& state, usize return {}; } -static void pure_end_pad(const conv_state& vstate, pure_format_state& state, usize start) -{ - if (vstate.flags & FLAG_LEFT_ALIGN) - { - while (start++ < vstate.width) pure_format_putchar(' ', state); - } -} - static flags_t parse_flags(const char** format) { flags_t result = 0; @@ -254,21 +216,7 @@ static Result output_integer_data(const conv_state& vstate, format_state& return {}; } -static void output_pure_integer_data(const conv_state& vstate, pure_format_state& state, char* buf, usize len) -{ - if (!(vstate.flags & FLAG_ZERO_PAD)) pure_start_pad(vstate, state, len); - - usize i = len; - - while (i--) pure_format_putchar(buf[i], state); - - pure_end_pad(vstate, state, len); -} - -template -static ReturnType output_integer_generic(char specifier, conv_state& vstate, FormatStateType& state, usize value, - bool negative, - ReturnType (*output_data)(const conv_state&, FormatStateType&, char*, usize)) +static Result output_integer(char specifier, conv_state& vstate, format_state& state, usize value, bool negative) { usize base = 10; bool uppercase = false; @@ -325,27 +273,10 @@ static ReturnType output_integer_generic(char specifier, conv_state& vstate, For buf[buflen++] = ' '; } - return output_data(vstate, state, buf, buflen); + return output_integer_data(vstate, state, buf, buflen); } -static Result output_integer(char specifier, conv_state& vstate, format_state& state, usize value, bool negative) -{ - return output_integer_generic, format_state>(specifier, vstate, state, value, negative, - output_integer_data); -} - -static void pure_output_integer(char specifier, conv_state& vstate, pure_format_state& state, usize value, - bool negative) -{ - return output_integer_generic(specifier, vstate, state, value, negative, - output_pure_integer_data); -} - -template -static ReturnType va_generic_output_integer(char specifier, conv_state& vstate, FormatStateType& state, - ReturnType (*integer_output)(char, conv_state&, FormatStateType&, usize, - bool), - va_list ap) +static Result va_output_integer(char specifier, conv_state& vstate, format_state& state, va_list ap) { bool is_signed = false; bool negative = false; @@ -364,12 +295,12 @@ static ReturnType va_generic_output_integer(char specifier, conv_state& vstate, v = -v; negative = true; } - return integer_output(specifier, vstate, state, (unsigned char)v, negative); + return output_integer(specifier, vstate, state, (unsigned char)v, negative); } else { const unsigned char v = (unsigned char)va_arg(ap, unsigned int); - return integer_output(specifier, vstate, state, v, false); + return output_integer(specifier, vstate, state, v, false); } } else if (vstate.flags & FLAG_SHORT) @@ -382,12 +313,12 @@ static ReturnType va_generic_output_integer(char specifier, conv_state& vstate, v = -v; negative = true; } - return integer_output(specifier, vstate, state, (unsigned short)v, negative); + return output_integer(specifier, vstate, state, (unsigned short)v, negative); } else { const unsigned short v = (unsigned short)va_arg(ap, unsigned int); - return integer_output(specifier, vstate, state, v, false); + return output_integer(specifier, vstate, state, v, false); } } else if (vstate.flags & FLAG_LONG_LONG) @@ -400,12 +331,12 @@ static ReturnType va_generic_output_integer(char specifier, conv_state& vstate, v = -v; negative = true; } - return integer_output(specifier, vstate, state, (unsigned long long)v, negative); + return output_integer(specifier, vstate, state, (unsigned long long)v, negative); } else { const unsigned long long v = va_arg(ap, unsigned long long); - return integer_output(specifier, vstate, state, v, false); + return output_integer(specifier, vstate, state, v, false); } } else if (vstate.flags & FLAG_LONG) @@ -418,12 +349,12 @@ static ReturnType va_generic_output_integer(char specifier, conv_state& vstate, v = -v; negative = true; } - return integer_output(specifier, vstate, state, (unsigned long)v, negative); + return output_integer(specifier, vstate, state, (unsigned long)v, negative); } else { const unsigned long v = va_arg(ap, unsigned long); - return integer_output(specifier, vstate, state, v, false); + return output_integer(specifier, vstate, state, v, false); } } else @@ -436,26 +367,16 @@ static ReturnType va_generic_output_integer(char specifier, conv_state& vstate, v = -v; negative = true; } - return integer_output(specifier, vstate, state, (unsigned int)v, negative); + return output_integer(specifier, vstate, state, (unsigned int)v, negative); } else { const unsigned int v = va_arg(ap, unsigned int); - return integer_output(specifier, vstate, state, v, false); + return output_integer(specifier, vstate, state, v, false); } } } -static Result va_output_integer(char specifier, conv_state& vstate, format_state& state, va_list ap) -{ - return va_generic_output_integer, format_state>(specifier, vstate, state, output_integer, ap); -} - -static void va_pure_output_integer(char specifier, conv_state& vstate, pure_format_state& state, va_list ap) -{ - return va_generic_output_integer(specifier, vstate, state, pure_output_integer, ap); -} - Result cstyle_format(const char* format, callback_t callback, void* arg, va_list ap) { format_state state; @@ -557,106 +478,6 @@ Result cstyle_format(const char* format, callback_t callback, void* arg, return state.count; } -usize pure_cstyle_format(const char* format, pure_callback_t callback, void* arg, va_list ap) -{ - pure_format_state state; - state.callback = callback; - state.arg = arg; - state.count = 0; - - while (*format) - { - if (*format != '%') - { - pure_format_putchar(*format, state); - format++; - continue; - } - - format++; - - if (*format == '%') - { - pure_format_putchar('%', state); - continue; - } - - // %[flags][width][.precision][length]conversion - - flags_t flags = parse_flags(&format); - const usize width = parse_width(&format, flags, ap); - usize precision = parse_precision(&format, flags, ap); - parse_length(&format, flags); - - conv_state vstate = { flags, width, precision }; - - const char specifier = *format; - format++; - - if (is_integer_format_specifier(specifier)) - { - va_pure_output_integer(specifier, vstate, state, ap); - continue; - } - else if (specifier == 'p') - { - const void* ptr = va_arg(ap, void*); - if (ptr == nullptr) - { - pure_start_pad(vstate, state, 5); - pure_format_puts("(nil)", state); - pure_end_pad(vstate, state, 5); - continue; - } - vstate.width = (sizeof(void*) * 2) + 2; - vstate.flags |= (FLAG_ZERO_PAD | FLAG_ALTERNATE); - pure_output_integer('p', vstate, state, (usize)ptr, false); - continue; - } - else if (specifier == 'c') - { - const char c = (char)va_arg(ap, int); - - pure_start_pad(vstate, state, 1); - pure_format_putchar(c, state); - pure_end_pad(vstate, state, 1); - - continue; - } - else if (specifier == 's') - { - const char* str = va_arg(ap, const char*); - if (str == nullptr) - { - pure_start_pad(vstate, state, 6); - pure_format_puts("(null)", state); - pure_end_pad(vstate, state, 6); - continue; - } - else - { - usize len = strlen(str); - - bool use_precision = (flags & FLAG_USE_PRECISION); - if (use_precision && len > precision) len = precision; - - pure_start_pad(vstate, state, len); - while (*str && (!use_precision || precision)) - { - pure_format_putchar(*str, state); - precision--; - str++; - } - pure_end_pad(vstate, state, len); - continue; - } - } - else { continue; } - } - - return state.count; -} - struct StringFormatInfo { char* buffer; @@ -667,17 +488,18 @@ usize vstring_format(char* buf, usize max, const char* format, va_list ap) { StringFormatInfo info = { .buffer = buf, .remaining = max - 1 }; - usize result = pure_cstyle_format( - format, - [](char c, void* arg) { - StringFormatInfo* info_arg = (StringFormatInfo*)arg; - if (!info_arg->remaining) return; - *(info_arg->buffer) = c; - info_arg->buffer++; - info_arg->remaining--; - return; - }, - &info, ap); + usize result = cstyle_format( + format, + [](char c, void* arg) -> Result { + StringFormatInfo* info_arg = (StringFormatInfo*)arg; + if (!info_arg->remaining) return {}; + *(info_arg->buffer) = c; + info_arg->buffer++; + info_arg->remaining--; + return {}; + }, + &info, ap) + .value(); *(info.buffer) = 0;