summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2025-05-02 08:46:04 -0600
committerSimon Glass <sjg@chromium.org>2025-05-30 09:49:31 +0100
commit4f4b9477f4476cd86ffd4219111065d610c5237a (patch)
tree3daecd9ea2c917e972afba0969d30d79f0bbd35d /lib
parentd58cebbbc7617fbc45e604c883e8501a58d25e62 (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.c35
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 */