]> git.ozlabs.org Git - ccan/commitdiff
tal/str: add tal_append_fmt() and tal_append_vfmt() helpers.
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 3 Dec 2012 08:59:39 +0000 (19:29 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 3 Dec 2012 08:59:39 +0000 (19:29 +1030)
They are far too convenient, despite their inefficiency.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ccan/tal/str/str.c
ccan/tal/str/str.h
ccan/tal/str/test/run-string.c

index 771c07c24ee69ddd2bac49c408f62766768f4c67..15aa0c046883633d956eb8abbf50c48e9e362c5e 100644 (file)
@@ -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;
-       buf = tal_arr(ctx, char, max);
-       while (buf) {
+       size_t max = strlen(fmt) * 2;
+       bool ok;
+
+       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))
                tal_free(fmt);
        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;
 }
 
        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;
 char *tal_strcat(const tal_t *ctx, const char *s1, const char *s2)
 {
        size_t len1, len2;
index 4a6c474a4428a3e79998d1168b09e8c28d2f57a9..f2a694896c6aa89deed462278a70c7aa41307e32 100644 (file)
@@ -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)
        PRINTF_FMT(2,0);
 
 char *tal_vfmt(const tal_t *ctx, const char *fmt, va_list ap)
        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
  * @ctx: NULL, or tal allocated object to be parent.
 /**
  * tal_strcat - join two strings together
  * @ctx: NULL, or tal allocated object to be parent.
index bb614ae2fa070e09af6da909cc61b456ec2693c2..7bf31a6cf6bce7057423e9dff1d9c4e7941f4cc3 100644 (file)
@@ -6,7 +6,7 @@ int main(void)
 {
        char *parent, *c;
 
 {
        char *parent, *c;
 
-       plan_tests(27);
+       plan_tests(32);
 
        parent = tal(NULL, char);
        ok1(parent);
 
        parent = tal(NULL, char);
        ok1(parent);
@@ -70,6 +70,15 @@ int main(void)
        ok1(!c);
        ok1(!tal_first(parent));
 
        ok1(!c);
        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);
 
        return exit_status();
        tal_free(parent);
 
        return exit_status();