story
struct strbuf { size_t cap, len; char *str; };
void sb_setf(struct allocator *a, struct strbuf *sb, const char *fmt, ...);
void sb_appendf(struct allocator *a, struct strbuf *sb, const char *fmt, ...);
// have other convenience functions for formatting fixed point values like "prefix AAA.BBB suffix" ("voltage: 7.23 V")
// special helpers for dates, times, etc.
Just keep building that library up and you'll have growable buffer, strings, lists, hashmap (uintptr -> uintptr is all you need in 99% of cases I've found, maybe some helper functions for string key -> void * built ontop of uintptr->uintptr) + replace/rewrite the standard library to operate on these types instead and you're good to go.