X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftal%2Fstr%2Fstr.c;h=15aa0c046883633d956eb8abbf50c48e9e362c5e;hp=4606b47e3356955f7989389b9729db33c5b3b71f;hb=e7ae27d64226dda9865f1e4b5d9a55adcee04694;hpb=a5ebf3146a57b7db05f6b6e2de0f2689a1b06751 diff --git a/ccan/tal/str/str.c b/ccan/tal/str/str.c index 4606b47e..15aa0c04 100644 --- a/ccan/tal/str/str.c +++ b/ccan/tal/str/str.c @@ -40,47 +40,83 @@ char *tal_strndup(const tal_t *ctx, const char *p, size_t n) return ret; } -char *tal_asprintf(const tal_t *ctx, const char *fmt, ...) +char *tal_fmt(const tal_t *ctx, const char *fmt, ...) { va_list ap; char *ret; va_start(ap, fmt); - ret = tal_vasprintf(ctx, fmt, ap); + ret = tal_vfmt(ctx, fmt, ap); va_end(ap); return ret; } -char *tal_vasprintf(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;