#pragma once #include "types.h" // A bounded string builder, because there is no snprintf in this kernel. // // These lived inside kernel/dev/procfs.c, where they were written, and were // static to it. The debugger's introspection registry needs the same thing -- // a subsystem rendering its own state into a caller's buffer, with no // allocation and no way to run off the end -- and the choice was to write a // second set or to move this one. See docs/plan/debugger.md, D2. // // Nothing here can overflow: every writer checks cap, and a full buffer // silently drops the rest. That is the right trade for something whose callers // are a /proc read and a crash-time dump; a builder that can fail is a builder // every caller has to check, and none of them would. struct sbuf { char *p; int len; int cap; }; void sb_putc(struct sbuf *sb, char c); void sb_puts(struct sbuf *sb, const char *s); // A string in a fixed-width column, space-padded. Over-long values run past // their column rather than being truncated: a misaligned row is easier to read // than a mangled name. void sb_pad(struct sbuf *sb, const char *s, int width); // Four lowercase hex digits, zero-padded. PCI and USB identifiers are always // written this way, and a lookup table keyed on "8086:100e" does not match // "8086:100E" or "8086:10e". void sb_puthex4(struct sbuf *sb, uint32 v); void sb_putu(struct sbuf *sb, uint64 v); // Zero-padded hex of a given width, for addresses. void sb_puthex(struct sbuf *sb, uint64 v, int digits); // A decimal number in a right-aligned column, so tables of sizes line up. void sb_putu_pad(struct sbuf *sb, uint64 v, int width); // "