Commit e7ae27d6 authored by Rusty Russell's avatar Rusty Russell

tal/str: add tal_append_fmt() and tal_append_vfmt() helpers.

They are far too convenient, despite their inefficiency.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 4710a928
...@@ -52,35 +52,71 @@ char *tal_fmt(const tal_t *ctx, const char *fmt, ...) ...@@ -52,35 +52,71 @@ char *tal_fmt(const tal_t *ctx, const char *fmt, ...)
return ret; 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. */ /* A decent guess to start. */
max = strlen(fmt) * 2; size_t max = strlen(fmt) * 2;
buf = tal_arr(ctx, char, max); bool ok;
while (buf) {
for (;;) {
va_list ap2; va_list ap2;
int ret;
if (!tal_resize(buf, off + max)) {
ok = false;
break;
}
va_copy(ap2, ap); va_copy(ap2, ap);
ret = vsnprintf(buf, max, fmt, ap2); ret = vsnprintf(*buf + off, max, fmt, ap2);
va_end(ap2); va_end(ap2);
if (ret < max) if (ret < max) {
ok = true;
break; break;
if (!tal_resize(&buf, max *= 2))
buf = tal_free(buf);
} }
max *= 2;
}
if (taken(fmt)) if (taken(fmt))
tal_free(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; 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) char *tal_strcat(const tal_t *ctx, const char *s1, const char *s2)
{ {
size_t len1, len2; size_t len1, len2;
......
...@@ -39,6 +39,25 @@ char *tal_fmt(const tal_t *ctx, const char *fmt, ...) PRINTF_FMT(2,3); ...@@ -39,6 +39,25 @@ char *tal_fmt(const tal_t *ctx, const char *fmt, ...) PRINTF_FMT(2,3);
char *tal_vfmt(const tal_t *ctx, const char *fmt, va_list ap) char *tal_vfmt(const tal_t *ctx, const char *fmt, va_list ap)
PRINTF_FMT(2,0); PRINTF_FMT(2,0);
/**
* tal_append_fmt - append a formatted string to a talloc string.
* @baseptr: a pointer to the tal string to be appended to.
* @fmt: the printf-style format (can be take()).
*
* Returns false on allocation failure.
*/
bool tal_append_fmt(char **baseptr, const char *fmt, ...) PRINTF_FMT(2,3);
/**
* tal_append_vfmt - append a formatted string to a talloc string (va_list)
* @baseptr: a pointer to the tal string to be appended to.
* @fmt: the printf-style format (can be take()).
* @va: the va_list containing the format args.
*
* Returns false on allocation failure.
*/
bool tal_append_vfmt(char **baseptr, const char *fmt, va_list ap);
/** /**
* tal_strcat - join two strings together * tal_strcat - join two strings together
* @ctx: NULL, or tal allocated object to be parent. * @ctx: NULL, or tal allocated object to be parent.
......
...@@ -6,7 +6,7 @@ int main(void) ...@@ -6,7 +6,7 @@ int main(void)
{ {
char *parent, *c; char *parent, *c;
plan_tests(27); plan_tests(32);
parent = tal(NULL, char); parent = tal(NULL, char);
ok1(parent); ok1(parent);
...@@ -70,6 +70,15 @@ int main(void) ...@@ -70,6 +70,15 @@ int main(void)
ok1(!c); ok1(!c);
ok1(!tal_first(parent)); ok1(!tal_first(parent));
/* Appending formatted strings. */
c = tal_strdup(parent, "hi");
ok1(tal_append_fmt(&c, "%s %s", "there", "world"));
ok1(strcmp(c, "hithere world") == 0);
ok1(tal_parent(c) == parent);
ok1(!tal_append_fmt(&c, take(NULL), "there", "world"));
ok1(strcmp(c, "hithere world") == 0);
tal_free(parent); tal_free(parent);
return exit_status(); return exit_status();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment