summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--membuffer.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/membuffer.c b/membuffer.c
index a222af60b..9d3167293 100644
--- a/membuffer.c
+++ b/membuffer.c
@@ -76,20 +76,28 @@ void put_string(struct membuffer *b, const char *str)
void put_vformat(struct membuffer *b, const char *fmt, va_list args)
{
- /* Handle the common case on the stack */
- char buffer[128], *p;
- int len;
-
- len = vsnprintf(buffer, sizeof(buffer), fmt, args);
- if (len <= sizeof(buffer)) {
- put_bytes(b, buffer, len);
- return;
- }
+ int room = 128;
+
+ for (;;) {
+ int len;
+ va_list copy;
+ char *target;
+
+ make_room(b, room);
+ room = b->alloc - b->len;
+ target = b->buffer + b->len;
- p = malloc(len);
- len = vsnprintf(p, len, fmt, args);
- put_bytes(b, p, len);
- free(p);
+ va_copy(copy, args);
+ len = vsnprintf(target, room, fmt, copy);
+ va_end(copy);
+
+ if (len < room) {
+ b->len += len;
+ return;
+ }
+
+ room = len+1;
+ }
}
void put_format(struct membuffer *b, const char *fmt, ...)