summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dstring.c24
-rw-r--r--dstring.h13
2 files changed, 28 insertions, 9 deletions
diff --git a/dstring.c b/dstring.c
index bfcf9bd..2ec0d72 100644
--- a/dstring.c
+++ b/dstring.c
@@ -129,6 +129,16 @@ int dstrapp(char **str, char c) {
}
char *dstrprintf(const char *format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ char *str = dstrvprintf(format, args);
+ va_end(args);
+
+ return str;
+}
+
+char *dstrvprintf(const char *format, va_list args) {
// Guess a length to try to avoid calling vsnprintf() twice
int len, cap = 2*strlen(format);
char *str = dstralloc(cap);
@@ -136,26 +146,22 @@ char *dstrprintf(const char *format, ...) {
return NULL;
}
- va_list args;
+ va_list args2;
+ va_copy(args2, args);
- va_start(args, format);
len = vsnprintf(str, cap + 1, format, args);
- va_end(args);
-
if (len > cap) {
if (dstreserve(&str, len) != 0) {
goto fail;
}
cap = len;
-
- va_start(args, format);
- len = vsnprintf(str, cap + 1, format, args);
- va_end(args);
-
+ len = vsnprintf(str, cap + 1, format, args2);
assert(len == cap);
}
+ va_end(args2);
+
if (len < 0) {
goto fail;
}
diff --git a/dstring.h b/dstring.h
index 19fd6d7..b556313 100644
--- a/dstring.h
+++ b/dstring.h
@@ -22,6 +22,7 @@
#define BFS_DSTRING_H
#include "util.h"
+#include <stdarg.h>
#include <stddef.h>
/**
@@ -130,6 +131,18 @@ BFS_FORMATTER(1, 2)
char *dstrprintf(const char *format, ...);
/**
+ * Create a dynamic string from a format string and a va_list.
+ *
+ * @param format
+ * The format string to fill in.
+ * @param args
+ * The arguments for the format string.
+ * @return
+ * The created string, or NULL on failure.
+ */
+char *dstrvprintf(const char *format, va_list args);
+
+/**
* Free a dynamic string.
*
* @param dstr