From 648bd3fb619b94887bc3487c28e98c5c6bf8d349 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 19 Nov 2022 16:13:25 +0100 Subject: [PATCH] Switch format.h to use Result --- kernel/src/arch/Serial.cpp | 10 ++--- kernel/src/arch/Serial.h | 6 ++- luna/Format.cpp | 80 ++++++++++++++++---------------------- luna/Format.h | 9 ++--- luna/FormatAttribute.h | 2 + 5 files changed, 49 insertions(+), 58 deletions(-) create mode 100644 luna/FormatAttribute.h diff --git a/kernel/src/arch/Serial.cpp b/kernel/src/arch/Serial.cpp index 07d9ce26..db860f2c 100644 --- a/kernel/src/arch/Serial.cpp +++ b/kernel/src/arch/Serial.cpp @@ -19,18 +19,18 @@ namespace Serial putchar('\n'); } - int printf(const char* format, ...) + Result printf(const char* format, ...) { va_list ap; va_start(ap, format); - isize rc = cstyle_format( + auto rc = cstyle_format( format, - [](char c, void*) -> int { + [](char c, void*) -> Result { putchar(c); - return 0; + return {}; }, nullptr, ap); va_end(ap); - return (int)rc; + return rc; } } \ No newline at end of file diff --git a/kernel/src/arch/Serial.h b/kernel/src/arch/Serial.h index 70553b25..61ca9000 100644 --- a/kernel/src/arch/Serial.h +++ b/kernel/src/arch/Serial.h @@ -1,12 +1,14 @@ #pragma once -#include +#include #include +template class Result; + namespace Serial { void putchar(u8 c); void write(const char* str, usize size); void print(const char* str); void println(const char* str); - int printf(const char* str, ...) _format(1, 2); + Result printf(const char* str, ...) _format(1, 2); } \ No newline at end of file diff --git a/luna/Format.cpp b/luna/Format.cpp index c16ff222..6a98be26 100644 --- a/luna/Format.cpp +++ b/luna/Format.cpp @@ -29,55 +29,43 @@ struct conv_state usize precision; }; -static inline int cstyle_format_putchar(char c, format_state& state) +static Result format_putchar(char c, format_state& state) { state.count++; return state.callback(c, state.arg); } -static inline int cstyle_format_puts(const char* s, format_state& state) +static Result format_puts(const char* s, format_state& state) { while (*s) { - if (cstyle_format_putchar(*s, state)) return -1; + TRY(format_putchar(*s, state)); s++; } - return 0; + return {}; } -#define TRY_PUTCHAR(c, state) \ - if (cstyle_format_putchar(c, state)) return -1; - -#define TRY_PUTS(s, state) \ - if (cstyle_format_puts(s, state)) return -1; - -static int start_pad(const conv_state& vstate, format_state& state, usize start) +static Result start_pad(const conv_state& vstate, format_state& state, usize start) { if (!(vstate.flags & FLAG_LEFT_ALIGN)) { - while (start++ < vstate.width) TRY_PUTCHAR(' ', state); + while (start++ < vstate.width) TRY(format_putchar(' ', state)); } - return 0; + return {}; } -#define TRY_START_PAD(vstate, state, start) \ - if (start_pad(vstate, state, start)) return -1; - -static int end_pad(const conv_state& vstate, format_state& state, usize start) +static Result end_pad(const conv_state& vstate, format_state& state, usize start) { if (vstate.flags & FLAG_LEFT_ALIGN) { - while (start++ < vstate.width) TRY_PUTCHAR(' ', state); + while (start++ < vstate.width) TRY(format_putchar(' ', state)); } - return 0; + return {}; } -#define TRY_END_PAD(vstate, state, start) \ - if (end_pad(vstate, state, start)) return -1; - static flags_t parse_flags(const char** format) { flags_t result = 0; @@ -210,7 +198,7 @@ static usize to_string(usize value, usize base, char* buf, usize max, bool upper return i; } -static int output_integer(char specifier, conv_state& vstate, format_state& state, usize value, bool negative) +static Result output_integer(char specifier, conv_state& vstate, format_state& state, usize value, bool negative) { usize base = 10; bool uppercase = false; @@ -267,18 +255,18 @@ static int output_integer(char specifier, conv_state& vstate, format_state& stat buf[buflen++] = ' '; } - if (!(vstate.flags & FLAG_ZERO_PAD)) TRY_START_PAD(vstate, state, buflen); + if (!(vstate.flags & FLAG_ZERO_PAD)) TRY(start_pad(vstate, state, buflen)); usize i = buflen; - while (i--) TRY_PUTCHAR(buf[i], state); + while (i--) TRY(format_putchar(buf[i], state)); - TRY_END_PAD(vstate, state, buflen); + TRY(end_pad(vstate, state, buflen)); - return 0; + return {}; } -static int va_output_integer(char specifier, conv_state& vstate, format_state& state, 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; @@ -379,7 +367,7 @@ static int va_output_integer(char specifier, conv_state& vstate, format_state& s } } -isize cstyle_format(const char* format, callback_t callback, void* arg, va_list ap) +Result cstyle_format(const char* format, callback_t callback, void* arg, va_list ap) { format_state state; state.callback = callback; @@ -390,7 +378,7 @@ isize cstyle_format(const char* format, callback_t callback, void* arg, va_list { if (*format != '%') { - TRY_PUTCHAR(*format, state); + TRY(format_putchar(*format, state)); format++; continue; } @@ -399,7 +387,7 @@ isize cstyle_format(const char* format, callback_t callback, void* arg, va_list if (*format == '%') { - TRY_PUTCHAR('%', state); + TRY(format_putchar('%', state)); continue; } @@ -417,7 +405,7 @@ isize cstyle_format(const char* format, callback_t callback, void* arg, va_list if (is_integer_format_specifier(specifier)) { - if (va_output_integer(specifier, vstate, state, ap)) return -1; + TRY(va_output_integer(specifier, vstate, state, ap)); continue; } else if (specifier == 'p') @@ -425,23 +413,23 @@ isize cstyle_format(const char* format, callback_t callback, void* arg, va_list void* ptr = va_arg(ap, void*); if (ptr == nullptr) { - TRY_START_PAD(vstate, state, 5); - TRY_PUTS("(nil)", state); - TRY_END_PAD(vstate, state, 5); + TRY(start_pad(vstate, state, 5)); + TRY(format_puts("(nil)", state)); + TRY(end_pad(vstate, state, 5)); continue; } vstate.width = (sizeof(void*) * 2) + 2; vstate.flags |= (FLAG_ZERO_PAD | FLAG_ALTERNATE); - if (output_integer('p', vstate, state, (usize)ptr, false)) return -1; + TRY(output_integer('p', vstate, state, (usize)ptr, false)); continue; } else if (specifier == 'c') { const char c = (char)va_arg(ap, int); - TRY_START_PAD(vstate, state, 1); - TRY_PUTCHAR(c, state); - TRY_END_PAD(vstate, state, 1); + TRY(start_pad(vstate, state, 1)); + TRY(format_putchar(c, state)); + TRY(end_pad(vstate, state, 1)); continue; } @@ -450,9 +438,9 @@ isize cstyle_format(const char* format, callback_t callback, void* arg, va_list const char* str = va_arg(ap, const char*); if (str == nullptr) { - TRY_START_PAD(vstate, state, 6); - TRY_PUTS("(null)", state); - TRY_END_PAD(vstate, state, 6); + TRY(start_pad(vstate, state, 6)); + TRY(format_puts("(null)", state)); + TRY(end_pad(vstate, state, 6)); continue; } else @@ -462,19 +450,19 @@ isize cstyle_format(const char* format, callback_t callback, void* arg, va_list bool use_precision = (flags & FLAG_USE_PRECISION); if (use_precision && len > precision) len = precision; - TRY_START_PAD(vstate, state, len); + TRY(start_pad(vstate, state, len)); while (*str && (!use_precision || precision)) { - TRY_PUTCHAR(*str, state); + TRY(format_putchar(*str, state)); precision--; str++; } - TRY_END_PAD(vstate, state, len); + TRY(end_pad(vstate, state, len)); continue; } } else { continue; } } - return (isize)state.count; + return state.count; } \ No newline at end of file diff --git a/luna/Format.h b/luna/Format.h index e908f76c..cb63c290 100644 --- a/luna/Format.h +++ b/luna/Format.h @@ -1,10 +1,9 @@ #pragma once #include -#include +#include +#include #include -#define _format(n, m) __attribute__((format(printf, n, m))) +typedef Result (*callback_t)(char, void*); -typedef int (*callback_t)(char, void*); - -isize cstyle_format(const char* format, callback_t callback, void* arg, va_list ap); \ No newline at end of file +Result cstyle_format(const char* format, callback_t callback, void* arg, va_list ap); \ No newline at end of file diff --git a/luna/FormatAttribute.h b/luna/FormatAttribute.h new file mode 100644 index 00000000..abed32dc --- /dev/null +++ b/luna/FormatAttribute.h @@ -0,0 +1,2 @@ +#pragma once +#define _format(n, m) __attribute__((format(printf, n, m))) \ No newline at end of file