tal/str: move tal string functions here from tal.
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 don't need anything internal to tal, they're just helpers.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ccan/tal/_info
ccan/tal/str/str.c
ccan/tal/str/str.h
ccan/tal/str/test/run-string.c [new file with mode: 0644]
ccan/tal/str/test/run-take.c [new file with mode: 0644]
ccan/tal/tal.c
ccan/tal/tal.h
ccan/tal/test/run-string.c [deleted file]
ccan/tal/test/run-take.c
ccan/tal/test/run-test-backend.c

index 3f7c22c717d93b0e69182c2a55de8db27ff85e82..853c69851ad5b9d7af8cdf3fd91d77304fc40248 100644 (file)
  * This allows you to build complex objects based on their lifetimes, eg:
  *
  *  struct foo *X = tal(NULL, struct foo);
- *  X->name = tal_strdup(X, "foo");
+ *  X->val = tal(X, int);
  *
- * and the pointer X->name would be a "child" of the tal context "X";
- * tal_free(X->name) would free X->name as expected, by tal_free(X) would
- * free X and X->name.
+ * and the pointer X->val would be a "child" of the tal context "X";
+ * tal_free(X->val) would free X->val as expected, by tal_free(X) would
+ * free X and X->val.
  *
  * With an overhead of approximately 4 pointers per object
  * (vs. talloc's 12 pointers), it uses dynamic allocation for
  * destructors and child lists, so those operations can fail.  It does
  * not support talloc's references or failing destructors.
  *
+ * See Also:
+ *     ccan/tal/str (useful string helpers)
+ *
  * Example:
  *     #include <stdio.h>
- *     #include <stdarg.h>
  *     #include <err.h>
  *     #include <ccan/talloc/talloc.h>
  *
  *     // A structure containing a popened command.
  *     struct command {
  *             FILE *f;
- *             const char *command;
+ *             char *command;
  *     };
  *
  *     // When struct command is freed, we also want to pclose pipe.
  *
  *     // This function opens a writable pipe to the given command.
  *     static struct command *open_output_cmd(const tal_t *ctx,
- *                                            const char *fmt, ...)
+ *                                            const char *a0, const char *a1)
  *     {
- *             va_list ap;
  *             struct command *cmd = tal(ctx, struct command);
  *
  *             if (!cmd)
  *                     return NULL;
  *
- *             va_start(ap, fmt);
- *             cmd->command = tal_vasprintf(cmd, fmt, ap);
- *             va_end(ap);
+ *             // Note that tal/str has helpers to make this much easier!
+ *             cmd->command = tal_arrz(cmd, char, strlen(a0) + strlen(a1) + 2);
  *             if (!cmd->command) {
  *                     tal_free(cmd);
  *                     return NULL;
  *             }
+ *             strcat(cmd->command, a0);
+ *             strcat(cmd->command, " ");
+ *             strcat(cmd->command, a1);
  *
  *             cmd->f = popen(cmd->command, "w");
  *             if (!cmd->f) {
@@ -75,7 +78,7 @@
  *             if (argc != 2)
  *                     errx(1, "Usage: %s <command>\n", argv[0]);
  *
- *             cmd = open_output_cmd(NULL, "%s hello", argv[1]);
+ *             cmd = open_output_cmd(NULL, argv[1], "hello");
  *             if (!cmd)
  *                     err(1, "Running '%s hello'", argv[1]);
  *             fprintf(cmd->f, "This is a test\n");
index cafb04bb50a7d2a78aea39113b1d32fec32334d8..b7df54c42af704eee6e1fbd9d941205ec54a2235 100644 (file)
@@ -9,10 +9,78 @@
 #include <regex.h>
 #include <stdarg.h>
 #include <unistd.h>
+#include <stdio.h>
 #include <ccan/str/str.h>
 #include <ccan/tal/tal.h>
 #include <ccan/take/take.h>
 
+char *tal_strdup(const tal_t *ctx, const char *p)
+{
+       /* We have to let through NULL for take(). */
+       return tal_dup_(ctx, p, 1, p ? strlen(p) + 1: 1, 0, false,
+                       TAL_LABEL(char, "[]"));
+}
+
+char *tal_strndup(const tal_t *ctx, const char *p, size_t n)
+{
+       size_t len;
+       char *ret;
+
+       /* We have to let through NULL for take(). */
+       if (likely(p)) {
+               len = strlen(p);
+               if (len > n)
+                       len = n;
+       } else
+               len = n;
+
+       ret = tal_dup_(ctx, p, 1, len, 1, false, TAL_LABEL(char, "[]"));
+       if (ret)
+               ret[len] = '\0';
+       return ret;
+}
+
+char *tal_asprintf(const tal_t *ctx, const char *fmt, ...)
+{
+       va_list ap;
+       char *ret;
+
+       va_start(ap, fmt);
+       ret = tal_vasprintf(ctx, fmt, ap);
+       va_end(ap);
+
+       return ret;
+}
+
+char *tal_vasprintf(const tal_t *ctx, 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) {
+               va_list ap2;
+
+               va_copy(ap2, ap);
+               ret = vsnprintf(buf, max, fmt, ap2);
+               va_end(ap2);
+
+               if (ret < max)
+                       break;
+               if (!tal_resize(&buf, max *= 2))
+                       buf = tal_free(buf);
+       }
+       if (taken(fmt))
+               tal_free(fmt);
+       return buf;
+}
+
 char **tal_strsplit(const tal_t *ctx,
                    const char *string, const char *delims, enum strsplit flags)
 {
index f30911e2df6f246cb39897fe11f00af0c61d0918..ab776e92c39d60fa3b0b239be9a51a253378b4c5 100644 (file)
@@ -6,6 +6,39 @@
 #include <string.h>
 #include <stdbool.h>
 
+/**
+ * tal_strdup - duplicate a string
+ * @ctx: NULL, or tal allocated object to be parent.
+ * @p: the string to copy (can be take()).
+ */
+char *tal_strdup(const tal_t *ctx, const char *p);
+
+/**
+ * tal_strndup - duplicate a limited amount of a string.
+ * @ctx: NULL, or tal allocated object to be parent.
+ * @p: the string to copy (can be take()).
+ * @n: the maximum length to copy.
+ *
+ * Always gives a nul-terminated string, with strlen() <= @n.
+ */
+char *tal_strndup(const tal_t *ctx, const char *p, size_t n);
+
+/**
+ * tal_asprintf - allocate a formatted string
+ * @ctx: NULL, or tal allocated object to be parent.
+ * @fmt: the printf-style format (can be take()).
+ */
+char *tal_asprintf(const tal_t *ctx, const char *fmt, ...) PRINTF_FMT(2,3);
+
+/**
+ * tal_vasprintf - allocate a formatted string (va_list version)
+ * @ctx: NULL, or tal allocated object to be parent.
+ * @fmt: the printf-style format (can be take()).
+ * @va: the va_list containing the format args.
+ */
+char *tal_vasprintf(const tal_t *ctx, const char *fmt, va_list ap)
+       PRINTF_FMT(2,0);
+
 enum strsplit {
        STR_EMPTY_OK,
        STR_NO_EMPTY
diff --git a/ccan/tal/str/test/run-string.c b/ccan/tal/str/test/run-string.c
new file mode 100644 (file)
index 0000000..4f8899d
--- /dev/null
@@ -0,0 +1,41 @@
+#include <ccan/tal/str/str.h>
+#include <ccan/tal/str/str.c>
+#include <ccan/tap/tap.h>
+
+int main(void)
+{
+       char *parent, *c;
+
+       plan_tests(13);
+
+       parent = tal(NULL, char);
+       ok1(parent);
+
+       c = tal_strdup(parent, "hello");
+       ok1(strcmp(c, "hello") == 0);
+       ok1(tal_parent(c) == parent);
+
+       c = tal_strndup(parent, "hello", 3);
+       ok1(strcmp(c, "hel") == 0);
+       ok1(tal_parent(c) == parent);
+
+       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);
+
+       /* Now with an extra byte. */
+       c = tal_dup(parent, char, "hello", 6, 1);
+       ok1(strcmp(c, "hello") == 0);
+       ok1(strcmp(tal_name(c), "char[]") == 0);
+       ok1(tal_parent(c) == parent);
+       strcat(c, "x");
+
+       c = tal_asprintf(parent, "hello %s", "there");
+       ok1(strcmp(c, "hello there") == 0);
+       ok1(tal_parent(c) == parent);
+       tal_free(parent);
+
+       return exit_status();
+}
diff --git a/ccan/tal/str/test/run-take.c b/ccan/tal/str/test/run-take.c
new file mode 100644 (file)
index 0000000..0cbab9e
--- /dev/null
@@ -0,0 +1,47 @@
+#include <ccan/tal/str/str.h>
+#include <ccan/tal/str/str.c>
+#include <ccan/tap/tap.h>
+
+int main(void)
+{
+       char *parent, *c;
+
+       plan_tests(14);
+
+       parent = tal(NULL, char);
+       ok1(parent);
+
+       c = tal_strdup(parent, "hello");
+
+       c = tal_strdup(parent, take(c));
+       ok1(strcmp(c, "hello") == 0);
+       ok1(tal_parent(c) == parent);
+
+       c = tal_strndup(parent, take(c), 5);
+       ok1(strcmp(c, "hello") == 0);
+       ok1(tal_parent(c) == parent);
+
+       c = tal_strndup(parent, take(c), 3);
+       ok1(strcmp(c, "hel") == 0);
+       ok1(tal_parent(c) == parent);
+       tal_free(c);
+
+       c = tal_strdup(parent, "hello %s");
+       c = tal_asprintf(parent, take(c), "there");
+       ok1(strcmp(c, "hello there") == 0);
+       ok1(tal_parent(c) == parent);
+       /* No leftover allocations. */
+       tal_free(c);
+       ok1(tal_first(parent) == NULL);
+
+       tal_free(parent);
+       ok1(!taken_any());
+
+       /* NULL pass-through. */
+       c = NULL;
+       ok1(tal_strdup(NULL, take(c)) == NULL);
+       ok1(tal_strndup(NULL, take(c), 5) == NULL);
+       ok1(tal_asprintf(NULL, take(c), 0) == NULL);
+
+       return exit_status();
+}
index c78185be01aa12715a0499088974ab8f561ccee6..4f7d56784dd9f2ffb46131f98b7f6288981d1c62 100644 (file)
@@ -5,7 +5,6 @@
 #include <ccan/take/take.h>
 #include <assert.h>
 #include <stdio.h>
-#include <stdarg.h>
 #include <stddef.h>
 #include <string.h>
 #include <limits.h>
@@ -713,32 +712,6 @@ bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
        return true;
 }
 
-char *tal_strdup(const tal_t *ctx, const char *p)
-{
-       /* We have to let through NULL for take(). */
-       return tal_dup_(ctx, p, 1, p ? strlen(p) + 1: 1, 0, false,
-                       TAL_LABEL(char, "[]"));
-}
-
-char *tal_strndup(const tal_t *ctx, const char *p, size_t n)
-{
-       size_t len;
-       char *ret;
-
-       /* We have to let through NULL for take(). */
-       if (likely(p)) {
-               len = strlen(p);
-               if (len > n)
-                       len = n;
-       } else
-               len = n;
-
-       ret = tal_dup_(ctx, p, 1, len, 1, false, TAL_LABEL(char, "[]"));
-       if (ret)
-               ret[len] = '\0';
-       return ret;
-}
-
 void *tal_dup_(const tal_t *ctx, const void *p, size_t size,
               size_t n, size_t extra, bool add_count,
               const char *label)
@@ -776,47 +749,6 @@ void *tal_dup_(const tal_t *ctx, const void *p, size_t size,
        return ret;
 }
 
-char *tal_asprintf(const tal_t *ctx, const char *fmt, ...)
-{
-       va_list ap;
-       char *ret;
-
-       va_start(ap, fmt);
-       ret = tal_vasprintf(ctx, fmt, ap);
-       va_end(ap);
-
-       return ret;
-}
-
-char *tal_vasprintf(const tal_t *ctx, 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) {
-               va_list ap2;
-
-               va_copy(ap2, ap);
-               ret = vsnprintf(buf, max, fmt, ap2);
-               va_end(ap2);
-
-               if (ret < max)
-                       break;
-               if (!tal_resize(&buf, max *= 2))
-                       buf = tal_free(buf);
-       }
-       if (taken(fmt))
-               tal_free(fmt);
-       return buf;
-}
-
 void tal_set_backend(void *(*alloc_fn)(size_t size),
                     void *(*resize_fn)(void *, size_t size),
                     void (*free_fn)(void *),
index efe21bc5eb1c619b1ad74c68b9505a2518279fd7..091eb034c1fbfb979f30f9021266c7c93278e695 100644 (file)
@@ -286,39 +286,6 @@ tal_t *tal_parent(const tal_t *ctx);
                          sizeof(type), (n), (extra),           \
                          true, TAL_LABEL(type, "[]")))
 
-/**
- * tal_strdup - duplicate a string
- * @ctx: NULL, or tal allocated object to be parent.
- * @p: the string to copy (can be take()).
- */
-char *tal_strdup(const tal_t *ctx, const char *p);
-
-/**
- * tal_strndup - duplicate a limited amount of a string.
- * @ctx: NULL, or tal allocated object to be parent.
- * @p: the string to copy (can be take()).
- * @n: the maximum length to copy.
- *
- * Always gives a nul-terminated string, with strlen() <= @n.
- */
-char *tal_strndup(const tal_t *ctx, const char *p, size_t n);
-
-/**
- * tal_asprintf - allocate a formatted string
- * @ctx: NULL, or tal allocated object to be parent.
- * @fmt: the printf-style format (can be take()).
- */
-char *tal_asprintf(const tal_t *ctx, const char *fmt, ...) PRINTF_FMT(2,3);
-
-/**
- * tal_vasprintf - allocate a formatted string (va_list version)
- * @ctx: NULL, or tal allocated object to be parent.
- * @fmt: the printf-style format (can be take()).
- * @va: the va_list containing the format args.
- */
-char *tal_vasprintf(const tal_t *ctx, const char *fmt, va_list ap)
-       PRINTF_FMT(2,0);
-
 
 /**
  * tal_set_backend - set the allocation or error functions to use
diff --git a/ccan/tal/test/run-string.c b/ccan/tal/test/run-string.c
deleted file mode 100644 (file)
index 0155ecb..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#include <ccan/tal/tal.h>
-#include <ccan/tal/tal.c>
-#include <ccan/tap/tap.h>
-
-int main(void)
-{
-       char *parent, *c;
-
-       plan_tests(13);
-
-       parent = tal(NULL, char);
-       ok1(parent);
-
-       c = tal_strdup(parent, "hello");
-       ok1(strcmp(c, "hello") == 0);
-       ok1(tal_parent(c) == parent);
-
-       c = tal_strndup(parent, "hello", 3);
-       ok1(strcmp(c, "hel") == 0);
-       ok1(tal_parent(c) == parent);
-
-       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);
-
-       /* Now with an extra byte. */
-       c = tal_dup(parent, char, "hello", 6, 1);
-       ok1(strcmp(c, "hello") == 0);
-       ok1(strcmp(tal_name(c), "char[]") == 0);
-       ok1(tal_parent(c) == parent);
-       strcat(c, "x");
-
-       c = tal_asprintf(parent, "hello %s", "there");
-       ok1(strcmp(c, "hello there") == 0);
-       ok1(tal_parent(c) == parent);
-       tal_free(parent);
-
-       return exit_status();
-}
index 9f0a22c6c4ea24bf6cae5b0701564573b7bdb347..72d2e8e3cabd2878377a4a03fbbef960777dd2eb 100644 (file)
@@ -6,7 +6,7 @@ int main(void)
 {
        char *parent, *c;
 
-       plan_tests(32);
+       plan_tests(21);
 
        /* We can take NULL. */
        ok1(take(NULL) == NULL);
@@ -24,20 +24,8 @@ int main(void)
        ok1(!is_taken(parent));
        ok1(!taken(parent));
 
-       c = tal_strdup(parent, "hello");
-
-       c = tal_strdup(parent, take(c));
-       ok1(strcmp(c, "hello") == 0);
-       ok1(tal_parent(c) == parent);
-
-       c = tal_strndup(parent, take(c), 5);
-       ok1(strcmp(c, "hello") == 0);
-       ok1(tal_parent(c) == parent);
-
-       c = tal_strndup(parent, take(c), 3);
-       ok1(strcmp(c, "hel") == 0);
-       ok1(tal_parent(c) == parent);
-
+       c = tal(parent, char);
+       *c = 'h';
        c = tal_dup(parent, char, take(c), 1, 0);
        ok1(c[0] == 'h');
        ok1(tal_parent(c) == parent);
@@ -56,23 +44,13 @@ int main(void)
        tal_free(c);
        ok1(tal_first(parent) == NULL);
 
-       c = tal_strdup(parent, "hello %s");
-       c = tal_asprintf(parent, take(c), "there");
-       ok1(strcmp(c, "hello there") == 0);
-       ok1(tal_parent(c) == parent);
-       /* No leftover allocations. */
-       tal_free(c);
-       ok1(tal_first(parent) == NULL);
-
        tal_free(parent);
        ok1(!taken_any());
 
        /* NULL pass-through. */
        c = NULL;
-       ok1(tal_strdup(NULL, take(c)) == NULL);
-       ok1(tal_strndup(NULL, take(c), 5) == NULL);
        ok1(tal_dup(NULL, char, take(c), 5, 5) == NULL);
-       ok1(tal_asprintf(NULL, take(c), 0) == NULL);
+       ok1(!taken_any());
 
        return exit_status();
 }
index 4663a5664a0bfedcb93cde5b8094791f2bf863f7..66144cb3a7356efdf99fba0524acc2cb0d8831ab 100644 (file)
@@ -53,7 +53,8 @@ int main(void)
        tal_add_destructor(p, destroy_p);
 
        tal_set_name(p, "test");
-       name = tal_asprintf(NULL, "test2");
+       name = tal_arr(NULL, char, 6);
+       strcpy(name, "test2");
        tal_set_name(p, name);
        /* makes us free old name */
        tal_set_name(p, name);