diff options
-rw-r--r-- | membuffer.c | 34 |
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, ...) |