X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftal%2Fstr%2Fstr.c;h=15aa0c046883633d956eb8abbf50c48e9e362c5e;hp=771c07c24ee69ddd2bac49c408f62766768f4c67;hb=e7ae27d64226dda9865f1e4b5d9a55adcee04694;hpb=4710a92838fc03ffa54ce2bc60cf0e214c97a199 diff --git a/ccan/tal/str/str.c b/ccan/tal/str/str.c index 771c07c2..15aa0c04 100644 --- a/ccan/tal/str/str.c +++ b/ccan/tal/str/str.c @@ -52,35 +52,71 @@ char *tal_fmt(const tal_t *ctx, const char *fmt, ...) return ret; } -char *tal_vfmt(const tal_t *ctx, const char *fmt, va_list ap) +static bool do_vfmt(char **buf, size_t off, const char *fmt, va_list ap) { - size_t max; - char *buf; - int ret; - - if (!fmt && taken(fmt)) - return NULL; - /* A decent guess to start. */ - max = strlen(fmt) * 2; - buf = tal_arr(ctx, char, max); - while (buf) { + size_t max = strlen(fmt) * 2; + bool ok; + + for (;;) { va_list ap2; + int ret; + + if (!tal_resize(buf, off + max)) { + ok = false; + break; + } va_copy(ap2, ap); - ret = vsnprintf(buf, max, fmt, ap2); + ret = vsnprintf(*buf + off, max, fmt, ap2); va_end(ap2); - if (ret < max) + if (ret < max) { + ok = true; break; - if (!tal_resize(&buf, max *= 2)) - buf = tal_free(buf); + } + max *= 2; } + if (taken(fmt)) tal_free(fmt); + return ok; +} + +char *tal_vfmt(const tal_t *ctx, const char *fmt, va_list ap) +{ + char *buf; + + if (!fmt && taken(fmt)) + return NULL; + + /* A decent guess to start. */ + buf = tal_arr(ctx, char, strlen(fmt) * 2); + if (!do_vfmt(&buf, 0, fmt, ap)) + buf = tal_free(buf); return buf; } +bool tal_append_vfmt(char **baseptr, const char *fmt, va_list ap) +{ + if (!fmt && taken(fmt)) + return false; + + return do_vfmt(baseptr, strlen(*baseptr), fmt, ap); +} + +bool tal_append_fmt(char **baseptr, const char *fmt, ...) +{ + va_list ap; + bool ret; + + va_start(ap, fmt); + ret = tal_append_vfmt(baseptr, fmt, ap); + va_end(ap); + + return ret; +} + char *tal_strcat(const tal_t *ctx, const char *s1, const char *s2) { size_t len1, len2;