summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-05-14 12:20:02 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-05-15 14:51:15 -0600
commit67cec6d2770aa14a13c89247612f16c628ebd54c (patch)
tree0a64beaa2f57f5b6e4db5e2ea84811cb05406958
parentf01b89b599d40df5d6c127310b0030cd41c8dc85 (diff)
libmisc: Remove uses of printf
-rw-r--r--build-aux/measurestack/app_main.py1
-rw-r--r--build-aux/measurestack/app_plugins.py3
-rw-r--r--build-aux/measurestack/test_app_plugins.py32
-rw-r--r--libfmt/libmisc.c29
-rw-r--r--libmisc/assert.c10
-rw-r--r--libmisc/include/libmisc/_intercept.h7
-rw-r--r--libmisc/intercept.c9
-rw-r--r--libmisc/tests/test_assert.c70
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;
}