summaryrefslogtreecommitdiff
path: root/libfmt
diff options
context:
space:
mode:
Diffstat (limited to 'libfmt')
-rw-r--r--libfmt/CMakeLists.txt14
-rw-r--r--libfmt/include/libfmt/fmt.h13
-rw-r--r--libfmt/libmisc.c59
3 files changed, 86 insertions, 0 deletions
diff --git a/libfmt/CMakeLists.txt b/libfmt/CMakeLists.txt
new file mode 100644
index 0000000..b8db764
--- /dev/null
+++ b/libfmt/CMakeLists.txt
@@ -0,0 +1,14 @@
+# libfmt/CMakeLists.txt - Support for pico-fmt
+#
+# Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+add_library(libfmt INTERFACE)
+target_include_directories(libfmt SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)
+target_sources(libfmt INTERFACE
+ libmisc.c
+)
+target_link_libraries(libfmt INTERFACE
+ pico_fmt
+ libmisc
+)
diff --git a/libfmt/include/libfmt/fmt.h b/libfmt/include/libfmt/fmt.h
new file mode 100644
index 0000000..3f2d4e7
--- /dev/null
+++ b/libfmt/include/libfmt/fmt.h
@@ -0,0 +1,13 @@
+/* libfmt/fmt.h - Support for pico-fmt
+ *
+ * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#ifndef _LIBFMT_FMT_H_
+#define _LIBFMT_FMT_H_
+
+#include <pico/fmt_printf.h>
+#include <pico/fmt_install.h>
+
+#endif /* _LIBFMT_FMT_H_ */
diff --git a/libfmt/libmisc.c b/libfmt/libmisc.c
new file mode 100644
index 0000000..4586c30
--- /dev/null
+++ b/libfmt/libmisc.c
@@ -0,0 +1,59 @@
+/* libfmt/libmisc.c - Integrate pico-fmt with libmisc
+ *
+ * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <stdarg.h> /* for va_list, va_start(), va_end() */
+#include <stdio.h> /* for vprintf(), putchar() */
+#if LIB_PICO_STDIO
+#include <pico/stdio.h> /* for stdio_putchar_raw() */
+#endif
+
+#include <libmisc/macro.h> /* for LM_UNUSED() */
+#include <libmisc/_intercept.h> /* for __lm_printf() and __lm_light_printf() */
+
+#include <libfmt/fmt.h> /* for fmt_vfctprintf() */
+
+#if LIB_PICO_STDIO
+static void libfmt_light_fct(char character, void *LM_UNUSED(arg)) {
+ stdio_putchar_raw(character);
+}
+#else
+static void libfmt_libc_fct(char character, void *LM_UNUSED(arg)) {
+ putchar(character);
+}
+#endif
+
+int __lm_printf(const char *format, ...) {
+ va_list va;
+ va_start(va, format);
+#if LIB_PICO_STDIO
+ /* pico_stdio has already intercepted vprintf for us, and
+ * their stdio_buffered_printer() is better than our
+ * libfmt_libc_fct() because buffering. */
+ int ret = vprintf(format, va);
+#else
+ int ret = fmt_vfctprintf(libfmt_libc_fct, NULL, format, va);
+#endif
+ va_end(va);
+ return ret;
+}
+
+int __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.) */
+ int ret = fmt_vfctprintf(libfmt_light_fct, NULL, format, va);
+ stdio_flush();
+#else
+ int ret = fmt_vfctprintf(libfmt_libc_fct, NULL, format, va);
+#endif
+ va_end(va);
+ return ret;
+}