diff options
author | Simon Glass <sjg@chromium.org> | 2025-05-02 08:46:04 -0600 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2025-05-30 09:49:31 +0100 |
commit | 4f4b9477f4476cd86ffd4219111065d610c5237a (patch) | |
tree | 3daecd9ea2c917e972afba0969d30d79f0bbd35d /lib | |
parent | d58cebbbc7617fbc45e604c883e8501a58d25e62 (diff) |
abuf: Add a way to printf() into a buffer
It is useful to format a string into a buffer, with the sizing handled
automatically. Add a function for this.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/abuf.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/abuf.c b/lib/abuf.c index 28c748acb9f..3a2fd1782e9 100644 --- a/lib/abuf.c +++ b/lib/abuf.c @@ -10,8 +10,11 @@ #include <malloc.h> #include <mapmem.h> #include <string.h> +#include <vsprintf.h> #endif +#include <errno.h> +#include <stdarg.h> #include <abuf.h> void abuf_set(struct abuf *abuf, void *data, size_t size) @@ -142,6 +145,38 @@ bool abuf_copy(const struct abuf *old, struct abuf *copy) return true; } +int abuf_printf(struct abuf *buf, const char *fmt, ...) +{ + int maxlen = buf->size; + va_list args; + int len; + + va_start(args, fmt); + len = vsnprintf(buf->data, buf->size, fmt, args); + va_end(args); + + /* add the terminator */ + len++; + + if (len > 4096) + return -E2BIG; + if (len > maxlen) { + /* make more space and try again */ + maxlen = len; + if (!abuf_realloc(buf, maxlen)) + return -ENOMEM; + va_start(args, fmt); + len = vsnprintf(buf->data, maxlen, fmt, args); + va_end(args); + + /* check there isn't anything strange going on */ + if (len > maxlen) + return -EFAULT; + } + + return len; +} + void abuf_init_const(struct abuf *abuf, const void *data, size_t size) { /* for now there is no flag indicating that the abuf data is constant */ |