tal/str: add tal_strcat().
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)
Useful for joining two strings.

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 b7df54c42af704eee6e1fbd9d941205ec54a2235..4606b47e3356955f7989389b9729db33c5b3b71f 100644 (file)
@@ -81,6 +81,31 @@ char *tal_vasprintf(const tal_t *ctx, const char *fmt, va_list ap)
        return buf;
 }
 
+char *tal_strcat(const tal_t *ctx, const char *s1, const char *s2)
+{
+       size_t len1, len2;
+       char *ret;
+
+       if (unlikely(!s2) && taken(s2)) {
+               if (taken(s1))
+                       tal_free(s1);
+               return NULL;
+       }
+       /* We have to let through NULL for take(). */
+       len1 = s1 ? strlen(s1) : 0;
+       len2 = strlen(s2);
+
+       /* We use tal_dup_ here to avoid attaching a length property. */
+       ret = tal_dup_(ctx, s1, 1, len1, len2 + 1, false,
+                      TAL_LABEL(char, "[]"));
+       if (likely(ret))
+               memcpy(ret + len1, s2, len2 + 1);
+
+       if (taken(s2))
+               tal_free(s2);
+       return ret;
+}
+
 char **tal_strsplit(const tal_t *ctx,
                    const char *string, const char *delims, enum strsplit flags)
 {
index ab776e92c39d60fa3b0b239be9a51a253378b4c5..4bb06b70c141ba47941a436fffe10cd53c7c6c82 100644 (file)
@@ -39,6 +39,14 @@ char *tal_asprintf(const tal_t *ctx, const char *fmt, ...) PRINTF_FMT(2,3);
 char *tal_vasprintf(const tal_t *ctx, const char *fmt, va_list ap)
        PRINTF_FMT(2,0);
 
+/**
+ * tal_strcat - join two strings together
+ * @ctx: NULL, or tal allocated object to be parent.
+ * @s1: the first string (can be take()).
+ * @s2: the second string (can be take()).
+ */
+char *tal_strcat(const tal_t *ctx, const char *s1, const char *s2);
+
 enum strsplit {
        STR_EMPTY_OK,
        STR_NO_EMPTY
index 4f8899de2acabe843ffe321fd06f4a34024d1858..5246a8aa0513e0f44c0d1f864be9d7fdf087444d 100644 (file)
@@ -6,7 +6,7 @@ int main(void)
 {
        char *parent, *c;
 
-       plan_tests(13);
+       plan_tests(27);
 
        parent = tal(NULL, char);
        ok1(parent);
@@ -14,16 +14,19 @@ int main(void)
        c = tal_strdup(parent, "hello");
        ok1(strcmp(c, "hello") == 0);
        ok1(tal_parent(c) == parent);
+       tal_free(c);
 
        c = tal_strndup(parent, "hello", 3);
        ok1(strcmp(c, "hel") == 0);
        ok1(tal_parent(c) == parent);
+       tal_free(c);
 
        c = tal_typechk_(parent, char *);
        c = tal_dup(parent, char, "hello", 6, 0);
        ok1(strcmp(c, "hello") == 0);
        ok1(strcmp(tal_name(c), "char[]") == 0);
        ok1(tal_parent(c) == parent);
+       tal_free(c);
 
        /* Now with an extra byte. */
        c = tal_dup(parent, char, "hello", 6, 1);
@@ -31,10 +34,42 @@ int main(void)
        ok1(strcmp(tal_name(c), "char[]") == 0);
        ok1(tal_parent(c) == parent);
        strcat(c, "x");
+       tal_free(c);
 
        c = tal_asprintf(parent, "hello %s", "there");
        ok1(strcmp(c, "hello there") == 0);
        ok1(tal_parent(c) == parent);
+       tal_free(c);
+
+       c = tal_strcat(parent, "hello ", "there");
+       ok1(strcmp(c, "hello there") == 0);
+       ok1(tal_parent(c) == parent);
+
+       /* Make sure take works correctly. */
+       c = tal_strcat(parent, take(c), " again");
+       ok1(strcmp(c, "hello there again") == 0);
+       ok1(tal_parent(c) == parent);
+       ok1(tal_first(parent) == c && !tal_next(parent, c));
+
+       c = tal_strcat(parent, "And ", take(c));
+       ok1(strcmp(c, "And hello there again") == 0);
+       ok1(tal_parent(c) == parent);
+       ok1(tal_first(parent) == c && !tal_next(parent, c));
+
+       /* NULL pass through works... */
+       c = tal_strcat(parent, take(NULL), take(c));
+       ok1(!c);
+       ok1(!tal_first(parent));
+
+       c = tal_strcat(parent, take(tal_strdup(parent, "hi")),
+                      take(NULL));
+       ok1(!c);
+       ok1(!tal_first(parent));
+
+       c = tal_strcat(parent, take(NULL), take(NULL));
+       ok1(!c);
+       ok1(!tal_first(parent));
+
        tal_free(parent);
 
        return exit_status();