diff options
-rw-r--r-- | build-aux/measurestack/app_main.py | 1 | ||||
-rw-r--r-- | build-aux/measurestack/app_plugins.py | 3 | ||||
-rw-r--r-- | build-aux/measurestack/test_app_plugins.py | 32 | ||||
-rw-r--r-- | libfmt/libmisc.c | 29 | ||||
-rw-r--r-- | libmisc/assert.c | 10 | ||||
-rw-r--r-- | libmisc/include/libmisc/_intercept.h | 7 | ||||
-rw-r--r-- | libmisc/intercept.c | 9 | ||||
-rw-r--r-- | libmisc/tests/test_assert.c | 70 |
8 files changed, 53 insertions, 108 deletions
diff --git a/build-aux/measurestack/app_main.py b/build-aux/measurestack/app_main.py index f933967..c5b5a79 100644 --- a/build-aux/measurestack/app_main.py +++ b/build-aux/measurestack/app_main.py @@ -89,7 +89,6 @@ def main( if name in [ QName("__assert_msg_fail"), QName("__lm_printf"), - QName("__lm_light_printf"), QName("fmt_vfctprintf"), QName("fmt_vsnprintf"), ]: diff --git a/build-aux/measurestack/app_plugins.py b/build-aux/measurestack/app_plugins.py index c6e4512..8009c0c 100644 --- a/build-aux/measurestack/app_plugins.py +++ b/build-aux/measurestack/app_plugins.py @@ -397,8 +397,6 @@ class PicoFmtPlugin: # pico_stdio BaseName("__wrap_vprintf"): BaseName("stdio_buffered_printer"), BaseName("stdio_vprintf"): BaseName("stdio_buffered_printer"), - # libfmt - BaseName("__lm_light_printf"): BaseName("libfmt_light_fct"), } ) case "host": @@ -406,7 +404,6 @@ class PicoFmtPlugin: { # libfmt BaseName("__lm_printf"): BaseName("libfmt_libc_fct"), - BaseName("__lm_light_printf"): BaseName("libfmt_libc_fct"), } ) self.wont_call_v = set([*self.known_fct.values(), *wont_call_v]) diff --git a/build-aux/measurestack/test_app_plugins.py b/build-aux/measurestack/test_app_plugins.py index 8a29a12..808d55a 100644 --- a/build-aux/measurestack/test_app_plugins.py +++ b/build-aux/measurestack/test_app_plugins.py @@ -12,11 +12,11 @@ from .analyze import BaseName, QName def test_fct() -> None: - # 1. | a + | b + | c + | - # 2. | fmt_vsnprintf + | vprintf + | __lm_light_printf + | - # 3. | fmt_vfctprintf + | fmt_vfctprintf + | fmt_vfctprintf + | - # 4. | fmt_state_putchar + | fmt_state_putchar + | fmt_state_putchar + | - # 5. | _out_buffer + | stdio_buffered_printer + | libfmt_light_fct + | + # 1. | a + | b + | + # 2. | fmt_vsnprintf + | vprintf + | + # 3. | fmt_vfctprintf + | fmt_vfctprintf + | + # 4. | fmt_state_putchar + | fmt_state_putchar + | + # 5. | _out_buffer + | stdio_buffered_printer + | max_call_depth = 5 exp_a = ["a", "fmt_vsnprintf", "fmt_vfctprintf", "fmt_state_putchar", "_out_buffer"] exp_b = [ @@ -26,32 +26,19 @@ def test_fct() -> None: "fmt_state_putchar", "stdio_buffered_printer", ] - exp_c = [ - "c", - "__lm_light_printf", - "fmt_vfctprintf", - "fmt_state_putchar", - "libfmt_light_fct", - ] graph: typing.Sequence[tuple[str, typing.Collection[str]]] = [ # main.c ("a", {"fmt_vsnprintf"}), # _out_buffer ("b", {"vprintf"}), # stdio_buffered_printer - ("c", {"__lm_light_printf"}), # libfmt_light_printf # wrappers ("fmt_vsnprintf", {"fmt_vfctprintf"}), ("__wrap_vprintf", {"fmt_vfctprintf"}), - ("__lm_light_printf", {"fmt_vfctprintf"}), # printf.c ("fmt_vfctprintf", {"fmt_state_putchar"}), - ( - "fmt_state_putchar", - {"_out_buffer", "stdio_buffered_printer", "libfmt_light_fct"}, - ), + ("fmt_state_putchar", {"_out_buffer", "stdio_buffered_printer"}), # fcts ("_out_buffer", {}), ("stdio_buffered_printer", {}), - ("libfmt_light_fct", {}), ] graph_plugin = testutil.GraphProviderPlugin(max_call_depth, graph) @@ -62,10 +49,8 @@ def test_fct() -> None: # if rp2040: # __wrap_vprintf => fct=stdio_buffered_printer # stdio_vprintf => fct=stdio_buffered_printer - # __lm_light_printf => fct=libfmt_light_fct # if host: # __lm_printf => fct=libfmt_libc_fct - # __lm_light_printf => fct=libfmt_libc_fct app_plugins.PicoFmtPlugin("rp2040", []), ] @@ -85,7 +70,6 @@ def test_fct() -> None: graph_plugin.assert_nstatic(result.groups["Main"].rows[QName("a")].nstatic, exp_a) graph_plugin.assert_nstatic(result.groups["Main"].rows[QName("b")].nstatic, exp_b) - graph_plugin.assert_nstatic(result.groups["Main"].rows[QName("c")].nstatic, exp_c) def test_assert_formatter() -> None: @@ -124,9 +108,9 @@ def test_assert_formatter() -> None: ("conv_builtin", {"fmt_state_putchar"}), ("libfmt_conv_formatter", {"lib9p_msg_Rread_format"}), ("lib9p_msg_Rread_format", {"fmt_state_putchar", "fmt_state_printf"}), - ("fmt_state_putchar", {"stdio_buffered_printer", "libfmt_light_fct"}), + ("fmt_state_putchar", {"stdio_buffered_printer", "_out_buffer"}), ("stdio_buffered_printer", {}), - ("libfmt_light_fct", {}), # wrong fct + ("_out_buffer", {}), # wrong fct ] # 1 2 3 4 5 6 7 8 9 10 11 <= call_depth diff --git a/libfmt/libmisc.c b/libfmt/libmisc.c index 04affb7..552b916 100644 --- a/libfmt/libmisc.c +++ b/libfmt/libmisc.c @@ -11,17 +11,11 @@ #endif #include <libmisc/macro.h> /* for LM_UNUSED() */ -#include <libmisc/_intercept.h> /* for __lm_printf() and __lm_light_printf() */ +#include <libmisc/_intercept.h> /* for __lm_printf() */ #include <libfmt/fmt.h> /* for fmt_vfctprintf() */ -#if LIB_PICO_STDIO -static void libfmt_light_fct(char character, void *LM_UNUSED(arg)) { - if (character == '\n') - stdio_putchar_raw('\r'); - stdio_putchar_raw(character); -} -#else +#if !LIB_PICO_STDIO static void libfmt_libc_fct(char character, void *LM_UNUSED(arg)) { putchar(character); } @@ -43,25 +37,6 @@ size_t __lm_printf(const char *format, ...) { return ret; } -size_t __lm_light_printf(const char *format, ...) { - va_list va; - va_start(va, format); -#if LIB_PICO_STDIO - /* libfmt_light_fct() and stdio_buffered_printer() both use 68 - * bytes of stack; but the buffer lives on the stack of - * stdio.c:__wrap_vprintf(); so that's where you'll see the - * numbers be different if you're analyzing it. (Also, being - * able to skip the stdio_stack_buffer_flush() call.) */ - size_t ret = (size_t) fmt_vfctprintf(libfmt_light_fct, NULL, format, va); - stdio_flush(); -#else - size_t ret = (size_t) fmt_vfctprintf(libfmt_libc_fct, NULL, format, va); - fflush(stdout); -#endif - va_end(va); - return ret; -} - static void libfmt_conv_formatter(struct fmt_state *state) { lo_interface fmt_formatter obj = va_arg(*state->args, lo_interface fmt_formatter); LO_CALL(obj, format, state); diff --git a/libmisc/assert.c b/libmisc/assert.c index 540d2fd..cb3a270 100644 --- a/libmisc/assert.c +++ b/libmisc/assert.c @@ -5,22 +5,20 @@ */ #define LOG_NAME ASSERT -#include <libmisc/log.h> /* for log_errorf() */ +#include <libmisc/log.h> /* for log_errorln() */ #include <libmisc/assert.h> #ifndef NDEBUG -#define __lm_printf __lm_light_printf void __assert_msg_fail(const char *expr, const char *file, unsigned int line, const char *func, const char *msg) { static bool in_fail = false; if (!in_fail) { in_fail = true; - log_errorf("%s:%u:%s(): assertion \"%s\" failed%s%s", - file, line, func, - expr, - msg ? ": " : "", msg ?: ""); + log_errorln(file, ":", line, ":", func, "(): ", + "assertion ", (qstr, expr), " failed", + msg ? ": " : "", msg ?: ""); in_fail = false; } __lm_abort(); diff --git a/libmisc/include/libmisc/_intercept.h b/libmisc/include/libmisc/_intercept.h index f9b7c8c..f02244a 100644 --- a/libmisc/include/libmisc/_intercept.h +++ b/libmisc/include/libmisc/_intercept.h @@ -21,13 +21,6 @@ size_t __lm_printf(const char *format, ...); [[noreturn]] void __lm_abort(void); -/* __lm_light_printf is expected to have less stack use than regular - * __lm_printf, if possible. - */ - -[[gnu::format(printf, 1, 2)]] -size_t __lm_light_printf(const char *format, ...); - /* While newlib defines putchar() to be [[gnu::weak]], pico_stdio does * not. Plus the above about optimizations. */ diff --git a/libmisc/intercept.c b/libmisc/intercept.c index af10ea3..70671f6 100644 --- a/libmisc/intercept.c +++ b/libmisc/intercept.c @@ -20,15 +20,6 @@ size_t __lm_printf(const char *format, ...) { } [[gnu::weak]] -size_t __lm_light_printf(const char *format, ...) { - va_list va; - va_start(va, format); - size_t ret = (size_t) vprintf(format, va); - va_end(va); - return ret; -} - -[[gnu::weak]] void __lm_putchar(unsigned char c) { (void) putchar(c); } diff --git a/libmisc/tests/test_assert.c b/libmisc/tests/test_assert.c index 131cd3a..cdbc567 100644 --- a/libmisc/tests/test_assert.c +++ b/libmisc/tests/test_assert.c @@ -9,23 +9,22 @@ #include <stdlib.h> #include <string.h> -#include <libmisc/macro.h> -#include <libmisc/assert.h> #include <libmisc/_intercept.h> +#include <libmisc/assert.h> +#include <libmisc/fmt.h> +#include <libmisc/macro.h> #include "test.h" /* Intercept failures and logging *********************************************/ -bool global_failed; -char *global_log; -jmp_buf global_env; +static bool global_failed; +static struct fmt_buf global_log; +static jmp_buf global_env; #define with_intercept() ({ \ global_failed = false; \ - if (global_log) \ - free(global_log); \ - global_log = NULL; \ + global_log_clear(); \ setjmp(global_env) == 0; \ }) @@ -34,12 +33,19 @@ void __lm_abort(void) { longjmp(global_env, 1); } -size_t __lm_light_printf(const char *format, ...) { - va_list va; - va_start(va, format); - size_t ret = (size_t) vasprintf(&global_log, format, va); - va_end(va); - return ret; +void __lm_putchar(unsigned char c) { + if (global_log.len+1 >= global_log.cap) { + global_log.cap += 16; + global_log.dat = realloc(global_log.dat, global_log.cap); + memset(global_log.dat + global_log.len, 0, global_log.cap - global_log.len); + } + ((uint8_t *)global_log.dat)[global_log.len++] = (uint8_t)c; +} + +static void global_log_clear(void) { + if (global_log.dat) + memset(global_log.dat, 0, global_log.cap); + global_log.len = 0; } #define __builtin_unreachable() test_assert(0) @@ -51,21 +57,21 @@ size_t __lm_light_printf(const char *format, ...) { test; \ } \ test_assert(global_failed == false); \ - test_assert(global_log == NULL); \ + test_assert(global_log.len == 0); \ } while (0) -#define test_should_fail(test, exp_log) do { \ - if (with_intercept()) { \ - test; \ - } \ - test_assert(global_failed == true); \ - if (!(global_log != NULL && \ - strcmp(global_log, exp_log) == 0)) { \ - printf("exp = \"%s\"\n" \ - "act = \"%s\"\n", \ - exp_log, global_log); \ - test_assert(0); \ - } \ +#define test_should_fail(test, exp_log) do { \ + if (with_intercept()) { \ + test; \ + } \ + test_assert(global_failed == true); \ + if (!(global_log.len != 0 && \ + strcmp(global_log.dat, exp_log) == 0)) { \ + printf("exp = \"%s\"\n" \ + "act = \"%s\"\n", \ + exp_log, (char *)global_log.dat); \ + test_assert(0); \ + } \ } while (0) /* Actual tests ***************************************************************/ @@ -83,11 +89,13 @@ int main() { test_should_fail(assert_msg(false, NULL), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"false\" failed\n"); test_should_fail(assert_notreached("xxx"), "error: ASSERT: "__FILE__":"LM_STR_(__LINE__)":main(): assertion \"notreached\" failed: xxx\n"); +#endif - if (global_log) { - free(global_log); - global_log = NULL; + if (global_log.dat) { + global_log_clear(); + free(global_log.dat); + global_log.dat = NULL; + global_log.cap = 0; } -#endif return 0; } |