From cd5b35eae82614f232b58a80a561f02fb4a13f70 Mon Sep 17 00:00:00 2001 From: Brian Whitman Date: Mon, 13 Jul 2026 14:13:20 -0700 Subject: [PATCH] sprint_event: avoid %hu format for osc field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PRIu16 expands to "%hu", which MicroPython's internal printf (mp_vprintf, used when MICROPY_USE_INTERNAL_PRINTF=1 overrides snprintf) does not support: it hits assert(*fmt == '%' || !"unsupported fmt char") in py/mpprint.c and aborts on debug builds. This fires in any MicroPython port that links AMY and binds snprintf to the internal implementation (e.g. Tulip Linux desktop, or the AMYboard VCV Rack plugin build) whenever sprint_event runs — amy_dump_state(), update_sketch_knobs(), etc. Print the osc field with %u and an unsigned cast instead. Co-Authored-By: Claude Fable 5 --- src/patches.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/patches.c b/src/patches.c index 4dd35a6a..8c840ee4 100644 --- a/src/patches.c +++ b/src/patches.c @@ -264,11 +264,14 @@ int sprint_event(amy_event *e, char *s, size_t len, bool wirecode) { // Return is how many chrs written to s. Will abort if it overruns. char *s_entry = s; if (!wirecode) { - snprintf(s, len - (size_t)(s - s_entry), "amy_event(time=%" PRIu32 ", osc=%" PRIu16 "): ", e->time, e->osc); + // %u, not PRIu16: PRIu16 is "%hu", which MicroPython's internal printf + // (mp_vprintf) doesn't support — it asserts on the 'h' length modifier + // in ports that override snprintf (MICROPY_USE_INTERNAL_PRINTF). + snprintf(s, len - (size_t)(s - s_entry), "amy_event(time=%" PRIu32 ", osc=%u): ", e->time, (unsigned)e->osc); s += strlen(s); } else { if (AMY_IS_SET(e->time)) { snprintf(s, len - (size_t)(s - s_entry), "t%" PRIu32, (int32_t)e->time); s += strlen(s); } - if (AMY_IS_SET(e->osc)) { snprintf(s, len - (size_t)(s - s_entry), "v%" PRIu16, (int16_t)e->osc); s += strlen(s); } + if (AMY_IS_SET(e->osc)) { snprintf(s, len - (size_t)(s - s_entry), "v%u", (unsigned)e->osc); s += strlen(s); } } _EPRINT_I(wave, "wave", "w"); _EPRINT_I(preset, "preset", "p");