diff options
Diffstat (limited to 'mem-pool.c')
-rw-r--r-- | mem-pool.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/mem-pool.c b/mem-pool.c index c7d6256020..a3ba38831d 100644 --- a/mem-pool.c +++ b/mem-pool.c @@ -4,6 +4,7 @@ #include "git-compat-util.h" #include "mem-pool.h" +#include "gettext.h" #define BLOCK_GROWTH_SIZE (1024 * 1024 - sizeof(struct mp_block)) @@ -107,6 +108,47 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len) return r; } +static char *mem_pool_strvfmt(struct mem_pool *pool, const char *fmt, + va_list ap) +{ + struct mp_block *block = pool->mp_block; + char *next_free = block ? block->next_free : NULL; + size_t available = block ? block->end - block->next_free : 0; + va_list cp; + int len, len2; + size_t size; + char *ret; + + va_copy(cp, ap); + len = vsnprintf(next_free, available, fmt, cp); + va_end(cp); + if (len < 0) + die(_("unable to format message: %s"), fmt); + + size = st_add(len, 1); /* 1 for NUL */ + ret = mem_pool_alloc(pool, size); + + /* Shortcut; relies on mem_pool_alloc() not touching buffer contents. */ + if (ret == next_free) + return ret; + + len2 = vsnprintf(ret, size, fmt, ap); + if (len2 != len) + BUG("your vsnprintf is broken (returns inconsistent lengths)"); + return ret; +} + +char *mem_pool_strfmt(struct mem_pool *pool, const char *fmt, ...) +{ + va_list ap; + char *ret; + + va_start(ap, fmt); + ret = mem_pool_strvfmt(pool, fmt, ap); + va_end(ap); + return ret; +} + void *mem_pool_calloc(struct mem_pool *pool, size_t count, size_t size) { size_t len = st_mult(count, size); |